diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 05:46:17 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 05:46:17 +0000 |
commit | 85adc697d2ec2a379ce6d721f0419ae5df3abdb6 (patch) | |
tree | 265f329bc4544c6f11a27ac3fd6022f593a10c11 /test/trie_map | |
parent | Initial commit. (diff) | |
download | mdds-85adc697d2ec2a379ce6d721f0419ae5df3abdb6.tar.xz mdds-85adc697d2ec2a379ce6d721f0419ae5df3abdb6.zip |
Adding upstream version 2.1.1.upstream/2.1.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'test/trie_map')
-rw-r--r-- | test/trie_map/Makefile.am | 14 | ||||
-rw-r--r-- | test/trie_map/Makefile.in | 990 | ||||
-rw-r--r-- | test/trie_map/test_main.cpp | 1909 |
3 files changed, 2913 insertions, 0 deletions
diff --git a/test/trie_map/Makefile.am b/test/trie_map/Makefile.am new file mode 100644 index 0000000..b4927a7 --- /dev/null +++ b/test/trie_map/Makefile.am @@ -0,0 +1,14 @@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/test/include \ + $(CXXFLAGS_UNITTESTS) + +check_PROGRAMS = test-main + +test_main_SOURCES = \ + test_main.cpp \ + $(top_srcdir)/test/test_global.cpp + +TESTS = test-main + +@VALGRIND_CHECK_RULES@ diff --git a/test/trie_map/Makefile.in b/test/trie_map/Makefile.in new file mode 100644 index 0000000..6630a00 --- /dev/null +++ b/test/trie_map/Makefile.in @@ -0,0 +1,990 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +check_PROGRAMS = test-main$(EXEEXT) +TESTS = test-main$(EXEEXT) +subdir = test/trie_map +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ + $(top_srcdir)/m4/ax_cxx_compile_stdcxx_17.m4 \ + $(top_srcdir)/m4/m4_ax_valgrind_check.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__dirstamp = $(am__leading_dot)dirstamp +am_test_main_OBJECTS = test_main.$(OBJEXT) \ + $(top_builddir)/test/test_global.$(OBJEXT) +test_main_OBJECTS = $(am_test_main_OBJECTS) +test_main_LDADD = $(LDADD) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = $(top_builddir)/test/$(DEPDIR)/test_global.Po \ + ./$(DEPDIR)/test_main.Po +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +SOURCES = $(test_main_SOURCES) +DIST_SOURCES = $(test_main_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__extra_recursive_targets = check-valgrind-recursive \ + check-valgrind-memcheck-recursive \ + check-valgrind-helgrind-recursive check-valgrind-drd-recursive \ + check-valgrind-sgcheck-recursive +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red='[0;31m'; \ + grn='[0;32m'; \ + lgn='[1;32m'; \ + blu='[1;34m'; \ + mgn='[0;35m'; \ + brg='[1m'; \ + std='[m'; \ + fi; \ +} +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__recheck_rx = ^[ ]*:recheck:[ ]* +am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +# A command that, given a newline-separated list of test names on the +# standard input, print the name of the tests that are to be re-run +# upon "make recheck". +am__list_recheck_tests = $(AWK) '{ \ + recheck = 1; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + { \ + if ((getline line2 < ($$0 ".log")) < 0) \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ + { \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ + { \ + break; \ + } \ + }; \ + if (recheck) \ + print $$0; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# A command that, given a newline-separated list of test names on the +# standard input, create the global log from their .trs and .log files. +am__create_global_log = $(AWK) ' \ +function fatal(msg) \ +{ \ + print "fatal: making $@: " msg | "cat >&2"; \ + exit 1; \ +} \ +function rst_section(header) \ +{ \ + print header; \ + len = length(header); \ + for (i = 1; i <= len; i = i + 1) \ + printf "="; \ + printf "\n\n"; \ +} \ +{ \ + copy_in_global_log = 1; \ + global_test_result = "RUN"; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".trs"); \ + if (line ~ /$(am__global_test_result_rx)/) \ + { \ + sub("$(am__global_test_result_rx)", "", line); \ + sub("[ ]*$$", "", line); \ + global_test_result = line; \ + } \ + else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ + copy_in_global_log = 0; \ + }; \ + if (copy_in_global_log) \ + { \ + rst_section(global_test_result ": " $$0); \ + while ((rc = (getline line < ($$0 ".log"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".log"); \ + print line; \ + }; \ + printf "\n"; \ + }; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# Restructured Text title. +am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +# Solaris 10 'make', and several other traditional 'make' implementations, +# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +# by disabling -e (using the XSI extension "set +e") if it's set. +am__sh_e_setup = case $$- in *e*) set +e;; esac +# Default flags passed to test drivers. +am__common_driver_flags = \ + --color-tests "$$am__color_tests" \ + --enable-hard-errors "$$am__enable_hard_errors" \ + --expect-failure "$$am__expect_failure" +# To be inserted before the command running the test. Creates the +# directory for the log if needed. Stores in $dir the directory +# containing $f, in $tst the test, in $log the log. Executes the +# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +# will run the test scripts (or their associated LOG_COMPILER, if +# thy have one). +am__check_pre = \ +$(am__sh_e_setup); \ +$(am__vpath_adj_setup) $(am__vpath_adj) \ +$(am__tty_colors); \ +srcdir=$(srcdir); export srcdir; \ +case "$@" in \ + */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ + *) am__odir=.;; \ +esac; \ +test "x$$am__odir" = x"." || test -d "$$am__odir" \ + || $(MKDIR_P) "$$am__odir" || exit $$?; \ +if test -f "./$$f"; then dir=./; \ +elif test -f "$$f"; then dir=; \ +else dir="$(srcdir)/"; fi; \ +tst=$$dir$$f; log='$@'; \ +if test -n '$(DISABLE_HARD_ERRORS)'; then \ + am__enable_hard_errors=no; \ +else \ + am__enable_hard_errors=yes; \ +fi; \ +case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ + am__expect_failure=yes;; \ + *) \ + am__expect_failure=no;; \ +esac; \ +$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +# A shell command to get the names of the tests scripts with any registered +# extension removed (i.e., equivalently, the names of the test logs, with +# the '.log' extension removed). The result is saved in the shell variable +# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +# since that might cause problem with VPATH rewrites for suffix-less tests. +# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +am__set_TESTS_bases = \ + bases='$(TEST_LOGS)'; \ + bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ + bases=`echo $$bases` +AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)' +RECHECK_LOGS = $(TEST_LOGS) +AM_RECURSIVE_TARGETS = check recheck +TEST_SUITE_LOG = test-suite.log +TEST_EXTENSIONS = @EXEEXT@ .test +LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver +LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) +am__set_b = \ + case '$@' in \ + */*) \ + case '$*' in \ + */*) b='$*';; \ + *) b=`echo '$@' | sed 's/\.log$$//'`; \ + esac;; \ + *) \ + b='$*';; \ + esac +am__test_logs1 = $(TESTS:=.log) +am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +TEST_LOGS = $(am__test_logs2:.test.log=.log) +TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver +TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ + $(TEST_LOG_FLAGS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ + $(top_srcdir)/test-driver +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +API_VERSION = @API_VERSION@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +CPPFLAGS_NODEBUG = @CPPFLAGS_NODEBUG@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CXXFLAGS_UNITTESTS = @CXXFLAGS_UNITTESTS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DOXYGEN = @DOXYGEN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +ENABLE_VALGRIND_drd = @ENABLE_VALGRIND_drd@ +ENABLE_VALGRIND_helgrind = @ENABLE_VALGRIND_helgrind@ +ENABLE_VALGRIND_memcheck = @ENABLE_VALGRIND_memcheck@ +ENABLE_VALGRIND_sgcheck = @ENABLE_VALGRIND_sgcheck@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +EXPECT = @EXPECT@ +GDB = @GDB@ +HAVE_CXX17 = @HAVE_CXX17@ +INCDIR = @INCDIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MISCDIR = @MISCDIR@ +MKDIR_P = @MKDIR_P@ +OBJDIR = @OBJDIR@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +QUICKCHECKDIR = @QUICKCHECKDIR@ +RUNTEST_BIN = @RUNTEST_BIN@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SPHINX = @SPHINX@ +STRIP = @STRIP@ +VALGRIND = @VALGRIND@ +VALGRIND_ENABLED = @VALGRIND_ENABLED@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +valgrind_enabled_tools = @valgrind_enabled_tools@ +valgrind_tools = @valgrind_tools@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/test/include \ + $(CXXFLAGS_UNITTESTS) + +test_main_SOURCES = \ + test_main.cpp \ + $(top_srcdir)/test/test_global.cpp + +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .log .o .obj .test .test$(EXEEXT) .trs +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/trie_map/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign test/trie_map/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-checkPROGRAMS: + -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS) +$(top_builddir)/test/$(am__dirstamp): + @$(MKDIR_P) $(top_builddir)/test + @: > $(top_builddir)/test/$(am__dirstamp) +$(top_builddir)/test/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) $(top_builddir)/test/$(DEPDIR) + @: > $(top_builddir)/test/$(DEPDIR)/$(am__dirstamp) +$(top_builddir)/test/test_global.$(OBJEXT): \ + $(top_builddir)/test/$(am__dirstamp) \ + $(top_builddir)/test/$(DEPDIR)/$(am__dirstamp) + +test-main$(EXEEXT): $(test_main_OBJECTS) $(test_main_DEPENDENCIES) $(EXTRA_test_main_DEPENDENCIES) + @rm -f test-main$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(test_main_OBJECTS) $(test_main_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f $(top_builddir)/test/*.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@$(top_builddir)/test/$(DEPDIR)/test_global.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_main.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.cpp.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +check-valgrind-local: +check-valgrind-memcheck-local: +check-valgrind-helgrind-local: +check-valgrind-drd-local: +check-valgrind-sgcheck-local: + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +# Recover from deleted '.trs' file; this should ensure that +# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +# to avoid problems with "make -n". +.log.trs: + rm -f $< $@ + $(MAKE) $(AM_MAKEFLAGS) $< + +# Leading 'am--fnord' is there to ensure the list of targets does not +# expand to empty, as could happen e.g. with make check TESTS=''. +am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +am--force-recheck: + @: + +$(TEST_SUITE_LOG): $(TEST_LOGS) + @$(am__set_TESTS_bases); \ + am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ + redo_bases=`for i in $$bases; do \ + am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ + done`; \ + if test -n "$$redo_bases"; then \ + redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ + redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ + if $(am__make_dryrun); then :; else \ + rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ + fi; \ + fi; \ + if test -n "$$am__remaking_logs"; then \ + echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ + "recursion detected" >&2; \ + elif test -n "$$redo_logs"; then \ + am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ + fi; \ + if $(am__make_dryrun); then :; else \ + st=0; \ + errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ + for i in $$redo_bases; do \ + test -f $$i.trs && test -r $$i.trs \ + || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ + test -f $$i.log && test -r $$i.log \ + || { echo "$$errmsg $$i.log" >&2; st=1; }; \ + done; \ + test $$st -eq 0 || exit 1; \ + fi + @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ + ws='[ ]'; \ + results=`for b in $$bases; do echo $$b.trs; done`; \ + test -n "$$results" || results=/dev/null; \ + all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ + pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ + fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ + skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ + xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ + xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ + error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ + if test `expr $$fail + $$xpass + $$error` -eq 0; then \ + success=true; \ + else \ + success=false; \ + fi; \ + br='==================='; br=$$br$$br$$br$$br; \ + result_count () \ + { \ + if test x"$$1" = x"--maybe-color"; then \ + maybe_colorize=yes; \ + elif test x"$$1" = x"--no-color"; then \ + maybe_colorize=no; \ + else \ + echo "$@: invalid 'result_count' usage" >&2; exit 4; \ + fi; \ + shift; \ + desc=$$1 count=$$2; \ + if test $$maybe_colorize = yes && test $$count -gt 0; then \ + color_start=$$3 color_end=$$std; \ + else \ + color_start= color_end=; \ + fi; \ + echo "$${color_start}# $$desc $$count$${color_end}"; \ + }; \ + create_testsuite_report () \ + { \ + result_count $$1 "TOTAL:" $$all "$$brg"; \ + result_count $$1 "PASS: " $$pass "$$grn"; \ + result_count $$1 "SKIP: " $$skip "$$blu"; \ + result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ + result_count $$1 "FAIL: " $$fail "$$red"; \ + result_count $$1 "XPASS:" $$xpass "$$red"; \ + result_count $$1 "ERROR:" $$error "$$mgn"; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + echo; \ + echo ".. contents:: :depth: 2"; \ + echo; \ + for b in $$bases; do echo $$b; done \ + | $(am__create_global_log); \ + } >$(TEST_SUITE_LOG).tmp || exit 1; \ + mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ + if $$success; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ + fi; \ + echo "$${col}$$br$${std}"; \ + echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \ + echo "$${col}$$br$${std}"; \ + create_testsuite_report --maybe-color; \ + echo "$$col$$br$$std"; \ + if $$success; then :; else \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: $(check_PROGRAMS) + @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list + @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + trs_list=`for i in $$bases; do echo $$i.trs; done`; \ + log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all $(check_PROGRAMS) + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + bases=`for i in $$bases; do echo $$i; done \ + | $(am__list_recheck_tests)` || exit 1; \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ + am__force_recheck=am--force-recheck \ + TEST_LOGS="$$log_list"; \ + exit $$? +test-main.log: test-main$(EXEEXT) + @p='test-main$(EXEEXT)'; \ + b='test-main'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +.test.log: + @p='$<'; \ + $(am__set_b); \ + $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +@am__EXEEXT_TRUE@.test$(EXEEXT).log: +@am__EXEEXT_TRUE@ @p='$<'; \ +@am__EXEEXT_TRUE@ $(am__set_b); \ +@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) + -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) + -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -test -z "$(top_builddir)/test/$(DEPDIR)/$(am__dirstamp)" || rm -f $(top_builddir)/test/$(DEPDIR)/$(am__dirstamp) + -test -z "$(top_builddir)/test/$(am__dirstamp)" || rm -f $(top_builddir)/test/$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +check-valgrind: check-valgrind-am + +check-valgrind-am: check-valgrind-local + +check-valgrind-drd: check-valgrind-drd-am + +check-valgrind-drd-am: check-valgrind-drd-local + +check-valgrind-helgrind: check-valgrind-helgrind-am + +check-valgrind-helgrind-am: check-valgrind-helgrind-local + +check-valgrind-memcheck: check-valgrind-memcheck-am + +check-valgrind-memcheck-am: check-valgrind-memcheck-local + +check-valgrind-sgcheck: check-valgrind-sgcheck-am + +check-valgrind-sgcheck-am: check-valgrind-sgcheck-local + +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic mostlyclean-am + +distclean: distclean-am + -rm -f $(top_builddir)/test/$(DEPDIR)/test_global.Po + -rm -f ./$(DEPDIR)/test_main.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f $(top_builddir)/test/$(DEPDIR)/test_global.Po + -rm -f ./$(DEPDIR)/test_main.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \ + check-am check-valgrind-am check-valgrind-drd-am \ + check-valgrind-drd-local check-valgrind-helgrind-am \ + check-valgrind-helgrind-local check-valgrind-local \ + check-valgrind-memcheck-am check-valgrind-memcheck-local \ + check-valgrind-sgcheck-am check-valgrind-sgcheck-local clean \ + clean-checkPROGRAMS clean-generic cscopelist-am ctags ctags-am \ + distclean distclean-compile distclean-generic distclean-tags \ + distdir dvi dvi-am html html-am info info-am install \ + install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ + recheck tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +@VALGRIND_CHECK_RULES@ + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/test/trie_map/test_main.cpp b/test/trie_map/test_main.cpp new file mode 100644 index 0000000..3b7aa19 --- /dev/null +++ b/test/trie_map/test_main.cpp @@ -0,0 +1,1909 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * Copyright (c) 2015-2018 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. + * + ************************************************************************/ + +#define MDDS_TRIE_MAP_DEBUG 1 +#include "test_global.hpp" // This must be the first header to be included. +//#define MDDS_TRIE_MAP_DEBUG_DUMP_TRIE 1 +//#define MDDS_TRIE_MAP_DEBUG_DUMP_PACKED 1 + +#include "mdds/trie_map.hpp" +#include "mdds/global.hpp" + +#include <iterator> +#include <fstream> +#include <vector> +#include <list> + +using namespace std; +using namespace mdds; + +using packed_int_map_type = packed_trie_map<trie::std_string_traits, int>; +using packed_str_map_type = packed_trie_map<trie::std_string_traits, std::string>; + +bool verify_entries(const packed_int_map_type& db, const packed_int_map_type::entry* entries, size_t entry_size) +{ + auto results = db.prefix_search(nullptr, 0); + for (auto it = results.begin(), ite = results.end(); it != ite; ++it) + cout << it->first << ": " << it->second << endl; + + const packed_int_map_type::entry* p = entries; + const packed_int_map_type::entry* p_end = p + entry_size; + for (; p != p_end; ++p) + { + auto it = db.find(p->key, p->keylen); + if (it == db.end() || it->second != p->value) + return false; + } + + return true; +} + +template<typename T> +bool check_equal(const T& left, const T& right) +{ + if (left.first != right.first) + { + cout << "left: " << left.first << "; right: " << right.first << endl; + return false; + } + + if (left.second != right.second) + { + cout << "left: " << left.second << "; right: " << right.second << endl; + return false; + } + + return true; +} + +void trie_packed_test1() +{ + stack_printer __stack_printer__("::trie_packed_test1"); + + packed_int_map_type::entry entries[] = { + {MDDS_ASCII("a"), 13}, + {MDDS_ASCII("aa"), 10}, + {MDDS_ASCII("ab"), 3}, + {MDDS_ASCII("b"), 7}, + }; + + size_t entry_size = std::size(entries); + packed_int_map_type db(entries, entry_size); + assert(db.size() == 4); + assert(verify_entries(db, entries, entry_size)); + + // invalid keys + assert(db.find(MDDS_ASCII("ac")) == db.end()); + assert(db.find(MDDS_ASCII("c")) == db.end()); + + { + // Get all key-value pairs. + auto results = db.prefix_search(nullptr, 0); + size_t n = std::distance(results.begin(), results.end()); + assert(n == 4); + auto it = results.begin(); + assert(it->first == "a"); + assert(it->second == 13); + ++it; + assert(it->first == "aa"); + assert(it->second == 10); + ++it; + assert(it->first == "ab"); + assert(it->second == 3); + ++it; + assert(it->first == "b"); + assert(it->second == 7); + ++it; + assert(it == results.end()); + } + + { + auto it = db.find(MDDS_ASCII("a")); + assert(it->first == "a"); + assert(it->second == 13); + ++it; + assert(it->first == "aa"); + assert(it->second == 10); + ++it; + assert(it->first == "ab"); + assert(it->second == 3); + ++it; + assert(it->first == "b"); + assert(it->second == 7); + ++it; + assert(it == db.end()); + } +} + +void trie_packed_test2() +{ + stack_printer __stack_printer__("::trie_packed_test2"); + + packed_int_map_type::entry entries[] = { + {MDDS_ASCII("aaron"), 0}, {MDDS_ASCII("al"), 1}, {MDDS_ASCII("aldi"), 2}, {MDDS_ASCII("andy"), 3}, + {MDDS_ASCII("bison"), 4}, {MDDS_ASCII("bruce"), 5}, {MDDS_ASCII("charlie"), 6}, {MDDS_ASCII("charlotte"), 7}, + {MDDS_ASCII("david"), 8}, {MDDS_ASCII("dove"), 9}, {MDDS_ASCII("e"), 10}, {MDDS_ASCII("eva"), 11}, + }; + + size_t entry_size = std::size(entries); + packed_int_map_type db(entries, entry_size); + assert(db.size() == 12); + assert(verify_entries(db, entries, entry_size)); + + // invalid keys + assert(db.find(MDDS_ASCII("aarons")) == db.end()); + assert(db.find(MDDS_ASCII("a")) == db.end()); + assert(db.find(MDDS_ASCII("biso")) == db.end()); + assert(db.find(MDDS_ASCII("dAvid")) == db.end()); +} + +void trie_packed_test3() +{ + stack_printer __stack_printer__("::trie_packed_test3"); + + packed_int_map_type::entry entries[] = { + {MDDS_ASCII("NULL"), 1}, + {MDDS_ASCII("Null"), 2}, + {MDDS_ASCII("null"), 3}, + {MDDS_ASCII("~"), 4}, + }; + + size_t entry_size = std::size(entries); + packed_int_map_type db(entries, entry_size); + assert(db.size() == 4); + assert(verify_entries(db, entries, entry_size)); + + // invalid keys + assert(db.find(MDDS_ASCII("NUll")) == db.end()); + assert(db.find(MDDS_ASCII("Oull")) == db.end()); + assert(db.find(MDDS_ASCII("Mull")) == db.end()); + assert(db.find(MDDS_ASCII("hell")) == db.end()); +} + +void trie_packed_test4() +{ + stack_printer __stack_printer__("::trie_packed_test4"); + + enum name_type + { + name_none = 0, + name_andy, + name_bruce, + name_charlie, + name_david + }; + + packed_int_map_type::entry entries[] = { + {MDDS_ASCII("andy"), name_andy}, {MDDS_ASCII("andy1"), name_andy}, {MDDS_ASCII("andy13"), name_andy}, + {MDDS_ASCII("bruce"), name_bruce}, {MDDS_ASCII("charlie"), name_charlie}, {MDDS_ASCII("david"), name_david}, + }; + + size_t entry_size = std::size(entries); + packed_int_map_type db(entries, entry_size); + assert(db.size() == 6); + assert(verify_entries(db, entries, entry_size)); + + // Try invalid keys. + assert(db.find("foo", 3) == db.end()); + assert(db.find("andy133", 7) == db.end()); + + // Test prefix search on 'andy'. + auto results = db.prefix_search(MDDS_ASCII("andy")); + size_t n = std::distance(results.begin(), results.end()); + assert(n == 3); + auto it = results.begin(); + assert(it->first == "andy"); + ++it; + assert(it->first == "andy1"); + ++it; + assert(it->first == "andy13"); + ++it; + assert(it == results.end()); + + results = db.prefix_search(MDDS_ASCII("andy's toy")); + n = std::distance(results.begin(), results.end()); + assert(n == 0); + + results = db.prefix_search(MDDS_ASCII("e")); + n = std::distance(results.begin(), results.end()); + assert(n == 0); + + results = db.prefix_search(MDDS_ASCII("b")); + n = std::distance(results.begin(), results.end()); + assert(n == 1); + it = results.begin(); + assert(it->first == "bruce"); + assert(it->second == name_bruce); + ++it; + assert(it == results.end()); +} + +struct value_wrapper +{ + int value; + + value_wrapper() : value(0) + {} + value_wrapper(int _value) : value(_value) + {} +}; + +std::ostream& operator<<(std::ostream& os, const value_wrapper& vw) +{ + os << vw.value; + return os; +} + +typedef packed_trie_map<trie::std_string_traits, value_wrapper> packed_value_map_type; + +void trie_packed_test_value_life_cycle() +{ + stack_printer __stack_printer__("::trie_packed_test_value_life_cycle"); + + using entry = packed_value_map_type::entry; + + // Entries must be sorted by the key! + std::unique_ptr<vector<entry>> entries(new vector<entry>); + entries->push_back(entry(MDDS_ASCII("fifteen"), value_wrapper(15))); + entries->push_back(entry(MDDS_ASCII("ten"), value_wrapper(10))); + entries->push_back(entry(MDDS_ASCII("twelve"), value_wrapper(12))); + entries->push_back(entry(MDDS_ASCII("two"), value_wrapper(2))); + + packed_value_map_type db(entries->data(), entries->size()); + + // Delete the original entry store. + entries.reset(); + + auto results = db.prefix_search(nullptr, 0); + std::for_each(results.begin(), results.end(), [](const packed_value_map_type::const_iterator::value_type& v) { + cout << v.first << ": " << v.second.value << endl; + }); + + auto it = db.find(MDDS_ASCII("twelve")); + assert(it->second.value == 12); + + it = db.find(MDDS_ASCII("two")); + assert(it->second.value == 2); + + it = db.find(MDDS_ASCII("foo")); + assert(it == db.end()); +} + +struct custom_string +{ + std::string data; + + custom_string() + {} + custom_string(const std::string& _data) : data(_data) + {} +}; + +struct custom_string_trait +{ + typedef uint16_t key_unit_type; + typedef custom_string key_type; + typedef std::vector<key_unit_type> key_buffer_type; + + static key_buffer_type to_key_buffer(const key_unit_type* str, size_t length) + { + key_buffer_type buf; + const key_unit_type* str_end = str + length; + for (; str != str_end; ++str) + buf.push_back(*str); + + return buf; + } + + static void push_back(key_buffer_type& buffer, key_unit_type c) + { + buffer.push_back(c); + } + + static void pop_back(key_buffer_type& buffer) + { + buffer.pop_back(); + } + + static key_type to_key(const key_buffer_type& buf) + { + // Cast all uint16_t chars to regular chars. + key_type s; + + std::for_each(buf.begin(), buf.end(), [&](key_unit_type c) { s.data.push_back(static_cast<char>(c)); }); + return s; + } +}; + +typedef packed_trie_map<custom_string_trait, std::string> packed_custom_str_map_type; + +void trie_packed_test_custom_string() +{ + stack_printer __stack_printer__("::trie_packed_test_custom_string"); + + const uint16_t key_alex[] = {0x41, 0x6C, 0x65, 0x78}; + const uint16_t key_bob[] = {0x42, 0x6F, 0x62}; + const uint16_t key_max[] = {0x4D, 0x61, 0x78}; + const uint16_t key_ming[] = {0x4D, 0x69, 0x6E, 0x67}; + + const packed_custom_str_map_type::entry entries[] = { + {key_alex, 4, "Alex"}, + {key_bob, 3, "Bob"}, + {key_max, 3, "Max"}, + {key_ming, 4, "Ming"}, + }; + + size_t n_entries = std::size(entries); + packed_custom_str_map_type db(entries, n_entries); + for (size_t i = 0; i < n_entries; ++i) + { + auto it = db.find(entries[i].key, entries[i].keylen); + cout << it->second << endl; + assert(it->second == entries[i].value); + } + + // Find all keys that start with 'M'. + auto results = db.prefix_search(key_max, 1); + size_t n = std::distance(results.begin(), results.end()); + assert(n == 2); + auto it = results.begin(); + assert(it->first.data == it->second); + assert(it->second == "Max"); + ++it; + assert(it->first.data == it->second); + assert(it->second == "Ming"); + ++it; + assert(it == results.end()); +} + +void trie_packed_test_iterator_empty() +{ + stack_printer __stack_printer__("::trie_packed_test_iterator_empty"); + packed_int_map_type db(nullptr, 0); + + // empty container + packed_int_map_type::const_iterator it = db.begin(); + packed_int_map_type::const_iterator ite = db.end(); + + assert(it == ite); +} + +void trie_packed_test_iterator() +{ + stack_printer __stack_printer__("::trie_packed_test_iterator"); + + using trie_map_type = trie_map<trie::std_string_traits, int>; + using packed_type = trie_map_type::packed_type; + using kv = packed_type::key_value_type; + + trie_map_type db; + + db.insert(MDDS_ASCII("a"), 1); + packed_type packed = db.pack(); + assert(db.size() == packed.size()); + packed_type::const_iterator it = packed.begin(); + packed_type::const_iterator ite = packed.end(); + assert(it != ite); + assert(it->first == "a"); + assert(it->second == 1); + + db.insert(MDDS_ASCII("ab"), 2); + packed = db.pack(); // this invalidates the end position. + assert(db.size() == packed.size()); + + it = packed.begin(); + ite = packed.end(); + assert(it != ite); + assert(it->first == "a"); + assert(it->second == 1); + + ++it; + bool check_true = check_equal(*it++, kv("ab", 2)); + assert(check_true); + assert(it == ite); + + db.insert(MDDS_ASCII("aba"), 3); + db.insert(MDDS_ASCII("abb"), 4); + db.insert(MDDS_ASCII("abc"), 5); + db.insert(MDDS_ASCII("bc"), 6); + db.insert(MDDS_ASCII("bcd"), 7); + + packed = db.pack(); + assert(db.size() == packed.size()); + + it = packed.begin(); + ite = packed.end(); + + assert(*it == kv("a", 1)); + assert(check_equal(*(++it), kv("ab", 2))); + assert(check_equal(*(++it), kv("aba", 3))); + assert(check_equal(*(++it), kv("abb", 4))); + assert(check_equal(*(++it), kv("abc", 5))); + assert(check_equal(*(++it), kv("bc", 6))); + assert(check_equal(*(++it), kv("bcd", 7))); + assert(it->first == "bcd"); + assert(it->second == 7); + ++it; + assert(it == ite); + + --it; + assert(it != ite); + assert(check_equal(*it, kv("bcd", 7))); + --it; + assert(check_equal(*it, kv("bc", 6))); + --it; + assert(check_equal(*it, kv("abc", 5))); + --it; + assert(check_equal(*it, kv("abb", 4))); + --it; + assert(check_equal(*it, kv("aba", 3))); + --it; + assert(check_equal(*it, kv("ab", 2))); + assert(check_equal(*(--it), kv("a", 1))); + assert(it == packed.begin()); + + assert(check_equal(*(++it), kv("ab", 2))); + assert(check_equal(*(++it), kv("aba", 3))); + --it; + assert(check_equal(*it, kv("ab", 2))); + --it; + assert(check_equal(*it, kv("a", 1))); + ++it; + assert(check_equal(*it, kv("ab", 2))); + ++it; + assert(check_equal(*it, kv("aba", 3))); + + // Post-decrement operator. + assert(check_equal(*it--, kv("aba", 3))); + assert(check_equal(*it, kv("ab", 2))); +} + +void trie_packed_test_prefix_search1() +{ + stack_printer __stack_printer__("::trie_packed_test_prefix_search1"); + + using trie_map_type = trie_map<trie::std_string_traits, int>; + using packed_type = trie_map_type::packed_type; + + trie_map_type db; + db.insert(MDDS_ASCII("andy"), 1); + db.insert(MDDS_ASCII("andy1"), 2); + db.insert(MDDS_ASCII("andy12"), 3); + + { + auto results = db.prefix_search(MDDS_ASCII("andy")); + auto it = results.begin(); + assert(it != results.end()); + assert(it->first == "andy"); + ++it; + assert(it->first == "andy1"); + ++it; + assert(it->first == "andy12"); + ++it; + assert(it == results.end()); + + size_t n = std::distance(results.begin(), results.end()); + assert(n == 3); + } + + packed_type packed = db.pack(); + { + auto results = packed.prefix_search(MDDS_ASCII("andy")); + auto it = results.begin(); + assert(it != results.end()); + assert(it->first == "andy"); + ++it; + assert(it->first == "andy1"); + ++it; + assert(it->first == "andy12"); + ++it; + assert(it == results.end()); + + size_t n = std::distance(results.begin(), results.end()); + assert(n == 3); + } +} + +void trie_packed_test_key_as_input() +{ + stack_printer __stack_printer__("::trie_packed_test_key_as_input"); + + typedef trie_map<trie::std_string_traits, int> trie_map_type; + trie_map_type db; + + db.insert(std::string("string as key"), 1); + db.insert("literal as key", 2); + auto packed = db.pack(); + + auto it = packed.find("literal as key"); + assert(it != packed.end()); + assert(it->first == "literal as key"); + assert(it->second == 2); + + auto results = packed.prefix_search("str"); + auto rit = results.begin(); + assert(rit != results.end()); + assert(rit->first == "string as key"); + assert(rit->second == 1); + ++rit; + assert(rit == results.end()); +} + +void trie_packed_test_copying() +{ + stack_printer __stack_printer__("::trie_packed_test_copying"); + using map_type = packed_trie_map<trie::std_string_traits, int>; + + map_type::entry entries[] = { + {MDDS_ASCII("aaron"), 0}, {MDDS_ASCII("al"), 1}, {MDDS_ASCII("aldi"), 2}, {MDDS_ASCII("andy"), 3}, + {MDDS_ASCII("bison"), 4}, {MDDS_ASCII("bruce"), 5}, {MDDS_ASCII("charlie"), 6}, {MDDS_ASCII("charlotte"), 7}, + {MDDS_ASCII("david"), 8}, {MDDS_ASCII("dove"), 9}, {MDDS_ASCII("e"), 10}, {MDDS_ASCII("eva"), 11}, + }; + + auto verify_content = [&entries](const map_type& db) { + auto it = db.begin(); + const map_type::entry* p_entries = entries; + const map_type::entry* p_entries_end = p_entries + db.size(); + size_t n = std::distance(p_entries, p_entries_end); + assert(db.size() == n); + assert(!db.empty()); + + for (; p_entries != p_entries_end; ++p_entries, ++it) + { + std::string key_expected(p_entries->key, p_entries->keylen); + assert(key_expected == it->first); + assert(p_entries->value == it->second); + } + }; + + auto db = std::make_unique<map_type>(entries, std::size(entries)); + auto db_copied(*db); + assert(*db == db_copied); + assert(db->size() == db_copied.size()); + db.reset(); + + auto it = db_copied.find("charlie"); + assert(it != db_copied.end()); + assert(it->first == "charlie"); + assert(it->second == 6); + + verify_content(db_copied); + + auto db_moved(std::move(db_copied)); + assert(db_copied.empty()); + assert(!db_moved.empty()); + assert(db_moved.size() == std::size(entries)); + + it = db_copied.find("bison"); + assert(it == db_copied.end()); + it = db_moved.find("bison"); + assert(it != db_moved.end()); + assert(it->first == "bison"); + assert(it->second == 4); + + verify_content(db_moved); + + map_type db_copy_assigned; + assert(db_copy_assigned.empty()); + db_copy_assigned = db_moved; + assert(db_copy_assigned == db_moved); + + verify_content(db_moved); + verify_content(db_copy_assigned); + + map_type db_move_assigned; + assert(db_move_assigned.empty()); + db_move_assigned = std::move(db_moved); + assert(db_move_assigned != db_moved); + + verify_content(db_move_assigned); + assert(db_moved.empty()); +} + +void trie_packed_test_non_equal() +{ + stack_printer __stack_printer__("::trie_packed_test_non_equal"); + + using map_type = packed_trie_map<trie::std_string_traits, int>; + + map_type::entry entries1[] = { + {MDDS_ASCII("aaron"), 0}, {MDDS_ASCII("al"), 1}, {MDDS_ASCII("aldi"), 2}, {MDDS_ASCII("andy"), 3}, + {MDDS_ASCII("bison"), 4}, {MDDS_ASCII("bruce"), 5}, {MDDS_ASCII("charlie"), 6}, {MDDS_ASCII("charlotte"), 7}, + {MDDS_ASCII("david"), 8}, {MDDS_ASCII("dove"), 9}, {MDDS_ASCII("e"), 10}, {MDDS_ASCII("eva"), 11}, + }; + + map_type::entry entries2[] = { + {MDDS_ASCII("aaron"), 0}, {MDDS_ASCII("al"), 1}, {MDDS_ASCII("aldi"), 2}, + {MDDS_ASCII("andy"), 3}, {MDDS_ASCII("bison"), 4}, {MDDS_ASCII("bruce"), 2}, // different value + {MDDS_ASCII("charlie"), 6}, {MDDS_ASCII("charlotte"), 7}, {MDDS_ASCII("david"), 8}, + {MDDS_ASCII("dove"), 9}, {MDDS_ASCII("e"), 10}, {MDDS_ASCII("eva"), 11}, + }; + + // fewer entries + map_type::entry entries3[] = { + {MDDS_ASCII("aaron"), 0}, {MDDS_ASCII("al"), 1}, {MDDS_ASCII("aldi"), 2}, {MDDS_ASCII("andy"), 3}, + {MDDS_ASCII("bison"), 4}, {MDDS_ASCII("bruce"), 5}, {MDDS_ASCII("charlie"), 6}, {MDDS_ASCII("charlotte"), 7}, + {MDDS_ASCII("david"), 8}, {MDDS_ASCII("dove"), 9}, {MDDS_ASCII("e"), 10}, + }; + + map_type db1(entries1, std::size(entries1)); + map_type db2(entries2, std::size(entries2)); + map_type db3(entries3, std::size(entries3)); + assert(db1 != db2); + assert(db1 != db3); + assert(db2 != db3); + + map_type db4(entries1, std::size(entries1)); + map_type db5(entries2, std::size(entries2)); + map_type db6(entries3, std::size(entries3)); + + assert(db1 == db4); + assert(db2 == db5); + assert(db3 == db6); +} + +namespace trie_packed_test_save_and_load_state { + +struct _custom_variable_value +{ + enum class v_type + { + unknown, + fp32, + int64 + }; + + v_type type; + + union + { + float fp32; + int64_t int64; + } value; + + _custom_variable_value() : type(v_type::unknown) + {} + + _custom_variable_value(float v) : type(v_type::fp32) + { + value.fp32 = v; + } + + _custom_variable_value(int v) : type(v_type::int64) + { + value.int64 = v; + } + + _custom_variable_value(const _custom_variable_value& other) : type(other.type) + { + switch (type) + { + case v_type::fp32: + value.fp32 = other.value.fp32; + break; + case v_type::int64: + value.int64 = other.value.int64; + break; + default:; + } + } + + bool operator==(const _custom_variable_value& other) const + { + if (type != other.type) + return false; + + switch (type) + { + case v_type::fp32: + return value.fp32 == other.value.fp32; + case v_type::int64: + return value.int64 == other.value.int64; + default:; + } + + return true; + } + + bool operator!=(const _custom_variable_value& other) const + { + return !operator==(other); + } +}; + +struct _custom_variable_serializer +{ + union bin_value + { + char buffer[8]; + float fp32; + int64_t int64; + }; + + static constexpr bool variable_size = true; + + static void write(std::ostream& os, const _custom_variable_value& v) + { + bin_value bv; + + switch (v.type) + { + case _custom_variable_value::v_type::unknown: + { + char c = 0; + os.write(&c, 1); + break; + } + case _custom_variable_value::v_type::fp32: + { + char c = 1; + os.write(&c, 1); + bv.fp32 = v.value.fp32; + os.write(bv.buffer, 4); + break; + } + case _custom_variable_value::v_type::int64: + { + char c = 2; + os.write(&c, 1); + bv.int64 = v.value.int64; + os.write(bv.buffer, 8); + break; + } + } + } + + static void read(std::istream& is, size_t n, _custom_variable_value& v) + { + assert(n > 0); + char c; + is.read(&c, 1); + + switch (c) + { + case 0: + v.type = _custom_variable_value::v_type::unknown; + break; + case 1: + v.type = _custom_variable_value::v_type::fp32; + break; + case 2: + v.type = _custom_variable_value::v_type::int64; + break; + default: + assert(!"invalid value type"); + } + + n -= 1; + bin_value bv; + + switch (v.type) + { + case _custom_variable_value::v_type::fp32: + assert(n == 4); + is.read(bv.buffer, 4); + v.value.fp32 = bv.fp32; + break; + case _custom_variable_value::v_type::int64: + assert(n == 8); + is.read(bv.buffer, 8); + v.value.int64 = bv.int64; + break; + case _custom_variable_value::v_type::unknown: + break; + default: + assert(!"invalid value type"); + } + } +}; + +/** + * mock value struct containing one value string that only stores "zero", + * "one", "two" or "three". We use a custom serializer to store the value + * using only 1 byte each. + */ +struct _custom_fixed_value +{ + std::string value_string; // only stores "zero", "one", "two" or "three". + + _custom_fixed_value() + {} + + _custom_fixed_value(const char* p) : value_string(p, std::strlen(p)) + {} + + bool operator==(const _custom_fixed_value& other) const + { + return value_string == other.value_string; + } + + bool operator!=(const _custom_fixed_value& other) const + { + return !operator==(other); + } +}; + +struct _custom_fixed_serializer +{ + static constexpr bool variable_size = false; + static constexpr size_t value_size = 1; + + static void write(std::ostream& os, const _custom_fixed_value& v) + { + char bv = -1; + + if (v.value_string == "zero") + bv = 0; + else if (v.value_string == "one") + bv = 1; + else if (v.value_string == "two") + bv = 2; + else if (v.value_string == "three") + bv = 3; + + os.write(&bv, 1); + } + + static void read(std::istream& is, size_t n, _custom_fixed_value& v) + { + assert(n == 1); + char bv = -1; + is.read(&bv, 1); + + switch (bv) + { + case 0: + v.value_string = "zero"; + break; + case 1: + v.value_string = "one"; + break; + case 2: + v.value_string = "two"; + break; + case 3: + v.value_string = "three"; + break; + default: + v.value_string = "???"; + } + } +}; + +void test1() +{ + stack_printer __stack_printer__("trie_packed_test_save_and_load_state::test1"); + packed_int_map_type empty_db; + + std::string saved_state; + + { + std::ostringstream state; + empty_db.save_state(state); + saved_state = state.str(); + } + + packed_int_map_type restored; + + { + std::istringstream state(saved_state); + restored.load_state(state); + } + + assert(restored == empty_db); +} + +void test2() +{ + stack_printer __stack_printer__("trie_packed_test_save_and_load_state::test2"); + packed_int_map_type::entry entries[] = { + {MDDS_ASCII("bruce"), 5}, {MDDS_ASCII("charlie"), 6}, {MDDS_ASCII("charlotte"), 7}, + {MDDS_ASCII("david"), 8}, {MDDS_ASCII("dove"), 9}, + }; + + packed_int_map_type db(entries, std::size(entries)); + + std::string saved_state; + + { + std::ostringstream state; + db.save_state(state); + saved_state = state.str(); + } + + packed_int_map_type restored; + assert(restored != db); + + { + std::istringstream state(saved_state); + restored.load_state(state); + } + + assert(restored == db); +} + +void test3() +{ + stack_printer __stack_printer__("trie_packed_test_save_and_load_state::test3"); + std::vector<packed_str_map_type::entry> entries = { + {MDDS_ASCII("Abby"), "ABBY"}, + {MDDS_ASCII("Ashley"), "ASHLEY"}, + {MDDS_ASCII("Candelaria"), "CANDELARIA"}, + {MDDS_ASCII("Carita"), "CARITA"}, + {MDDS_ASCII("Christal"), "CHRISTAL"}, + {MDDS_ASCII("Cory"), "CORY"}, + {MDDS_ASCII("Estrella"), "ESTRELLA"}, + {MDDS_ASCII("Etha"), "ETHA"}, + {MDDS_ASCII("Harley"), "HARLEY"}, + {MDDS_ASCII("Irish"), "IRISH"}, + {MDDS_ASCII("Kiara"), "KIARA"}, + {MDDS_ASCII("Korey"), "KOREY"}, + {MDDS_ASCII("Laurene"), "LAURENE"}, + {MDDS_ASCII("Michiko"), "MICHIKO"}, + {MDDS_ASCII("Miriam"), "MIRIAM"}, + {MDDS_ASCII("Mitzi"), "MITZI"}, + {MDDS_ASCII("Seth"), "SETH"}, + {MDDS_ASCII("Sindy"), "SINDY"}, + {MDDS_ASCII("Tawanna"), "TAWANNA"}, + {MDDS_ASCII("Tyra"), "TYRA"}, + }; + + packed_str_map_type db(entries.data(), entries.size()); + + // Run some search. + auto results = db.prefix_search("Mi"); + auto it = results.begin(); + assert(it != results.end()); + assert(it->first == "Michiko"); + assert(it->second == "MICHIKO"); + ++it; + assert(it != results.end()); + assert(it->first == "Miriam"); + assert(it->second == "MIRIAM"); + ++it; + assert(it != results.end()); + assert(it->first == "Mitzi"); + assert(it->second == "MITZI"); + ++it; + assert(it == results.end()); + + std::string saved_state; + + { + std::ostringstream state; + db.save_state(state); + saved_state = state.str(); + } + + packed_str_map_type restored; + + { + std::istringstream state(saved_state); + restored.load_state(state); + } + + assert(db == restored); +} + +void test4() +{ + stack_printer __stack_printer__("trie_packed_test_save_and_load_state::test4"); + using map_type = packed_trie_map<trie::std_string_traits, std::vector<int64_t>>; + + std::vector<map_type::entry> entries = { + {MDDS_ASCII("Abby"), {65, 98, 98, 121}}, + {MDDS_ASCII("Ashley"), {65, 115, 104, 108, 101, 121}}, + {MDDS_ASCII("Christal"), {67, 104, 114, 105, 115, 116, 97, 108}}, + {MDDS_ASCII("Cory"), {67, 111, 114, 121}}, + {MDDS_ASCII("Harley"), {72, 97, 114, 108, 101, 121}}, + {MDDS_ASCII("Kiara"), {75, 105, 97, 114, 97}}, + {MDDS_ASCII("Mitzi"), {77, 105, 116, 122, 105}}, + }; + + map_type db(entries.data(), entries.size()); + assert(db.size() == entries.size()); + + std::string saved_state; + { + std::ostringstream state; + db.save_state(state); + saved_state = state.str(); + } + + map_type restored; + + { + std::istringstream state(saved_state); + restored.load_state(state); + } + + assert(db == restored); +} + +void test5() +{ + stack_printer __stack_printer__("trie_packed_test_save_and_load_state::test5"); + using map_type = packed_trie_map<trie::std_string_traits, float>; + + std::vector<map_type::entry> entries = { + {MDDS_ASCII("Abby"), 1.0f}, {MDDS_ASCII("Ashley"), 1.1f}, {MDDS_ASCII("Christal"), 1.2f}, + {MDDS_ASCII("Cory"), 1.3f}, {MDDS_ASCII("Harley"), 1.4f}, {MDDS_ASCII("Kiara"), 1.5f}, + {MDDS_ASCII("Mitzi"), 1.6f}, + }; + + map_type db(entries.data(), entries.size()); + assert(db.size() == entries.size()); + + std::string saved_state; + { + std::ostringstream state; + db.save_state(state); + saved_state = state.str(); + } + + map_type restored; + + { + std::istringstream state(saved_state); + restored.load_state(state); + } + + assert(db == restored); +} + +template<typename SeqT> +void test6() +{ + stack_printer __stack_printer__("trie_packed_test_save_and_load_state::test6"); + using map_type = packed_trie_map<trie::std_string_traits, SeqT>; + + std::vector<typename map_type::entry> entries = { + {MDDS_ASCII("Abby"), {65.0, 98.1, 98.2, 121.3}}, + {MDDS_ASCII("Ashley"), {65.0, 11.5, 1.04, 1.08, .101, .12586}}, + {MDDS_ASCII("Christal"), {67.0, -10.4, -114.236}}, + {MDDS_ASCII("Cory"), {67.0, 122.111}}, + {MDDS_ASCII("Harley"), {72.0, 97.12, -1.114}}, + {MDDS_ASCII("Kiara"), {75.0, 1.05, 9.7, 1.14, -97.5}}, + {MDDS_ASCII("Mitzi"), {77.0, 10.5, 11.6, 1.22, 10.5}}, + }; + + map_type db(entries.data(), entries.size()); + assert(db.size() == entries.size()); + + std::string saved_state; + { + std::ostringstream state; + db.save_state(state); + saved_state = state.str(); + } + + map_type restored; + + { + std::istringstream state(saved_state); + restored.load_state(state); + } + + assert(db == restored); +} + +void test7() +{ + stack_printer __stack_printer__("trie_packed_test_save_and_load_state::test7"); + using map_type = packed_trie_map<trie::std_string_traits, _custom_variable_value>; + + std::vector<map_type::entry> entries = { + {MDDS_ASCII("Alan"), 1.2f}, {MDDS_ASCII("Cory"), -125}, {MDDS_ASCII("Eleni"), 966}, + {MDDS_ASCII("Evia"), -0.987f}, {MDDS_ASCII("Nathaniel"), 0}, {MDDS_ASCII("Rebbecca"), 1.234f}, + {MDDS_ASCII("Rodrick"), 34253536}, {MDDS_ASCII("Stuart"), 12}, {MDDS_ASCII("Verline"), 56}, + }; + + map_type db(entries.data(), entries.size()); + assert(db.size() == entries.size()); + + std::string saved_state; + { + std::ostringstream state; + db.save_state<_custom_variable_serializer>(state); + saved_state = state.str(); + } + + map_type restored; + + { + std::istringstream state(saved_state); + restored.load_state<_custom_variable_serializer>(state); + } + + assert(db == restored); +} + +void test8() +{ + stack_printer __stack_printer__("trie_packed_test_save_and_load_state::test8"); + using map_type = packed_trie_map<trie::std_string_traits, _custom_fixed_value>; + + std::vector<map_type::entry> entries = { + {MDDS_ASCII("Bernardine"), "zero"}, {MDDS_ASCII("Donny"), "two"}, {MDDS_ASCII("Julia"), "one"}, + {MDDS_ASCII("Lindsy"), "three"}, {MDDS_ASCII("Martine"), "three"}, {MDDS_ASCII("Shana"), "two"}, + {MDDS_ASCII("Sonia"), "zero"}, {MDDS_ASCII("Tracie"), "one"}, {MDDS_ASCII("Vanita"), "two"}, + {MDDS_ASCII("Yung"), "zero"}, + }; + + map_type db(entries.data(), entries.size()); + assert(db.size() == entries.size()); + + std::string saved_state; + { + std::ostringstream state; + db.save_state<_custom_fixed_serializer>(state); + saved_state = state.str(); + } + + map_type restored; + + { + std::istringstream state(saved_state); + restored.load_state<_custom_fixed_serializer>(state); + } + + assert(db == restored); + + // Run some query to make sure it is still functional. + auto it = restored.find("Tracie"); + assert(it->first == "Tracie"); + assert(it->second.value_string == "one"); +} + +void run() +{ + test1(); + test2(); + test3(); + test4(); + test5(); + test6<std::vector<double>>(); + test6<std::deque<double>>(); + test6<std::list<double>>(); + test7(); + test8(); +} + +} // namespace trie_packed_test_save_and_load_state + +void trie_test1() +{ + stack_printer __stack_printer__("::trie_test1"); + + typedef trie_map<trie::std_string_traits, custom_string> trie_map_type; + typedef packed_trie_map<trie::std_string_traits, custom_string> packed_trie_map_type; + + trie_map_type db; + const trie_map_type& dbc = db; + + assert(db.size() == 0); + db.insert(MDDS_ASCII("Barak"), custom_string("Obama")); + assert(db.size() == 1); + db.insert(MDDS_ASCII("Bob"), custom_string("Marley")); + assert(db.size() == 2); + db.insert(MDDS_ASCII("Hideki"), custom_string("Matsui")); + assert(db.size() == 3); + + auto it = dbc.find(MDDS_ASCII("Barak")); + assert(it->first == "Barak"); + custom_string res = it->second; + assert(res.data == "Obama"); + + res = dbc.find(MDDS_ASCII("Bob"))->second; + assert(res.data == "Marley"); + res = dbc.find(MDDS_ASCII("Hideki"))->second; + assert(res.data == "Matsui"); + + // Non-existent key. + it = dbc.find(MDDS_ASCII("Von")); + assert(it == dbc.end()); + it = dbc.find(MDDS_ASCII("Bar")); + assert(it == dbc.end()); + + // Perform prefix search on "B", which should return both "Barak" and "Bob". + // The results should be sorted. + { + auto matches = dbc.prefix_search(MDDS_ASCII("B")); + size_t n = std::distance(matches.begin(), matches.end()); + assert(n == 2); + auto it2 = matches.begin(); + assert(it2->first == "Barak"); + assert(it2->second.data == "Obama"); + ++it2; + assert(it2->first == "Bob"); + assert(it2->second.data == "Marley"); + + matches = dbc.prefix_search(MDDS_ASCII("Hi")); + n = std::distance(matches.begin(), matches.end()); + assert(n == 1); + it2 = matches.begin(); + assert(it2->first == "Hideki"); + assert(it2->second.data == "Matsui"); + + // Invalid prefix searches. + matches = dbc.prefix_search(MDDS_ASCII("Bad")); + assert(matches.begin() == matches.end()); + matches = dbc.prefix_search(MDDS_ASCII("Foo")); + assert(matches.begin() == matches.end()); + } + + { + // Create a packed version from it, and make sure it still generates the + // same results. + packed_trie_map_type packed(dbc); + assert(packed.size() == dbc.size()); + + { + auto results = packed.prefix_search(MDDS_ASCII("B")); + size_t n = std::distance(results.begin(), results.end()); + assert(n == 2); + auto it2 = results.begin(); + assert(it2->first == "Barak"); + assert(it2->second.data == "Obama"); + ++it2; + assert(it2->first == "Bob"); + assert(it2->second.data == "Marley"); + ++it2; + assert(it2 == results.end()); + } + + { + auto results = dbc.prefix_search(MDDS_ASCII("Hi")); + size_t n = std::distance(results.begin(), results.end()); + assert(n == 1); + auto it2 = results.begin(); + assert(it2->first == "Hideki"); + assert(it2->second.data == "Matsui"); + } + + // Invalid prefix searches. + auto results = dbc.prefix_search(MDDS_ASCII("Bad")); + assert(results.begin() == results.end()); + results = dbc.prefix_search(MDDS_ASCII("Foo")); + assert(results.begin() == results.end()); + } + + { + auto packed = dbc.pack(); + auto results = packed.prefix_search(MDDS_ASCII("B")); + size_t n = std::distance(results.begin(), results.end()); + assert(n == 2); + auto it2 = results.begin(); + assert(it2->first == "Barak"); + assert(it2->second.data == "Obama"); + ++it2; + assert(it2->first == "Bob"); + assert(it2->second.data == "Marley"); + } + + // Erase an existing key. + bool erased = db.erase(MDDS_ASCII("Hideki")); + assert(erased); + assert(db.size() == 2); + + it = dbc.find(MDDS_ASCII("Hideki")); + assert(it == dbc.end()); + + // Try to erase a key that doesn't exist. + erased = db.erase(MDDS_ASCII("Foo")); + assert(!erased); + assert(db.size() == 2); + + // Clear the whole thing. + db.clear(); + assert(db.size() == 0); +} + +void trie_test2() +{ + stack_printer __stack_printer__("::trie_test2"); + using key_trait = trie::std_container_traits<std::vector<uint16_t>>; + using map_type = trie_map<key_trait, int>; + using key_type = map_type::key_type; + + auto print_key = [](const std::vector<uint16_t>& key, const char* msg) { + cout << msg << ": "; + std::copy(key.begin(), key.end(), std::ostream_iterator<uint16_t>(std::cout, " ")); + cout << endl; + }; + + map_type db; + key_type key = {2393, 99, 32589, 107, 0, 65535}; + print_key(key, "original"); + int value = 1; + db.insert(key, value); + assert(db.size() == 1); + { + auto it = db.begin(); + assert(it != db.end()); + assert(it->first == key); + + print_key(it->first, "from trie_map"); + } + + auto packed = db.pack(); + assert(packed.size() == 1); + + { + auto it = packed.begin(); + assert(it != packed.end()); + print_key(it->first, "from packed_trie_map"); + assert(it->first == key); + } +} + +void trie_test_iterator_empty() +{ + stack_printer __stack_printer__("::trie_test_iterator_empty"); + typedef trie_map<trie::std_string_traits, int> trie_map_type; + trie_map_type db; + const trie_map_type& dbc = db; + + // empty container + trie_map_type::const_iterator it = dbc.begin(); + trie_map_type::const_iterator ite = dbc.end(); + + assert(it == ite); + assert(db.begin() == dbc.begin()); // non-const vs const iterators + assert(dbc.end() == db.end()); // const vs non-const iterators +} + +void trie_test_iterator() +{ + stack_printer __stack_printer__("::trie_test_iterator"); + typedef trie_map<trie::std_string_traits, int> trie_map_type; + using kv = trie_map_type::key_value_type; + trie_map_type db; + const trie_map_type& dbc = db; + + cout << "empty container" << endl; + + // empty container + trie_map_type::const_iterator it = dbc.begin(); + trie_map_type::const_iterator ite = dbc.end(); + + // The end iterator will never get invalidated since it only references + // the root node which will never get modified as long as the parent + // container is alive. + + assert(it == ite); + + cout << "one element" << endl; + + db.insert(MDDS_ASCII("a"), 1); + it = dbc.begin(); + assert(it != ite); + assert(*it == kv("a", 1)); + ++it; + assert(it == ite); + + cout << "two elements" << endl; + + db.insert(MDDS_ASCII("ab"), 2); + it = dbc.begin(); + assert(it != ite); + assert(*it == kv("a", 1)); + ++it; + assert(it != ite); + assert(*it == kv("ab", 2)); + ++it; + assert(it == ite); + + cout << "more than two elements" << endl; + + db.insert(MDDS_ASCII("aba"), 3); + db.insert(MDDS_ASCII("abb"), 4); + db.insert(MDDS_ASCII("abc"), 5); + db.insert(MDDS_ASCII("bc"), 6); + db.insert(MDDS_ASCII("bcd"), 7); + + it = dbc.begin(); + assert(*it == kv("a", 1)); + ++it; + assert(*it == kv("ab", 2)); + ++it; + assert(*it == kv("aba", 3)); + ++it; + assert(*it == kv("abb", 4)); + ++it; + assert(*it == kv("abc", 5)); + ++it; + assert(*it == kv("bc", 6)); + ++it; + assert(*it == kv("bcd", 7)); + assert(it->first == "bcd"); + assert(it->second == 7); + ++it; + assert(it == ite); + + --it; + assert(it != ite); + assert(*it == kv("bcd", 7)); + --it; + assert(*it == kv("bc", 6)); + --it; + assert(*it == kv("abc", 5)); + --it; + assert(*it == kv("abb", 4)); + --it; + assert(*it == kv("aba", 3)); + --it; + assert(*it == kv("ab", 2)); + --it; + assert(*it == kv("a", 1)); + assert(it == dbc.begin()); + ++it; + assert(*it == kv("ab", 2)); + ++it; + assert(*it == kv("aba", 3)); + --it; + assert(*it == kv("ab", 2)); + --it; + assert(*it == kv("a", 1)); + ++it; + assert(*it == kv("ab", 2)); + ++it; + assert(*it == kv("aba", 3)); + + assert(db.begin() != dbc.end()); // non-const vs const iterators + assert(dbc.begin() != db.end()); // const vs non-const iterators +} + +void trie_test_iterator_with_erase() +{ + stack_printer __stack_printer__("::trie_test_iterator_with_erase"); + typedef trie_map<trie::std_string_traits, int> trie_map_type; + using kv = trie_map_type::key_value_type; + trie_map_type db; + const trie_map_type& dbc = db; + bool check_true = false; + + db.insert(MDDS_ASCII("Python"), 1); + db.insert(MDDS_ASCII("C++"), 2); + + auto it = dbc.begin(), ite = dbc.end(); + check_true = (*it++ == kv("C++", 2)); + assert(check_true); + check_true = (*it++ == kv("Python", 1)); + assert(check_true); + assert(it == ite); + + db.erase(MDDS_ASCII("C++")); + it = dbc.begin(); + check_true = (*it++ == kv("Python", 1)); + assert(check_true); + assert(it == ite); + check_true = (*(--it) == kv("Python", 1)); + assert(check_true); + assert(it == dbc.begin()); + + db.clear(); + assert(dbc.begin() == dbc.end()); + + db.insert(MDDS_ASCII("A"), 1); + db.insert(MDDS_ASCII("AB"), 2); + db.insert(MDDS_ASCII("ABC"), 3); + db.erase(MDDS_ASCII("AB")); + + it = dbc.begin(); + check_true = (*it++ == kv("A", 1)); + assert(check_true); + check_true = (*it++ == kv("ABC", 3)); + assert(check_true); + assert(it == ite); + + check_true = (*(--it) == kv("ABC", 3)); + assert(check_true); + check_true = (*(--it) == kv("A", 1)); + assert(check_true); + assert(it == dbc.begin()); + + db.clear(); + db.insert(MDDS_ASCII("A"), 1); + db.insert(MDDS_ASCII("AB"), 2); + db.insert(MDDS_ASCII("ABC"), 3); + db.erase(MDDS_ASCII("ABC")); + + it = dbc.begin(); + check_true = (*it++ == kv("A", 1)); + assert(check_true); + check_true = (*it++ == kv("AB", 2)); + assert(check_true); + assert(it == ite); + + check_true = (*(--it) == kv("AB", 2)); + assert(check_true); + check_true = (*(--it) == kv("A", 1)); + assert(check_true); + assert(it == dbc.begin()); + + it = ite; + --it; + assert(*it-- == kv("AB", 2)); // test post-decrement operator. + assert(*it == kv("A", 1)); +} + +void trie_test_find_iterator() +{ + stack_printer __stack_printer__("::trie_test_find_iterator"); + typedef trie_map<trie::std_string_traits, int> trie_map_type; + trie_map_type db; + const trie_map_type& dbc = db; + + db.insert(MDDS_ASCII("a"), 1); + db.insert(MDDS_ASCII("aa"), 2); + db.insert(MDDS_ASCII("ab"), 3); + db.insert(MDDS_ASCII("b"), 4); + { + auto it = dbc.find(MDDS_ASCII("a")); + assert(it->first == "a"); + assert(it->second == 1); + ++it; + assert(it->first == "aa"); + assert(it->second == 2); + ++it; + assert(it->first == "ab"); + assert(it->second == 3); + ++it; + assert(it->first == "b"); + assert(it->second == 4); + ++it; + assert(it == dbc.end()); + + it = dbc.find(MDDS_ASCII("aa")); + assert(it->first == "aa"); + assert(it->second == 2); + ++it; + assert(it->first == "ab"); + assert(it->second == 3); + ++it; + assert(it->first == "b"); + assert(it->second == 4); + ++it; + assert(it == dbc.end()); + + it = dbc.find(MDDS_ASCII("ab")); + assert(it->first == "ab"); + assert(it->second == 3); + ++it; + assert(it->first == "b"); + assert(it->second == 4); + ++it; + assert(it == dbc.end()); + + it = dbc.find(MDDS_ASCII("b")); + assert(it->first == "b"); + assert(it->second == 4); + ++it; + assert(it == dbc.end()); + } + + trie_map_type::packed_type packed = db.pack(); + { + auto it = packed.find(MDDS_ASCII("a")); + assert(it->first == "a"); + assert(it->second == 1); + ++it; + assert(it->first == "aa"); + assert(it->second == 2); + ++it; + assert(it->first == "ab"); + assert(it->second == 3); + ++it; + assert(it->first == "b"); + assert(it->second == 4); + ++it; + assert(it == packed.end()); + + it = packed.find(MDDS_ASCII("aa")); + assert(it->first == "aa"); + assert(it->second == 2); + ++it; + assert(it->first == "ab"); + assert(it->second == 3); + ++it; + assert(it->first == "b"); + assert(it->second == 4); + ++it; + assert(it == packed.end()); + + it = packed.find(MDDS_ASCII("ab")); + assert(it->first == "ab"); + assert(it->second == 3); + ++it; + assert(it->first == "b"); + assert(it->second == 4); + ++it; + assert(it == packed.end()); + + it = packed.find(MDDS_ASCII("b")); + assert(it->first == "b"); + assert(it->second == 4); + ++it; + assert(it == packed.end()); + } +} + +void trie_test_prefix_search() +{ + stack_printer __stack_printer__("::trie_test_prefix_search"); + + typedef trie_map<trie::std_string_traits, int> trie_map_type; + trie_map_type db; + const trie_map_type& dbc = db; + + db.insert(MDDS_ASCII("a"), 1); + db.insert(MDDS_ASCII("aa"), 2); + db.insert(MDDS_ASCII("ab"), 3); + db.insert(MDDS_ASCII("b"), 4); + + cout << "Performing prefix search on 'a'..." << endl; + + trie_map_type::search_results results = dbc.prefix_search(MDDS_ASCII("a")); + auto it = results.begin(); + auto ite = results.end(); + assert(it != ite); + assert(it->first == "a"); + assert(it->second == 1); + ++it; + assert(it->first == "aa"); + assert(it->second == 2); + ++it; + assert(it->first == "ab"); + assert(it->second == 3); + ++it; + assert(it == ite); + size_t n = std::distance(results.begin(), results.end()); + assert(n == 3); + + cout << "Performing prefix search on 'b'..." << endl; + + results = dbc.prefix_search(MDDS_ASCII("b")); + it = results.begin(); + ite = results.end(); + assert(it != ite); + assert(it->first == "b"); + assert(it->second == 4); + ++it; + assert(it == ite); + --it; + assert(it->first == "b"); + assert(it->second == 4); + n = std::distance(results.begin(), results.end()); + assert(n == 1); + + // Only one element. + db.clear(); + db.insert(MDDS_ASCII("dust"), 10); + + cout << "Performing prefix search on 'du'..." << endl; + + results = dbc.prefix_search(MDDS_ASCII("du")); + it = results.begin(); + assert(it->first == "dust"); + assert(it->second == 10); + bool check_true = (++it == results.end()); + assert(check_true); + --it; + assert(it->first == "dust"); + assert(it->second == 10); + n = std::distance(results.begin(), results.end()); + assert(n == 1); +} + +void trie_test_key_as_input() +{ + stack_printer __stack_printer__("::trie_test_key_as_input"); + + typedef trie_map<trie::std_string_traits, int> trie_map_type; + trie_map_type db; + const trie_map_type& dbc = db; + + db.insert(std::string("string as key"), 1); + db.insert("literal as key", 2); + + auto it = dbc.find("literal as key"); + assert(it != dbc.end()); + assert(it->first == "literal as key"); + assert(it->second == 2); + + auto results = dbc.prefix_search("str"); + auto rit = results.begin(); + assert(rit != results.end()); + assert(rit->first == "string as key"); + assert(rit->second == 1); + ++rit; + assert(rit == results.end()); +} + +void trie_test_copying() +{ + stack_printer __stack_printer__("::trie_test_copying"); + + typedef trie_map<trie::std_string_traits, int> trie_map_type; + trie_map_type db; + assert(db.empty()); + + { + auto db_copied(db); + assert(db_copied.empty()); + } + + db.insert("twenty", 20); + db.insert("twelve", 12); + assert(db.size() == 2); + + { + // copy constructor + auto db_copied(db); + const trie_map_type& dbc_copied = db_copied; + assert(db_copied.size() == 2); + + auto it = dbc_copied.find("twenty"); + assert(it != dbc_copied.end()); + assert(it->first == "twenty"); + assert(it->second == 20); + + it = dbc_copied.find("twelve"); + assert(it != dbc_copied.end()); + assert(it->first == "twelve"); + assert(it->second == 12); + } + + { + // copy assignment + trie_map_type db_copied; + db_copied = db; + const trie_map_type& dbc_copied = db_copied; + assert(db_copied.size() == 2); + + auto it = dbc_copied.find("twenty"); + assert(it != dbc_copied.end()); + assert(it->first == "twenty"); + assert(it->second == 20); + + it = dbc_copied.find("twelve"); + assert(it != dbc_copied.end()); + assert(it->first == "twelve"); + assert(it->second == 12); + } + + { + // move constructor + auto db_copied(db); + auto db_moved(std::move(db_copied)); + const trie_map_type& dbc_moved = db_moved; + assert(db_moved.size() == 2); + assert(db_copied.empty()); + + auto it = dbc_moved.find("twenty"); + assert(it != dbc_moved.end()); + assert(it->first == "twenty"); + assert(it->second == 20); + + it = dbc_moved.find("twelve"); + assert(it != dbc_moved.end()); + assert(it->first == "twelve"); + assert(it->second == 12); + } + + { + // move assignment + auto db_copied(db); + trie_map_type db_moved; + db_moved = std::move(db_copied); + const trie_map_type& dbc_moved = db_moved; + assert(db_moved.size() == 2); + assert(db_copied.empty()); + + auto it = dbc_moved.find("twenty"); + assert(it != dbc_moved.end()); + assert(it->first == "twenty"); + assert(it->second == 20); + + it = dbc_moved.find("twelve"); + assert(it != dbc_moved.end()); + assert(it->first == "twelve"); + assert(it->second == 12); + } +} + +void trie_test_value_update_from_iterator() +{ + stack_printer __stack_printer__("::trie_test_value_update_from_iterator"); + + typedef trie_map<trie::std_string_traits, int> trie_map_type; + trie_map_type db; + db.insert("one", 1); + db.insert("two", 2); + db.insert("three", 3); + + trie_map_type::iterator it = db.begin(); + assert(it->first == "one"); + assert(it->second == 1); + it->second = 10; // update the value. + it = db.begin(); + assert(it->first == "one"); + assert(it->second == 10); + + it = db.find("three"); + assert(it->first == "three"); + assert(it->second == 3); + it->second = 345; // update the value again. + it = db.find("three"); + assert(it->first == "three"); + assert(it->second == 345); +} + +int main() +{ + try + { + trie_packed_test1(); + trie_packed_test2(); + trie_packed_test3(); + trie_packed_test4(); + trie_packed_test_value_life_cycle(); + trie_packed_test_custom_string(); + trie_packed_test_iterator_empty(); + trie_packed_test_iterator(); + trie_packed_test_prefix_search1(); + trie_packed_test_key_as_input(); + trie_packed_test_copying(); + trie_packed_test_non_equal(); + trie_packed_test_save_and_load_state::run(); + + trie_test1(); + trie_test2(); + + trie_test_iterator_empty(); + trie_test_iterator(); + trie_test_iterator_with_erase(); + trie_test_find_iterator(); + trie_test_prefix_search(); + trie_test_key_as_input(); + trie_test_copying(); + trie_test_value_update_from_iterator(); + } + catch (const std::exception& e) + { + cout << "Test failed: " << e.what() << endl; + return EXIT_FAILURE; + } + + cout << "Test finished successfully!" << endl; + + return EXIT_SUCCESS; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |