// file : tests/small-forward-list/driver.cxx -*- C++ -*- // license : MIT; see accompanying LICENSE file #include <cassert> #ifndef __cpp_lib_modules_ts #include <string> #include <iostream> #endif // Other includes. #ifdef __cpp_modules_ts #ifdef __cpp_lib_modules_ts 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)); } }