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-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-list/driver.cxx')
-rw-r--r-- | tests/small-list/driver.cxx | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/tests/small-list/driver.cxx b/tests/small-list/driver.cxx new file mode 100644 index 0000000..970adc3 --- /dev/null +++ b/tests/small-list/driver.cxx @@ -0,0 +1,162 @@ +// file : tests/small-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_list; +#else +#include <libbutl/small-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_list<T, N>& l) +{ + // In VC it is always "large" (see note in small_list) so we omit this + // test. + // +#ifndef _MSC_VER + for (const T& x: l) + { + const void* p (&x); + + if (p < &l || p >= (&l + 1)) + return false; + } +#endif + + return true; +} + +template <typename T, size_t N> +inline bool +large (const small_list<T, N>& l) +{ +#ifndef _MSC_VER + return !small (l); +#else + return true; +#endif +} + +int +main () +{ + using list = small_list<string, 1>; + + { + list l; + + l.push_back ("abc"); + assert (l.front () == "abc" && small (l)); + + l.push_back ("ABC"); + assert (l.front () == "abc" && l.back () == "ABC" && large (l)); + + l.pop_back (); + assert (l.front () == "abc" && small (l)); + + l.push_back ("ABC"); + l.pop_front (); + assert (l.front () == "ABC" && large (l)); + + l.push_back ("abc"); + l.pop_front (); + assert (l.front () == "abc" && small (l)); + + l.clear (); + l.push_back ("abc"); + assert (l.front () == "abc" && small (l)); + } + + // Copy constructor. + // + { + list s1 ({"abc"}), s2 (s1); + assert (s1 == s2 && small (s2)); + + list l1 ({"abc", "ABC"}), l2 (l1); + assert (l1 == l2 && large (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_list<mstring, 1>; + + { + list s1; + s1.emplace_back ("abc"); + list s2 (move (s1)); + assert (s2.front () == "abc" && small (s2)); + } + + { + list l1; + l1.emplace_back ("abc"); + l1.emplace_back ("ABC"); + list l2 (move (l1)); + assert (l2.front () == "abc" && l2.back () == "ABC" && large (l2)); + } + } + + // Other constructors. + // + + { + const char* sa[] = {"abc"}; + const char* la[] = {"abc", "ABC"}; + + list s (sa, sa + 1); + assert (s.front () == "abc" && small (s)); + + list l (la, la + 2); + assert (l.front () == "abc" && l.back () == "ABC" && large (l)); + } + + { + list s (1, "abc"); + assert (s.front () == "abc" && small (s)); + + list l (3, "abc"); + assert (l.front () == "abc" && l.back () == "abc" && large (l)); + } + + { + list s (1); + assert (s.front () == "" && small (s)); + + list l (3); + assert (l.front () == "" && l.back () == "" && large (l)); + } +} |