diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2018-01-04 09:49:34 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2018-01-04 14:27:16 +0200 |
commit | b62ccc5d017e54beecd72d64d2074473c49192a7 (patch) | |
tree | 3497d3b6da5d9feb29fa5edc8a0713f391ac209d /tests/small-forward-list/driver.cxx | |
parent | 496aee483a5ccfa9c396de84dc0cedd234930ddc (diff) |
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).
Diffstat (limited to 'tests/small-forward-list/driver.cxx')
-rw-r--r-- | tests/small-forward-list/driver.cxx | 164 |
1 files changed, 164 insertions, 0 deletions
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 <cassert> + +#ifndef __cpp_lib_modules +#include <string> +#include <iostream> +#endif + +// Other includes. + +#ifdef __cpp_modules +#ifdef __cpp_lib_modules +import std.core; +import std.io; +#endif +import butl.small_forward_list; +#else +#include <libbutl/small-forward-list.mxx> +#endif + +using namespace std; +using namespace butl; + +// Return true if the data is stored entirely inside l. +// +template <typename T, size_t N> +inline bool +small (const small_forward_list<T, N>& l) +{ + for (const T& x: l) + { + const void* p (&x); + + if (p < &l || p >= (&l + 1)) + return false; + } + + return true; +} + +template <typename T, size_t N> +inline const T& +front (const small_forward_list<T, N>& l) +{ + return l.front (); +} + +template <typename T, size_t N> +inline const T& +back (const small_forward_list<T, N>& l) +{ + auto i (l.begin ());; + for (auto j (i); ++j != l.end (); ) i = j; + return *i; +} + +int +main () +{ + using list = small_forward_list<string, 1>; + + { + 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<mstring, 1>; + + { + 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)); + } +} |