[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[mdds] 33/62: Imported Upstream version 0.8.1



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 <rene@debian.org>
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 <kohei.yoshida@gmail.com>.
 #
 #
-# 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='kohei.yoshida@gmail.com'
 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, kohei.yoshida@gmail.com)
+AC_INIT(mdds, 0.8.1, kohei.yoshida@gmail.com)
 
 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


Reply to: