[mdds] 31/62: Imported Upstream version 0.8.0
This is an automated email from the git hooks/post-receive script.
rene pushed a commit to branch master
in repository mdds.
commit 8d31f677855a16cb1a7a5dac09f3d84dfa038d43
Author: Rene Engelhard <rene@debian.org>
Date: Thu Apr 21 14:50:50 2016 +0200
Imported Upstream version 0.8.0
---
AUTHORS | 1 +
Makefile.in | 96 +-
NEWS | 30 +
README | 10 +
configure | 1526 ++++++++++++++++++++---
configure.ac | 15 +-
include/mdds/flat_segment_tree.hpp | 16 +-
include/mdds/flat_segment_tree_def.inl | 16 +-
include/mdds/mixed_type_matrix.hpp | 2 +-
include/mdds/mixed_type_matrix_def.inl | 2 +-
include/mdds/mixed_type_matrix_flag_storage.hpp | 4 +-
include/mdds/multi_type_vector.hpp | 156 ++-
include/mdds/multi_type_vector_custom_func1.hpp | 200 +++
include/mdds/multi_type_vector_custom_func2.hpp | 241 ++++
include/mdds/multi_type_vector_def.inl | 612 ++++++++-
include/mdds/multi_type_vector_itr.hpp | 17 +
include/mdds/multi_type_vector_trait.hpp | 60 +
include/mdds/multi_type_vector_types.hpp | 28 +-
include/mdds/node.hpp | 37 +-
include/mdds/point_quad_tree.hpp | 2 +-
include/mdds/quad_node.hpp | 8 +-
include/mdds/rectangle_set.hpp | 4 +-
include/mdds/rectangle_set_def.inl | 2 +-
include/mdds/segment_tree.hpp | 14 +-
misc/mdds.pc.in | 7 +
src/flat_segment_tree_test.cpp | 59 +-
src/multi_type_vector_test_custom.cpp | 687 +++++++---
src/multi_type_vector_test_default.cpp | 123 +-
28 files changed, 3445 insertions(+), 530 deletions(-)
diff --git a/AUTHORS b/AUTHORS
index a0ef3db..857c3f7 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,5 +1,6 @@
Kohei Yoshida <kohei.yoshida@gmail.com> (Maintainer)
David Tardon <dtardon@redhat.com>
+Fridrich Štrba <fridrich.strba@bluewin.ch>
Markus Mohrhard <markus.mohrhard@googlemail.com>
Petr Mladek <pmladek@suse.cz>
Caolán McNamara <caolanm@redhat.com>
diff --git a/Makefile.in b/Makefile.in
index 481b84a..116b714 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -5,6 +5,7 @@ PACKAGE_TARNAME=@PACKAGE_TARNAME@
OBJDIR=@OBJDIR@
SRCDIR=@SRCDIR@
INCDIR=@INCDIR@
+MISCDIR=@MISCDIR@
QUICKCHECKDIR=@QUICKCHECKDIR@
CPPFLAGS=@CPPFLAGS@ -I$(INCDIR)
@@ -21,27 +22,27 @@ EXECS= \
multi_type_vector_test_custom
HEADERS= \
- $(INCDIR)/mdds/compat/unique_ptr.hpp \
- $(INCDIR)/mdds/flat_segment_tree_def.inl \
- $(INCDIR)/mdds/flat_segment_tree.hpp \
- $(INCDIR)/mdds/flat_segment_tree_itr.hpp \
- $(INCDIR)/mdds/global.hpp \
- $(INCDIR)/mdds/hash_container/map.hpp \
- $(INCDIR)/mdds/mixed_type_matrix_def.inl \
- $(INCDIR)/mdds/mixed_type_matrix_element.hpp \
- $(INCDIR)/mdds/mixed_type_matrix_flag_storage.hpp \
- $(INCDIR)/mdds/mixed_type_matrix.hpp \
- $(INCDIR)/mdds/mixed_type_matrix_storage_filled_linear.inl \
- $(INCDIR)/mdds/mixed_type_matrix_storage.hpp \
- $(INCDIR)/mdds/mixed_type_matrix_storage_sparse.inl \
- $(INCDIR)/mdds/multi_type_matrix.hpp \
- $(INCDIR)/mdds/multi_type_matrix_def.inl \
- $(INCDIR)/mdds/node.hpp \
- $(INCDIR)/mdds/point_quad_tree.hpp \
- $(INCDIR)/mdds/quad_node.hpp \
- $(INCDIR)/mdds/rectangle_set_def.inl \
- $(INCDIR)/mdds/rectangle_set.hpp \
- $(INCDIR)/mdds/segment_tree.hpp
+ @top_srcdir@/$(INCDIR)/mdds/compat/unique_ptr.hpp \
+ @top_srcdir@/$(INCDIR)/mdds/flat_segment_tree_def.inl \
+ @top_srcdir@/$(INCDIR)/mdds/flat_segment_tree.hpp \
+ @top_srcdir@/$(INCDIR)/mdds/flat_segment_tree_itr.hpp \
+ @top_srcdir@/$(INCDIR)/mdds/global.hpp \
+ @top_srcdir@/$(INCDIR)/mdds/hash_container/map.hpp \
+ @top_srcdir@/$(INCDIR)/mdds/mixed_type_matrix_def.inl \
+ @top_srcdir@/$(INCDIR)/mdds/mixed_type_matrix_element.hpp \
+ @top_srcdir@/$(INCDIR)/mdds/mixed_type_matrix_flag_storage.hpp \
+ @top_srcdir@/$(INCDIR)/mdds/mixed_type_matrix.hpp \
+ @top_srcdir@/$(INCDIR)/mdds/mixed_type_matrix_storage_filled_linear.inl \
+ @top_srcdir@/$(INCDIR)/mdds/mixed_type_matrix_storage.hpp \
+ @top_srcdir@/$(INCDIR)/mdds/mixed_type_matrix_storage_sparse.inl \
+ @top_srcdir@/$(INCDIR)/mdds/multi_type_matrix.hpp \
+ @top_srcdir@/$(INCDIR)/mdds/multi_type_matrix_def.inl \
+ @top_srcdir@/$(INCDIR)/mdds/node.hpp \
+ @top_srcdir@/$(INCDIR)/mdds/point_quad_tree.hpp \
+ @top_srcdir@/$(INCDIR)/mdds/quad_node.hpp \
+ @top_srcdir@/$(INCDIR)/mdds/rectangle_set_def.inl \
+ @top_srcdir@/$(INCDIR)/mdds/rectangle_set.hpp \
+ @top_srcdir@/$(INCDIR)/mdds/segment_tree.hpp
DEPENDS= \
$(HEADERS)
@@ -74,29 +75,29 @@ all: $(EXECS)
pre:
mkdir -p $(OBJDIR)
-$(OBJDIR)/flat_segment_tree_test.o: $(SRCDIR)/flat_segment_tree_test.cpp $(DEPENDS)
- $(CXX) $(CPPFLAGS) -c -o $@ $(SRCDIR)/flat_segment_tree_test.cpp
+$(OBJDIR)/flat_segment_tree_test.o: @top_srcdir@/$(SRCDIR)/flat_segment_tree_test.cpp $(DEPENDS)
+ $(CXX) $(CPPFLAGS) -c -o $@ @top_srcdir@/$(SRCDIR)/flat_segment_tree_test.cpp
-$(OBJDIR)/segment_tree_test.o: $(SRCDIR)/segment_tree_test.cpp $(DEPENDS)
- $(CXX) $(CPPFLAGS) -c -o $@ $(SRCDIR)/segment_tree_test.cpp
+$(OBJDIR)/segment_tree_test.o: @top_srcdir@/$(SRCDIR)/segment_tree_test.cpp $(DEPENDS)
+ $(CXX) $(CPPFLAGS) -c -o $@ @top_srcdir@/$(SRCDIR)/segment_tree_test.cpp
-$(OBJDIR)/rectangle_set_test.o: $(SRCDIR)/rectangle_set_test.cpp $(DEPENDS)
- $(CXX) $(CPPFLAGS) -c -o $@ $(SRCDIR)/rectangle_set_test.cpp
+$(OBJDIR)/rectangle_set_test.o: @top_srcdir@/$(SRCDIR)/rectangle_set_test.cpp $(DEPENDS)
+ $(CXX) $(CPPFLAGS) -c -o $@ @top_srcdir@/$(SRCDIR)/rectangle_set_test.cpp
-$(OBJDIR)/point_quad_tree_test.o: $(SRCDIR)/point_quad_tree_test.cpp $(DEPENDS)
- $(CXX) $(CPPFLAGS) -c -o $@ $(SRCDIR)/point_quad_tree_test.cpp
+$(OBJDIR)/point_quad_tree_test.o: @top_srcdir@/$(SRCDIR)/point_quad_tree_test.cpp $(DEPENDS)
+ $(CXX) $(CPPFLAGS) -c -o $@ @top_srcdir@/$(SRCDIR)/point_quad_tree_test.cpp
-$(OBJDIR)/mixed_type_matrix_test.o: $(SRCDIR)/mixed_type_matrix_test.cpp $(DEPENDS)
- $(CXX) $(CPPFLAGS) -c -o $@ $(SRCDIR)/mixed_type_matrix_test.cpp
+$(OBJDIR)/mixed_type_matrix_test.o: @top_srcdir@/$(SRCDIR)/mixed_type_matrix_test.cpp $(DEPENDS)
+ $(CXX) $(CPPFLAGS) -c -o $@ @top_srcdir@/$(SRCDIR)/mixed_type_matrix_test.cpp
-$(OBJDIR)/multi_type_vector_test_default.o: $(SRCDIR)/multi_type_vector_test_default.cpp $(DEPENDS)
- $(CXX) $(CPPFLAGS) -c -o $@ $(SRCDIR)/multi_type_vector_test_default.cpp
+$(OBJDIR)/multi_type_vector_test_default.o: @top_srcdir@/$(SRCDIR)/multi_type_vector_test_default.cpp $(DEPENDS)
+ $(CXX) $(CPPFLAGS) -c -o $@ @top_srcdir@/$(SRCDIR)/multi_type_vector_test_default.cpp
-$(OBJDIR)/multi_type_vector_test_custom.o: $(SRCDIR)/multi_type_vector_test_custom.cpp $(DEPENDS)
- $(CXX) $(CPPFLAGS) -c -o $@ $(SRCDIR)/multi_type_vector_test_custom.cpp
+$(OBJDIR)/multi_type_vector_test_custom.o: @top_srcdir@/$(SRCDIR)/multi_type_vector_test_custom.cpp $(DEPENDS)
+ $(CXX) $(CPPFLAGS) -c -o $@ @top_srcdir@/$(SRCDIR)/multi_type_vector_test_custom.cpp
-$(OBJDIR)/multi_type_matrix_test.o: $(SRCDIR)/multi_type_matrix_test.cpp $(DEPENDS)
- $(CXX) $(CPPFLAGS) -c -o $@ $(SRCDIR)/multi_type_matrix_test.cpp
+$(OBJDIR)/multi_type_matrix_test.o: @top_srcdir@/$(SRCDIR)/multi_type_matrix_test.cpp $(DEPENDS)
+ $(CXX) $(CPPFLAGS) -c -o $@ @top_srcdir@/$(SRCDIR)/multi_type_matrix_test.cpp
flat_segment_tree_test: pre $(OBJDIR)/flat_segment_tree_test.o
$(CXX) $(LDFLAGS) $(OBJDIR)/flat_segment_tree_test.o -o $@
@@ -124,11 +125,11 @@ multi_type_matrix_test: pre $(OBJDIR)/multi_type_matrix_test.o
multi_type_vector_test: multi_type_vector_test_default multi_type_vector_test_custom
-stlperf_test: pre $(SRCDIR)/stlperf_test.cpp
- $(CXX) $(LDFLAGS) $(CPPFLAGS) $(SRCDIR)/stlperf_test.cpp -o $@
+stlperf_test: pre @top_srcdir@/$(SRCDIR)/stlperf_test.cpp
+ $(CXX) $(LDFLAGS) $(CPPFLAGS) @top_srcdir@/$(SRCDIR)/stlperf_test.cpp -o $@
-$(OBJDIR)/template_test.o: $(SRCDIR)/template_test.cpp $(DEPENDS)
- $(CXX) $(CPPFLAGS) -c -o $@ $(SRCDIR)/template_test.cpp
+$(OBJDIR)/template_test.o: @top_srcdir@/$(SRCDIR)/template_test.cpp $(DEPENDS)
+ $(CXX) $(CPPFLAGS) -c -o $@ @top_srcdir@/$(SRCDIR)/template_test.cpp
test.fst: flat_segment_tree_test
./flat_segment_tree_test func
@@ -207,11 +208,14 @@ install: $(HEADERS)
install -d $(DESTDIR)@includedir@/mdds/hash_container
install -d $(DESTDIR)@includedir@/mdds/compat
install -d $(DESTDIR)@docdir@
- install -m 644 -t $(DESTDIR)@includedir@/mdds $(INCDIR)/mdds/*.hpp
- install -m 644 -t $(DESTDIR)@includedir@/mdds $(INCDIR)/mdds/*.inl
- install -m 644 -t $(DESTDIR)@includedir@/mdds/compat $(INCDIR)/mdds/compat/*.hpp
- install -m 644 -t $(DESTDIR)@includedir@/mdds/hash_container $(INCDIR)/mdds/hash_container/*.hpp
- install -m 644 -t $(DESTDIR)@docdir@ AUTHORS COPYING NEWS README VERSION
+ install -d $(DESTDIR)@datarootdir@
+ install -d $(DESTDIR)@datarootdir@/pkgconfig
+ install -m 644 -t $(DESTDIR)@includedir@/mdds @top_srcdir@/$(INCDIR)/mdds/*.hpp
+ install -m 644 -t $(DESTDIR)@includedir@/mdds @top_srcdir@/$(INCDIR)/mdds/*.inl
+ install -m 644 -t $(DESTDIR)@includedir@/mdds/compat @top_srcdir@/$(INCDIR)/mdds/compat/*.hpp
+ install -m 644 -t $(DESTDIR)@includedir@/mdds/hash_container @top_srcdir@/$(INCDIR)/mdds/hash_container/*.hpp
+ install -m 644 -t $(DESTDIR)@datarootdir@/pkgconfig $(MISCDIR)/mdds.pc
+ install -m 644 -t $(DESTDIR)@docdir@ @top_srcdir@/AUTHORS @top_srcdir@/COPYING @top_srcdir@/NEWS @top_srcdir@/README @top_srcdir@/VERSION
check: $(ALL_TESTS)
diff --git a/NEWS b/NEWS
index a0d4491..3863506 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,33 @@
+mdds 0.8.0
+
+* all
+
+ * added .pc file for pkg-config.
+
+* flat_segment_tree
+
+ * changed the return type of search_tree from bool to
+ std::pair<const_iterator,bool>, to make it consistent with the
+ search() method. Note that this is an API-incompatible change.
+
+* multi_type_vector
+
+ * added char and unsigned char types to the standard types supported
+ by default.
+
+ * added position() member method that takes a logical element
+ position and returns a pair of block iterator where the element
+ resides and its offset within that block.
+
+ * added at() static member method to the data block, which calls the
+ at() method of the underlying std::vector container.
+
+ * added release() member method to allow caller to release an object
+ stored inside a managed block.
+
+ * added two templates to ease creation of custom element block
+ functions when using one or two custom element types.
+
mdds 0.7.1
* multi_type_vector
diff --git a/README b/README
index 084c55a..4f08fd5 100644
--- a/README
+++ b/README
@@ -68,6 +68,16 @@ directory on how to use these data structures.
API Incompatibility Note
========================
+0.7.1 to 0.8.0
+
+flat_segment_tree
+
+* The search_tree() method in 0.8.0 returns std::pair<const_iterator,
+ bool> instead of just returning bool as of 0.7.1. If you use this
+ method and relies on the return value of the old version, use the
+ second parameter of the new return value which is equivalent of the
+ previous return value.
+
0.4.0 to 0.5.0
flat_segment_tree
diff --git a/configure b/configure
index 0bb3dcc..97b90dd 100755
--- a/configure
+++ b/configure
@@ -1,11 +1,13 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for mdds 0.7.1.
+# Generated by GNU Autoconf 2.68 for mdds 0.8.0.
#
# Report bugs to <kohei.yoshida@gmail.com>.
#
#
-# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
+# Foundation, Inc.
#
#
# This configure script is free software; the Free Software Foundation
@@ -134,31 +136,6 @@ 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
@@ -192,8 +169,7 @@ 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 / || exit 1"
+test x\$exitcode = x0 || 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'\" &&
@@ -237,25 +213,21 @@ IFS=$as_save_IFS
if test "x$CONFIG_SHELL" != x; then :
- 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
+ # 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+"$@"}
fi
if test x$as_have_required = xno; then :
@@ -358,14 +330,6 @@ $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
@@ -487,10 +451,6 @@ 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).
@@ -525,16 +485,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 -pR'.
+ # In both cases, we have to default to `cp -p'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -pR'
+ as_ln_s='cp -p'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
- as_ln_s='cp -pR'
+ as_ln_s='cp -p'
fi
else
- as_ln_s='cp -pR'
+ as_ln_s='cp -p'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
@@ -546,8 +506,28 @@ else
as_mkdir_p=false
fi
-as_test_x='test -x'
-as_executable_p=as_fn_executable_p
+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
# 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'"
@@ -579,8 +559,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='mdds'
PACKAGE_TARNAME='mdds'
-PACKAGE_VERSION='0.7.1'
-PACKAGE_STRING='mdds 0.7.1'
+PACKAGE_VERSION='0.8.0'
+PACKAGE_STRING='mdds 0.8.0'
PACKAGE_BUGREPORT='kohei.yoshida@gmail.com'
PACKAGE_URL=''
@@ -589,6 +569,7 @@ LIBOBJS
CPPFLAGS_NODEBUG
CPPFLAGS
QUICKCHECKDIR
+MISCDIR
INCDIR
SRCDIR
OBJDIR
@@ -1094,6 +1075,8 @@ 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
@@ -1179,7 +1162,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.7.1 to adapt to many kinds of systems.
+\`configure' configures mdds 0.8.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1240,7 +1223,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of mdds 0.7.1:";;
+ short | recursive ) echo "Configuration of mdds 0.8.0:";;
esac
cat <<\_ACEOF
@@ -1324,10 +1307,10 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-mdds configure 0.7.1
-generated by GNU Autoconf 2.69
+mdds configure 0.8.0
+generated by GNU Autoconf 2.68
-Copyright (C) 2012 Free Software Foundation, Inc.
+Copyright (C) 2010 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
@@ -1341,8 +1324,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.7.1, which was
-generated by GNU Autoconf 2.69. Invocation command line was
+It was created by mdds $as_me 0.8.0, which was
+generated by GNU Autoconf 2.68. Invocation command line was
$ $0 $@
@@ -1690,7 +1673,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
-VERSION=0.7.1
+VERSION=0.8.0
PACKAGE_TARNAME=mdds
@@ -1710,10 +1693,12 @@ $as_echo_n "checking hash container type... " >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_hash_container" >&5
$as_echo "$with_hash_container" >&6; }
-OBJDIR=./obj
-SRCDIR=./src
-INCDIR=./include
-QUICKCHECKDIR=./quickcheck
+OBJDIR=obj
+SRCDIR=src
+INCDIR=include
+MISCDIR=misc
+QUICKCHECKDIR=quickcheck
+
@@ -1726,7 +1711,7 @@ elif test $with_hash_container = boost; then
CPPFLAGS_NODEBUG="$CPPFLAGS_NODEBUG -DMDDS_HASH_CONTAINER_BOOST"
fi
-CPPFLAGS="$CPPFLAGS_NODEBUG -DDEBUG_NODE_BASE -DUNIT_TEST -std=c++0x"
+CPPFLAGS="$CPPFLAGS_NODEBUG -DMDDS_DEBUG_NODE_BASE -DMDDS_UNIT_TEST -std=c++0x"
@@ -2175,16 +2160,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 -pR'.
+ # In both cases, we have to default to `cp -p'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -pR'
+ as_ln_s='cp -p'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
- as_ln_s='cp -pR'
+ as_ln_s='cp -p'
fi
else
- as_ln_s='cp -pR'
+ as_ln_s='cp -p'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
@@ -2244,16 +2229,28 @@ else
as_mkdir_p=false
fi
-
-# 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
+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
# 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'"
@@ -2274,8 +2271,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.7.1, which was
-generated by GNU Autoconf 2.69. Invocation command line was
+This file was extended by mdds $as_me 0.8.0, which was
+generated by GNU Autoconf 2.68. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS
@@ -2327,11 +2324,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.7.1
-configured by $0, generated by GNU Autoconf 2.69,
+mdds config.status 0.8.0
+configured by $0, generated by GNU Autoconf 2.68,
with options \\"\$ac_cs_config\\"
-Copyright (C) 2012 Free Software Foundation, Inc.
+Copyright (C) 2010 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."
@@ -2408,7 +2405,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'
@@ -3332,16 +3329,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 -pR'.
+ # In both cases, we have to default to `cp -p'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -pR'
+ as_ln_s='cp -p'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
- as_ln_s='cp -pR'
+ as_ln_s='cp -p'
fi
else
- as_ln_s='cp -pR'
+ as_ln_s='cp -p'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
@@ -3401,16 +3398,28 @@ else
as_mkdir_p=false
fi
-
-# 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
+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
# 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'"
@@ -3431,8 +3440,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.7.1, which was
-generated by GNU Autoconf 2.69. Invocation command line was
+This file was extended by mdds $as_me 0.8.0, which was
+generated by GNU Autoconf 2.68. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS
@@ -3484,11 +3493,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.7.1
-configured by $0, generated by GNU Autoconf 2.69,
+mdds config.status 0.8.0
+configured by $0, generated by GNU Autoconf 2.68,
with options \\"\$ac_cs_config\\"
-Copyright (C) 2012 Free Software Foundation, Inc.
+Copyright (C) 2010 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."
@@ -3565,7 +3574,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'
@@ -4490,16 +4499,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 -pR'.
+ # In both cases, we have to default to `cp -p'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -pR'
+ as_ln_s='cp -p'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
- as_ln_s='cp -pR'
+ as_ln_s='cp -p'
fi
else
- as_ln_s='cp -pR'
+ as_ln_s='cp -p'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
@@ -4559,16 +4568,28 @@ else
as_mkdir_p=false
fi
-
-# 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
+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
# 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'"
@@ -4589,8 +4610,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.7.1, which was
-generated by GNU Autoconf 2.69. Invocation command line was
+This file was extended by mdds $as_me 0.8.0, which was
+generated by GNU Autoconf 2.68. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS
@@ -4642,11 +4663,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.7.1
-configured by $0, generated by GNU Autoconf 2.69,
+mdds config.status 0.8.0
+configured by $0, generated by GNU Autoconf 2.68,
with options \\"\$ac_cs_config\\"
-Copyright (C) 2012 Free Software Foundation, Inc.
+Copyright (C) 2010 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."
@@ -4723,7 +4744,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'
@@ -5204,7 +5225,7 @@ if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
fi
-ac_config_files="$ac_config_files VERSION"
+ac_config_files="$ac_config_files misc/mdds.pc"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
@@ -5649,16 +5670,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 -pR'.
+ # In both cases, we have to default to `cp -p'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -pR'
+ as_ln_s='cp -p'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
- as_ln_s='cp -pR'
+ as_ln_s='cp -p'
fi
else
- as_ln_s='cp -pR'
+ as_ln_s='cp -p'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
@@ -5718,16 +5739,1200 @@ 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
+
+# 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'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# 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
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration. Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ --config print configuration, then exit
+ -q, --quiet, --silent
+ do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Report bugs to <kohei.yoshida@gmail.com>."
+
+_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,
+ with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2010 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=?*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ --*=)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --config | --confi | --conf | --con | --co | --c )
+ $as_echo "$ac_cs_config"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ '') as_fn_error $? "missing file argument" ;;
+ esac
+ as_fn_append CONFIG_FILES " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h | --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+ *) as_fn_append ac_config_targets " $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+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
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "example/Makefile") CONFIG_FILES="$CONFIG_FILES example/Makefile" ;;
+ "misc/mdds.spec") CONFIG_FILES="$CONFIG_FILES misc/mdds.spec" ;;
+ "misc/mdds.pc") CONFIG_FILES="$CONFIG_FILES misc/mdds.pc" ;;
+
+ *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp= ac_tmp=
+ trap 'exit_status=$?
+ : "${ac_tmp:=$tmp}"
+ { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+ trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
-# 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
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+ eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{
+h
+s///
+s/^/:/
+s/[ ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[ ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+
+eval set X " :F $CONFIG_FILES "
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$ac_tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ as_fn_append ac_file_inputs " '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$ac_tmp/stdin" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir="$ac_dir"; as_fn_mkdir_p
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \
+ "$ac_tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&2;}
+
+ rm -f "$ac_tmp/stdin"
+ case $ac_file in
+ -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+ *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+ esac \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+
+
+
+ esac
+
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
+ac_config_files="$ac_config_files VERSION"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes: double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \.
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ if test "x$cache_file" != "x/dev/null"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ if test ! -f "$cache_file" || test -h "$cache_file"; then
+ cat confcache >"$cache_file"
+ else
+ case $cache_file in #(
+ */* | ?:*)
+ mv -f confcache "$cache_file"$$ &&
+ mv -f "$cache_file"$$ "$cache_file" ;; #(
+ *)
+ mv -f confcache "$cache_file" ;;
+ esac
+ fi
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then branch to the quote section. Otherwise,
+# look for a macro that doesn't take arguments.
+ac_script='
+:mline
+/\\$/{
+ N
+ s,\\\n,,
+ b mline
+}
+t clear
+:clear
+s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g
+t quote
+s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g
+t quote
+b any
+:quote
+s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g
+s/\[/\\&/g
+s/\]/\\&/g
+s/\$/$$/g
+H
+:any
+${
+ g
+ s/^\n//
+ s/\n/ /g
+ p
+}
+'
+DEFS=`sed -n "$ac_script" confdefs.h`
+
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... 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'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -p'
+ fi
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ 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
# 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'"
@@ -5748,8 +6953,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.7.1, which was
-generated by GNU Autoconf 2.69. Invocation command line was
+This file was extended by mdds $as_me 0.8.0, which was
+generated by GNU Autoconf 2.68. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS
@@ -5801,11 +7006,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.7.1
-configured by $0, generated by GNU Autoconf 2.69,
+mdds config.status 0.8.0
+configured by $0, generated by GNU Autoconf 2.68,
with options \\"\$ac_cs_config\\"
-Copyright (C) 2012 Free Software Foundation, Inc.
+Copyright (C) 2010 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."
@@ -5882,7 +7087,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'
@@ -5914,6 +7119,7 @@ do
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
"example/Makefile") CONFIG_FILES="$CONFIG_FILES example/Makefile" ;;
"misc/mdds.spec") CONFIG_FILES="$CONFIG_FILES misc/mdds.spec" ;;
+ "misc/mdds.pc") CONFIG_FILES="$CONFIG_FILES misc/mdds.pc" ;;
"VERSION") CONFIG_FILES="$CONFIG_FILES VERSION" ;;
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
diff --git a/configure.ac b/configure.ac
index 0c87941..0458f69 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT(mdds, 0.7.1, kohei.yoshida@gmail.com)
+AC_INIT(mdds, 0.8.0, kohei.yoshida@gmail.com)
VERSION=AC_PACKAGE_VERSION
AC_SUBST(VERSION)
@@ -25,13 +25,15 @@ AC_ARG_WITH(hash-container,
AC_MSG_CHECKING([hash container type])
AC_MSG_RESULT([$with_hash_container])
-OBJDIR=./obj
-SRCDIR=./src
-INCDIR=./include
-QUICKCHECKDIR=./quickcheck
+OBJDIR=obj
+SRCDIR=src
+INCDIR=include
+MISCDIR=misc
+QUICKCHECKDIR=quickcheck
AC_SUBST(OBJDIR)
AC_SUBST(SRCDIR)
AC_SUBST(INCDIR)
+AC_SUBST(MISCDIR)
AC_SUBST(QUICKCHECKDIR)
CPPFLAGS_NODEBUG="-Wall -Os -g -pedantic-errors"
@@ -41,11 +43,12 @@ elif test $with_hash_container = boost; then
CPPFLAGS_NODEBUG="$CPPFLAGS_NODEBUG -DMDDS_HASH_CONTAINER_BOOST"
fi
-CPPFLAGS="$CPPFLAGS_NODEBUG -DDEBUG_NODE_BASE -DUNIT_TEST -std=c++0x"
+CPPFLAGS="$CPPFLAGS_NODEBUG -DMDDS_DEBUG_NODE_BASE -DMDDS_UNIT_TEST -std=c++0x"
AC_SUBST(CPPFLAGS)
AC_SUBST(CPPFLAGS_NODEBUG)
AC_OUTPUT(Makefile)
AC_OUTPUT(example/Makefile)
AC_OUTPUT(misc/mdds.spec)
+AC_OUTPUT(misc/mdds.pc)
AC_OUTPUT(VERSION)
diff --git a/include/mdds/flat_segment_tree.hpp b/include/mdds/flat_segment_tree.hpp
index 2b2b937..481b9c0 100644
--- a/include/mdds/flat_segment_tree.hpp
+++ b/include/mdds/flat_segment_tree.hpp
@@ -37,7 +37,7 @@
#include "node.hpp"
#include "flat_segment_tree_itr.hpp"
-#ifdef UNIT_TEST
+#ifdef MDDS_UNIT_TEST
#include <cstdio>
#include <vector>
#endif
@@ -344,7 +344,6 @@ public:
* @return a pair of const_iterator corresponding to the start position of
* the segment containing the key, and a boolean value indicating
* whether or not the search has been successful.
- *
*/
::std::pair<const_iterator, bool>
search(const const_iterator& pos, key_type key, value_type& value, key_type* start_key = NULL, key_type* end_key = NULL) const;
@@ -362,11 +361,12 @@ public:
* @param end_key pointer to a varaible where the end key value of the
* segment that contains the key gets stored upon
* successful search.
- * @return a boolean value indicating whether or not the search has been
- * successful.
- *
+ * @return a pair of const_iterator corresponding to the start position of
+ * the segment containing the key, and a boolean value indicating
+ * whether or not the search has been successful.
*/
- bool search_tree(key_type key, value_type& value, key_type* start_key = NULL, key_type* end_key = NULL) const;
+ std::pair<const_iterator, bool>
+ search_tree(key_type key, value_type& value, key_type* start_key = NULL, key_type* end_key = NULL) const;
void build_tree();
@@ -402,7 +402,7 @@ public:
return m_init_val;
}
-#ifdef UNIT_TEST
+#ifdef MDDS_UNIT_TEST
node_ptr get_root_node() const
{
return m_root_node;
@@ -544,7 +544,7 @@ private:
return;
}
-#ifdef UNIT_TEST
+#ifdef MDDS_UNIT_TEST
// The start position must come after the position of the last node
// before the right-most node.
assert(m_right_leaf->left->value_leaf.key < start_key);
diff --git a/include/mdds/flat_segment_tree_def.inl b/include/mdds/flat_segment_tree_def.inl
index 91add6c..5158c3c 100644
--- a/include/mdds/flat_segment_tree_def.inl
+++ b/include/mdds/flat_segment_tree_def.inl
@@ -565,19 +565,21 @@ flat_segment_tree<_Key, _Value>::search(const const_iterator& pos,
}
template<typename _Key, typename _Value>
-bool flat_segment_tree<_Key, _Value>::search_tree(
+std::pair<typename flat_segment_tree<_Key, _Value>::const_iterator, bool>
+flat_segment_tree<_Key, _Value>::search_tree(
key_type key, value_type& value, key_type* start_key, key_type* end_key) const
{
+ typedef std::pair<const_iterator, bool> ret_type;
if (!m_root_node || !m_valid_tree)
{
// either tree has not been built, or is in an invalid state.
- return false;
+ return ret_type(const_iterator(this, true), false);
}
if (key < m_left_leaf->value_leaf.key || m_right_leaf->value_leaf.key <= key)
{
// key value is out-of-bound.
- return false;
+ return ret_type(const_iterator(this, true), false);
}
// Descend down the tree through the last non-leaf layer.
@@ -600,7 +602,7 @@ bool flat_segment_tree<_Key, _Value>::search_tree(
else
{
// left child node can't be missing !
- return false;
+ return ret_type(const_iterator(this, true), false);
}
if (cur_node->right)
@@ -612,7 +614,7 @@ bool flat_segment_tree<_Key, _Value>::search_tree(
continue;
}
}
- return false;
+ return ret_type(const_iterator(this, true), false);
}
assert(cur_node->left->is_leaf && cur_node->right->is_leaf);
@@ -633,7 +635,7 @@ bool flat_segment_tree<_Key, _Value>::search_tree(
if (!cur_node)
{
- return false;
+ return ret_type(const_iterator(this, true), false);
}
value = cur_node->value_leaf.value;
@@ -650,7 +652,7 @@ bool flat_segment_tree<_Key, _Value>::search_tree(
*end_key = m_right_leaf->value_leaf.key;
}
- return true;
+ return ret_type(const_iterator(this, cur_node), true);
}
template<typename _Key, typename _Value>
diff --git a/include/mdds/mixed_type_matrix.hpp b/include/mdds/mixed_type_matrix.hpp
index e3f2fcd..ca037b8 100644
--- a/include/mdds/mixed_type_matrix.hpp
+++ b/include/mdds/mixed_type_matrix.hpp
@@ -215,7 +215,7 @@ public:
*/
void swap(mixed_type_matrix& r);
-#ifdef UNIT_TEST
+#ifdef MDDS_UNIT_TEST
void dump() const;
void dump_flags() const;
size_pair_type get_storage_size() const;
diff --git a/include/mdds/mixed_type_matrix_def.inl b/include/mdds/mixed_type_matrix_def.inl
index 2c33799..99c7d18 100644
--- a/include/mdds/mixed_type_matrix_def.inl
+++ b/include/mdds/mixed_type_matrix_def.inl
@@ -262,7 +262,7 @@ void mixed_type_matrix<_String,_Flag>::swap(mixed_type_matrix& r)
m_cached_size = temp;
}
-#ifdef UNIT_TEST
+#ifdef MDDS_UNIT_TEST
template<typename _String, typename _Flag>
void mixed_type_matrix<_String,_Flag>::dump() const
{
diff --git a/include/mdds/mixed_type_matrix_flag_storage.hpp b/include/mdds/mixed_type_matrix_flag_storage.hpp
index 3a9f7a1..380557c 100644
--- a/include/mdds/mixed_type_matrix_flag_storage.hpp
+++ b/include/mdds/mixed_type_matrix_flag_storage.hpp
@@ -25,7 +25,7 @@
*
************************************************************************/
-#if UNIT_TEST
+#ifdef MDDS_UNIT_TEST
#include <iostream>
#endif
@@ -74,7 +74,7 @@ public:
// Flag is stored at this position. Remove it.
m_flags.erase(itr);
}
-#if UNIT_TEST
+#ifdef MDDS_UNIT_TEST
void dump() const
{
using namespace std;
diff --git a/include/mdds/multi_type_vector.hpp b/include/mdds/multi_type_vector.hpp
index 8eb71ed..cefb8c4 100644
--- a/include/mdds/multi_type_vector.hpp
+++ b/include/mdds/multi_type_vector.hpp
@@ -205,7 +205,7 @@ public:
* inserted.
*/
template<typename _T>
- iterator set(iterator pos_hint, size_type pos, const _T& value);
+ iterator set(const iterator& pos_hint, size_type pos, const _T& value);
/**
* Set multiple values of identical type to a range of elements starting
@@ -269,7 +269,7 @@ public:
* is empty, the end iterator position is returned.
*/
template<typename _T>
- iterator set(iterator pos_hint, size_type pos, const _T& it_begin, const _T& it_end);
+ iterator set(const iterator& pos_hint, size_type pos, const _T& it_begin, const _T& it_end);
/**
* Insert multiple values of identical type to a specified position.
@@ -333,7 +333,7 @@ public:
* is empty, the end iterator position is returned.
*/
template<typename _T>
- iterator insert(iterator pos_hint, size_type pos, const _T& it_begin, const _T& it_end);
+ iterator insert(const iterator& pos_hint, size_type pos, const _T& it_begin, const _T& it_end);
/**
* Get the value of an element at specified position. The caller must
@@ -356,12 +356,116 @@ 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 position position of the element value to retrieve.
+ * @param pos position of the element value to retrieve.
* @return element value.
*/
template<typename _T>
_T get(size_type pos) const;
+ /**
+ * Return the value of an element at specified position and set that
+ * position empty. If the element resides in a managed block, this call
+ * will <i>not</i> delete that element. If the element is on a
+ * non-managed block, this call is equivalent to set_empty(pos, pos).
+ *
+ * <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 to release.
+ *
+ * @return element value.
+ */
+ template<typename _T>
+ _T release(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.
+ */
+ std::pair<iterator, size_type> position(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.
+ */
+ std::pair<const_iterator, size_type> position(size_type pos) const;
+
+ /**
+ * Move elements from one container to another. After the move, the
+ * segment where the elements were in the original container becomes
+ * empty. When transferring managed elements, this call transfers
+ * ownership of the moved elements to the new container. The moved
+ * elements will overwrite any existing elements in the destination range.
+ * Transfer of elements within the same container is not allowed.
+ *
+ * <p>The method will throw an <code>std::out_of_range</code> exception if
+ * either the starting or the ending position is outside the current
+ * container size, or the destination container is not large enough to
+ * accommodate the transferred elements.</p>
+ *
+ * @param start_pos starting position
+ * @param end_pos ending position, inclusive.
+ * @param dest destination container to which the elements are to be
+ * moved.
+ * @param dest_pos position in the destination container to which the
+ * elements are to be moved.
+ *
+ * @return iterator referencing the block where the moved elements were
+ * prior to the transfer.
+ */
+ iterator transfer(size_type start_pos, size_type end_pos, multi_type_vector& dest, size_type dest_pos);
+
+ /**
+ * Move elements from one container to another. After the move, the
+ * segment where the elements were in the original container becomes
+ * empty. When transferring managed elements, this call transfers
+ * ownership of the moved elements to the new container. The moved
+ * elements will overwrite any existing elements in the destination range.
+ * Transfer of elements within the same container is not allowed.
+ *
+ * <p>The method will throw an <code>std::out_of_range</code> exception if
+ * either the starting or the ending position is outside the current
+ * container size, or the destination container is not large enough to
+ * accommodate the transferred elements.</p>
+ *
+ * @param pos_hint iterator used as a block position hint, to specify
+ * which block to start when searching for the blocks
+ * where the elements to be transferred reside.
+ * @param start_pos starting position
+ * @param end_pos ending position, inclusive.
+ * @param dest destination container to which the elements are to be
+ * moved.
+ * @param dest_pos position in the destination container to which the
+ * elements are to be moved.
+ *
+ * @return iterator referencing the block where the moved elements were
+ * prior to the transfer.
+ */
+ iterator transfer(const iterator& pos_hint, size_type start_pos, size_type end_pos, multi_type_vector& dest, size_type dest_pos);
+
+ /**
+ * Get the type of an element at specified position.
+ *
+ * @param pos position of the element.
+ *
+ * @return element type.
+ */
mtv::element_t get_type(size_type pos) const;
/**
@@ -420,7 +524,7 @@ public:
* @return iterator position pointing to the block where the elements are
* emptied.
*/
- iterator set_empty(iterator pos_hint, size_type start_pos, size_type end_pos);
+ iterator set_empty(const iterator& pos_hint, size_type start_pos, size_type end_pos);
/**
* Erase elements located between specified start and end positions. The
@@ -488,7 +592,7 @@ public:
* is inserted. When no insertion occurs because the length is
* zero, the end iterator position is returned.
*/
- iterator insert_empty(iterator pos_hint, size_type pos, size_type length);
+ iterator insert_empty(const iterator& pos_hint, size_type pos, size_type length);
/**
* Clear the content of the container. The size of the container will
@@ -557,6 +661,10 @@ public:
template<typename _T>
static mtv::element_t get_element_type(const _T& elem);
+#ifdef MDDS_UNIT_TEST
+ void dump_blocks() const;
+#endif
+
private:
template<typename _T>
@@ -587,7 +695,7 @@ private:
* Same as above, but try to infer block position from the iterator first
* before trying full search.
*/
- void get_block_position(iterator pos_hint, size_type pos, size_type& start_pos, size_type& block_index) const;
+ void get_block_position(const iterator& pos_hint, size_type pos, size_type& start_pos, size_type& block_index) const;
template<typename _T>
static void create_new_block_with_new_cell(element_block_type*& data, const _T& cell);
@@ -615,17 +723,26 @@ private:
void set_cell_to_bottom_of_data_block(
size_type block_index, const _T& cell);
+ iterator transfer_impl(
+ size_type start_pos, size_type end_pos, size_type start_pos_in_block1, size_type block_index1,
+ multi_type_vector& dest, size_type dest_pos);
+
+ iterator transfer_single_block(
+ size_type start_pos, size_type end_pos, size_type start_pos_in_block1, size_type block_index1,
+ multi_type_vector& dest, size_type dest_pos);
+
iterator set_empty_impl(size_type start_pos, size_type end_pos, size_type start_pos_in_block1, size_type block_index1);
- iterator set_whole_block_empty(size_type block_index, size_type start_pos_in_block);
+ iterator set_whole_block_empty(size_type block_index, size_type start_pos_in_block, bool overwrite);
iterator set_empty_in_single_block(
- size_type start_pos, size_type end_pos, size_type block_index, size_type start_pos_in_block);
+ size_type start_pos, size_type end_pos, size_type block_index, size_type start_pos_in_block,
+ bool overwrite);
iterator set_empty_in_multi_blocks(
size_type start_pos, size_type end_pos,
size_type block_index1, size_type start_pos_in_block1,
- size_type block_index2, size_type start_pos_in_block2);
+ size_type block_index2, size_type start_pos_in_block2, bool overwrite);
void erase_impl(size_type start_pos, size_type end_pos);
@@ -668,7 +785,24 @@ private:
size_type block_index2, size_type start_pos_in_block2,
const _T& it_begin, const _T& it_end);
- void merge_with_next_block(size_type block_index);
+ /**
+ * Merge with previous or next block as needed.
+ *
+ * @param block_index index of the block that may need merging.
+ *
+ * @return size of previous block if the block is merged with the previous
+ * block, or 0 if it didn't merge with the previous block.
+ */
+ size_type merge_with_adjacent_blocks(size_type block_index);
+
+ /**
+ * Merge only with the next block if the two are of the same type.
+ *
+ * @param block_index index of the block that may need merging.
+ *
+ * @return true if merge occurs, false otherwise.
+ */
+ bool merge_with_next_block(size_type block_index);
template<typename _T>
bool append_to_prev_block(
diff --git a/include/mdds/multi_type_vector_custom_func1.hpp b/include/mdds/multi_type_vector_custom_func1.hpp
new file mode 100644
index 0000000..f67c896
--- /dev/null
+++ b/include/mdds/multi_type_vector_custom_func1.hpp
@@ -0,0 +1,200 @@
+/*************************************************************************
+ *
+ * Copyright (c) 2013 Kohei Yoshida
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ ************************************************************************/
+
+#ifndef MDDS_MULTI_TYPE_VECTOR_CUSTOM_FUNC1_HPP
+#define MDDS_MULTI_TYPE_VECTOR_CUSTOM_FUNC1_HPP
+
+#include "multi_type_vector_types.hpp"
+#include "multi_type_vector_trait.hpp"
+
+namespace mdds { namespace mtv {
+
+/**
+ * Block function template for multi_type_vector with 1 user-defined block.
+ */
+template<element_t _TypeId, typename _Block>
+struct custom_block_func1
+{
+ static base_element_block* create_new_block(element_t type, size_t init_size)
+ {
+ switch (type)
+ {
+ case _TypeId:
+ return _Block::create_block(init_size);
+ default:
+ ;
+ }
+
+ return element_block_func::create_new_block(type, init_size);
+ }
+
+ static base_element_block* clone_block(const base_element_block& block)
+ {
+ switch (get_block_type(block))
+ {
+ case _TypeId:
+ return _Block::clone_block(block);
+ default:
+ ;
+ }
+
+ return element_block_func::clone_block(block);
+ }
+
+ static void delete_block(base_element_block* p)
+ {
+ if (!p)
+ return;
+
+ switch (get_block_type(*p))
+ {
+ case _TypeId:
+ _Block::delete_block(p);
+ break;
+ default:
+ element_block_func::delete_block(p);
+ }
+ }
+
+ static void resize_block(base_element_block& block, size_t new_size)
+ {
+ switch (get_block_type(block))
+ {
+ case _TypeId:
+ _Block::resize_block(block, new_size);
+ break;
+ default:
+ element_block_func::resize_block(block, new_size);
+ }
+ }
+
+ static void print_block(const base_element_block& block)
+ {
+ switch (get_block_type(block))
+ {
+ case _TypeId:
+ _Block::print_block(block);
+ break;
+ default:
+ element_block_func::print_block(block);
+ }
+ }
+
+ static void erase(base_element_block& block, size_t pos)
+ {
+ switch (get_block_type(block))
+ {
+ case _TypeId:
+ _Block::erase_block(block, pos);
+ break;
+ default:
+ element_block_func::erase(block, pos);
+ }
+ }
+
+ static void erase(base_element_block& block, size_t pos, size_t size)
+ {
+ switch (get_block_type(block))
+ {
+ case _TypeId:
+ _Block::erase_block(block, pos, size);
+ break;
+ default:
+ element_block_func_base::erase(block, pos, size);
+ }
+ }
+
+ static void append_values_from_block(base_element_block& dest, const base_element_block& src)
+ {
+ switch (get_block_type(dest))
+ {
+ case _TypeId:
+ _Block::append_values_from_block(dest, src);
+ break;
+ default:
+ element_block_func_base::append_values_from_block(dest, src);
+ }
+ }
+
+ static void append_values_from_block(
+ base_element_block& dest, const base_element_block& src, size_t begin_pos, size_t len)
+ {
+ switch (get_block_type(dest))
+ {
+ case _TypeId:
+ _Block::append_values_from_block(dest, src, begin_pos, len);
+ break;
+ default:
+ element_block_func_base::append_values_from_block(dest, src, begin_pos, len);
+ }
+ }
+
+ static void assign_values_from_block(
+ base_element_block& dest, const base_element_block& src, size_t begin_pos, size_t len)
+ {
+ switch (get_block_type(dest))
+ {
+ case _TypeId:
+ _Block::assign_values_from_block(dest, src, begin_pos, len);
+ break;
+ default:
+ element_block_func_base::assign_values_from_block(dest, src, begin_pos, len);
+ }
+ }
+
+ static bool equal_block(
+ const base_element_block& left, const base_element_block& right)
+ {
+ if (get_block_type(left) == _TypeId)
+ {
+ if (get_block_type(right) != _TypeId)
+ return false;
+
+ return _Block::get(left) == _Block::get(right);
+ }
+ else if (mtv::get_block_type(right) == _TypeId)
+ return false;
+
+ return element_block_func::equal_block(left, right);
+ }
+
+ static void overwrite_values(base_element_block& block, size_t pos, size_t len)
+ {
+ switch (get_block_type(block))
+ {
+ case _TypeId:
+ _Block::overwrite_values(block, pos, len);
+ break;
+ default:
+ element_block_func::overwrite_values(block, pos, len);
+ }
+ }
+};
+
+}}
+
+#endif
diff --git a/include/mdds/multi_type_vector_custom_func2.hpp b/include/mdds/multi_type_vector_custom_func2.hpp
new file mode 100644
index 0000000..5b2c146
--- /dev/null
+++ b/include/mdds/multi_type_vector_custom_func2.hpp
@@ -0,0 +1,241 @@
+/*************************************************************************
+ *
+ * Copyright (c) 2013 Kohei Yoshida
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ ************************************************************************/
+
+#ifndef MDDS_MULTI_TYPE_VECTOR_CUSTOM_FUNC2_HPP
+#define MDDS_MULTI_TYPE_VECTOR_CUSTOM_FUNC2_HPP
+
+#include "multi_type_vector_types.hpp"
+#include "multi_type_vector_trait.hpp"
+
+namespace mdds { namespace mtv {
+
+/**
+ * Block function template for multi_type_vector with 1 user-defined block.
+ */
+template<element_t _TypeId1, typename _Block1, element_t _TypeId2, typename _Block2>
+struct custom_block_func2
+{
+ static base_element_block* create_new_block(element_t type, size_t init_size)
+ {
+ switch (type)
+ {
+ case _TypeId1:
+ return _Block1::create_block(init_size);
+ case _TypeId2:
+ return _Block2::create_block(init_size);
+ default:
+ ;
+ }
+
+ return element_block_func::create_new_block(type, init_size);
+ }
+
+ static base_element_block* clone_block(const base_element_block& block)
+ {
+ switch (get_block_type(block))
+ {
+ case _TypeId1:
+ return _Block1::clone_block(block);
+ case _TypeId2:
+ return _Block2::clone_block(block);
+ default:
+ ;
+ }
+
+ return element_block_func::clone_block(block);
+ }
+
+ static void delete_block(base_element_block* p)
+ {
+ if (!p)
+ return;
+
+ switch (get_block_type(*p))
+ {
+ case _TypeId1:
+ _Block1::delete_block(p);
+ break;
+ case _TypeId2:
+ _Block2::delete_block(p);
+ break;
+ default:
+ element_block_func::delete_block(p);
+ }
+ }
+
+ static void resize_block(base_element_block& block, size_t new_size)
+ {
+ switch (get_block_type(block))
+ {
+ case _TypeId1:
+ _Block1::resize_block(block, new_size);
+ break;
+ case _TypeId2:
+ _Block2::resize_block(block, new_size);
+ break;
+ default:
+ element_block_func::resize_block(block, new_size);
+ }
+ }
+
+ static void print_block(const base_element_block& block)
+ {
+ switch (get_block_type(block))
+ {
+ case _TypeId1:
+ _Block1::print_block(block);
+ break;
+ case _TypeId2:
+ _Block2::print_block(block);
+ break;
+ default:
+ element_block_func::print_block(block);
+ }
+ }
+
+ static void erase(base_element_block& block, size_t pos)
+ {
+ switch (get_block_type(block))
+ {
+ case _TypeId1:
+ _Block1::erase_block(block, pos);
+ break;
+ case _TypeId2:
+ _Block2::erase_block(block, pos);
+ break;
+ default:
+ element_block_func::erase(block, pos);
+ }
+ }
+
+ static void erase(base_element_block& block, size_t pos, size_t size)
+ {
+ switch (get_block_type(block))
+ {
+ case _TypeId1:
+ _Block1::erase_block(block, pos, size);
+ break;
+ case _TypeId2:
+ _Block2::erase_block(block, pos, size);
+ break;
+ default:
+ element_block_func_base::erase(block, pos, size);
+ }
+ }
+
+ static void append_values_from_block(base_element_block& dest, const base_element_block& src)
+ {
+ switch (get_block_type(dest))
+ {
+ case _TypeId1:
+ _Block1::append_values_from_block(dest, src);
+ break;
+ case _TypeId2:
+ _Block2::append_values_from_block(dest, src);
+ break;
+ default:
+ element_block_func_base::append_values_from_block(dest, src);
+ }
+ }
+
+ static void append_values_from_block(
+ base_element_block& dest, const base_element_block& src, size_t begin_pos, size_t len)
+ {
+ switch (get_block_type(dest))
+ {
+ case _TypeId1:
+ _Block1::append_values_from_block(dest, src, begin_pos, len);
+ break;
+ case _TypeId2:
+ _Block2::append_values_from_block(dest, src, begin_pos, len);
+ break;
+ default:
+ element_block_func_base::append_values_from_block(dest, src, begin_pos, len);
+ }
+ }
+
+ static void assign_values_from_block(
+ base_element_block& dest, const base_element_block& src, size_t begin_pos, size_t len)
+ {
+ switch (get_block_type(dest))
+ {
+ case _TypeId1:
+ _Block1::assign_values_from_block(dest, src, begin_pos, len);
+ break;
+ case _TypeId2:
+ _Block2::assign_values_from_block(dest, src, begin_pos, len);
+ break;
+ default:
+ element_block_func_base::assign_values_from_block(dest, src, begin_pos, len);
+ }
+ }
+
+ static bool equal_block(
+ const base_element_block& left, const base_element_block& right)
+ {
+ if (get_block_type(left) == _TypeId1)
+ {
+ if (get_block_type(right) != _TypeId1)
+ return false;
+
+ return _Block1::get(left) == _Block1::get(right);
+ }
+ else if (mtv::get_block_type(right) == _TypeId1)
+ return false;
+
+ if (get_block_type(left) == _TypeId2)
+ {
+ if (get_block_type(right) != _TypeId2)
+ return false;
+
+ return _Block2::get(left) == _Block2::get(right);
+ }
+ else if (mtv::get_block_type(right) == _TypeId2)
+ return false;
+
+ return element_block_func::equal_block(left, right);
+ }
+
+ static void overwrite_values(base_element_block& block, size_t pos, size_t len)
+ {
+ switch (get_block_type(block))
+ {
+ case _TypeId1:
+ _Block1::overwrite_values(block, pos, len);
+ break;
+ case _TypeId2:
+ _Block2::overwrite_values(block, pos, len);
+ break;
+ default:
+ element_block_func::overwrite_values(block, pos, len);
+ }
+ }
+};
+
+}}
+
+#endif
diff --git a/include/mdds/multi_type_vector_def.inl b/include/mdds/multi_type_vector_def.inl
index 32e6c99..2299a7b 100644
--- a/include/mdds/multi_type_vector_def.inl
+++ b/include/mdds/multi_type_vector_def.inl
@@ -29,7 +29,7 @@
#include <stdexcept>
-#if UNIT_TEST
+#ifdef MDDS_UNIT_TEST
#include <iostream>
using std::cout;
using std::endl;
@@ -46,6 +46,8 @@ MDDS_MTV_DEFINE_ELEMENT_CALLBACKS(unsigned int, mtv::element_type_uint, 0, mtv::
MDDS_MTV_DEFINE_ELEMENT_CALLBACKS(long, mtv::element_type_long, 0, mtv::long_element_block)
MDDS_MTV_DEFINE_ELEMENT_CALLBACKS(unsigned long, mtv::element_type_ulong, 0, mtv::ulong_element_block)
MDDS_MTV_DEFINE_ELEMENT_CALLBACKS(bool, mtv::element_type_boolean, false, mtv::boolean_element_block)
+MDDS_MTV_DEFINE_ELEMENT_CALLBACKS(char, mtv::element_type_char, 0, mtv::char_element_block)
+MDDS_MTV_DEFINE_ELEMENT_CALLBACKS(unsigned char, mtv::element_type_uchar, 0, mtv::uchar_element_block)
template<typename _CellBlockFunc>
multi_type_vector<_CellBlockFunc>::block::block() : m_size(0), mp_data(NULL) {}
@@ -189,7 +191,7 @@ multi_type_vector<_CellBlockFunc>::set(size_type pos, const _T& value)
template<typename _CellBlockFunc>
template<typename _T>
typename multi_type_vector<_CellBlockFunc>::iterator
-multi_type_vector<_CellBlockFunc>::set(iterator pos_hint, size_type pos, const _T& value)
+multi_type_vector<_CellBlockFunc>::set(const iterator& pos_hint, size_type pos, const _T& value)
{
size_type start_row = 0;
size_type block_index = 0;
@@ -377,7 +379,7 @@ multi_type_vector<_CellBlockFunc>::set(size_type pos, const _T& it_begin, const
template<typename _CellBlockFunc>
template<typename _T>
typename multi_type_vector<_CellBlockFunc>::iterator
-multi_type_vector<_CellBlockFunc>::set(iterator pos_hint, size_type pos, const _T& it_begin, const _T& it_end)
+multi_type_vector<_CellBlockFunc>::set(const iterator& pos_hint, size_type pos, const _T& it_begin, const _T& it_end)
{
size_type end_pos = 0;
if (!set_cells_precheck(pos, it_begin, it_end, end_pos))
@@ -404,7 +406,7 @@ multi_type_vector<_CellBlockFunc>::insert(size_type pos, const _T& it_begin, con
template<typename _CellBlockFunc>
template<typename _T>
typename multi_type_vector<_CellBlockFunc>::iterator
-multi_type_vector<_CellBlockFunc>::insert(iterator pos_hint, size_type pos, const _T& it_begin, const _T& it_end)
+multi_type_vector<_CellBlockFunc>::insert(const iterator& pos_hint, size_type pos, const _T& it_begin, const _T& it_end)
{
size_type block_index = 0, start_pos = 0;
get_block_position(pos_hint, pos, start_pos, block_index);
@@ -435,7 +437,7 @@ bool multi_type_vector<_CellBlockFunc>::get_block_position(
template<typename _CellBlockFunc>
void multi_type_vector<_CellBlockFunc>::get_block_position(
- iterator pos_hint, size_type pos, size_type& start_row, size_type& block_index) const
+ const iterator& pos_hint, size_type pos, size_type& start_row, size_type& block_index) const
{
start_row = 0;
block_index = 0;
@@ -1057,6 +1059,96 @@ _T multi_type_vector<_CellBlockFunc>::get(size_type pos) const
}
template<typename _CellBlockFunc>
+template<typename _T>
+_T multi_type_vector<_CellBlockFunc>::release(size_type pos)
+{
+ size_type start_row = 0;
+ size_type block_index = 0;
+ if (!get_block_position(pos, start_row, block_index))
+ throw std::out_of_range("Block position not found!");
+
+ const block* blk = m_blocks[block_index];
+ assert(blk);
+
+ _T value;
+ if (!blk->mp_data)
+ {
+ // Empty cell block. There is no element to release.
+ mdds_mtv_get_empty_value(value);
+ return value;
+ }
+
+ assert(pos >= start_row);
+ assert(blk->mp_data); // data for non-empty blocks should never be NULL.
+ size_type idx = pos - start_row;
+ mdds_mtv_get_value(*blk->mp_data, idx, value);
+
+ // Set the element slot empty without overwriting it.
+ set_empty_in_single_block(pos, pos, block_index, start_row, false);
+ return value;
+}
+
+template<typename _CellBlockFunc>
+std::pair<typename multi_type_vector<_CellBlockFunc>::iterator, typename multi_type_vector<_CellBlockFunc>::size_type>
+multi_type_vector<_CellBlockFunc>::position(size_type pos)
+{
+ typedef std::pair<iterator, size_type> ret_type;
+
+ size_type start_row = 0;
+ size_type block_index = 0;
+ if (!get_block_position(pos, start_row, 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);
+}
+
+template<typename _CellBlockFunc>
+std::pair<typename multi_type_vector<_CellBlockFunc>::const_iterator, typename multi_type_vector<_CellBlockFunc>::size_type>
+multi_type_vector<_CellBlockFunc>::position(size_type pos) const
+{
+ typedef std::pair<const_iterator, size_type> ret_type;
+
+ size_type start_row = 0;
+ size_type block_index = 0;
+ if (!get_block_position(pos, start_row, block_index))
+ throw std::out_of_range("Block position not found!");
+
+ typename blocks_type::const_iterator block_pos = m_blocks.begin();
+ std::advance(block_pos, block_index);
+ const_iterator it = const_iterator(block_pos, m_blocks.end(), start_row, block_index);
+ return ret_type(it, pos - start_row);
+}
+
+template<typename _CellBlockFunc>
+typename multi_type_vector<_CellBlockFunc>::iterator
+multi_type_vector<_CellBlockFunc>::transfer(
+ size_type start_pos, size_type end_pos, multi_type_vector& dest, size_type dest_pos)
+{
+ if (&dest == this)
+ throw invalid_arg_error("You cannot transfer between the same container.");
+
+ size_type start_pos_in_block1 = 0;
+ size_type block_index1 = 0;
+ 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);
+}
+
+template<typename _CellBlockFunc>
+typename multi_type_vector<_CellBlockFunc>::iterator
+multi_type_vector<_CellBlockFunc>::transfer(
+ const iterator& pos_hint, size_type start_pos, size_type end_pos,
+ multi_type_vector& dest, size_type dest_pos)
+{
+ 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);
+}
+
+template<typename _CellBlockFunc>
mtv::element_t multi_type_vector<_CellBlockFunc>::get_type(size_type pos) const
{
size_type start_row = 0;
@@ -1096,7 +1188,7 @@ multi_type_vector<_CellBlockFunc>::set_empty(size_type start_pos, size_type end_
template<typename _CellBlockFunc>
typename multi_type_vector<_CellBlockFunc>::iterator
-multi_type_vector<_CellBlockFunc>::set_empty(iterator pos_hint, size_type start_pos, size_type end_pos)
+multi_type_vector<_CellBlockFunc>::set_empty(const iterator& pos_hint, size_type start_pos, size_type end_pos)
{
size_type start_pos_in_block1 = 0;
size_type block_index1 = 0;
@@ -1106,6 +1198,326 @@ multi_type_vector<_CellBlockFunc>::set_empty(iterator pos_hint, size_type start_
template<typename _CellBlockFunc>
typename multi_type_vector<_CellBlockFunc>::iterator
+multi_type_vector<_CellBlockFunc>::transfer_impl(
+ size_type start_pos, size_type end_pos, size_type start_pos_in_block1, size_type block_index1,
+ multi_type_vector& dest, size_type dest_pos)
+{
+ if (start_pos > end_pos)
+ throw std::out_of_range("Start row is larger than the end row.");
+
+ size_type start_pos_in_block2 = start_pos_in_block1;
+ size_type block_index2 = block_index1;
+ if (!get_block_position(end_pos, start_pos_in_block2, block_index2))
+ throw std::out_of_range("Block position not found!");
+
+ size_type len = end_pos - start_pos + 1;
+ size_type last_dest_pos = dest_pos + len - 1;
+
+ // Make sure the destination container is large enough.
+ if (last_dest_pos >= dest.size())
+ throw std::out_of_range("Destination vector is too small for the elements being transferred.");
+
+ if (block_index1 == block_index2)
+ {
+ // All elements are in the same block.
+ return transfer_single_block(start_pos, end_pos, start_pos_in_block1, block_index1, dest, dest_pos);
+ }
+
+ assert(block_index1 < block_index2);
+
+ // Empty the region in the destination container where the elements
+ // are to be transferred to. This ensures that the destination region
+ // consists of a single block.
+ iterator it_dest_blk = dest.set_empty(dest_pos, last_dest_pos);
+
+ size_type dest_block_index = it_dest_blk->__private_data.block_index;
+ size_type dest_pos_in_block = dest_pos - it_dest_blk->__private_data.start_pos;
+ block* blk_dest = dest.m_blocks[dest_block_index];
+ assert(!blk_dest->mp_data); // should be already emptied.
+
+ size_type block_len = block_index2 - block_index1 + 1;
+
+ // Create slots for new blocks in the destination.
+
+ size_type dest_block_index1 = dest_block_index;
+ if (dest_pos_in_block == 0)
+ {
+ // Copy to the top part of destination block.
+ if (len < blk_dest->m_size)
+ {
+ // Shrink the existing block and insert slots for new blocks before it.
+ assert(len < blk_dest->m_size);
+ blk_dest->m_size -= len;
+ dest.m_blocks.insert(dest.m_blocks.begin()+dest_block_index, block_len, NULL);
+ }
+ else
+ {
+ // Destination block is exactly of the length of the elements being transferred.
+ delete dest.m_blocks[dest_block_index];
+ dest.m_blocks[dest_block_index] = NULL;
+ if (block_len > 1)
+ dest.m_blocks.insert(dest.m_blocks.begin()+dest_block_index, block_len-1, NULL);
+ }
+ }
+ else if (dest_pos_in_block + len - 1 == it_dest_blk->size - 1)
+ {
+ // Copy to the bottom part of destination block. Insert slots for new
+ // blocks below current, and shrink the current block.
+ dest.m_blocks.insert(dest.m_blocks.begin()+dest_block_index+1, block_len, NULL);
+ blk_dest->m_size -= len;
+
+ ++dest_block_index1;
+ }
+ else
+ {
+ // Copy to the middle of destination block. Insert slots for new
+ // blocks (plus one for the empty block) 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, block_len+1, NULL);
+ dest.m_blocks[dest_block_index+block_len+1] = new block(blk2_size);
+ blk_dest->m_size = dest_pos_in_block;
+
+ ++dest_block_index1;
+ }
+
+ size_type del_index1 = block_index1, del_index2 = block_index2;
+ size_type ret_block_index = block_index1, ret_start_pos = start_pos_in_block1;
+
+ // Now that the new slots have been created, start transferring the blocks.
+
+ // Transfer the first block.
+ size_type offset = start_pos - start_pos_in_block1;
+ if (offset)
+ {
+ // Transfer the lower part of the first block.
+ block* blk = m_blocks[block_index1];
+ assert(!dest.m_blocks[dest_block_index1]);
+ dest.m_blocks[dest_block_index1] = new block(blk->m_size - offset);
+ if (blk->mp_data)
+ {
+ element_category_type cat = mtv::get_block_type(*blk->mp_data);
+ blk_dest = dest.m_blocks[dest_block_index1];
+ blk_dest->mp_data = element_block_func::create_new_block(cat, 0);
+ assert(blk_dest->mp_data);
+
+ // Shallow-copy the elements to the destination block, and shrink
+ // the source block to remove the transferred elements.
+ element_block_func::assign_values_from_block(*blk_dest->mp_data, *blk->mp_data, offset, blk->m_size-offset);
+ element_block_func::resize_block(*blk->mp_data, offset);
+ }
+
+ blk->m_size = offset;
+ ++del_index1; // Retain this block.
+
+ // Move the return block position to the next block.
+ ++ret_block_index;
+ ret_start_pos += blk->m_size;
+ }
+ else
+ {
+ // Just move the whole block over.
+ dest.m_blocks[dest_block_index1] = m_blocks[block_index1];
+ m_blocks[block_index1] = NULL;
+ }
+
+ if (block_len > 2)
+ {
+ // Transfer all blocks in between.
+ for (size_type i = 0; i < block_len - 2; ++i)
+ {
+ size_type src_block_pos = block_index1 + 1 + i;
+ size_type dest_block_pos = dest_block_index1 + 1 + i;
+ assert(!dest.m_blocks[dest_block_pos]);
+ dest.m_blocks[dest_block_pos] = m_blocks[src_block_pos];
+ m_blocks[src_block_pos] = NULL;
+ }
+ }
+
+ // Transfer the last block.
+ if (block_len > 1)
+ {
+ size_type size_to_trans = end_pos - start_pos_in_block2 + 1;
+ size_type dest_block_pos = dest_block_index1 + block_len - 1;
+ assert(!dest.m_blocks[dest_block_pos]);
+
+ block* blk = m_blocks[block_index2];
+ if (size_to_trans < blk->m_size)
+ {
+ // Transfer the upper part of this block.
+ dest.m_blocks[dest_block_pos] = new block(size_to_trans);
+ blk_dest = dest.m_blocks[dest_block_pos];
+ if (blk->mp_data)
+ {
+ element_category_type cat = mtv::get_block_type(*blk->mp_data);
+ blk_dest->mp_data = element_block_func::create_new_block(cat, 0);
+
+ element_block_func::assign_values_from_block(*blk_dest->mp_data, *blk->mp_data, 0, size_to_trans);
+ element_block_func::erase(*blk->mp_data, 0, size_to_trans);
+ }
+ blk->m_size -= size_to_trans;
+ --del_index2; // Retain this block.
+ }
+ else
+ {
+ // Just move the whole block over.
+ dest.m_blocks[dest_block_pos] = m_blocks[block_index2];
+ m_blocks[block_index2] = NULL;
+ }
+ }
+
+ // Now that all the elements have been transferred, check the bordering
+ // blocks in the destination and merge them as needed.
+ if (block_len > 1)
+ dest.merge_with_adjacent_blocks(dest_block_index1+block_len-1);
+ dest.merge_with_adjacent_blocks(dest_block_index1);
+
+ // Delete all transferred blocks, and replace it with one empty block.
+ assert(del_index2 >= del_index1);
+ if (del_index1 > 0 && !m_blocks[del_index1-1]->mp_data)
+ {
+ // The block before the first block to be deleted is empty. Simply
+ // extend that block to cover the deleted block segment.
+ block* blk_prev = m_blocks[del_index1-1];
+
+ // This previous empty block will be returned. Adjust the return block position.
+ --ret_block_index;
+ ret_start_pos -= blk_prev->m_size;
+
+ // Extend the previous block.
+ blk_prev->m_size += len;
+ }
+ else
+ {
+ // Block before is not empty (or doesn't exist). Keep the first slot,
+ // and erase the rest.
+ m_blocks[del_index1] = new block(len); // Insert an empty
+ ++del_index1;
+ }
+
+ if (del_index2 >= del_index1)
+ {
+ typename blocks_type::iterator it_blk = m_blocks.begin();
+ typename blocks_type::iterator it_blk_end = m_blocks.begin();
+ std::advance(it_blk, del_index1);
+ std::advance(it_blk_end, del_index2+1);
+
+#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG
+ typename blocks_type::iterator it_test = it_blk;
+ for (; it_test != it_blk_end; ++it_test)
+ {
+ // All slots to be erased should be NULL.
+ assert(!*it_test);
+ }
+#endif
+ m_blocks.erase(it_blk, it_blk_end);
+ }
+
+ size_type start_pos_offset = merge_with_adjacent_blocks(ret_block_index);
+ if (start_pos_offset)
+ {
+ // Merged with the previous block. Adjust the return block position.
+ --ret_block_index;
+ ret_start_pos -= start_pos_offset;
+ }
+
+ return get_iterator(ret_block_index, ret_start_pos);
+}
+
+template<typename _CellBlockFunc>
+typename multi_type_vector<_CellBlockFunc>::iterator
+multi_type_vector<_CellBlockFunc>::transfer_single_block(
+ size_type start_pos, size_type end_pos, size_type start_pos_in_block1, size_type block_index1,
+ multi_type_vector& dest, size_type dest_pos)
+{
+ size_type len = end_pos - start_pos + 1;
+ size_type last_dest_pos = dest_pos + len - 1;
+
+ // All elements are in the same block.
+ block* blk = m_blocks[block_index1];
+
+ // Empty the region in the destination container where the elements
+ // are to be transferred to. This ensures that the destination region
+ // consists of a single block.
+ iterator it_dest_blk = dest.set_empty(dest_pos, last_dest_pos);
+
+ if (!blk->mp_data)
+ return get_iterator(block_index1, start_pos_in_block1);
+
+ element_category_type cat = get_block_type(*blk->mp_data);
+
+ size_type dest_block_index = it_dest_blk->__private_data.block_index;
+ block* blk_dest = dest.m_blocks[dest_block_index];
+
+ size_type dest_pos_in_block = dest_pos - it_dest_blk->__private_data.start_pos;
+ if (dest_pos_in_block == 0)
+ {
+ // Copy to the top part of destination block.
+
+ assert(!blk_dest->mp_data); // should be already emptied.
+
+ if (len < blk_dest->m_size)
+ {
+ // Shrink the existing block and insert a new block before it.
+ assert(len < blk_dest->m_size);
+ blk_dest->m_size -= len;
+ dest.m_blocks.insert(dest.m_blocks.begin()+dest_block_index, new block(len));
+ blk_dest = dest.m_blocks[dest_block_index];
+ }
+ }
+ else if (dest_pos_in_block + len - 1 == it_dest_blk->size - 1)
+ {
+ // Copy to the bottom part of destination block.
+
+ // Insert a new block below current, and shrink the current block.
+ dest.m_blocks.insert(dest.m_blocks.begin()+dest_block_index+1, new block(len));
+ blk_dest->m_size -= len;
+ blk_dest = dest.m_blocks[dest_block_index+1];
+ }
+ else
+ {
+ // Copy to the middle of destination 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[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;
+
+ blk_dest = dest.m_blocks[dest_block_index+1];
+ }
+
+ assert(blk_dest->m_size == len);
+ size_type offset = start_pos - start_pos_in_block1;
+ if (offset == 0 && len == blk->m_size)
+ {
+ // Just move the whole data array.
+ blk_dest->mp_data = blk->mp_data;
+ blk->mp_data = NULL;
+ dest.merge_with_adjacent_blocks(dest_block_index);
+ size_type start_pos_offset = merge_with_adjacent_blocks(block_index1);
+ if (start_pos_offset)
+ {
+ // Merged with the previous block. Adjust the return block position.
+ --block_index1;
+ start_pos_in_block1 -= start_pos_offset;
+ }
+ return get_iterator(block_index1, start_pos_in_block1);
+ }
+
+ blk_dest->mp_data = element_block_func::create_new_block(cat, 0);
+ assert(blk_dest->mp_data);
+
+ // Shallow-copy the elements to the destination block.
+ element_block_func::assign_values_from_block(*blk_dest->mp_data, *blk->mp_data, offset, len);
+ dest.merge_with_adjacent_blocks(dest_block_index);
+
+ // Set the source range empty without overwriting the elements.
+ return set_empty_in_single_block(start_pos, end_pos, block_index1, start_pos_in_block1, false);
+}
+
+template<typename _CellBlockFunc>
+typename multi_type_vector<_CellBlockFunc>::iterator
multi_type_vector<_CellBlockFunc>::set_empty_impl(
size_type start_pos, size_type end_pos, size_type start_pos_in_block1, size_type block_index1)
{
@@ -1118,10 +1530,10 @@ multi_type_vector<_CellBlockFunc>::set_empty_impl(
throw std::out_of_range("Block position not found!");
if (block_index1 == block_index2)
- return set_empty_in_single_block(start_pos, end_pos, block_index1, start_pos_in_block1);
+ return set_empty_in_single_block(start_pos, end_pos, block_index1, start_pos_in_block1, true);
return set_empty_in_multi_blocks(
- start_pos, end_pos, block_index1, start_pos_in_block1, block_index2, start_pos_in_block2);
+ start_pos, end_pos, block_index1, start_pos_in_block1, block_index2, start_pos_in_block2, true);
}
template<typename _CellBlockFunc>
@@ -1283,7 +1695,7 @@ multi_type_vector<_CellBlockFunc>::insert_empty(size_type pos, size_type length)
template<typename _CellBlockFunc>
typename multi_type_vector<_CellBlockFunc>::iterator
-multi_type_vector<_CellBlockFunc>::insert_empty(iterator pos_hint, size_type pos, size_type length)
+multi_type_vector<_CellBlockFunc>::insert_empty(const iterator& pos_hint, size_type pos, size_type length)
{
if (!length)
// Nothing to insert.
@@ -1960,25 +2372,129 @@ multi_type_vector<_CellBlockFunc>::set_cells_to_multi_blocks_block1_non_empty(
}
template<typename _CellBlockFunc>
-void multi_type_vector<_CellBlockFunc>::merge_with_next_block(size_type block_index)
+typename multi_type_vector<_CellBlockFunc>::size_type
+multi_type_vector<_CellBlockFunc>::merge_with_adjacent_blocks(size_type block_index)
{
+ assert(!m_blocks.empty());
+ assert(block_index < m_blocks.size());
+ block* blk_prev = block_index > 0 ? m_blocks[block_index-1] : NULL;
+
+ if (!blk_prev)
+ {
+ // No previous block.
+ merge_with_next_block(block_index);
+ return 0;
+ }
+
+ size_type size_prev = blk_prev->m_size; // size of previous block.
+ block* blk = m_blocks[block_index];
+ block* blk_next = block_index < (m_blocks.size()-1) ? m_blocks[block_index+1] : NULL;
+
+ // Check the previous block.
+ if (blk_prev->mp_data)
+ {
+ // Previous block has data.
+ element_category_type cat_prev = mtv::get_block_type(*blk_prev->mp_data);
+ if (!blk->mp_data || cat_prev != mtv::get_block_type(*blk->mp_data))
+ {
+ // Current block is empty or is of different type from the previous one.
+ merge_with_next_block(block_index);
+ return 0;
+ }
+
+ // Previous and current blocks are of the same type.
+ if (blk_next && blk_next->mp_data && cat_prev == get_block_type(*blk_next->mp_data))
+ {
+ // Merge all three blocks.
+ blk_prev->m_size += blk->m_size + blk_next->m_size;
+ element_block_func::append_values_from_block(*blk_prev->mp_data, *blk->mp_data);
+ element_block_func::append_values_from_block(*blk_prev->mp_data, *blk_next->mp_data);
+ // Avoid overwriting the transferred elements.
+ element_block_func::resize_block(*blk->mp_data, 0);
+ element_block_func::resize_block(*blk_next->mp_data, 0);
+
+ delete blk;
+ delete blk_next;
+ typename blocks_type::iterator it = m_blocks.begin();
+ std::advance(it, block_index);
+ typename blocks_type::iterator it_end = it;
+ std::advance(it_end, 2);
+ m_blocks.erase(it, it_end);
+ return size_prev;
+ }
+
+ // Merge only the previous and current blocks.
+ bool merged = merge_with_next_block(block_index-1);
+ if (!merged)
+ assert(!"Blocks were not merged!");
+
+ return size_prev;
+ }
+
+ // Previous block is empty.
+ if (blk->mp_data)
+ {
+ // Current block is not empty. Check with the next block.
+ merge_with_next_block(block_index);
+ return 0;
+ }
+
+ // Previous and current blocks are both empty.
+ if (blk_next && !blk_next->mp_data)
+ {
+ // Next block is empty too. Merge all three.
+ blk_prev->m_size += blk->m_size + blk_next->m_size;
+ delete blk;
+ delete blk_next;
+ typename blocks_type::iterator it = m_blocks.begin();
+ std::advance(it, block_index);
+ typename blocks_type::iterator it_end = it;
+ std::advance(it_end, 2);
+ m_blocks.erase(it, it_end);
+ return size_prev;
+ }
+
+ // Next block is not empty, or does not exist. Merge the current block with the previous one.
+ bool merged = merge_with_next_block(block_index-1);
+ if (!merged)
+ assert(!"Blocks were not merged!");
+
+ return size_prev;
+}
+
+template<typename _CellBlockFunc>
+bool multi_type_vector<_CellBlockFunc>::merge_with_next_block(size_type block_index)
+{
+ assert(!m_blocks.empty());
+ assert(block_index < m_blocks.size());
+
if (block_index >= m_blocks.size()-1)
// No more block below this one.
- return;
+ return false;
// Block exists below.
block* blk = m_blocks[block_index];
+ block* blk_next = m_blocks[block_index+1];
if (!blk->mp_data)
- // Don't merge an empty block.
- return;
+ {
+ // Empty block. Merge only if the next block is also empty.
+ if (blk_next->mp_data)
+ // Next block is not empty.
+ return false;
+
+ // Merge the two blocks.
+ blk->m_size += blk_next->m_size;
+ delete m_blocks[block_index+1];
+ m_blocks.erase(m_blocks.begin()+block_index+1);
+ return true;
+ }
- block* blk_next = m_blocks[block_index+1];
if (!blk_next->mp_data)
- return;
+ return false;
if (mdds::mtv::get_block_type(*blk->mp_data) != mdds::mtv::get_block_type(*blk_next->mp_data))
// Block types differ. Don't merge.
- return;
+ return false;
// Merge it with the next block.
element_block_func::append_values_from_block(*blk->mp_data, *blk_next->mp_data);
@@ -1986,6 +2502,7 @@ void multi_type_vector<_CellBlockFunc>::merge_with_next_block(size_type block_in
blk->m_size += blk_next->m_size;
delete m_blocks[block_index+1];
m_blocks.erase(m_blocks.begin()+block_index+1);
+ return true;
}
template<typename _CellBlockFunc>
@@ -2177,9 +2694,14 @@ mtv::element_t multi_type_vector<_CellBlockFunc>::get_element_type(const _T& ele
template<typename _CellBlockFunc>
typename multi_type_vector<_CellBlockFunc>::iterator
-multi_type_vector<_CellBlockFunc>::set_whole_block_empty(size_type block_index, size_type start_pos_in_block)
+multi_type_vector<_CellBlockFunc>::set_whole_block_empty(
+ size_type block_index, size_type start_pos_in_block, bool overwrite)
{
block* blk = m_blocks[block_index];
+ if (!overwrite)
+ // Resize block to 0 before deleting, to prevent its elements from getting deleted.
+ element_block_func::resize_block(*blk->mp_data, 0);
+
element_block_func::delete_block(blk->mp_data);
blk->mp_data = NULL;
@@ -2252,7 +2774,7 @@ multi_type_vector<_CellBlockFunc>::set_whole_block_empty(size_type block_index,
template<typename _CellBlockFunc>
typename multi_type_vector<_CellBlockFunc>::iterator
multi_type_vector<_CellBlockFunc>::set_empty_in_single_block(
- size_type start_row, size_type end_row, size_type block_index, size_type start_row_in_block)
+ size_type start_row, size_type end_row, size_type block_index, size_type start_row_in_block, bool overwrite)
{
// Range is within a single block.
block* blk = m_blocks[block_index];
@@ -2269,10 +2791,11 @@ multi_type_vector<_CellBlockFunc>::set_empty_in_single_block(
// start row coincides with the start of a block.
if (end_row == end_row_in_block)
- return set_whole_block_empty(block_index, start_row_in_block);
+ return set_whole_block_empty(block_index, start_row_in_block, overwrite);
// Set the upper part of the block empty.
- element_block_func::overwrite_values(*blk->mp_data, 0, empty_block_size);
+ if (overwrite)
+ element_block_func::overwrite_values(*blk->mp_data, 0, empty_block_size);
element_block_func::erase(*blk->mp_data, 0, empty_block_size);
blk->m_size -= empty_block_size;
@@ -2306,7 +2829,8 @@ multi_type_vector<_CellBlockFunc>::set_empty_in_single_block(
// Set the lower part of the block empty.
size_type start_pos = start_row - start_row_in_block;
- element_block_func::overwrite_values(*blk->mp_data, start_pos, empty_block_size);
+ if (overwrite)
+ element_block_func::overwrite_values(*blk->mp_data, start_pos, empty_block_size);
element_block_func::erase(*blk->mp_data, start_pos, empty_block_size);
blk->m_size -= empty_block_size;
@@ -2349,10 +2873,13 @@ multi_type_vector<_CellBlockFunc>::set_empty_in_single_block(
end_row_in_block-start_row_in_block-lower_block_size+1,
lower_block_size);
- // Overwrite cells that will become empty.
size_type new_cur_size = start_row - start_row_in_block;
- element_block_func::overwrite_values(
- *blk->mp_data, new_cur_size, empty_block_size);
+ if (overwrite)
+ {
+ // Overwrite cells that will become empty.
+ element_block_func::overwrite_values(
+ *blk->mp_data, new_cur_size, empty_block_size);
+ }
// Shrink the current data block.
element_block_func::erase(
@@ -2367,7 +2894,7 @@ typename multi_type_vector<_CellBlockFunc>::iterator
multi_type_vector<_CellBlockFunc>::set_empty_in_multi_blocks(
size_type start_row, size_type end_row,
size_type block_index1, size_type start_row_in_block1,
- size_type block_index2, size_type start_row_in_block2)
+ size_type block_index2, size_type start_row_in_block2, bool overwrite)
{
assert(block_index1 < block_index2);
@@ -2401,6 +2928,9 @@ multi_type_vector<_CellBlockFunc>::set_empty_in_multi_blocks(
else
{
// Make block 1 empty.
+ if (!overwrite)
+ element_block_func::resize_block(*blk->mp_data, 0);
+
element_block_func::delete_block(blk->mp_data);
blk->mp_data = NULL;
}
@@ -2409,7 +2939,9 @@ multi_type_vector<_CellBlockFunc>::set_empty_in_multi_blocks(
{
// Empty the lower part.
size_type new_size = start_row - start_row_in_block1;
- element_block_func::overwrite_values(*blk->mp_data, new_size, blk->m_size-new_size);
+ if (overwrite)
+ element_block_func::overwrite_values(*blk->mp_data, new_size, blk->m_size-new_size);
+
element_block_func::resize_block(*blk->mp_data, new_size);
blk->m_size = new_size;
}
@@ -2456,7 +2988,9 @@ multi_type_vector<_CellBlockFunc>::set_empty_in_multi_blocks(
{
// Empty the upper part.
size_type size_to_erase = end_row - start_row_in_block2 + 1;
- element_block_func::overwrite_values(*blk->mp_data, 0, size_to_erase);
+ if (overwrite)
+ element_block_func::overwrite_values(*blk->mp_data, 0, size_to_erase);
+
element_block_func::erase(*blk->mp_data, 0, size_to_erase);
blk->m_size -= size_to_erase;
}
@@ -2475,7 +3009,13 @@ multi_type_vector<_CellBlockFunc>::set_empty_in_multi_blocks(
// Remove all blocks in-between, from block_index1+1 to end_block_to_erase-1.
for (size_type i = block_index1 + 1; i < end_block_to_erase; ++i)
- delete m_blocks[i];
+ {
+ block* blk = m_blocks[i];
+ if (!overwrite && blk->mp_data)
+ element_block_func::resize_block(*blk->mp_data, 0);
+
+ delete blk;
+ }
typename blocks_type::iterator it = m_blocks.begin() + block_index1 + 1;
typename blocks_type::iterator it_end = m_blocks.begin() + end_block_to_erase;
@@ -2496,4 +3036,20 @@ multi_type_vector<_CellBlockFunc>::set_empty_in_multi_blocks(
return get_iterator(block_index1, start_row);
}
+#ifdef MDDS_UNIT_TEST
+template<typename _CellBlockFunc>
+void multi_type_vector<_CellBlockFunc>::dump_blocks() const
+{
+ cout << "--- 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;
+ }
+}
+#endif
+
}
diff --git a/include/mdds/multi_type_vector_itr.hpp b/include/mdds/multi_type_vector_itr.hpp
index 60e533c..a7954d2 100644
--- a/include/mdds/multi_type_vector_itr.hpp
+++ b/include/mdds/multi_type_vector_itr.hpp
@@ -25,6 +25,11 @@
*
************************************************************************/
+#ifndef MDDS_MULTI_TYPE_VECTOR_ITR_HPP
+#define MDDS_MULTI_TYPE_VECTOR_ITR_HPP
+
+#include "multi_type_vector_types.hpp"
+
namespace mdds { namespace __mtv {
/**
@@ -359,6 +364,18 @@ public:
{
return dec();
}
+
+ bool operator== (const const_iterator_base& other) const
+ {
+ return iterator_common_base<_Trait>::operator==(other);
+ }
+
+ bool operator!= (const const_iterator_base& other) const
+ {
+ return iterator_common_base<_Trait>::operator!=(other);
+ }
};
}}
+
+#endif
diff --git a/include/mdds/multi_type_vector_trait.hpp b/include/mdds/multi_type_vector_trait.hpp
index 466ed8f..19807ba 100644
--- a/include/mdds/multi_type_vector_trait.hpp
+++ b/include/mdds/multi_type_vector_trait.hpp
@@ -92,6 +92,10 @@ base_element_block* element_block_func_base::create_new_block(element_t type, si
return ulong_element_block::create_block(init_size);
case element_type_boolean:
return boolean_element_block::create_block(init_size);
+ case element_type_char:
+ return char_element_block::create_block(init_size);
+ case element_type_uchar:
+ return uchar_element_block::create_block(init_size);
default:
throw general_error("create_new_block: failed to create a new block of unknown type.");
}
@@ -119,6 +123,10 @@ base_element_block* element_block_func_base::clone_block(const base_element_bloc
return ulong_element_block::clone_block(block);
case element_type_boolean:
return boolean_element_block::clone_block(block);
+ case element_type_char:
+ return char_element_block::clone_block(block);
+ case element_type_uchar:
+ return uchar_element_block::clone_block(block);
default:
throw general_error("clone_block: failed to clone a block of unknown type.");
}
@@ -158,6 +166,12 @@ void element_block_func_base::delete_block(base_element_block* p)
case element_type_boolean:
boolean_element_block::delete_block(p);
break;
+ case element_type_char:
+ char_element_block::delete_block(p);
+ break;
+ case element_type_uchar:
+ uchar_element_block::delete_block(p);
+ break;
default:
throw general_error("delete_block: failed to delete a block of unknown type.");
}
@@ -194,6 +208,12 @@ void element_block_func_base::resize_block(base_element_block& block, size_t new
case element_type_boolean:
boolean_element_block::resize_block(block, new_size);
break;
+ case element_type_char:
+ char_element_block::resize_block(block, new_size);
+ break;
+ case element_type_uchar:
+ uchar_element_block::resize_block(block, new_size);
+ break;
default:
throw general_error("resize_block: failed to resize a block of unknown type.");
}
@@ -230,6 +250,12 @@ void element_block_func_base::print_block(const base_element_block& block)
case element_type_boolean:
boolean_element_block::print_block(block);
break;
+ case element_type_char:
+ char_element_block::print_block(block);
+ break;
+ case element_type_uchar:
+ uchar_element_block::print_block(block);
+ break;
default:
throw general_error("print_block: failed to print a block of unknown type.");
}
@@ -266,6 +292,12 @@ void element_block_func_base::erase(base_element_block& block, size_t pos)
case element_type_boolean:
boolean_element_block::erase_block(block, pos);
break;
+ case element_type_char:
+ char_element_block::erase_block(block, pos);
+ break;
+ case element_type_uchar:
+ uchar_element_block::erase_block(block, pos);
+ break;
default:
throw general_error("erase: failed to erase an element from a block of unknown type.");
}
@@ -302,6 +334,12 @@ void element_block_func_base::erase(base_element_block& block, size_t pos, size_
case element_type_boolean:
boolean_element_block::erase_block(block, pos, size);
break;
+ case element_type_char:
+ char_element_block::erase_block(block, pos, size);
+ break;
+ case element_type_uchar:
+ uchar_element_block::erase_block(block, pos, size);
+ break;
default:
throw general_error("erase: failed to erase elements from a block of unknown type.");
}
@@ -338,6 +376,12 @@ void element_block_func_base::append_values_from_block(base_element_block& dest,
case element_type_boolean:
boolean_element_block::append_values_from_block(dest, src);
break;
+ case element_type_char:
+ char_element_block::append_values_from_block(dest, src);
+ break;
+ case element_type_uchar:
+ uchar_element_block::append_values_from_block(dest, src);
+ break;
default:
throw general_error("append_values: failed to append values to a block of unknown type.");
}
@@ -375,6 +419,12 @@ void element_block_func_base::append_values_from_block(
case element_type_boolean:
boolean_element_block::append_values_from_block(dest, src, begin_pos, len);
break;
+ case element_type_char:
+ char_element_block::append_values_from_block(dest, src, begin_pos, len);
+ break;
+ case element_type_uchar:
+ uchar_element_block::append_values_from_block(dest, src, begin_pos, len);
+ break;
default:
throw general_error("append_values: failed to append values to a block of unknown type.");
}
@@ -412,6 +462,12 @@ void element_block_func_base::assign_values_from_block(
case element_type_boolean:
boolean_element_block::assign_values_from_block(dest, src, begin_pos, len);
break;
+ case element_type_char:
+ char_element_block::assign_values_from_block(dest, src, begin_pos, len);
+ break;
+ case element_type_uchar:
+ uchar_element_block::assign_values_from_block(dest, src, begin_pos, len);
+ break;
default:
throw general_error("assign_values: failed to assign values to a block of unknown type.");
}
@@ -443,6 +499,10 @@ bool element_block_func_base::equal_block(const base_element_block& left, const
return ulong_element_block::get(left) == ulong_element_block::get(right);
case element_type_boolean:
return boolean_element_block::get(left) == boolean_element_block::get(right);
+ case element_type_char:
+ return char_element_block::get(left) == char_element_block::get(right);
+ case element_type_uchar:
+ return uchar_element_block::get(left) == uchar_element_block::get(right);
default:
;
}
diff --git a/include/mdds/multi_type_vector_types.hpp b/include/mdds/multi_type_vector_types.hpp
index 5680233..327e7b7 100644
--- a/include/mdds/multi_type_vector_types.hpp
+++ b/include/mdds/multi_type_vector_types.hpp
@@ -33,9 +33,15 @@
#include "global.hpp"
#include <vector>
-#include <iostream>
#include <boost/noncopyable.hpp>
+#ifdef MDDS_UNIT_TEST
+#include <iostream>
+using std::cout;
+using std::cerr;
+using std::endl;
+#endif
+
namespace mdds { namespace mtv {
typedef int element_t;
@@ -51,6 +57,8 @@ const element_t element_type_uint = 5;
const element_t element_type_long = 6;
const element_t element_type_ulong = 7;
const element_t element_type_boolean = 8;
+const element_t element_type_char = 9;
+const element_t element_type_uchar = 10;
const element_t element_type_user_start = 50;
@@ -77,6 +85,7 @@ protected:
template<typename _Self, element_t _TypeId, typename _Data>
class element_block : public base_element_block
{
+#ifdef MDDS_UNIT_TEST
struct print_block_array
{
void operator() (const _Data& val) const
@@ -84,6 +93,7 @@ class element_block : public base_element_block
std::cout << val << " ";
}
};
+#endif
protected:
typedef std::vector<_Data> store_type;
@@ -110,6 +120,16 @@ public:
return !operator==(r);
}
+ static const value_type& at(const base_element_block& block, typename store_type::size_type pos)
+ {
+ return get(block).m_array.at(pos);
+ }
+
+ static value_type& at(base_element_block& block, typename store_type::size_type pos)
+ {
+ return get(block).m_array.at(pos);
+ }
+
static iterator begin(base_element_block& block)
{
return get(block).m_array.begin();
@@ -204,12 +224,16 @@ public:
static_cast<_Self&>(blk).m_array.resize(new_size);
}
+#ifdef MDDS_UNIT_TEST
static void print_block(const base_element_block& blk)
{
const store_type& blk2 = get(blk).m_array;
std::for_each(blk2.begin(), blk2.end(), print_block_array());
std::cout << std::endl;
}
+#else
+ static void print_block(const base_element_block&) {}
+#endif
static void erase_block(base_element_block& blk, size_t pos)
{
@@ -467,6 +491,8 @@ typedef default_element_block<mtv::element_type_uint, unsigned int> uint_ele
typedef default_element_block<mtv::element_type_long, long> long_element_block;
typedef default_element_block<mtv::element_type_ulong, unsigned long> ulong_element_block;
typedef default_element_block<mtv::element_type_boolean, bool> boolean_element_block;
+typedef default_element_block<mtv::element_type_char, char> char_element_block;
+typedef default_element_block<mtv::element_type_uchar, unsigned char> uchar_element_block;
}}
diff --git a/include/mdds/node.hpp b/include/mdds/node.hpp
index 6791363..585c342 100644
--- a/include/mdds/node.hpp
+++ b/include/mdds/node.hpp
@@ -36,36 +36,25 @@
namespace mdds {
-#ifdef DEBUG_NODE_BASE
+#ifdef MDDS_DEBUG_NODE_BASE
size_t node_instance_count = 0;
#endif
template<typename T>
-struct node_traits
-{
- typedef typename T::nonleaf_value_type nonleaf_value_type;
- typedef typename T::leaf_value_type leaf_value_type;
- typedef typename T::fill_nonleaf_value_handler fill_nonleaf_value_handler;
- typedef typename T::to_string_handler to_string_handler;
- typedef typename T::init_handler init_handler;
- typedef typename T::dispose_handler dispose_handler;
-};
-
-template<typename T>
struct node
{
typedef ::boost::intrusive_ptr<node> node_ptr;
- typedef typename node_traits<T>::nonleaf_value_type nonleaf_value_type;
- typedef typename node_traits<T>::leaf_value_type leaf_value_type;
- typedef typename node_traits<T>::fill_nonleaf_value_handler fill_nonleaf_value_handler;
- typedef typename node_traits<T>::to_string_handler to_string_handler;
- typedef typename node_traits<T>::init_handler init_handler;
- typedef typename node_traits<T>::dispose_handler dispose_handler;
+ typedef typename T::nonleaf_value_type nonleaf_value_type;
+ typedef typename T::leaf_value_type leaf_value_type;
+ typedef typename T::fill_nonleaf_value_handler fill_nonleaf_value_handler;
+ typedef typename T::to_string_handler to_string_handler;
+ typedef typename T::init_handler init_handler;
+ typedef typename T::dispose_handler dispose_handler;
static size_t get_instance_count()
{
-#ifdef DEBUG_NODE_BASE
+#ifdef MDDS_DEBUG_NODE_BASE
return node_instance_count;
#else
return 0;
@@ -95,7 +84,7 @@ public:
is_leaf(_is_leaf),
refcount(0)
{
-#ifdef DEBUG_NODE_BASE
+#ifdef MDDS_DEBUG_NODE_BASE
++node_instance_count;
#endif
_hdl_init(*this);
@@ -109,7 +98,7 @@ public:
is_leaf(r.is_leaf),
refcount(0)
{
-#ifdef DEBUG_NODE_BASE
+#ifdef MDDS_DEBUG_NODE_BASE
++node_instance_count;
#endif
if (is_leaf)
@@ -137,7 +126,7 @@ public:
~node()
{
-#ifdef DEBUG_NODE_BASE
+#ifdef MDDS_DEBUG_NODE_BASE
--node_instance_count;
#endif
dispose();
@@ -166,7 +155,7 @@ public:
_hdl_fill_nonleaf(*this, left_node, right_node);
}
-#ifdef UNIT_TEST
+#ifdef MDDS_UNIT_TEST
void dump_value() const
{
::std::cout << _hdl_to_string(*this);
@@ -335,7 +324,7 @@ _NodePtr build_tree(const _NodePtr& left_leaf_node)
return build_tree_non_leaf<_NodePtr, _NodeType>(node_list);
}
-#ifdef UNIT_TEST
+#ifdef MDDS_UNIT_TEST
template<typename _NodePtr>
size_t dump_tree_layer(const ::std::list<_NodePtr>& node_list, unsigned int level)
{
diff --git a/include/mdds/point_quad_tree.hpp b/include/mdds/point_quad_tree.hpp
index aac1b02..4ac8f61 100644
--- a/include/mdds/point_quad_tree.hpp
+++ b/include/mdds/point_quad_tree.hpp
@@ -475,7 +475,7 @@ public:
bool operator!= (const point_quad_tree& r) const { return !operator== (r); }
-#ifdef UNIT_TEST
+#ifdef MDDS_UNIT_TEST
public:
#else
private:
diff --git a/include/mdds/quad_node.hpp b/include/mdds/quad_node.hpp
index b632868..30cd9f4 100644
--- a/include/mdds/quad_node.hpp
+++ b/include/mdds/quad_node.hpp
@@ -34,7 +34,7 @@
namespace mdds {
-#ifdef DEBUG_NODE_BASE
+#ifdef MDDS_DEBUG_NODE_BASE
size_t node_instance_count = 0;
inline size_t get_node_instance_count()
{
@@ -140,7 +140,7 @@ struct quad_node_base
x(_x),
y(_y)
{
-#ifdef DEBUG_NODE_BASE
+#ifdef MDDS_DEBUG_NODE_BASE
++node_instance_count;
#endif
}
@@ -159,7 +159,7 @@ struct quad_node_base
x(r.x),
y(r.y)
{
-#ifdef DEBUG_NODE_BASE
+#ifdef MDDS_DEBUG_NODE_BASE
++node_instance_count;
#endif
}
@@ -190,7 +190,7 @@ struct quad_node_base
~quad_node_base()
{
-#ifdef DEBUG_NODE_BASE
+#ifdef MDDS_DEBUG_NODE_BASE
--node_instance_count;
#endif
static_cast<node_type*>(this)->dispose();
diff --git a/include/mdds/rectangle_set.hpp b/include/mdds/rectangle_set.hpp
index 82269a3..c898953 100644
--- a/include/mdds/rectangle_set.hpp
+++ b/include/mdds/rectangle_set.hpp
@@ -44,7 +44,7 @@ public:
typedef _Key key_type;
typedef _Data data_type;
-#ifdef UNIT_TEST
+#ifdef MDDS_UNIT_TEST
public:
#else
private:
@@ -221,7 +221,7 @@ public:
private:
void build_outer_segment_tree();
-#ifdef UNIT_TEST
+#ifdef MDDS_UNIT_TEST
public:
void dump_rectangles() const;
bool verify_rectangles(const dataset_type& expected) const;
diff --git a/include/mdds/rectangle_set_def.inl b/include/mdds/rectangle_set_def.inl
index bd0cb7f..3d074ed 100644
--- a/include/mdds/rectangle_set_def.inl
+++ b/include/mdds/rectangle_set_def.inl
@@ -233,7 +233,7 @@ void rectangle_set<_Key,_Data>::build_outer_segment_tree()
}
}
-#ifdef UNIT_TEST
+#ifdef MDDS_UNIT_TEST
template<typename _Key, typename _Data>
void rectangle_set<_Key,_Data>::dump_rectangles() const
{
diff --git a/include/mdds/segment_tree.hpp b/include/mdds/segment_tree.hpp
index 9ece0c5..292d048 100644
--- a/include/mdds/segment_tree.hpp
+++ b/include/mdds/segment_tree.hpp
@@ -39,7 +39,7 @@
#include <boost/shared_ptr.hpp>
#include <boost/ptr_container/ptr_map.hpp>
-#ifdef UNIT_TEST
+#ifdef MDDS_UNIT_TEST
#include <sstream>
#endif
@@ -125,7 +125,7 @@ public:
typedef size_t size_type;
typedef ::std::vector<data_type*> search_result_type;
-#ifdef UNIT_TEST
+#ifdef MDDS_UNIT_TEST
struct segment_data
{
key_type begin_key;
@@ -230,7 +230,7 @@ public:
{
::std::string operator() (const node& _self) const
{
-#ifdef UNIT_TEST
+#ifdef MDDS_UNIT_TEST
::std::ostringstream os;
if (_self.is_leaf)
{
@@ -285,7 +285,7 @@ public:
}
};
-#if UNIT_TEST
+#ifdef MDDS_UNIT_TEST
struct node_printer : public ::std::unary_function<const node*, void>
{
void operator() (const node* p) const
@@ -650,7 +650,7 @@ public:
*/
bool empty() const;
-#ifdef UNIT_TEST
+#ifdef MDDS_UNIT_TEST
void dump_tree() const;
void dump_leaf_nodes() const;
void dump_segment_data() const;
@@ -702,7 +702,7 @@ private:
void clear_all_nodes();
-#ifdef UNIT_TEST
+#ifdef MDDS_UNIT_TEST
static bool has_data_pointer(const node_list_type& node_list, const data_type* pdata);
static void print_leaf_value(const leaf_value_type& v);
#endif
@@ -1058,7 +1058,7 @@ void segment_tree<_Key, _Data>::clear_all_nodes()
m_root_node.reset();
}
-#ifdef UNIT_TEST
+#ifdef MDDS_UNIT_TEST
template<typename _Key, typename _Data>
void segment_tree<_Key, _Data>::dump_tree() const
{
diff --git a/misc/mdds.pc.in b/misc/mdds.pc.in
new file mode 100644
index 0000000..47caf03
--- /dev/null
+++ b/misc/mdds.pc.in
@@ -0,0 +1,7 @@
+prefix=@prefix@
+includedir=@includedir@
+
+Name: mdds
+Description: A collection of multi-dimensional data structure and indexing algorithm
+Version: @VERSION@
+Cflags: -I${includedir}
diff --git a/src/flat_segment_tree_test.cpp b/src/flat_segment_tree_test.cpp
index aec838d..3106745 100644
--- a/src/flat_segment_tree_test.cpp
+++ b/src/flat_segment_tree_test.cpp
@@ -40,7 +40,7 @@
using namespace std;
using namespace mdds;
-void printTitle(const char* msg)
+void print_title(const char* msg)
{
cout << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl;
cout << " " << msg << endl;
@@ -50,7 +50,7 @@ void printTitle(const char* msg)
void fst_test_leaf_search()
{
{
- printTitle("Simple insert test");
+ print_title("Simple insert test");
flat_segment_tree<int, int> int_ranges(0, 100, -1);
for (int i = 0; i < 20; ++i)
{
@@ -62,7 +62,7 @@ void fst_test_leaf_search()
}
{
- printTitle("Merge test 1");
+ print_title("Merge test 1");
flat_segment_tree<int, int> merge_test(0, 100, -1);
merge_test.insert_front(10, 20, 5);
merge_test.dump_leaf_nodes();
@@ -77,7 +77,7 @@ void fst_test_leaf_search()
}
{
- printTitle("Merge test 2");
+ print_title("Merge test 2");
flat_segment_tree<int, int> merge_test(0, 100, -1);
// This should not change the node configuration.
@@ -104,7 +104,7 @@ void fst_test_leaf_search()
}
{
- printTitle("Search test");
+ print_title("Search test");
flat_segment_tree<int, int> db(0, 100, -1);
for (int i = 0; i < 10; ++i)
{
@@ -179,7 +179,7 @@ void fst_perf_test_search(bool tree_search)
int val;
for (int i = lower; i < upper; ++i)
{
- if (db.search_tree(i, val))
+ if (db.search_tree(i, val).second)
++success;
else
++failure;
@@ -193,7 +193,7 @@ void fst_perf_test_search(bool tree_search)
{
if (tree_search)
{
- if (db.search_tree(i, val))
+ if (db.search_tree(i, val).second)
++success;
else
++failure;
@@ -213,8 +213,9 @@ void fst_perf_test_search(bool tree_search)
void fst_test_tree_search()
{
stack_printer __stack_printer__("::fst_test_tree_search");
+ typedef flat_segment_tree<int, int> fst_type;
int lower = 0, upper = 200, delta = 5;
- flat_segment_tree<int, int> db(lower, upper, 0);
+ fst_type db(lower, upper, 0);
for (int i = lower; i < upper; i += delta)
db.insert_front(i, i+delta, i);
@@ -226,7 +227,7 @@ void fst_test_tree_search()
int success = 0, failure = 0;
for (int i = lower-10; i < upper+10; ++i)
{
- if (db.search_tree(i, val, &start, &end))
+ if (db.search_tree(i, val, &start, &end).second)
{
cout << "key = " << i << "; value = " << val << " (" << start << "-" << end << ")" << endl;
++success;
@@ -238,12 +239,48 @@ void fst_test_tree_search()
}
}
cout << "search: success (" << success << ") failure (" << failure << ")" << endl;
+
+ // Make sure search_tree() returns correct iterator position.
+ db.clear();
+ db.insert_back(5, 10, 2);
+ db.insert_back(15, 18, 3);
+ db.insert_back(23, 28, 4);
+ db.build_tree();
+
+ typedef pair<fst_type::const_iterator,bool> ret_type;
+ ret_type ret = db.search_tree(0, val, &start, &end);
+ assert(ret.second);
+ assert(start == 0 && end == 5 && val == 0);
+ assert(ret.first == db.begin());
+
+ ret = db.search_tree(6, val, &start, &end);
+ assert(ret.second);
+ assert(start == 5 && end == 10 && val == 2);
+ fst_type::const_iterator check = db.begin();
+ ++check; // 5-10 is the 2nd segment from the top.
+ assert(ret.first == check);
+
+ ret = db.search_tree(17, val, &start, &end);
+ assert(ret.second);
+ assert(start == 15 && end == 18 && val == 3);
+ std::advance(check, 2);
+ assert(ret.first == check);
+
+ ret = db.search_tree(55, val, &start, &end);
+ assert(ret.second);
+ assert(start == 28 && end == upper && val == 0);
+ std::advance(check, 3);
+ assert(ret.first == check);
+
+ ret = db.search_tree(upper+10, val, &start, &end);
+ assert(!ret.second); // This search should fail.
+ assert(ret.first == db.end());
}
void test_single_tree_search(const flat_segment_tree<int, int>& db, int key, int val, int start, int end)
{
int r_val, r_start, r_end;
- if (db.search_tree(key, r_val, &r_start, &r_end))
+ if (db.search_tree(key, r_val, &r_start, &r_end).second)
assert(r_val == val && r_start == start && r_end == end);
else
assert(!"tree search failed!");
@@ -1764,7 +1801,7 @@ void fst_test_swap()
// Tree search should work on db2.
db_type::value_type val;
- assert(db2.search_tree(35, val));
+ assert(db2.search_tree(35, val).second);
assert(val == 2);
}
diff --git a/src/multi_type_vector_test_custom.cpp b/src/multi_type_vector_test_custom.cpp
index a0b877d..0700b2a 100644
--- a/src/multi_type_vector_test_custom.cpp
+++ b/src/multi_type_vector_test_custom.cpp
@@ -30,6 +30,8 @@
#define MDDS_MULTI_TYPE_VECTOR_DEBUG 1
#include <mdds/multi_type_vector.hpp>
#include <mdds/multi_type_vector_trait.hpp>
+#include <mdds/multi_type_vector_custom_func1.hpp>
+#include <mdds/multi_type_vector_custom_func2.hpp>
#include <cassert>
#include <sstream>
@@ -48,6 +50,9 @@ namespace {
/** custom cell type definition. */
const mtv::element_t element_type_user_block = mtv::element_type_user_start;
const mtv::element_t element_type_muser_block = mtv::element_type_user_start+1;
+const mtv::element_t element_type_fruit_block = mtv::element_type_user_start+2;
+
+enum my_fruit_type { unknown_fruit = 0, apple, orange, mango, peach };
/** Caller manages the life cycle of these cells. */
struct user_cell
@@ -71,9 +76,6 @@ struct muser_cell
muser_cell(double _v) : value(_v) {}
};
-typedef mdds::mtv::default_element_block<element_type_user_block, user_cell*> user_cell_block;
-typedef mdds::mtv::managed_element_block<element_type_muser_block, muser_cell> muser_cell_block;
-
template<typename T>
class cell_pool : boost::noncopyable
{
@@ -99,216 +101,21 @@ public:
}
};
+typedef mdds::mtv::default_element_block<element_type_user_block, user_cell*> user_cell_block;
+typedef mdds::mtv::managed_element_block<element_type_muser_block, muser_cell> muser_cell_block;
+typedef mdds::mtv::default_element_block<element_type_fruit_block, my_fruit_type> fruit_block;
+
MDDS_MTV_DEFINE_ELEMENT_CALLBACKS_PTR(user_cell, element_type_user_block, NULL, user_cell_block)
MDDS_MTV_DEFINE_ELEMENT_CALLBACKS_PTR(muser_cell, element_type_muser_block, NULL, muser_cell_block)
+MDDS_MTV_DEFINE_ELEMENT_CALLBACKS(my_fruit_type, element_type_fruit_block, unknown_fruit, fruit_block)
}
-struct my_cell_block_func
-{
- static mdds::mtv::base_element_block* create_new_block(
- mdds::mtv::element_t type, size_t init_size)
- {
- switch (type)
- {
- case element_type_user_block:
- return user_cell_block::create_block(init_size);
- case element_type_muser_block:
- return muser_cell_block::create_block(init_size);
- default:
- ;
- }
-
- return mtv::element_block_func_base::create_new_block(type, init_size);
- }
-
- static mdds::mtv::base_element_block* clone_block(const mdds::mtv::base_element_block& block)
- {
- switch (mtv::get_block_type(block))
- {
- case element_type_user_block:
- return user_cell_block::clone_block(block);
- case element_type_muser_block:
- return muser_cell_block::clone_block(block);
- default:
- ;
- }
-
- return mtv::element_block_func_base::clone_block(block);
- }
-
- static void delete_block(mdds::mtv::base_element_block* p)
- {
- if (!p)
- return;
-
- switch (mtv::get_block_type(*p))
- {
- case element_type_user_block:
- user_cell_block::delete_block(p);
- break;
- case element_type_muser_block:
- muser_cell_block::delete_block(p);
- break;
- default:
- mtv::element_block_func_base::delete_block(p);
- }
- }
-
- static void resize_block(mdds::mtv::base_element_block& block, size_t new_size)
- {
- switch (mtv::get_block_type(block))
- {
- case element_type_user_block:
- user_cell_block::resize_block(block, new_size);
- break;
- case element_type_muser_block:
- muser_cell_block::resize_block(block, new_size);
- break;
- default:
- mtv::element_block_func_base::resize_block(block, new_size);
- }
- }
-
- static void print_block(const mdds::mtv::base_element_block& block)
- {
- switch (mtv::get_block_type(block))
- {
- case element_type_user_block:
- user_cell_block::print_block(block);
- break;
- case element_type_muser_block:
- muser_cell_block::print_block(block);
- break;
- default:
- mtv::element_block_func_base::print_block(block);
- }
- }
-
- static void erase(mdds::mtv::base_element_block& block, size_t pos)
- {
- switch (mtv::get_block_type(block))
- {
- case element_type_user_block:
- user_cell_block::erase_block(block, pos);
- break;
- case element_type_muser_block:
- muser_cell_block::erase_block(block, pos);
- break;
- default:
- mtv::element_block_func_base::erase(block, pos);
- }
- }
-
- static void erase(mdds::mtv::base_element_block& block, size_t pos, size_t size)
- {
- switch (mtv::get_block_type(block))
- {
- case element_type_user_block:
- user_cell_block::erase_block(block, pos, size);
- break;
- case element_type_muser_block:
- muser_cell_block::erase_block(block, pos, size);
- break;
- default:
- mtv::element_block_func_base::erase(block, pos, size);
- }
- }
-
- static void append_values_from_block(
- mdds::mtv::base_element_block& dest, const mdds::mtv::base_element_block& src)
- {
- switch (mtv::get_block_type(dest))
- {
- case element_type_user_block:
- user_cell_block::append_values_from_block(dest, src);
- break;
- case element_type_muser_block:
- muser_cell_block::append_values_from_block(dest, src);
- break;
- default:
- mtv::element_block_func_base::append_values_from_block(dest, src);
- }
- }
-
- static void append_values_from_block(
- mdds::mtv::base_element_block& dest, const mdds::mtv::base_element_block& src,
- size_t begin_pos, size_t len)
- {
- switch (mtv::get_block_type(dest))
- {
- case element_type_user_block:
- user_cell_block::append_values_from_block(dest, src, begin_pos, len);
- break;
- case element_type_muser_block:
- muser_cell_block::append_values_from_block(dest, src, begin_pos, len);
- break;
- default:
- mtv::element_block_func_base::append_values_from_block(dest, src, begin_pos, len);
- }
- }
-
- static void assign_values_from_block(
- mdds::mtv::base_element_block& dest, const mdds::mtv::base_element_block& src,
- size_t begin_pos, size_t len)
- {
- switch (mtv::get_block_type(dest))
- {
- case element_type_user_block:
- user_cell_block::assign_values_from_block(dest, src, begin_pos, len);
- break;
- case element_type_muser_block:
- muser_cell_block::assign_values_from_block(dest, src, begin_pos, len);
- break;
- default:
- mtv::element_block_func_base::assign_values_from_block(dest, src, begin_pos, len);
- }
- }
-
- static bool equal_block(
- const mdds::mtv::base_element_block& left, const mdds::mtv::base_element_block& right)
- {
- if (mtv::get_block_type(left) == element_type_user_block)
- {
- if (mtv::get_block_type(right) != element_type_user_block)
- return false;
-
- return user_cell_block::get(left) == user_cell_block::get(right);
- }
- else if (mtv::get_block_type(right) == element_type_user_block)
- return false;
-
- if (mtv::get_block_type(left) == element_type_muser_block)
- {
- if (mtv::get_block_type(right) != element_type_muser_block)
- return false;
-
- return muser_cell_block::get(left) == muser_cell_block::get(right);
- }
- else if (mtv::get_block_type(right) == element_type_muser_block)
- return false;
-
- return mtv::element_block_func_base::equal_block(left, right);
- }
-
- static void overwrite_values(mdds::mtv::base_element_block& block, size_t pos, size_t len)
- {
- switch (mtv::get_block_type(block))
- {
- case element_type_user_block:
- // Do nothing. The client code manages the life cycle of these cells.
- break;
- case element_type_muser_block:
- muser_cell_block::overwrite_values(block, pos, len);
- break;
- default:
- mtv::element_block_func_base::overwrite_values(block, pos, len);
- }
- }
-};
-
namespace {
+typedef multi_type_vector<mtv::custom_block_func2<element_type_user_block, user_cell_block, element_type_muser_block, muser_cell_block> > mtv_type;
+typedef multi_type_vector<mtv::custom_block_func1<element_type_fruit_block, fruit_block> > mtv_fruit_type;
+
template<typename _ColT, typename _ValT>
bool test_cell_insertion(_ColT& col_db, size_t row, _ValT val)
{
@@ -318,8 +125,6 @@ bool test_cell_insertion(_ColT& col_db, size_t row, _ValT val)
return val == test;
}
-typedef mdds::multi_type_vector<my_cell_block_func> mtv_type;
-
void mtv_test_types()
{
stack_printer __stack_printer__("::mtv_test_types");
@@ -342,6 +147,10 @@ void mtv_test_types()
user_cell* p = NULL;
ct = mtv_type::get_element_type(p);
assert(ct == element_type_user_block && ct >= mtv::element_type_user_start);
+ ct = mtv_type::get_element_type(static_cast<muser_cell*>(NULL));
+ assert(ct == element_type_muser_block && ct >= mtv::element_type_user_start);
+ ct = mtv_fruit_type::get_element_type(unknown_fruit);
+ assert(ct == element_type_fruit_block && ct >= mtv::element_type_user_start);
}
void mtv_test_basic()
@@ -1048,6 +857,466 @@ void mtv_test_managed_block()
db.set_empty(1, 1);
assert(db.block_size() == 1);
}
+
+ {
+ // Release an element.
+ mtv_type db(1);
+ muser_cell* p = new muser_cell(4.5);
+ db.set(0, p);
+ muser_cell* p2 = db.release<muser_cell*>(0);
+ assert(p == p2);
+ assert(p2->value == 4.5);
+ assert(db.is_empty(0));
+ delete p2;
+
+ db = mtv_type(2);
+ db.set(0, new muser_cell(23.3));
+ assert(db.block_size() == 2);
+ p2 = db.release<muser_cell*>(0);
+ assert(db.is_empty(0));
+ assert(db.is_empty(1));
+ assert(db.block_size() == 1);
+ delete p2;
+
+ db = mtv_type(2);
+ db.set(0, new muser_cell(1.2));
+ db.set(1, new muser_cell(1.3));
+
+ p2 = db.release<muser_cell*>(0);
+ assert(db.is_empty(0));
+ assert(!db.is_empty(1));
+ assert(p2->value == 1.2);
+ delete p2;
+
+ db.set(0, new muser_cell(1.4));
+ p2 = db.release<muser_cell*>(1);
+ assert(!db.is_empty(0));
+ assert(db.is_empty(1));
+ assert(p2->value == 1.3);
+ delete p2;
+
+ db = mtv_type(3);
+ db.set(0, new muser_cell(2.1));
+ db.set(1, new muser_cell(2.2));
+ db.set(2, new muser_cell(2.3));
+
+ p2 = db.release<muser_cell*>(1);
+ assert(p2->value == 2.2);
+ assert(!db.is_empty(0));
+ assert(db.is_empty(1));
+ assert(!db.is_empty(2));
+
+ delete p2;
+
+ db = mtv_type(3);
+ db.set(0, new muser_cell(2.1));
+ db.set(1, new muser_cell(2.2));
+ db.set(2, new muser_cell(2.3));
+ db.set_empty(0, 2); // Make sure this doesn't release anything.
+ }
+}
+
+void mtv_test_custom_block_func1()
+{
+ stack_printer __stack_printer__("::mtv_test_custom_block_func1");
+ mtv_fruit_type db(10);
+ db.set(0, apple);
+ db.set(1, orange);
+ db.set(2, mango);
+ db.set(3, peach);
+ assert(db.block_size() == 2);
+ assert(db.get_type(0) == element_type_fruit_block);
+ assert(db.get<my_fruit_type>(0) == apple);
+ assert(db.get<my_fruit_type>(1) == orange);
+ assert(db.get<my_fruit_type>(2) == mango);
+ assert(db.get<my_fruit_type>(3) == peach);
+ db.set<int>(1, 234);
+ assert(db.block_size() == 4);
+ db.set(1, apple);
+ assert(db.block_size() == 2);
+}
+
+void mtv_test_transfer()
+{
+ stack_printer __stack_printer__("::mtv_test_transfer");
+ mtv_type db1(3), db2(4); // db2 is larger than db1.
+ db1.set(0, new muser_cell(1.1));
+ db1.set(1, new muser_cell(1.2));
+ db1.set(2, new muser_cell(1.3));
+ assert(db1.block_size() == 1);
+
+ try
+ {
+ db1.transfer(0, 1, db1, 0);
+ assert(!"Exception should have been thrown");
+ }
+ catch (const invalid_arg_error&)
+ {
+ // Good.
+ }
+
+ // Do the transfer.
+ db1.transfer(0, 2, db2, 0);
+
+ // Now db1 should be totally empty.
+ assert(db1.block_size() == 1);
+ mtv_type::iterator check = db1.begin();
+ assert(check != db1.end());
+ assert(check->type == mtv::element_type_empty);
+ assert(check->size == 3);
+
+ assert(db2.block_size() == 2);
+ assert(db2.get<muser_cell*>(0)->value == 1.1);
+ assert(db2.get<muser_cell*>(1)->value == 1.2);
+ assert(db2.get<muser_cell*>(2)->value == 1.3);
+ assert(db2.is_empty(3));
+
+ // Transfer back to db1. This should make db2 to be totally empty again.
+ db2.transfer(0, 2, db1, 0);
+ assert(db2.block_size() == 1);
+ check = db2.begin();
+ assert(check != db2.end());
+ assert(check->size == 4);
+ assert(check->type == mtv::element_type_empty);
+
+ assert(db1.block_size() == 1);
+ assert(db1.get<muser_cell*>(0)->value == 1.1);
+ assert(db1.get<muser_cell*>(1)->value == 1.2);
+ assert(db1.get<muser_cell*>(2)->value == 1.3);
+
+ // Now, transfer only the top 2 elements.
+ db1.transfer(0, 1, db2, 0);
+ assert(db1.is_empty(0));
+ assert(db1.is_empty(1));
+ assert(db1.get<muser_cell*>(2)->value == 1.3);
+
+ assert(db2.get<muser_cell*>(0)->value == 1.1);
+ assert(db2.get<muser_cell*>(1)->value == 1.2);
+ assert(db2.is_empty(2));
+ assert(db2.is_empty(3));
+
+ // .. and back.
+ db2.transfer(0, 1, db1, 0);
+ assert(db1.block_size() == 1);
+ assert(db1.get<muser_cell*>(0)->value == 1.1);
+ assert(db1.get<muser_cell*>(1)->value == 1.2);
+ assert(db1.get<muser_cell*>(2)->value == 1.3);
+
+ assert(db2.block_size() == 1);
+ check = db2.begin();
+ assert(check != db2.end());
+ assert(check->size == 4);
+ assert(check->type == mtv::element_type_empty);
+
+ db1 = mtv_type(4);
+ db2 = mtv_type(4);
+ db2.set(1, new muser_cell(2.1));
+ db2.set(2, new muser_cell(2.2));
+ assert(db2.block_size() == 3);
+ db1.transfer(0, 1, db2, 1); // This causes db2's 3 blocks to merge into one.
+ assert(db2.block_size() == 1);
+ check = db2.begin();
+ assert(check != db2.end());
+ assert(check->size == 4);
+ assert(check->type == mtv::element_type_empty);
+ assert(db1.block_size() == 1);
+ check = db1.begin();
+ assert(check != db1.end());
+ assert(check->size == 4);
+ assert(check->type == mtv::element_type_empty);
+
+ db2.set(0, new muser_cell(3.1));
+ assert(db2.block_size() == 2);
+
+ db1.set(1, new muser_cell(3.2));
+ db1.set(2, new muser_cell(3.3));
+ db1.set(3, new muser_cell(3.4));
+ assert(db1.block_size() == 2);
+
+ db1.transfer(1, 2, db2, 1);
+ assert(db1.block_size() == 2);
+ assert(db1.is_empty(0));
+ assert(db1.is_empty(1));
+ assert(db1.is_empty(2));
+ assert(db1.get<muser_cell*>(3)->value == 3.4);
+ assert(db2.block_size() == 2);
+ assert(db2.get<muser_cell*>(0)->value == 3.1);
+ assert(db2.get<muser_cell*>(1)->value == 3.2);
+ assert(db2.get<muser_cell*>(2)->value == 3.3);
+ assert(db2.is_empty(3));
+
+ db1 = mtv_type(3);
+ db2 = mtv_type(3);
+ db1.set(1, new muser_cell(4.2));
+ db2.set(0, new muser_cell(4.1));
+ db2.set(2, new muser_cell(4.3));
+
+ db1.transfer(1, 1, db2, 1);
+ assert(db1.block_size() == 1);
+ check = db1.begin();
+ assert(check != db1.end());
+ assert(check->size == 3);
+ assert(check->type == mtv::element_type_empty);
+ assert(db2.block_size() == 1);
+ assert(db2.get<muser_cell*>(0)->value == 4.1);
+ assert(db2.get<muser_cell*>(1)->value == 4.2);
+ assert(db2.get<muser_cell*>(2)->value == 4.3);
+
+ // Transfer to middle of block.
+ db1 = mtv_type(3);
+ db2 = mtv_type(3);
+ db1.set(0, new muser_cell(5.2));
+ assert(db1.block_size() == 2);
+ db1.transfer(0, 0, db2, 1);
+ assert(db1.block_size() == 1);
+ check = db1.begin();
+ assert(check != db1.end());
+ assert(check->size == 3);
+ assert(check->type == mtv::element_type_empty);
+ assert(db2.block_size() == 3);
+ assert(db2.is_empty(0));
+ assert(db2.get<muser_cell*>(1)->value == 5.2);
+ assert(db2.is_empty(2));
+
+ db1 = mtv_type(2);
+ db2 = mtv_type(3);
+ db1.set(0, new muser_cell(11.1));
+ db1.set(1, new muser_cell(11.2));
+ db1.transfer(1, 1, db2, 1);
+ assert(db1.block_size() == 2);
+ assert(db1.get<muser_cell*>(0)->value == 11.1);
+ assert(db1.is_empty(1));
+ assert(db2.block_size() == 3);
+ assert(db2.is_empty(0));
+ assert(db2.get<muser_cell*>(1)->value == 11.2);
+ assert(db2.is_empty(2));
+
+ // Transfer to bottom of block.
+ db1 = mtv_type(4);
+ db2 = mtv_type(5);
+ db1.set(0, new muser_cell(6.1));
+ db1.set(1, new muser_cell(6.2));
+ db1.transfer(0, 1, db2, 3);
+ assert(db1.block_size() == 1);
+ check = db1.begin();
+ assert(check != db1.end());
+ assert(check->size == 4);
+ assert(check->type == mtv::element_type_empty);
+ assert(db2.block_size() == 2);
+ assert(db2.is_empty(0));
+ assert(db2.is_empty(1));
+ assert(db2.is_empty(2));
+ assert(db2.get<muser_cell*>(3)->value == 6.1);
+ assert(db2.get<muser_cell*>(4)->value == 6.2);
+
+ // Transfer multiple blocks. Very simple use case.
+ db1 = mtv_type(4);
+ db2 = mtv_type(3);
+ db1.set(1, new muser_cell(10.1));
+ db1.set(3, new muser_cell(10.2));
+ db1.transfer(1, 3, db2, 0);
+
+ // db1 should be completely empty.
+ assert(db1.block_size() == 1);
+ check = db1.begin();
+ assert(check != db1.end());
+ assert(check->size == 4);
+ assert(check->type == mtv::element_type_empty);
+
+ assert(db2.block_size() == 3);
+ assert(db2.get<muser_cell*>(0)->value == 10.1);
+ assert(db2.is_empty(1));
+ assert(db2.get<muser_cell*>(2)->value == 10.2);
+
+ // Multiple-block transfer that involves merging.
+ db1 = mtv_type(5);
+ db2 = mtv_type(5);
+ db1.set(0, new muser_cell(0.1));
+ db1.set(1, new muser_cell(0.2));
+ db1.set(3, new muser_cell(0.3));
+ db1.set(4, new muser_cell(0.4));
+
+ db2.set(0, new muser_cell(1.1));
+ db2.set(4, new muser_cell(1.2));
+
+ mtv_type::iterator it = db1.transfer(1, 3, db2, 1);
+ assert(db1.block_size() == 3);
+ assert(db1.get<muser_cell*>(0)->value == 0.1);
+ assert(db1.is_empty(1));
+ assert(db1.is_empty(2));
+ assert(db1.is_empty(3));
+ assert(db1.get<muser_cell*>(4)->value == 0.4);
+
+ assert(db2.block_size() == 3);
+ assert(db2.get<muser_cell*>(0)->value == 1.1);
+ assert(db2.get<muser_cell*>(1)->value == 0.2);
+ assert(db2.is_empty(2));
+ assert(db2.get<muser_cell*>(3)->value == 0.3);
+ assert(db2.get<muser_cell*>(4)->value == 1.2);
+
+ assert(it != db1.end());
+ assert(it->size == 3);
+ assert(it->type == mtv::element_type_empty);
+ it = db1.transfer(it, 4, 4, db2, 2); // Transfer single element at 4.
+ assert(db1.block_size() == 2);
+ assert(db1.get<muser_cell*>(0)->value == 0.1);
+ assert(db1.is_empty(1));
+ assert(db1.is_empty(2));
+ assert(db1.is_empty(3));
+ assert(db1.is_empty(4));
+
+ assert(db2.block_size() == 1);
+ assert(db2.get<muser_cell*>(0)->value == 1.1);
+ assert(db2.get<muser_cell*>(1)->value == 0.2);
+ assert(db2.get<muser_cell*>(2)->value == 0.4);
+ assert(db2.get<muser_cell*>(3)->value == 0.3);
+ assert(db2.get<muser_cell*>(4)->value == 1.2);
+
+ assert(it != db1.end());
+ assert(it->size == 4);
+ assert(it->type == mtv::element_type_empty);
+ ++it;
+ assert(it == db1.end());
+
+ // Multi-block transfer to the top part of destination block.
+ db1 = mtv_type(5);
+ db2 = mtv_type(5);
+ db1.set(0, new muser_cell(-1.1));
+ db1.set(1, new muser_cell(-2.1));
+ db1.set(2, new muser_cell(-3.1));
+ db1.set(3, string("foo"));
+ db1.set(4, new muser_cell(-5.1));
+ db2.set(1, true);
+ db2.set(2, false);
+ db2.set(3, true);
+ it = db1.transfer(2, 3, db2, 2);
+ assert(it != db1.end());
+ assert(it->size == 2);
+ assert(it->type == mtv::element_type_empty);
+ std::advance(it, 2);
+ assert(it == db1.end());
+ assert(db1.block_size() == 3);
+ assert(db1.get<muser_cell*>(0)->value == -1.1);
+ assert(db1.get<muser_cell*>(1)->value == -2.1);
+ assert(db1.is_empty(2));
+ assert(db1.is_empty(3));
+ assert(db1.get<muser_cell*>(4)->value == -5.1);
+
+ assert(db2.block_size() == 5);
+ assert(db2.is_empty(0));
+ assert(db2.get<bool>(1) == true);
+ assert(db2.get<muser_cell*>(2)->value == -3.1);
+ assert(db2.get<string>(3) == "foo");
+ assert(db2.is_empty(4));
+
+ // Multi-block transfer to the bottom part of destination block.
+ db1 = mtv_type(10);
+ db2 = mtv_type(10);
+ db1.set(0, new muser_cell(2.1));
+ db1.set(1, new muser_cell(2.2));
+ db1.set(2, char('a'));
+ db1.set(3, char('b'));
+ db2.set(0, true);
+ db2.set(1, false);
+
+ it = db1.transfer(0, 2, db2, 7);
+ assert(it != db1.end());
+ assert(it->size == 3);
+ assert(it->type == mtv::element_type_empty);
+ ++it;
+ assert(it != db1.end());
+ assert(it->size == 1);
+ assert(it->type == mtv::element_type_char);
+ ++it;
+ assert(it != db1.end());
+ assert(it->size == 6);
+ assert(it->type == mtv::element_type_empty);
+ ++it;
+ assert(it == db1.end());
+ assert(db1.block_size() == 3);
+ assert(db1.get<char>(3) == 'b');
+
+ assert(db2.block_size() == 4);
+ assert(db2.get<bool>(0) == true);
+ assert(db2.get<bool>(1) == false);
+ assert(db2.is_empty(2));
+ assert(db2.is_empty(3));
+ assert(db2.is_empty(4));
+ assert(db2.is_empty(5));
+ assert(db2.is_empty(6));
+ assert(db2.get<muser_cell*>(7)->value == 2.1);
+ assert(db2.get<muser_cell*>(8)->value == 2.2);
+ assert(db2.get<char>(9) == 'a');
+
+ // Multi-block transfer to the middle part of destination block.
+ db1 = mtv_type(10);
+ db2 = mtv_type(10);
+ db2.set(0, true);
+ db2.set(9, true);
+ db1.set(3, new muser_cell(2.4));
+ db1.set(4, new muser_cell(2.5));
+ db1.set(5, string("abc"));
+ db1.set(6, new muser_cell(2.6));
+ db1.set(7, new muser_cell(2.7));
+ db1.set(8, true);
+ it = db1.transfer(3, 6, db2, 2);
+ assert(it != db1.end());
+ assert(it->size == 7);
+ assert(it->type == mtv::element_type_empty);
+ ++it;
+ assert(it != db1.end());
+ assert(it->size == 1);
+ assert(it->type == element_type_muser_block);
+ ++it;
+ assert(it->size == 1);
+ assert(it->type == mtv::element_type_boolean);
+ ++it;
+ assert(it->size == 1);
+ assert(it->type == mtv::element_type_empty);
+ ++it;
+ assert(it == db1.end());
+
+ assert(db1.block_size() == 4);
+ assert(db1.is_empty(6));
+ assert(db1.get<muser_cell*>(7)->value == 2.7);
+ assert(db1.get<bool>(8) == true);
+ assert(db1.is_empty(9));
+
+ assert(db2.block_size() == 7);
+ assert(db2.get<bool>(0) == true);
+ assert(db2.is_empty(1));
+ assert(db2.get<muser_cell*>(2)->value == 2.4);
+ assert(db2.get<muser_cell*>(3)->value == 2.5);
+ assert(db2.get<string>(4) == "abc");
+ assert(db2.get<muser_cell*>(5)->value == 2.6);
+ assert(db2.is_empty(6));
+ assert(db2.is_empty(7));
+ assert(db2.is_empty(8));
+ assert(db2.get<bool>(9) == true);
+
+ db1 = mtv_type(10);
+ db2 = mtv_type(10);
+ db1.set(3, true);
+ db2.set(3, string("test"));
+ db1.transfer(0, 6, db2, 0);
+ assert(db1.block_size() == 1);
+ check = db1.begin();
+ assert(check != db1.end());
+ assert(check->size == 10);
+ assert(check->type == mtv::element_type_empty);
+ ++check;
+ assert(check == db1.end());
+ assert(db2.block_size() == 3);
+ assert(db2.is_empty(0));
+ assert(db2.is_empty(1));
+ assert(db2.is_empty(2));
+ assert(db2.get<bool>(3) == true);
+ assert(db2.is_empty(4));
+ assert(db2.is_empty(5));
+ assert(db2.is_empty(6));
+ assert(db2.is_empty(7));
+ assert(db2.is_empty(8));
+ assert(db2.is_empty(9));
}
}
@@ -1064,6 +1333,8 @@ int main (int argc, char **argv)
mtv_test_basic();
mtv_test_equality();
mtv_test_managed_block();
+ mtv_test_custom_block_func1();
+ mtv_test_transfer();
}
if (opt.test_perf)
diff --git a/src/multi_type_vector_test_default.cpp b/src/multi_type_vector_test_default.cpp
index 1a18dcc..31d43ec 100644
--- a/src/multi_type_vector_test_default.cpp
+++ b/src/multi_type_vector_test_default.cpp
@@ -58,7 +58,7 @@ bool test_cell_insertion(_ColT& col_db, size_t row, _ValT val)
typedef mdds::multi_type_vector<mdds::mtv::element_block_func> mtv_type;
enum test_mtv_type {
- _bool, _short, _ushort, _int, _uint, _long, _ulong, _double, _string
+ _bool, _short, _ushort, _int, _uint, _long, _ulong, _double, _string, _char, _uchar
};
#define TEST_TYPE(_type_,_type_enum_) test_mtv_type test_type(_type_) { return _type_enum_; }
@@ -71,6 +71,8 @@ TEST_TYPE(long,_long)
TEST_TYPE(unsigned long,_ulong)
TEST_TYPE(double,_double)
TEST_TYPE(string,_string)
+TEST_TYPE(char,_char)
+TEST_TYPE(unsigned char,_uchar)
void mtv_test_types()
{
@@ -122,6 +124,16 @@ void mtv_test_types()
assert(test_type(val) == _string);
cout << "string is good" << endl;
}
+ {
+ char val = 0;
+ assert(test_type(val) == _char);
+ cout << "char is good" << endl;
+ }
+ {
+ unsigned char val = 0;
+ assert(test_type(val) == _uchar);
+ cout << "unsigned char is good" << endl;
+ }
}
void mtv_test_construction()
@@ -714,6 +726,46 @@ void mtv_test_basic()
assert(db.get<double>(6) == 1.2);
assert(db.get<bool>(7) == true);
}
+
+ {
+ mtv_type db(10, false);
+ db.set<char>(0, 'a');
+ db.set<char>(1, 'b');
+ db.set<char>(2, 'c');
+
+ db.set<unsigned char>(3, 'd');
+ db.set<unsigned char>(4, 'e');
+ db.set<unsigned char>(5, 'f');
+
+ assert(db.block_size() == 3);
+ db.set<char>(0, 'r'); // overwrite.
+ db.set<unsigned char>(5, 'z'); // overwrite
+
+ assert(db.block_size() == 3);
+ mtv_type::const_iterator it = db.begin();
+ assert(it != db.end());
+ assert(it->type == mtv::element_type_char);
+ {
+ const char* p = &mtv::char_element_block::at(*it->data, 0);
+ assert(*p == 'r');
+ ++p;
+ assert(*p == 'b');
+ ++p;
+ assert(*p == 'c');
+ }
+
+ ++it;
+ assert(it != db.end());
+ assert(it->type == mtv::element_type_uchar);
+ {
+ const unsigned char* p = &mtv::uchar_element_block::at(*it->data, 0);
+ assert(*p == 'd');
+ ++p;
+ assert(*p == 'e');
+ ++p;
+ assert(*p == 'z');
+ }
+ }
}
void mtv_test_empty_cells()
@@ -2388,6 +2440,18 @@ void mtv_test_data_iterators()
assert(*it_data == 1.3);
++it_data;
assert(it_data == it_data_end);
+
+ assert(mtv::numeric_element_block::at(*it_blk->data, 0) == 1.1);
+ assert(mtv::numeric_element_block::at(*it_blk->data, 1) == 1.2);
+ assert(mtv::numeric_element_block::at(*it_blk->data, 2) == 1.3);
+
+ // Access the underlying data array directly.
+ const double* array = &mtv::numeric_element_block::at(*it_blk->data, 0);
+ assert(*array == 1.1);
+ ++array;
+ assert(*array == 1.2);
+ ++array;
+ assert(*array == 1.3);
}
// Next block is empty.
@@ -3947,6 +4011,62 @@ void mtv_test_insert_empty_with_position()
assert(check == db.end());
}
+void mtv_test_position()
+{
+ stack_printer __stack_printer__("::mtv_test_position");
+ mtv_type db(10, false);
+ mtv_type::iterator check;
+ db.set(6, 1.1);
+ db.set(7, 1.2);
+ db.set(8, 1.3);
+ db.set(9, 1.4);
+
+ pair<mtv_type::iterator,mtv_type::size_type> pos = db.position(0);
+ assert(pos.first == db.begin());
+ assert(pos.second == 0);
+
+ pos = db.position(1);
+ assert(pos.first == db.begin());
+ assert(pos.second == 1);
+
+ pos = db.position(5);
+ assert(pos.first == db.begin());
+ assert(pos.second == 5);
+
+ check = db.begin();
+ ++check;
+
+ // These positions should be on the 2nd block.
+
+ pos = db.position(6);
+ assert(pos.first == check);
+ assert(pos.second == 0);
+
+ pos = db.position(7);
+ assert(pos.first == check);
+ assert(pos.second == 1);
+
+ pos = db.position(9);
+ assert(pos.first == check);
+ assert(pos.second == 3);
+
+ {
+ // Make sure you get the right element.
+ mtv_type::iterator it = pos.first;
+ assert(it->type == mtv::element_type_numeric);
+ assert(it->data);
+ mtv::numeric_element_block::iterator it_elem = mtv::numeric_element_block::begin(*it->data);
+ advance(it_elem, pos.second);
+ assert(*it_elem == 1.4);
+ }
+
+ // Quick check for the const variant.
+ const mtv_type& db_ref = db;
+ 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);
+}
+
void mtv_perf_test_block_position_lookup()
{
size_t n = 24000;
@@ -4022,6 +4142,7 @@ int main (int argc, char **argv)
mtv_test_insert_cells_with_position();
mtv_test_set_empty_with_position();
mtv_test_insert_empty_with_position();
+ mtv_test_position();
}
if (opt.test_perf)
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-openoffice/mdds.git
Reply to: