summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/sol2/Optional/test_optional.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/sol2/Optional/test_optional.cpp')
-rw-r--r--3rdparty/sol2/Optional/test_optional.cpp1459
1 files changed, 0 insertions, 1459 deletions
diff --git a/3rdparty/sol2/Optional/test_optional.cpp b/3rdparty/sol2/Optional/test_optional.cpp
deleted file mode 100644
index 8ed356a562b..00000000000
--- a/3rdparty/sol2/Optional/test_optional.cpp
+++ /dev/null
@@ -1,1459 +0,0 @@
-// Copyright (C) 2011 - 2012 Andrzej Krzemienski.
-//
-// Use, modification, and distribution is subject to the Boost Software
-// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-//
-// The idea and interface is based on Boost.Optional library
-// authored by Fernando Luis Cacciola Carballal
-
-# include "optional.hpp"
-# include <vector>
-# include <iostream>
-# include <functional>
-# include <complex>
-
-
-
-struct caller {
- template <class T> caller(T fun) { fun(); }
-};
-# define CAT2(X, Y) X ## Y
-# define CAT(X, Y) CAT2(X, Y)
-# define TEST(NAME) caller CAT(__VAR, __LINE__) = []
-
-enum State
-{
- sDefaultConstructed,
- sValueCopyConstructed,
- sValueMoveConstructed,
- sCopyConstructed,
- sMoveConstructed,
- sMoveAssigned,
- sCopyAssigned,
- sValueCopyAssigned,
- sValueMoveAssigned,
- sMovedFrom,
- sValueConstructed
-};
-
-struct OracleVal
-{
- State s;
- int i;
- OracleVal(int i = 0) : s(sValueConstructed), i(i) {}
-};
-
-struct Oracle
-{
- State s;
- OracleVal val;
-
- Oracle() : s(sDefaultConstructed) {}
- Oracle(const OracleVal& v) : s(sValueCopyConstructed), val(v) {}
- Oracle(OracleVal&& v) : s(sValueMoveConstructed), val(std::move(v)) {v.s = sMovedFrom;}
- Oracle(const Oracle& o) : s(sCopyConstructed), val(o.val) {}
- Oracle(Oracle&& o) : s(sMoveConstructed), val(std::move(o.val)) {o.s = sMovedFrom;}
-
- Oracle& operator=(const OracleVal& v) { s = sValueCopyConstructed; val = v; return *this; }
- Oracle& operator=(OracleVal&& v) { s = sValueMoveConstructed; val = std::move(v); v.s = sMovedFrom; return *this; }
- Oracle& operator=(const Oracle& o) { s = sCopyConstructed; val = o.val; return *this; }
- Oracle& operator=(Oracle&& o) { s = sMoveConstructed; val = std::move(o.val); o.s = sMovedFrom; return *this; }
-};
-
-struct Guard
-{
- std::string val;
- Guard() : val{} {}
- explicit Guard(std::string s, int = 0) : val(s) {}
- Guard(const Guard&) = delete;
- Guard(Guard&&) = delete;
- void operator=(const Guard&) = delete;
- void operator=(Guard&&) = delete;
-};
-
-struct ExplicitStr
-{
- std::string s;
- explicit ExplicitStr(const char* chp) : s(chp) {};
-};
-
-struct Date
-{
- int i;
- Date() = delete;
- Date(int i) : i{i} {};
- Date(Date&& d) : i(d.i) { d.i = 0; }
- Date(const Date&) = delete;
- Date& operator=(const Date&) = delete;
- Date& operator=(Date&& d) { i = d.i; d.i = 0; return *this;};
-};
-
-bool operator==( Oracle const& a, Oracle const& b ) { return a.val.i == b.val.i; }
-bool operator!=( Oracle const& a, Oracle const& b ) { return a.val.i != b.val.i; }
-
-
-namespace tr2 = std::experimental;
-
-
-TEST(disengaged_ctor)
-{
- tr2::optional<int> o1;
- assert (!o1);
-
- tr2::optional<int> o2 = tr2::nullopt;
- assert (!o2);
-
- tr2::optional<int> o3 = o2;
- assert (!o3);
-
- assert (o1 == tr2::nullopt);
- assert (o1 == tr2::optional<int>{});
- assert (!o1);
- assert (bool(o1) == false);
-
- assert (o2 == tr2::nullopt);
- assert (o2 == tr2::optional<int>{});
- assert (!o2);
- assert (bool(o2) == false);
-
- assert (o3 == tr2::nullopt);
- assert (o3 == tr2::optional<int>{});
- assert (!o3);
- assert (bool(o3) == false);
-
- assert (o1 == o2);
- assert (o2 == o1);
- assert (o1 == o3);
- assert (o3 == o1);
- assert (o2 == o3);
- assert (o3 == o2);
-};
-
-
-TEST(value_ctor)
-{
- OracleVal v;
- tr2::optional<Oracle> oo1(v);
- assert (oo1 != tr2::nullopt);
- assert (oo1 != tr2::optional<Oracle>{});
- assert (oo1 == tr2::optional<Oracle>{v});
- assert (!!oo1);
- assert (bool(oo1));
- // NA: assert (oo1->s == sValueCopyConstructed);
- assert (oo1->s == sMoveConstructed);
- assert (v.s == sValueConstructed);
-
- tr2::optional<Oracle> oo2(std::move(v));
- assert (oo2 != tr2::nullopt);
- assert (oo2 != tr2::optional<Oracle>{});
- assert (oo2 == oo1);
- assert (!!oo2);
- assert (bool(oo2));
- // NA: assert (oo2->s == sValueMoveConstructed);
- assert (oo2->s == sMoveConstructed);
- assert (v.s == sMovedFrom);
-
- {
- OracleVal v;
- tr2::optional<Oracle> oo1{tr2::in_place, v};
- assert (oo1 != tr2::nullopt);
- assert (oo1 != tr2::optional<Oracle>{});
- assert (oo1 == tr2::optional<Oracle>{v});
- assert (!!oo1);
- assert (bool(oo1));
- assert (oo1->s == sValueCopyConstructed);
- assert (v.s == sValueConstructed);
-
- tr2::optional<Oracle> oo2{tr2::in_place, std::move(v)};
- assert (oo2 != tr2::nullopt);
- assert (oo2 != tr2::optional<Oracle>{});
- assert (oo2 == oo1);
- assert (!!oo2);
- assert (bool(oo2));
- assert (oo2->s == sValueMoveConstructed);
- assert (v.s == sMovedFrom);
- }
-};
-
-
-TEST(assignment)
-{
- tr2::optional<int> oi;
- oi = tr2::optional<int>{1};
- assert (*oi == 1);
-
- oi = tr2::nullopt;
- assert (!oi);
-
- oi = 2;
- assert (*oi == 2);
-
- oi = {};
- assert (!oi);
-};
-
-
-template <class T>
-struct MoveAware
-{
- T val;
- bool moved;
- MoveAware(T val) : val(val), moved(false) {}
- MoveAware(MoveAware const&) = delete;
- MoveAware(MoveAware&& rhs) : val(rhs.val), moved(rhs.moved) {
- rhs.moved = true;
- }
- MoveAware& operator=(MoveAware const&) = delete;
- MoveAware& operator=(MoveAware&& rhs) {
- val = (rhs.val);
- moved = (rhs.moved);
- rhs.moved = true;
- return *this;
- }
-};
-
-TEST(moved_from_state)
-{
- // first, test mock:
- MoveAware<int> i{1}, j{2};
- assert (i.val == 1);
- assert (!i.moved);
- assert (j.val == 2);
- assert (!j.moved);
-
- MoveAware<int> k = std::move(i);
- assert (k.val == 1);
- assert (!k.moved);
- assert (i.val == 1);
- assert (i.moved);
-
- k = std::move(j);
- assert (k.val == 2);
- assert (!k.moved);
- assert (j.val == 2);
- assert (j.moved);
-
- // now, test optional
- tr2::optional<MoveAware<int>> oi{1}, oj{2};
- assert (oi);
- assert (!oi->moved);
- assert (oj);
- assert (!oj->moved);
-
- tr2::optional<MoveAware<int>> ok = std::move(oi);
- assert (ok);
- assert (!ok->moved);
- assert (oi);
- assert (oi->moved);
-
- ok = std::move(oj);
- assert (ok);
- assert (!ok->moved);
- assert (oj);
- assert (oj->moved);
-};
-
-
-TEST(copy_move_ctor_optional_int)
-{
- tr2::optional<int> oi;
- tr2::optional<int> oj = oi;
-
- assert (!oj);
- assert (oj == oi);
- assert (oj == tr2::nullopt);
- assert (!bool(oj));
-
- oi = 1;
- tr2::optional<int> ok = oi;
- assert (!!ok);
- assert (bool(ok));
- assert (ok == oi);
- assert (ok != oj);
- assert (*ok == 1);
-
- tr2::optional<int> ol = std::move(oi);
- assert (!!ol);
- assert (bool(ol));
- assert (ol == oi);
- assert (ol != oj);
- assert (*ol == 1);
-};
-
-
-TEST(optional_optional)
-{
- tr2::optional<tr2::optional<int>> oi1 = tr2::nullopt;
- assert (oi1 == tr2::nullopt);
- assert (!oi1);
-
- {
- tr2::optional<tr2::optional<int>> oi2 {tr2::in_place};
- assert (oi2 != tr2::nullopt);
- assert (bool(oi2));
- assert (*oi2 == tr2::nullopt);
- //assert (!(*oi2));
- //std::cout << typeid(**oi2).name() << std::endl;
- }
-
- {
- tr2::optional<tr2::optional<int>> oi2 {tr2::in_place, tr2::nullopt};
- assert (oi2 != tr2::nullopt);
- assert (bool(oi2));
- assert (*oi2 == tr2::nullopt);
- assert (!*oi2);
- }
-
- {
- tr2::optional<tr2::optional<int>> oi2 {tr2::optional<int>{}};
- assert (oi2 != tr2::nullopt);
- assert (bool(oi2));
- assert (*oi2 == tr2::nullopt);
- assert (!*oi2);
- }
-
- tr2::optional<int> oi;
- auto ooi = tr2::make_optional(oi);
- static_assert( std::is_same<tr2::optional<tr2::optional<int>>, decltype(ooi)>::value, "");
-
-};
-
-TEST(example_guard)
-{
- using namespace tr2;
- //FAILS: optional<Guard> ogx(Guard("res1"));
- //FAILS: optional<Guard> ogx = "res1";
- //FAILS: optional<Guard> ogx("res1");
- optional<Guard> oga; // Guard is non-copyable (and non-moveable)
- optional<Guard> ogb(in_place, "res1"); // initialzes the contained value with "res1"
- assert (bool(ogb));
- assert (ogb->val == "res1");
-
- optional<Guard> ogc(in_place); // default-constructs the contained value
- assert (bool(ogc));
- assert (ogc->val == "");
-
- oga.emplace("res1"); // initialzes the contained value with "res1"
- assert (bool(oga));
- assert (oga->val == "res1");
-
- oga.emplace(); // destroys the contained value and
- // default-constructs the new one
- assert (bool(oga));
- assert (oga->val == "");
-
- oga = nullopt; // OK: make disengaged the optional Guard
- assert (!(oga));
- //FAILS: ogb = {}; // ERROR: Guard is not Moveable
-};
-
-
-void process(){}
-void process(int ){}
-void processNil(){}
-
-
-TEST(example1)
-{
- using namespace tr2;
- optional<int> oi; // create disengaged object
- optional<int> oj = nullopt; // alternative syntax
- oi = oj; // assign disengaged object
- optional<int> ok = oj; // ok is disengaged
-
- if (oi) assert(false); // 'if oi is engaged...'
- if (!oi) assert(true); // 'if oi is disengaged...'
-
- if (oi != nullopt) assert(false); // 'if oi is engaged...'
- if (oi == nullopt) assert(true); // 'if oi is disengaged...'
-
- assert(oi == ok); // two disengaged optionals compare equal
-
- ///////////////////////////////////////////////////////////////////////////
- optional<int> ol{1}; // ol is engaged; its contained value is 1
- ok = 2; // ok becomes engaged; its contained value is 2
- oj = ol; // oj becomes engaged; its contained value is 1
-
- assert(oi != ol); // disengaged != engaged
- assert(ok != ol); // different contained values
- assert(oj == ol); // same contained value
- assert(oi < ol); // disengaged < engaged
- assert(ol < ok); // less by contained value
-
- /////////////////////////////////////////////////////////////////////////////
- optional<int> om{1}; // om is engaged; its contained value is 1
- optional<int> on = om; // on is engaged; its contained value is 1
- om = 2; // om is engaged; its contained value is 2
- assert (on != om); // on still contains 3. They are not pointers
-
- /////////////////////////////////////////////////////////////////////////////
- int i = *ol; // i obtains the value contained in ol
- assert (i == 1);
- *ol = 9; // the object contained in ol becomes 9
- assert(*ol == 9);
- assert(ol == make_optional(9));
-
- ///////////////////////////////////
- int p = 1;
- optional<int> op = p;
- assert(*op == 1);
- p = 2;
- assert(*op == 1); // value contained in op is separated from p
-
- ////////////////////////////////
- if (ol)
- process(*ol); // use contained value if present
- else
- process(); // proceed without contained value
-
- if (!om)
- processNil();
- else
- process(*om);
-
- /////////////////////////////////////////
- process(ol.value_or(0)); // use 0 if ol is disengaged
-
- ////////////////////////////////////////////
- ok = nullopt; // if ok was engaged calls T's dtor
- oj = {}; // assigns a temporary disengaged optional
-};
-
-
-TEST(example_guard)
-{
- using std::experimental::optional;
- const optional<int> c = 4;
- int i = *c; // i becomes 4
- assert (i == 4);
- // FAILS: *c = i; // ERROR: cannot assign to const int&
-};
-
-
-TEST(example_ref)
-{
- using namespace std::experimental;
- int i = 1;
- int j = 2;
- optional<int&> ora; // disengaged optional reference to int
- optional<int&> orb = i; // contained reference refers to object i
-
- *orb = 3; // i becomes 3
- // FAILS: ora = j; // ERROR: optional refs do not have assignment from T
- // FAILS: ora = {j}; // ERROR: optional refs do not have copy/move assignment
- // FAILS: ora = orb; // ERROR: no copy/move assignment
- ora.emplace(j); // OK: contained reference refers to object j
- ora.emplace(i); // OK: contained reference now refers to object i
-
- ora = nullopt; // OK: ora becomes disengaged
-};
-
-
-template <typename T>
-T getValue( tr2::optional<T> newVal = tr2::nullopt, tr2::optional<T&> storeHere = tr2::nullopt )
-{
- T cached{};
-
- if (newVal) {
- cached = *newVal;
-
- if (storeHere) {
- *storeHere = *newVal; // LEGAL: assigning T to T
- }
- }
- return cached;
-}
-
-TEST(example_optional_arg)
-{
- int iii = 0;
- iii = getValue<int>(iii, iii);
- iii = getValue<int>(iii);
- iii = getValue<int>();
-
- {
- using namespace std::experimental;
- optional<Guard> grd1{in_place, "res1", 1}; // guard 1 initialized
- optional<Guard> grd2;
-
- grd2.emplace("res2", 2); // guard 2 initialized
- grd1 = nullopt; // guard 1 released
-
- } // guard 2 released (in dtor)
-};
-
-
-std::tuple<Date, Date, Date> getStartMidEnd() { return std::tuple<Date, Date, Date>{Date{1}, Date{2}, Date{3}}; }
-void run(Date const&, Date const&, Date const&) {}
-
-TEST(example_date)
-{
- using namespace std::experimental;
- optional<Date> start, mid, end; // Date doesn't have default ctor (no good default date)
-
- std::tie(start, mid, end) = getStartMidEnd();
- run(*start, *mid, *end);
-};
-
-
-std::experimental::optional<char> readNextChar(){ return{}; }
-
-void run(std::experimental::optional<std::string>) {}
-void run(std::complex<double>) {}
-
-
-template <class T>
-void assign_norebind(tr2::optional<T&>& optref, T& obj)
-{
- if (optref) *optref = obj;
- else optref.emplace(obj);
-}
-
-template <typename T> void unused(T&&) {}
-
-TEST(example_conceptual_model)
-{
- using namespace std::experimental;
-
- optional<int> oi = 0;
- optional<int> oj = 1;
- optional<int> ok = nullopt;
-
- oi = 1;
- oj = nullopt;
- ok = 0;
-
- unused(oi == nullopt);
- unused(oj == 0);
- unused(ok == 1);
-};
-
-TEST(example_rationale)
-{
- using namespace std::experimental;
- if (optional<char> ch = readNextChar()) {
- unused(ch);
- // ...
- }
-
- //////////////////////////////////
- optional<int> opt1 = nullopt;
- optional<int> opt2 = {};
-
- opt1 = nullopt;
- opt2 = {};
-
- if (opt1 == nullopt) {}
- if (!opt2) {}
- if (opt2 == optional<int>{}) {}
-
-
-
- ////////////////////////////////
-
- run(nullopt); // pick the second overload
- // FAILS: run({}); // ambiguous
-
- if (opt1 == nullopt) {} // fine
- // FAILS: if (opt2 == {}) {} // ilegal
-
- ////////////////////////////////
- assert (optional<unsigned>{} < optional<unsigned>{0});
- assert (optional<unsigned>{0} < optional<unsigned>{1});
- assert (!(optional<unsigned>{} < optional<unsigned>{}) );
- assert (!(optional<unsigned>{1} < optional<unsigned>{1}));
-
- assert (optional<unsigned>{} != optional<unsigned>{0});
- assert (optional<unsigned>{0} != optional<unsigned>{1});
- assert (optional<unsigned>{} == optional<unsigned>{} );
- assert (optional<unsigned>{0} == optional<unsigned>{0});
-
- /////////////////////////////////
- optional<int> o;
- o = make_optional(1); // copy/move assignment
- o = 1; // assignment from T
- o.emplace(1); // emplacement
-
- ////////////////////////////////////
- int isas = 0, i = 9;
- optional<int&> asas = i;
- assign_norebind(asas, isas);
-
- /////////////////////////////////////
- ////tr2::optional<std::vector<int>> ov2 = {2, 3};
- ////assert (bool(ov2));
- ////assert ((*ov2)[1] == 3);
- ////
- ////////////////////////////////
- ////std::vector<int> v = {1, 2, 4, 8};
- ////optional<std::vector<int>> ov = {1, 2, 4, 8};
-
- ////assert (v == *ov);
- ////
- ////ov = {1, 2, 4, 8};
-
- ////std::allocator<int> a;
- ////optional<std::vector<int>> ou { in_place, {1, 2, 4, 8}, a };
-
- ////assert (ou == ov);
-
- //////////////////////////////
- // inconvenient syntax:
- {
-
- tr2::optional<std::vector<int>> ov2{tr2::in_place, {2, 3}};
-
- assert (bool(ov2));
- assert ((*ov2)[1] == 3);
-
- ////////////////////////////
-
- std::vector<int> v = {1, 2, 4, 8};
- optional<std::vector<int>> ov{tr2::in_place, {1, 2, 4, 8}};
-
- assert (v == *ov);
-
- ov.emplace({1, 2, 4, 8});
-/*
- std::allocator<int> a;
- optional<std::vector<int>> ou { in_place, {1, 2, 4, 8}, a };
-
- assert (ou == ov);
-*/
- }
-
- /////////////////////////////////
- {
- typedef int T;
- optional<optional<T>> ot {in_place};
- optional<optional<T>> ou {in_place, nullopt};
- optional<optional<T>> ov {optional<T>{}};
-
- optional<int> oi;
- auto ooi = make_optional(oi);
- static_assert( std::is_same<optional<optional<int>>, decltype(ooi)>::value, "");
- }
-};
-
-
-bool fun(std::string , std::experimental::optional<int> oi = std::experimental::nullopt)
-{
- return bool(oi);
-}
-
-TEST(example_converting_ctor)
-{
- using namespace std::experimental;
-
- assert (true == fun("dog", 2));
- assert (false == fun("dog"));
- assert (false == fun("dog", nullopt)); // just to be explicit
-};
-
-
-TEST(bad_comparison)
-{
- tr2::optional<int> oi, oj;
- int i;
- bool b = (oi == oj);
- b = (oi >= i);
- b = (oi == i);
- unused(b);
-};
-
-
-//// NOT APPLICABLE ANYMORE
-////TEST(perfect_ctor)
-////{
-//// //tr2::optional<std::string> ois = "OS";
-//// assert (*ois == "OS");
-////
-//// // FAILS: tr2::optional<ExplicitStr> oes = "OS";
-//// tr2::optional<ExplicitStr> oes{"OS"};
-//// assert (oes->s == "OS");
-////};
-
-TEST(value_or)
-{
- tr2::optional<int> oi = 1;
- int i = oi.value_or(0);
- assert (i == 1);
-
- oi = tr2::nullopt;
- assert (oi.value_or(3) == 3);
-
- tr2::optional<std::string> os{"AAA"};
- assert (os.value_or("BBB") == "AAA");
- os = {};
- assert (os.value_or("BBB") == "BBB");
-};
-
-TEST(mixed_order)
-{
- using namespace std::experimental;
-
- optional<int> oN {nullopt};
- optional<int> o0 {0};
- optional<int> o1 {1};
-
- assert ( (oN < 0));
- assert ( (oN < 1));
- assert (!(o0 < 0));
- assert ( (o0 < 1));
- assert (!(o1 < 0));
- assert (!(o1 < 1));
-
- assert (!(oN >= 0));
- assert (!(oN >= 1));
- assert ( (o0 >= 0));
- assert (!(o0 >= 1));
- assert ( (o1 >= 0));
- assert ( (o1 >= 1));
-
- assert (!(oN > 0));
- assert (!(oN > 1));
- assert (!(o0 > 0));
- assert (!(o0 > 1));
- assert ( (o1 > 0));
- assert (!(o1 > 1));
-
- assert ( (oN <= 0));
- assert ( (oN <= 1));
- assert ( (o0 <= 0));
- assert ( (o0 <= 1));
- assert (!(o1 <= 0));
- assert ( (o1 <= 1));
-
- assert ( (0 > oN));
- assert ( (1 > oN));
- assert (!(0 > o0));
- assert ( (1 > o0));
- assert (!(0 > o1));
- assert (!(1 > o1));
-
- assert (!(0 <= oN));
- assert (!(1 <= oN));
- assert ( (0 <= o0));
- assert (!(1 <= o0));
- assert ( (0 <= o1));
- assert ( (1 <= o1));
-
- assert (!(0 < oN));
- assert (!(1 < oN));
- assert (!(0 < o0));
- assert (!(1 < o0));
- assert ( (0 < o1));
- assert (!(1 < o1));
-
- assert ( (0 >= oN));
- assert ( (1 >= oN));
- assert ( (0 >= o0));
- assert ( (1 >= o0));
- assert (!(0 >= o1));
- assert ( (1 >= o1));
-};
-
-struct BadRelops
-{
- int i;
-};
-
-constexpr bool operator<(BadRelops a, BadRelops b) { return a.i < b.i; }
-constexpr bool operator>(BadRelops a, BadRelops b) { return a.i < b.i; } // intentional error!
-
-TEST(bad_relops)
-{
- using namespace std::experimental;
- BadRelops a{1}, b{2};
- assert (a < b);
- assert (a > b);
-
- optional<BadRelops> oa = a, ob = b;
- assert (oa < ob);
- assert (!(oa > ob));
-
- assert (oa < b);
- assert (oa > b);
-
- optional<BadRelops&> ra = a, rb = b;
- assert (ra < rb);
- assert (!(ra > rb));
-
- assert (ra < b);
- assert (ra > b);
-};
-
-
-TEST(mixed_equality)
-{
- using namespace std::experimental;
-
- assert (make_optional(0) == 0);
- assert (make_optional(1) == 1);
- assert (make_optional(0) != 1);
- assert (make_optional(1) != 0);
-
- optional<int> oN {nullopt};
- optional<int> o0 {0};
- optional<int> o1 {1};
-
- assert (o0 == 0);
- assert ( 0 == o0);
- assert (o1 == 1);
- assert ( 1 == o1);
- assert (o1 != 0);
- assert ( 0 != o1);
- assert (o0 != 1);
- assert ( 1 != o0);
-
- assert ( 1 != oN);
- assert ( 0 != oN);
- assert (oN != 1);
- assert (oN != 0);
- assert (!( 1 == oN));
- assert (!( 0 == oN));
- assert (!(oN == 1));
- assert (!(oN == 0));
-
- std::string cat{"cat"}, dog{"dog"};
- optional<std::string> oNil{}, oDog{"dog"}, oCat{"cat"};
-
- assert (oCat == cat);
- assert ( cat == oCat);
- assert (oDog == dog);
- assert ( dog == oDog);
- assert (oDog != cat);
- assert ( cat != oDog);
- assert (oCat != dog);
- assert ( dog != oCat);
-
- assert ( dog != oNil);
- assert ( cat != oNil);
- assert (oNil != dog);
- assert (oNil != cat);
- assert (!( dog == oNil));
- assert (!( cat == oNil));
- assert (!(oNil == dog));
- assert (!(oNil == cat));
-};
-
-TEST(const_propagation)
-{
- using namespace std::experimental;
-
- optional<int> mmi{0};
- static_assert(std::is_same<decltype(*mmi), int&>::value, "WTF");
-
- const optional<int> cmi{0};
- static_assert(std::is_same<decltype(*cmi), const int&>::value, "WTF");
-
- optional<const int> mci{0};
- static_assert(std::is_same<decltype(*mci), const int&>::value, "WTF");
-
- optional<const int> cci{0};
- static_assert(std::is_same<decltype(*cci), const int&>::value, "WTF");
-};
-
-
-static_assert(std::is_base_of<std::logic_error, std::experimental::bad_optional_access>::value, "");
-
-TEST(safe_value)
-{
- using namespace std::experimental;
-
- try {
- optional<int> ovN{}, ov1{1};
-
- int& r1 = ov1.value();
- assert (r1 == 1);
-
- try {
- ovN.value();
- assert (false);
- }
- catch (bad_optional_access const&) {
- }
-
- { // ref variant
- int i1 = 1;
- optional<int&> orN{}, or1{i1};
-
- int& r2 = or1.value();
- assert (r2 == 1);
-
- try {
- orN.value();
- assert (false);
- }
- catch (bad_optional_access const&) {
- }
- }
- }
- catch(...) {
- assert (false);
- }
-};
-
-TEST(optional_ref)
-{
- using namespace tr2;
- // FAILS: optional<int&&> orr;
- // FAILS: optional<nullopt_t&> on;
- int i = 8;
- optional<int&> ori;
- assert (!ori);
- ori.emplace(i);
- assert (bool(ori));
- assert (*ori == 8);
- assert (&*ori == &i);
- *ori = 9;
- assert (i == 9);
-
- // FAILS: int& ir = ori.value_or(i);
- int ii = ori.value_or(i);
- assert (ii == 9);
- ii = 7;
- assert (*ori == 9);
-
- int j = 22;
- auto&& oj = make_optional(std::ref(j));
- *oj = 23;
- assert (&*oj == &j);
- assert (j == 23);
-};
-
-TEST(optional_ref_const_propagation)
-{
- using namespace std::experimental;
-
- int i = 9;
- const optional<int&> mi = i;
- int& r = *mi;
- optional<const int&> ci = i;
- static_assert(std::is_same<decltype(*mi), int&>::value, "WTF");
- static_assert(std::is_same<decltype(*ci), const int&>::value, "WTF");
-
- unused(r);
-};
-
-TEST(optional_ref_assign)
-{
- using namespace std::experimental;
-
- int i = 9;
- optional<int&> ori = i;
-
- int j = 1;
- ori = optional<int&>{j};
- ori = {j};
- // FAILS: ori = j;
-
- optional<int&> orx = ori;
- ori = orx;
-
- optional<int&> orj = j;
-
- assert (ori);
- assert (*ori == 1);
- assert (ori == orj);
- assert (i == 9);
-
- *ori = 2;
- assert (*ori == 2);
- assert (ori == 2);
- assert (2 == ori);
- assert (ori != 3);
-
- assert (ori == orj);
- assert (j == 2);
- assert (i == 9);
-
- ori = {};
- assert (!ori);
- assert (ori != orj);
- assert (j == 2);
- assert (i == 9);
-};
-
-
-TEST(optional_ref_swap)
-{
- using namespace std::experimental;
- int i = 0;
- int j = 1;
- optional<int&> oi = i;
- optional<int&> oj = j;
-
- assert (&*oi == &i);
- assert (&*oj == &j);
-
- swap(oi, oj);
- assert (&*oi == &j);
- assert (&*oj == &i);
-};
-
-TEST(optional_initialization)
-{
- using namespace tr2;
- using std::string;
- string s = "STR";
-
- optional<string> os{s};
- optional<string> ot = s;
- optional<string> ou{"STR"};
- optional<string> ov = string{"STR"};
-
-};
-
-#include <unordered_set>
-
-TEST(optional_hashing)
-{
- using namespace tr2;
- using std::string;
-
- std::hash<int> hi;
- std::hash<optional<int>> hoi;
- std::hash<string> hs;
- std::hash<optional<string>> hos;
-
- assert (hi(0) == hoi(optional<int>{0}));
- assert (hi(1) == hoi(optional<int>{1}));
- assert (hi(3198) == hoi(optional<int>{3198}));
-
- assert (hs("") == hos(optional<string>{""}));
- assert (hs("0") == hos(optional<string>{"0"}));
- assert (hs("Qa1#") == hos(optional<string>{"Qa1#"}));
-
- std::unordered_set<optional<string>> set;
- assert(set.find({"Qa1#"}) == set.end());
-
- set.insert({"0"});
- assert(set.find({"Qa1#"}) == set.end());
-
- set.insert({"Qa1#"});
- assert(set.find({"Qa1#"}) != set.end());
-};
-
-
-// optional_ref_emulation
-template <class T>
-struct generic
-{
- typedef T type;
-};
-
-template <class U>
-struct generic<U&>
-{
- typedef std::reference_wrapper<U> type;
-};
-
-template <class T>
-using Generic = typename generic<T>::type;
-
-template <class X>
-bool generic_fun()
-{
- std::experimental::optional<Generic<X>> op;
- return bool(op);
-}
-
-TEST(optional_ref_emulation)
-{
- using namespace std::experimental;
- optional<Generic<int>> oi = 1;
- assert (*oi == 1);
-
- int i = 8;
- int j = 4;
- optional<Generic<int&>> ori {i};
- assert (*ori == 8);
- assert ((void*)&*ori != (void*)&i); // !DIFFERENT THAN optional<T&>
-
- *ori = j;
- assert (*ori == 4);
-};
-
-
-# if OPTIONAL_HAS_THIS_RVALUE_REFS == 1
-TEST(moved_on_value_or)
-{
- using namespace tr2;
- optional<Oracle> oo{in_place};
-
- assert (oo);
- assert (oo->s == sDefaultConstructed);
-
- Oracle o = std::move(oo).value_or( Oracle{OracleVal{}} );
- assert (oo);
- assert (oo->s == sMovedFrom);
- assert (o.s == sMoveConstructed);
-
- optional<MoveAware<int>> om {in_place, 1};
- assert (om);
- assert (om->moved == false);
-
- /*MoveAware<int> m =*/ std::move(om).value_or( MoveAware<int>{1} );
- assert (om);
- assert (om->moved == true);
-
-# if OPTIONAL_HAS_MOVE_ACCESSORS == 1
- {
- Date d = optional<Date>{in_place, 1}.value();
- assert (d.i); // to silence compiler warning
-
- Date d2 = *optional<Date>{in_place, 1};
- assert (d2.i); // to silence compiler warning
- }
-# endif
-};
-# endif
-
-
-TEST(optional_ref_hashing)
-{
- using namespace tr2;
- using std::string;
-
- std::hash<int> hi;
- std::hash<optional<int&>> hoi;
- std::hash<string> hs;
- std::hash<optional<string&>> hos;
-
- int i0 = 0;
- int i1 = 1;
- assert (hi(0) == hoi(optional<int&>{i0}));
- assert (hi(1) == hoi(optional<int&>{i1}));
-
- string s{""};
- string s0{"0"};
- string sCAT{"CAT"};
- assert (hs("") == hos(optional<string&>{s}));
- assert (hs("0") == hos(optional<string&>{s0}));
- assert (hs("CAT") == hos(optional<string&>{sCAT}));
-
- std::unordered_set<optional<string&>> set;
- assert(set.find({sCAT}) == set.end());
-
- set.insert({s0});
- assert(set.find({sCAT}) == set.end());
-
- set.insert({sCAT});
- assert(set.find({sCAT}) != set.end());
-};
-
-struct Combined
-{
- int m = 0;
- int n = 1;
-
- constexpr Combined() : m{5}, n{6} {}
- constexpr Combined(int m, int n) : m{m}, n{n} {}
-};
-
-struct Nasty
-{
- int m = 0;
- int n = 1;
-
- constexpr Nasty() : m{5}, n{6} {}
- constexpr Nasty(int m, int n) : m{m}, n{n} {}
-
- int operator&() { return n; }
- int operator&() const { return n; }
-};
-
-TEST(arrow_operator)
-{
- using namespace std::experimental;
-
- optional<Combined> oc1{in_place, 1, 2};
- assert (oc1);
- assert (oc1->m == 1);
- assert (oc1->n == 2);
-
- optional<Nasty> on{in_place, 1, 2};
- assert (on);
- assert (on->m == 1);
- assert (on->n == 2);
-};
-
-TEST(arrow_wit_optional_ref)
-{
- using namespace std::experimental;
-
- Combined c{1, 2};
- optional<Combined&> oc = c;
- assert (oc);
- assert (oc->m == 1);
- assert (oc->n == 2);
-
- Nasty n{1, 2};
- Nasty m{3, 4};
- Nasty p{5, 6};
-
- optional<Nasty&> on{n};
- assert (on);
- assert (on->m == 1);
- assert (on->n == 2);
-
- on = {m};
- assert (on);
- assert (on->m == 3);
- assert (on->n == 4);
-
- on.emplace(p);
- assert (on);
- assert (on->m == 5);
- assert (on->n == 6);
-
- optional<Nasty&> om{in_place, n};
- assert (om);
- assert (om->m == 1);
- assert (om->n == 2);
-};
-
-TEST(no_dangling_reference_in_value)
-{
- // this mostly tests compiler warnings
- using namespace std::experimental;
- optional<int> oi {2};
- unused (oi.value());
- const optional<int> coi {3};
- unused (coi.value());
-};
-
-struct CountedObject
-{
- static int _counter;
- bool _throw;
- CountedObject(bool b) : _throw(b) { ++_counter; }
- CountedObject(CountedObject const& rhs) : _throw(rhs._throw) { if (_throw) throw int(); }
- ~CountedObject() { --_counter; }
-};
-
-int CountedObject::_counter = 0;
-
-TEST(exception_safety)
-{
- using namespace std::experimental;
- try {
- optional<CountedObject> oo(in_place, true); // throw
- optional<CountedObject> o1(oo);
- }
- catch(...)
- {
- //
- }
- assert(CountedObject::_counter == 0);
-
- try {
- optional<CountedObject> oo(in_place, true); // throw
- optional<CountedObject> o1(std::move(oo)); // now move
- }
- catch(...)
- {
- //
- }
- assert(CountedObject::_counter == 0);
-};
-
-//// constexpr tests
-
-// these 4 classes have different noexcept signatures in move operations
-struct NothrowBoth {
- NothrowBoth(NothrowBoth&&) noexcept(true) {};
- void operator=(NothrowBoth&&) noexcept(true) {};
-};
-struct NothrowCtor {
- NothrowCtor(NothrowCtor&&) noexcept(true) {};
- void operator=(NothrowCtor&&) noexcept(false) {};
-};
-struct NothrowAssign {
- NothrowAssign(NothrowAssign&&) noexcept(false) {};
- void operator=(NothrowAssign&&) noexcept(true) {};
-};
-struct NothrowNone {
- NothrowNone(NothrowNone&&) noexcept(false) {};
- void operator=(NothrowNone&&) noexcept(false) {};
-};
-
-void test_noexcept()
-{
- {
- tr2::optional<NothrowBoth> b1, b2;
- static_assert(noexcept(tr2::optional<NothrowBoth>{tr2::constexpr_move(b1)}), "bad noexcept!");
- static_assert(noexcept(b1 = tr2::constexpr_move(b2)), "bad noexcept!");
- }
- {
- tr2::optional<NothrowCtor> c1, c2;
- static_assert(noexcept(tr2::optional<NothrowCtor>{tr2::constexpr_move(c1)}), "bad noexcept!");
- static_assert(!noexcept(c1 = tr2::constexpr_move(c2)), "bad noexcept!");
- }
- {
- tr2::optional<NothrowAssign> a1, a2;
- static_assert(!noexcept(tr2::optional<NothrowAssign>{tr2::constexpr_move(a1)}), "bad noexcept!");
- static_assert(!noexcept(a1 = tr2::constexpr_move(a2)), "bad noexcept!");
- }
- {
- tr2::optional<NothrowNone> n1, n2;
- static_assert(!noexcept(tr2::optional<NothrowNone>{tr2::constexpr_move(n1)}), "bad noexcept!");
- static_assert(!noexcept(n1 = tr2::constexpr_move(n2)), "bad noexcept!");
- }
-}
-
-
-void constexpr_test_disengaged()
-{
- constexpr tr2::optional<int> g0{};
- constexpr tr2::optional<int> g1{tr2::nullopt};
- static_assert( !g0, "initialized!" );
- static_assert( !g1, "initialized!" );
-
- static_assert( bool(g1) == bool(g0), "ne!" );
-
- static_assert( g1 == g0, "ne!" );
- static_assert( !(g1 != g0), "ne!" );
- static_assert( g1 >= g0, "ne!" );
- static_assert( !(g1 > g0), "ne!" );
- static_assert( g1 <= g0, "ne!" );
- static_assert( !(g1 <g0), "ne!" );
-
- static_assert( g1 == tr2::nullopt, "!" );
- static_assert( !(g1 != tr2::nullopt), "!" );
- static_assert( g1 <= tr2::nullopt, "!" );
- static_assert( !(g1 < tr2::nullopt), "!" );
- static_assert( g1 >= tr2::nullopt, "!" );
- static_assert( !(g1 > tr2::nullopt), "!" );
-
- static_assert( (tr2::nullopt == g0), "!" );
- static_assert( !(tr2::nullopt != g0), "!" );
- static_assert( (tr2::nullopt >= g0), "!" );
- static_assert( !(tr2::nullopt > g0), "!" );
- static_assert( (tr2::nullopt <= g0), "!" );
- static_assert( !(tr2::nullopt < g0), "!" );
-
- static_assert( (g1 != tr2::optional<int>(1)), "!" );
- static_assert( !(g1 == tr2::optional<int>(1)), "!" );
- static_assert( (g1 < tr2::optional<int>(1)), "!" );
- static_assert( (g1 <= tr2::optional<int>(1)), "!" );
- static_assert( !(g1 > tr2::optional<int>(1)), "!" );
- static_assert( !(g1 > tr2::optional<int>(1)), "!" );
-}
-
-
-constexpr tr2::optional<int> g0{};
-constexpr tr2::optional<int> g2{2};
-static_assert( g2, "not initialized!" );
-static_assert( *g2 == 2, "not 2!" );
-static_assert( g2 == tr2::optional<int>(2), "not 2!" );
-static_assert( g2 != g0, "eq!" );
-
-# if OPTIONAL_HAS_MOVE_ACCESSORS == 1
-static_assert( *tr2::optional<int>{3} == 3, "WTF!" );
-static_assert( tr2::optional<int>{3}.value() == 3, "WTF!" );
-static_assert( tr2::optional<int>{3}.value_or(1) == 3, "WTF!" );
-static_assert( tr2::optional<int>{}.value_or(4) == 4, "WTF!" );
-# endif
-
-constexpr tr2::optional<Combined> gc0{tr2::in_place};
-static_assert(gc0->n == 6, "WTF!");
-
-// optional refs
-int gi = 0;
-constexpr tr2::optional<int&> gori = gi;
-constexpr tr2::optional<int&> gorn{};
-constexpr int& gri = *gori;
-static_assert(gori, "WTF");
-static_assert(!gorn, "WTF");
-static_assert(gori != tr2::nullopt, "WTF");
-static_assert(gorn == tr2::nullopt, "WTF");
-static_assert(&gri == &*gori, "WTF");
-
-constexpr int gci = 1;
-constexpr tr2::optional<int const&> gorci = gci;
-constexpr tr2::optional<int const&> gorcn{};
-
-static_assert(gorcn < gorci, "WTF");
-static_assert(gorcn <= gorci, "WTF");
-static_assert(gorci == gorci, "WTF");
-static_assert(*gorci == 1, "WTF");
-static_assert(gorci == gci, "WTF");
-
-namespace constexpr_optional_ref_and_arrow
-{
- using namespace std::experimental;
- constexpr Combined c{1, 2};
- constexpr optional<Combined const&> oc = c;
- static_assert(oc, "WTF!");
- static_assert(oc->m == 1, "WTF!");
- static_assert(oc->n == 2, "WTF!");
-}
-
-#if OPTIONAL_HAS_CONSTEXPR_INIT_LIST
-
-namespace InitList
-{
- using namespace std::experimental;
-
- struct ConstInitLister
- {
- template <typename T>
- constexpr ConstInitLister(std::initializer_list<T> il) : len (il.size()) {}
- size_t len;
- };
-
- constexpr ConstInitLister CIL {2, 3, 4};
- static_assert(CIL.len == 3, "WTF!");
-
- constexpr optional<ConstInitLister> oil {in_place, {4, 5, 6, 7}};
- static_assert(oil, "WTF!");
- static_assert(oil->len == 4, "WTF!");
-}
-
-#endif // OPTIONAL_HAS_CONSTEXPR_INIT_LIST
-
-// end constexpr tests
-
-
-#include <string>
-
-
-struct VEC
-{
- std::vector<int> v;
- template <typename... X>
- VEC( X&&...x) : v(std::forward<X>(x)...) {}
-
- template <typename U, typename... X>
- VEC(std::initializer_list<U> il, X&&...x) : v(il, std::forward<X>(x)...) {}
-};
-
-
-
-int main() {
- tr2::optional<int> oi = 1;
- assert (bool(oi));
- oi.operator=({});
- assert (!oi);
-
- VEC v = {5, 6};
-
- if (OPTIONAL_HAS_THIS_RVALUE_REFS)
- std::cout << "Optional has rvalue references for *this" << std::endl;
- else
- std::cout << "Optional doesn't have rvalue references for *this" << std::endl;
-
- if (OPTIONAL_HAS_CONSTEXPR_INIT_LIST)
- std::cout << "Optional has constexpr initializer_list" << std::endl;
- else
- std::cout << "Optional doesn't have constexpr initializer_list" << std::endl;
-
- if (OPTIONAL_HAS_MOVE_ACCESSORS)
- std::cout << "Optional has constexpr move accessors" << std::endl;
- else
- std::cout << "Optional doesn't have constexpr move accessors" << std::endl;
-}
-