This is an automated email from the git hooks/post-receive script. rene pushed a commit to branch master in repository mdds.
commit b163deb6754f52541618eaa40d37daf19ea1c446 Author: Rene Engelhard <[email protected]> Date: Thu Apr 21 14:50:50 2016 +0200 Imported Upstream version 0.8.1 --- NEWS | 16 ++ configure | 394 +++++++++++++---------------- configure.ac | 2 +- include/mdds/multi_type_vector.hpp | 39 ++- include/mdds/multi_type_vector_def.inl | 422 ++++++++++++++++++++++++------- include/mdds/multi_type_vector_types.hpp | 6 +- src/multi_type_vector_test_default.cpp | 42 +++ 7 files changed, 609 insertions(+), 312 deletions(-) diff --git a/NEWS b/NEWS index 3863506..ca0d792 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,14 @@ +mdds 0.8.1 + +* multi_type_vector + + * fixed a bug in the erase() method where adjacent blocks of the + same type would fail to merge after the erase() call. + + * add a variant of the position() method that takes an iterator as + positional hint. Note that there is no variant of position() that + takes const_iterator. + mdds 0.8.0 * all @@ -28,6 +39,11 @@ mdds 0.8.0 * added two templates to ease creation of custom element block functions when using one or two custom element types. + * added transfer() member method to allow elements in a specified + range to be transferred from one container to another. When + transferring elements stored in a managed element block, the + ownership of those elements is also transferred. + mdds 0.7.1 * multi_type_vector diff --git a/configure b/configure index 97b90dd..47b463f 100755 --- a/configure +++ b/configure @@ -1,13 +1,11 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for mdds 0.8.0. +# Generated by GNU Autoconf 2.69 for mdds 0.8.1. # # Report bugs to <[email protected]>. # # -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software -# Foundation, Inc. +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation @@ -136,6 +134,31 @@ export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh @@ -169,7 +192,8 @@ if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi -test x\$exitcode = x0 || exit 1" +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && @@ -213,21 +237,25 @@ IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : - # We cannot yet assume a decent shell, so we have to provide a - # neutralization value for shells without unset; and this also - # works around shells that cannot unset nonexistent variables. - # Preserve -v and -x to the replacement shell. - BASH_ENV=/dev/null - ENV=/dev/null - (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV - export CONFIG_SHELL - case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; - esac - exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 fi if test x$as_have_required = xno; then : @@ -330,6 +358,14 @@ $as_echo X"$as_dir" | } # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take @@ -451,6 +487,10 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). @@ -485,16 +525,16 @@ if (echo >conf$$.file) 2>/dev/null; then # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. + # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' + as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null @@ -506,28 +546,8 @@ else as_mkdir_p=false fi -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in #( - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x +as_test_x='test -x' +as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -559,8 +579,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='mdds' PACKAGE_TARNAME='mdds' -PACKAGE_VERSION='0.8.0' -PACKAGE_STRING='mdds 0.8.0' +PACKAGE_VERSION='0.8.1' +PACKAGE_STRING='mdds 0.8.1' PACKAGE_BUGREPORT='[email protected]' PACKAGE_URL='' @@ -1075,8 +1095,6 @@ target=$target_alias if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe - $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. - If a cross compiler is detected then cross compile mode will be used" >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi @@ -1162,7 +1180,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures mdds 0.8.0 to adapt to many kinds of systems. +\`configure' configures mdds 0.8.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1223,7 +1241,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of mdds 0.8.0:";; + short | recursive ) echo "Configuration of mdds 0.8.1:";; esac cat <<\_ACEOF @@ -1307,10 +1325,10 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -mdds configure 0.8.0 -generated by GNU Autoconf 2.68 +mdds configure 0.8.1 +generated by GNU Autoconf 2.69 -Copyright (C) 2010 Free Software Foundation, Inc. +Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF @@ -1324,8 +1342,8 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by mdds $as_me 0.8.0, which was -generated by GNU Autoconf 2.68. Invocation command line was +It was created by mdds $as_me 0.8.1, which was +generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -1673,7 +1691,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu -VERSION=0.8.0 +VERSION=0.8.1 PACKAGE_TARNAME=mdds @@ -2160,16 +2178,16 @@ if (echo >conf$$.file) 2>/dev/null; then # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. + # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' + as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null @@ -2229,28 +2247,16 @@ else as_mkdir_p=false fi -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in #( - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -2271,8 +2277,8 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by mdds $as_me 0.8.0, which was -generated by GNU Autoconf 2.68. Invocation command line was +This file was extended by mdds $as_me 0.8.1, which was +generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -2324,11 +2330,11 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -mdds config.status 0.8.0 -configured by $0, generated by GNU Autoconf 2.68, +mdds config.status 0.8.1 +configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" -Copyright (C) 2010 Free Software Foundation, Inc. +Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." @@ -2405,7 +2411,7 @@ fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then - set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' @@ -3329,16 +3335,16 @@ if (echo >conf$$.file) 2>/dev/null; then # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. + # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' + as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null @@ -3398,28 +3404,16 @@ else as_mkdir_p=false fi -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in #( - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -3440,8 +3434,8 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by mdds $as_me 0.8.0, which was -generated by GNU Autoconf 2.68. Invocation command line was +This file was extended by mdds $as_me 0.8.1, which was +generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -3493,11 +3487,11 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -mdds config.status 0.8.0 -configured by $0, generated by GNU Autoconf 2.68, +mdds config.status 0.8.1 +configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" -Copyright (C) 2010 Free Software Foundation, Inc. +Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." @@ -3574,7 +3568,7 @@ fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then - set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' @@ -4499,16 +4493,16 @@ if (echo >conf$$.file) 2>/dev/null; then # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. + # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' + as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null @@ -4568,28 +4562,16 @@ else as_mkdir_p=false fi -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in #( - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -4610,8 +4592,8 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by mdds $as_me 0.8.0, which was -generated by GNU Autoconf 2.68. Invocation command line was +This file was extended by mdds $as_me 0.8.1, which was +generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -4663,11 +4645,11 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -mdds config.status 0.8.0 -configured by $0, generated by GNU Autoconf 2.68, +mdds config.status 0.8.1 +configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" -Copyright (C) 2010 Free Software Foundation, Inc. +Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." @@ -4744,7 +4726,7 @@ fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then - set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' @@ -5670,16 +5652,16 @@ if (echo >conf$$.file) 2>/dev/null; then # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. + # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' + as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null @@ -5739,28 +5721,16 @@ else as_mkdir_p=false fi -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in #( - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -5781,8 +5751,8 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by mdds $as_me 0.8.0, which was -generated by GNU Autoconf 2.68. Invocation command line was +This file was extended by mdds $as_me 0.8.1, which was +generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -5834,11 +5804,11 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -mdds config.status 0.8.0 -configured by $0, generated by GNU Autoconf 2.68, +mdds config.status 0.8.1 +configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" -Copyright (C) 2010 Free Software Foundation, Inc. +Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." @@ -5915,7 +5885,7 @@ fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then - set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' @@ -6842,16 +6812,16 @@ if (echo >conf$$.file) 2>/dev/null; then # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. + # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' + as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null @@ -6911,28 +6881,16 @@ else as_mkdir_p=false fi -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in #( - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -6953,8 +6911,8 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by mdds $as_me 0.8.0, which was -generated by GNU Autoconf 2.68. Invocation command line was +This file was extended by mdds $as_me 0.8.1, which was +generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -7006,11 +6964,11 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -mdds config.status 0.8.0 -configured by $0, generated by GNU Autoconf 2.68, +mdds config.status 0.8.1 +configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" -Copyright (C) 2010 Free Software Foundation, Inc. +Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." @@ -7087,7 +7045,7 @@ fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then - set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' diff --git a/configure.ac b/configure.ac index 0458f69..31d1e3a 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT(mdds, 0.8.0, [email protected]) +AC_INIT(mdds, 0.8.1, [email protected]) VERSION=AC_PACKAGE_VERSION AC_SUBST(VERSION) diff --git a/include/mdds/multi_type_vector.hpp b/include/mdds/multi_type_vector.hpp index cefb8c4..22c0438 100644 --- a/include/mdds/multi_type_vector.hpp +++ b/include/mdds/multi_type_vector.hpp @@ -25,8 +25,8 @@ * ************************************************************************/ -#ifndef __MDDS_MULTI_TYPE_VECTOR_HPP__ -#define __MDDS_MULTI_TYPE_VECTOR_HPP__ +#ifndef MDDS_MULTI_TYPE_VECTOR_HPP +#define MDDS_MULTI_TYPE_VECTOR_HPP #include "default_deleter.hpp" #include "compat/unique_ptr.hpp" @@ -38,6 +38,14 @@ #include <algorithm> #include <cassert> +#if defined(MDDS_UNIT_TEST) || defined (MDDS_MULTI_TYPE_VECTOR_DEBUG) +#include <sstream> +#include <iostream> +using std::cout; +using std::cerr; +using std::endl; +#endif + namespace mdds { /** @@ -386,7 +394,7 @@ public: * <p>The method will throw an <code>std::out_of_range</code> exception if * the specified position is outside the current container range.</p> * - * @param pos position of the element. + * @param pos logical position of the element. * @return iterator referencing the block where the element resides, and * its offset within the block. */ @@ -400,6 +408,23 @@ public: * <p>The method will throw an <code>std::out_of_range</code> exception if * the specified position is outside the current container range.</p> * + * @param pos_hint iterator used as a block position hint, to specify + * which block to start when searching for the element + * position. + * @param pos logical position of the element. + * @return iterator referencing the block where the element resides, and + * its offset within the block. + */ + std::pair<iterator, size_type> position(const iterator& pos_hint, size_type pos); + + /** + * Given the logical position of an element, get the iterator of the block + * where the element is located, and its offset from the first element of + * that block. + * + * <p>The method will throw an <code>std::out_of_range</code> exception if + * the specified position is outside the current container range.</p> + * * @param pos position of the element. * @return iterator referencing the block where the element resides, and * its offset within the block. @@ -661,8 +686,10 @@ public: template<typename _T> static mtv::element_t get_element_type(const _T& elem); -#ifdef MDDS_UNIT_TEST - void dump_blocks() const; +#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG + void dump_blocks(std::ostream& os) const; + + bool check_block_integrity() const; #endif private: @@ -745,6 +772,8 @@ private: size_type block_index2, size_type start_pos_in_block2, bool overwrite); void erase_impl(size_type start_pos, size_type end_pos); + void erase_in_single_block( + size_type start_pos, size_type end_pos, size_type block_pos, size_type start_pos_in_block); iterator insert_empty_impl(size_type row, size_type start_pos, size_type block_index, size_type length); diff --git a/include/mdds/multi_type_vector_def.inl b/include/mdds/multi_type_vector_def.inl index 2299a7b..f3074af 100644 --- a/include/mdds/multi_type_vector_def.inl +++ b/include/mdds/multi_type_vector_def.inl @@ -29,12 +29,6 @@ #include <stdexcept> -#ifdef MDDS_UNIT_TEST -#include <iostream> -using std::cout; -using std::endl; -#endif - namespace mdds { MDDS_MTV_DEFINE_ELEMENT_CALLBACKS(double, mtv::element_type_numeric, 0.0, mtv::numeric_element_block) @@ -185,7 +179,24 @@ multi_type_vector<_CellBlockFunc>::set(size_type pos, const _T& value) if (!get_block_position(pos, start_row, block_index)) throw std::out_of_range("Block position not found!"); - return set_impl(pos, start_row, block_index, value); +#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG + std::ostringstream os_prev_block; + dump_blocks(os_prev_block); +#endif + + iterator ret = set_impl(pos, start_row, block_index, value); + +#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG + if (!check_block_integrity()) + { + cerr << "block integrity check failed in set (" << pos << ")" << endl; + cerr << "previous block state:" << endl; + cerr << os_prev_block.str(); + abort(); + } +#endif + + return ret; } template<typename _CellBlockFunc> @@ -196,7 +207,25 @@ multi_type_vector<_CellBlockFunc>::set(const iterator& pos_hint, size_type pos, size_type start_row = 0; size_type block_index = 0; get_block_position(pos_hint, pos, start_row, block_index); - return set_impl(pos, start_row, block_index, value); + +#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG + std::ostringstream os_prev_block; + dump_blocks(os_prev_block); +#endif + + iterator ret = set_impl(pos, start_row, block_index, value); + +#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG + if (!check_block_integrity()) + { + cerr << "block integrity check failed in set (" << pos << ")" << endl; + cerr << "previous block state:" << endl; + cerr << os_prev_block.str(); + abort(); + } +#endif + + return ret; } template<typename _CellBlockFunc> @@ -400,7 +429,24 @@ multi_type_vector<_CellBlockFunc>::insert(size_type pos, const _T& it_begin, con if (!get_block_position(pos, start_pos, block_index)) throw std::out_of_range("Block position not found!"); - return insert_cells_impl(pos, start_pos, block_index, it_begin, it_end); +#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG + std::ostringstream os_prev_block; + dump_blocks(os_prev_block); +#endif + + iterator ret = insert_cells_impl(pos, start_pos, block_index, it_begin, it_end); + +#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG + if (!check_block_integrity()) + { + cerr << "block integrity check failed in insert (" << pos << ")" << endl; + cerr << "previous block state:" << endl; + cerr << os_prev_block.str(); + abort(); + } +#endif + + return ret; } template<typename _CellBlockFunc> @@ -411,7 +457,24 @@ multi_type_vector<_CellBlockFunc>::insert(const iterator& pos_hint, size_type po size_type block_index = 0, start_pos = 0; get_block_position(pos_hint, pos, start_pos, block_index); - return insert_cells_impl(pos, start_pos, block_index, it_begin, it_end); +#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG + std::ostringstream os_prev_block; + dump_blocks(os_prev_block); +#endif + + iterator ret = insert_cells_impl(pos, start_pos, block_index, it_begin, it_end); + +#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG + if (!check_block_integrity()) + { + cerr << "block integrity check failed in insert (" << pos << ")" << endl; + cerr << "previous block state:" << endl; + cerr << os_prev_block.str(); + abort(); + } +#endif + + return ret; } template<typename _CellBlockFunc> @@ -1094,13 +1157,27 @@ multi_type_vector<_CellBlockFunc>::position(size_type pos) { typedef std::pair<iterator, size_type> ret_type; - size_type start_row = 0; + size_type start_pos = 0; size_type block_index = 0; - if (!get_block_position(pos, start_row, block_index)) + if (!get_block_position(pos, start_pos, block_index)) throw std::out_of_range("Block position not found!"); - iterator it = get_iterator(block_index, start_row); - return ret_type(it, pos - start_row); + iterator it = get_iterator(block_index, start_pos); + return ret_type(it, pos - start_pos); +} + +template<typename _CellBlockFunc> +std::pair<typename multi_type_vector<_CellBlockFunc>::iterator, typename multi_type_vector<_CellBlockFunc>::size_type> +multi_type_vector<_CellBlockFunc>::position(const iterator& pos_hint, size_type pos) +{ + typedef std::pair<iterator, size_type> ret_type; + + size_type start_pos = 0; + size_type block_index = 0; + get_block_position(pos_hint, pos, start_pos, block_index); + + iterator it = get_iterator(block_index, start_pos); + return ret_type(it, pos - start_pos); } template<typename _CellBlockFunc> @@ -1133,7 +1210,28 @@ multi_type_vector<_CellBlockFunc>::transfer( if (!get_block_position(start_pos, start_pos_in_block1, block_index1)) throw std::out_of_range("Block position not found!"); - return transfer_impl(start_pos, end_pos, start_pos_in_block1, block_index1, dest, dest_pos); +#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG + std::ostringstream os_prev_block; + os_prev_block << "source:" << endl; + dump_blocks(os_prev_block); + os_prev_block << "destination:" << endl; + dest.dump_blocks(os_prev_block); +#endif + + iterator ret = transfer_impl(start_pos, end_pos, start_pos_in_block1, block_index1, dest, dest_pos); + +#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG + if (!check_block_integrity() || !dest.check_block_integrity()) + { + cerr << "block integrity check failed in transfer (start_pos=" << start_pos + << ",end_pos=" << end_pos << ",dest_pos=" << dest_pos << ")" << endl; + cerr << "previous block state:" << endl; + cerr << os_prev_block.str(); + abort(); + } +#endif + + return ret; } template<typename _CellBlockFunc> @@ -1145,7 +1243,29 @@ multi_type_vector<_CellBlockFunc>::transfer( size_type start_pos_in_block1 = 0; size_type block_index1 = 0; get_block_position(pos_hint, start_pos, start_pos_in_block1, block_index1); - return transfer_impl(start_pos, end_pos, start_pos_in_block1, block_index1, dest, dest_pos); + +#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG + std::ostringstream os_prev_block; + os_prev_block << "source:" << endl; + dump_blocks(os_prev_block); + os_prev_block << "destination:" << endl; + dest.dump_blocks(os_prev_block); +#endif + + iterator ret = transfer_impl(start_pos, end_pos, start_pos_in_block1, block_index1, dest, dest_pos); + +#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG + if (!check_block_integrity() || !dest.check_block_integrity()) + { + cerr << "block integrity check failed in transfer (start_pos=" << start_pos + << ",end_pos=" << end_pos << ",dest_pos=" << dest_pos << ")" << endl; + cerr << "previous block state:" << endl; + cerr << os_prev_block.str(); + abort(); + } +#endif + + return ret; } template<typename _CellBlockFunc> @@ -1479,7 +1599,7 @@ multi_type_vector<_CellBlockFunc>::transfer_single_block( // Insert two new blocks below current. size_type blk2_size = blk_dest->m_size - dest_pos_in_block - len; - dest.m_blocks.insert(dest.m_blocks.begin()+dest_block_index+1, 2, NULL); + dest.m_blocks.insert(dest.m_blocks.begin()+dest_block_index+1, 2u, NULL); dest.m_blocks[dest_block_index+1] = new block(len); dest.m_blocks[dest_block_index+2] = new block(blk2_size); blk_dest->m_size = dest_pos_in_block; @@ -1529,11 +1649,28 @@ multi_type_vector<_CellBlockFunc>::set_empty_impl( if (!get_block_position(end_pos, start_pos_in_block2, block_index2)) throw std::out_of_range("Block position not found!"); +#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG + std::ostringstream os_prev_block; + dump_blocks(os_prev_block); +#endif + + iterator ret_it; if (block_index1 == block_index2) - return set_empty_in_single_block(start_pos, end_pos, block_index1, start_pos_in_block1, true); + ret_it = set_empty_in_single_block(start_pos, end_pos, block_index1, start_pos_in_block1, true); + else + ret_it = set_empty_in_multi_blocks( + start_pos, end_pos, block_index1, start_pos_in_block1, block_index2, start_pos_in_block2, true); - return set_empty_in_multi_blocks( - start_pos, end_pos, block_index1, start_pos_in_block1, block_index2, start_pos_in_block2, true); +#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG + if (!check_block_integrity()) + { + cerr << "block integrity check failed in set_empty (" << start_pos << "-" << end_pos << ")" << endl; + cerr << "previous block state:" << endl; + cerr << os_prev_block.str(); + abort(); + } +#endif + return ret_it; } template<typename _CellBlockFunc> @@ -1542,7 +1679,22 @@ void multi_type_vector<_CellBlockFunc>::erase(size_type start_pos, size_type end if (start_pos > end_pos) throw std::out_of_range("Start row is larger than the end row."); +#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG + std::ostringstream os_prev_block; + dump_blocks(os_prev_block); +#endif + erase_impl(start_pos, end_pos); + +#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG + if (!check_block_integrity()) + { + cerr << "block integrity check failed in erase (" << start_pos << "-" << end_pos << ")" << endl; + cerr << "previous block state:" << endl; + cerr << os_prev_block.str(); + abort(); + } +#endif } template<typename _CellBlockFunc> @@ -1564,65 +1716,7 @@ void multi_type_vector<_CellBlockFunc>::erase_impl(size_type start_row, size_typ if (block_pos1 == block_pos2) { - // Range falls within the same block. - block* blk = m_blocks[block_pos1]; - size_type size_to_erase = end_row - start_row + 1; - if (blk->mp_data) - { - // Erase data in the data block. - size_type offset = start_row - start_row_in_block1; - element_block_func::overwrite_values(*blk->mp_data, offset, size_to_erase); - element_block_func::erase(*blk->mp_data, offset, size_to_erase); - } - - blk->m_size -= size_to_erase; - m_cur_size -= size_to_erase; - - if (blk->m_size == 0) - { - delete blk; - m_blocks.erase(m_blocks.begin()+block_pos1); - - if (block_pos1 > 0 && block_pos1 < m_blocks.size()) - { - // Check the previous and next blocks to see if they should be merged. - block* blk_prev = m_blocks[block_pos1-1]; - block* blk_next = m_blocks[block_pos1]; - if (blk_prev->mp_data) - { - // Previous block has data. - if (!blk_next->mp_data) - // Next block is empty. Nothing to do. - return; - - element_category_type cat1 = mdds::mtv::get_block_type(*blk_prev->mp_data); - element_category_type cat2 = mdds::mtv::get_block_type(*blk_next->mp_data); - if (cat1 == cat2) - { - // Merge the two blocks. - element_block_func::append_values_from_block(*blk_prev->mp_data, *blk_next->mp_data); - blk_prev->m_size += blk_next->m_size; - // Resize to 0 to prevent deletion of cells in case of managed cells. - element_block_func::resize_block(*blk_next->mp_data, 0); - delete blk_next; - m_blocks.erase(m_blocks.begin()+block_pos1); - } - } - else - { - // Previous block is empty. - if (blk_next->mp_data) - // Next block is not empty. Nothing to do. - return; - - // Both blocks are empty. Simply increase the size of the - // previous block. - blk_prev->m_size += blk_next->m_size; - delete blk_next; - m_blocks.erase(m_blocks.begin()+block_pos1); - } - } - } + erase_in_single_block(start_row, end_row, block_pos1, start_row_in_block1); return; } @@ -1672,10 +1766,83 @@ void multi_type_vector<_CellBlockFunc>::erase_impl(size_type start_row, size_typ } } + // Get the index of the block that sits before the blocks being erased. + block_pos1 = std::distance(m_blocks.begin(), it_erase_begin); + if (block_pos1 > 0) + --block_pos1; + // Now, erase all blocks in between. std::for_each(it_erase_begin, it_erase_end, default_deleter<block>()); m_blocks.erase(it_erase_begin, it_erase_end); m_cur_size -= end_row - start_row + 1; + + if (!m_blocks.empty()) + merge_with_next_block(block_pos1); +} + +template<typename _CellBlockFunc> +void multi_type_vector<_CellBlockFunc>::erase_in_single_block( + size_type start_pos, size_type end_pos, size_type block_pos, size_type start_pos_in_block) +{ + // Range falls within the same block. + block* blk = m_blocks[block_pos]; + size_type size_to_erase = end_pos - start_pos + 1; + if (blk->mp_data) + { + // Erase data in the data block. + size_type offset = start_pos - start_pos_in_block; + element_block_func::overwrite_values(*blk->mp_data, offset, size_to_erase); + element_block_func::erase(*blk->mp_data, offset, size_to_erase); + } + + blk->m_size -= size_to_erase; + m_cur_size -= size_to_erase; + + if (blk->m_size == 0) + { + delete blk; + m_blocks.erase(m_blocks.begin()+block_pos); + + if (block_pos > 0 && block_pos < m_blocks.size()) + { + // Check the previous and next blocks to see if they should be merged. + block* blk_prev = m_blocks[block_pos-1]; + block* blk_next = m_blocks[block_pos]; + if (blk_prev->mp_data) + { + // Previous block has data. + if (!blk_next->mp_data) + // Next block is empty. Nothing to do. + return; + + element_category_type cat1 = mdds::mtv::get_block_type(*blk_prev->mp_data); + element_category_type cat2 = mdds::mtv::get_block_type(*blk_next->mp_data); + if (cat1 == cat2) + { + // Merge the two blocks. + element_block_func::append_values_from_block(*blk_prev->mp_data, *blk_next->mp_data); + blk_prev->m_size += blk_next->m_size; + // Resize to 0 to prevent deletion of cells in case of managed cells. + element_block_func::resize_block(*blk_next->mp_data, 0); + delete blk_next; + m_blocks.erase(m_blocks.begin()+block_pos); + } + } + else + { + // Previous block is empty. + if (blk_next->mp_data) + // Next block is not empty. Nothing to do. + return; + + // Both blocks are empty. Simply increase the size of the + // previous block. + blk_prev->m_size += blk_next->m_size; + delete blk_next; + m_blocks.erase(m_blocks.begin()+block_pos); + } + } + } } template<typename _CellBlockFunc> @@ -1690,7 +1857,24 @@ multi_type_vector<_CellBlockFunc>::insert_empty(size_type pos, size_type length) if (!get_block_position(pos, start_pos, block_index)) throw std::out_of_range("Block position not found!"); - return insert_empty_impl(pos, start_pos, block_index, length); +#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG + std::ostringstream os_prev_block; + dump_blocks(os_prev_block); +#endif + + iterator ret = insert_empty_impl(pos, start_pos, block_index, length); + +#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG + if (!check_block_integrity()) + { + cerr << "block integrity check failed in insert_empty (pos=" << pos << ",length=" << length << ")" << endl; + cerr << "previous block state:" << endl; + cerr << os_prev_block.str(); + abort(); + } +#endif + + return ret; } template<typename _CellBlockFunc> @@ -1704,7 +1888,24 @@ multi_type_vector<_CellBlockFunc>::insert_empty(const iterator& pos_hint, size_t size_type start_pos = 0, block_index = 0; get_block_position(pos_hint, pos, start_pos, block_index); - return insert_empty_impl(pos, start_pos, block_index, length); +#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG + std::ostringstream os_prev_block; + dump_blocks(os_prev_block); +#endif + + iterator ret = insert_empty_impl(pos, start_pos, block_index, length); + +#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG + if (!check_block_integrity()) + { + cerr << "block integrity check failed in insert_empty (pos=" << pos << ",length=" << length << ")" << endl; + cerr << "previous block state:" << endl; + cerr << os_prev_block.str(); + abort(); + } +#endif + + return ret; } template<typename _CellBlockFunc> @@ -3036,19 +3237,70 @@ multi_type_vector<_CellBlockFunc>::set_empty_in_multi_blocks( return get_iterator(block_index1, start_row); } -#ifdef MDDS_UNIT_TEST +#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG template<typename _CellBlockFunc> -void multi_type_vector<_CellBlockFunc>::dump_blocks() const +void multi_type_vector<_CellBlockFunc>::dump_blocks(std::ostream& os) const { - cout << "--- blocks" << endl; + os << "--- blocks" << endl; for (size_type i = 0, n = m_blocks.size(); i < n; ++i) { block* blk = m_blocks[i]; element_category_type cat = mtv::element_type_empty; if (blk->mp_data) cat = mtv::get_block_type(*blk->mp_data); - cout << " block " << i << ": size=" << blk->m_size << " type=" << cat << endl; + os << " block " << i << ": size=" << blk->m_size << " type=" << cat << endl; + } +} + +template<typename _CellBlockFunc> +bool multi_type_vector<_CellBlockFunc>::check_block_integrity() const +{ + if (m_blocks.empty()) + // Nothing to check. + return true; + + if (m_blocks.size() == 1 && !m_blocks[0]) + { + cerr << "block should never be null!" << endl; + return false; + } + + const block* blk_prev = m_blocks[0]; + if (!blk_prev) + { + cerr << "block should never be null!" << endl; + return false; + } + + element_category_type cat_prev = mtv::element_type_empty; + if (blk_prev->mp_data) + cat_prev = mtv::get_block_type(*blk_prev->mp_data); + + for (size_type i = 1, n = m_blocks.size(); i < n; ++i) + { + block* blk = m_blocks[i]; + if (!blk) + { + cerr << "block should never be null!" << endl; + return false; + } + + element_category_type cat = mtv::element_type_empty; + if (blk->mp_data) + cat = mtv::get_block_type(*blk->mp_data); + + if (cat_prev == cat) + { + cerr << "Two adjacent blocks should never be of the same type." << endl; + dump_blocks(cerr); + return false; + } + + blk_prev = blk; + cat_prev = cat; } + + return true; } #endif diff --git a/include/mdds/multi_type_vector_types.hpp b/include/mdds/multi_type_vector_types.hpp index 327e7b7..3c3093f 100644 --- a/include/mdds/multi_type_vector_types.hpp +++ b/include/mdds/multi_type_vector_types.hpp @@ -25,8 +25,8 @@ * ************************************************************************/ -#ifndef __MDDS_GRID_MAP_TYPES_HPP__ -#define __MDDS_GRID_MAP_TYPES_HPP__ +#ifndef MDDS_MULTI_TYPE_VECTOR_TYPES_HPP +#define MDDS_MULTI_TYPE_VECTOR_TYPES_HPP #include "default_deleter.hpp" #include "compat/unique_ptr.hpp" @@ -35,7 +35,7 @@ #include <vector> #include <boost/noncopyable.hpp> -#ifdef MDDS_UNIT_TEST +#if defined(MDDS_UNIT_TEST) || defined (MDDS_MULTI_TYPE_VECTOR_DEBUG) #include <iostream> using std::cout; using std::cerr; diff --git a/src/multi_type_vector_test_default.cpp b/src/multi_type_vector_test_default.cpp index 31d43ec..96895e8 100644 --- a/src/multi_type_vector_test_default.cpp +++ b/src/multi_type_vector_test_default.cpp @@ -1512,6 +1512,29 @@ void mtv_test_erase() assert(db.is_empty(1)); assert(db.is_empty(2)); } + + { + mtv_type db(6); + db.set(0, 1.0); + db.set(1, 2.0); + db.set(2, string("A")); + db.set(3, string("B")); + db.set(4, 5.0); + db.set(5, 6.0); + assert(db.block_size() == 3); + assert(db.size() == 6); + assert(db.get<double>(0) == 1.0); + assert(db.get<double>(1) == 2.0); + assert(db.get<string>(2) == "A"); + assert(db.get<string>(3) == "B"); + assert(db.get<double>(4) == 5.0); + assert(db.get<double>(5) == 6.0); + db.erase(1, 4); + assert(db.block_size() == 1); + assert(db.size() == 2); + assert(db.get<double>(0) == 1.0); + assert(db.get<double>(1) == 6.0); + } } void mtv_test_insert_empty() @@ -4065,6 +4088,25 @@ void mtv_test_position() pair<mtv_type::const_iterator,mtv_type::size_type> const_pos = db_ref.position(3); assert(const_pos.first == db_ref.begin()); assert(const_pos.second == 3); + + // Check for the variant that takes position hint. + pos = db.position(0); + assert(pos.first == db.begin()); + assert(pos.second == 0); + + pos = db.position(pos.first, 6); + check = db.begin(); + ++check; + assert(pos.first == check); + assert(pos.second == 0); + + pos = db.position(pos.first, 7); + assert(pos.first == check); + assert(pos.second == 1); + + pos = db.position(pos.first, 9); + assert(pos.first == check); + assert(pos.second == 3); } void mtv_perf_test_block_position_lookup() -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-openoffice/mdds.git

