From b62ccc5d017e54beecd72d64d2074473c49192a7 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 4 Jan 2018 09:49:34 +0200 Subject: Implement small_list, small_forward_list Note that with VC small_list is never "small" because of the extra "headnode" that this implementation allocates (see notes in small-list.mxx for details). --- tests/small-forward-list/buildfile | 8 ++ tests/small-forward-list/driver.cxx | 164 ++++++++++++++++++++++++++++++++++++ 2 files changed, 172 insertions(+) create mode 100644 tests/small-forward-list/buildfile create mode 100644 tests/small-forward-list/driver.cxx (limited to 'tests/small-forward-list') diff --git a/tests/small-forward-list/buildfile b/tests/small-forward-list/buildfile new file mode 100644 index 0000000..8a6c7d6 --- /dev/null +++ b/tests/small-forward-list/buildfile @@ -0,0 +1,8 @@ +# file : tests/small-forward-list/buildfile +# copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +# license : MIT; see accompanying LICENSE file + +import libs = libbutl%lib{butl} +libs += $stdmod_lib + +exe{driver}: {hxx cxx}{*} $libs diff --git a/tests/small-forward-list/driver.cxx b/tests/small-forward-list/driver.cxx new file mode 100644 index 0000000..e6fc717 --- /dev/null +++ b/tests/small-forward-list/driver.cxx @@ -0,0 +1,164 @@ +// file : tests/small-forward-list/driver.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#include + +#ifndef __cpp_lib_modules +#include +#include +#endif + +// Other includes. + +#ifdef __cpp_modules +#ifdef __cpp_lib_modules +import std.core; +import std.io; +#endif +import butl.small_forward_list; +#else +#include +#endif + +using namespace std; +using namespace butl; + +// Return true if the data is stored entirely inside l. +// +template +inline bool +small (const small_forward_list& l) +{ + for (const T& x: l) + { + const void* p (&x); + + if (p < &l || p >= (&l + 1)) + return false; + } + + return true; +} + +template +inline const T& +front (const small_forward_list& l) +{ + return l.front (); +} + +template +inline const T& +back (const small_forward_list& l) +{ + auto i (l.begin ());; + for (auto j (i); ++j != l.end (); ) i = j; + return *i; +} + +int +main () +{ + using list = small_forward_list; + + { + list l; + + l.push_front ("abc"); + assert (front (l) == "abc" && small (l)); + + l.push_front ("ABC"); + assert (front (l) == "ABC" && back (l) == "abc" && !small (l)); + + l.pop_front (); + assert (front (l) == "abc" && small (l)); + + l.push_front ("ABC"); + l.reverse (); + l.pop_front (); + assert (front (l) == "ABC" && !small (l)); + + l.push_front ("abc"); + l.reverse (); + l.pop_front (); + assert (front (l) == "abc" && small (l)); + + l.clear (); + l.push_front ("abc"); + assert (front (l) == "abc" && small (l)); + } + + // Copy constructor. + // + { + list s1 ({"abc"}), s2 (s1); + assert (s1 == s2 && small (s2)); + + list l1 ({"abc", "ABC"}), l2 (l1); + assert (l1 == l2 && !small (l2)); + } + + // Move constructor. + // + { + struct mstring: string // Move-only string. + { + mstring () = default; + explicit mstring (const char* s): string (s) {} + + mstring (mstring&&) = default; + mstring& operator= (mstring&&) = default; + + mstring (const mstring&) = delete; + mstring& operator= (const mstring&) = delete; + }; + + using list = small_forward_list; + + { + list s1; + s1.emplace_front ("abc"); + list s2 (move (s1)); + assert (front (s2) == "abc" && small (s2)); + } + + { + list l1; + l1.emplace_front ("ABC"); + l1.emplace_front ("abc"); + list l2 (move (l1)); + assert (front (l2) == "abc" && back (l2) == "ABC" && !small (l2)); + } + } + + // Other constructors. + // + + { + const char* sa[] = {"abc"}; + const char* la[] = {"abc", "ABC"}; + + list s (sa, sa + 1); + assert (front (s) == "abc" && small (s)); + + list l (la, la + 2); + assert (front (l) == "abc" && back (l) == "ABC" && !small (l)); + } + + { + list s (1, "abc"); + assert (front (s) == "abc" && small (s)); + + list l (3, "abc"); + assert (front (l) == "abc" && back (l) == "abc" && !small (l)); + } + + { + list s (1); + assert (s.front () == "" && small (s)); + + list l (3); + assert (front (l) == "" && back (l) == "" && !small (l)); + } +} -- cgit v1.1