aboutsummaryrefslogtreecommitdiff
path: root/tests/small-list/driver.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2018-01-04 09:49:34 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2018-01-04 14:27:16 +0200
commitb62ccc5d017e54beecd72d64d2074473c49192a7 (patch)
tree3497d3b6da5d9feb29fa5edc8a0713f391ac209d /tests/small-list/driver.cxx
parent496aee483a5ccfa9c396de84dc0cedd234930ddc (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.cxx162
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));
+ }
+}