123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352 |
- // Copyright (C) 2014 - 2015 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)
- //
- // See http://www.boost.org/lib/optional for documentation.
- //
- // You are welcome to contact the author at:
- // akrzemi1@gmail.com
- #include "boost/optional/optional.hpp"
- #ifdef __BORLANDC__
- #pragma hdrstop
- #endif
- #include "boost/core/lightweight_test.hpp"
- using boost::optional;
- using boost::none;
- //#ifndef BOOST_OPTIONAL_NO_CONVERTING_ASSIGNMENT
- //#ifndef BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR
- #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
- enum State
- {
- sDefaultConstructed,
- sValueCopyConstructed,
- sValueMoveConstructed,
- sCopyConstructed,
- sMoveConstructed,
- sMoveAssigned,
- sCopyAssigned,
- sValueCopyAssigned,
- sValueMoveAssigned,
- sMovedFrom,
- sIntConstructed
- };
- struct OracleVal
- {
- State s;
- int i;
- OracleVal(int i = 0) : s(sIntConstructed), 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 = sValueCopyAssigned; val = v; return *this; }
- Oracle& operator=(OracleVal&& v) { s = sValueMoveAssigned; val = std::move(v); v.s = sMovedFrom; return *this; }
- Oracle& operator=(const Oracle& o) { s = sCopyAssigned; val = o.val; return *this; }
- Oracle& operator=(Oracle&& o) { s = sMoveAssigned; val = std::move(o.val); o.s = sMovedFrom; 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; }
- void test_move_ctor_from_U()
- {
- optional<Oracle> o1 ((OracleVal()));
- BOOST_TEST(o1);
- BOOST_TEST(o1->s == sValueMoveConstructed || o1->s == sMoveConstructed);
-
- OracleVal v1;
- optional<Oracle> o2 (v1);
- BOOST_TEST(o2);
- BOOST_TEST(o2->s == sValueCopyConstructed || o2->s == sCopyConstructed || o2->s == sMoveConstructed );
- BOOST_TEST(v1.s == sIntConstructed);
-
- optional<Oracle> o3 (boost::move(v1));
- BOOST_TEST(o3);
- BOOST_TEST(o3->s == sValueMoveConstructed || o3->s == sMoveConstructed);
- BOOST_TEST(v1.s == sMovedFrom);
- }
- void test_move_ctor_form_T()
- {
- optional<Oracle> o1 ((Oracle()));
- BOOST_TEST(o1);
- BOOST_TEST(o1->s == sMoveConstructed);
-
- Oracle v1;
- optional<Oracle> o2 (v1);
- BOOST_TEST(o2);
- BOOST_TEST(o2->s == sCopyConstructed);
- BOOST_TEST(v1.s == sDefaultConstructed);
-
- optional<Oracle> o3 (boost::move(v1));
- BOOST_TEST(o3);
- BOOST_TEST(o3->s == sMoveConstructed);
- BOOST_TEST(v1.s == sMovedFrom);
- }
- void test_move_ctor_from_optional_T()
- {
- optional<Oracle> o1;
- optional<Oracle> o2(boost::move(o1));
-
- BOOST_TEST(!o1);
- BOOST_TEST(!o2);
-
- optional<Oracle> o3((Oracle()));
- optional<Oracle> o4(boost::move(o3));
- BOOST_TEST(o3);
- BOOST_TEST(o4);
- BOOST_TEST(o3->s == sMovedFrom);
- BOOST_TEST(o4->s == sMoveConstructed);
-
- optional<Oracle> o5((optional<Oracle>()));
- BOOST_TEST(!o5);
-
- optional<Oracle> o6((optional<Oracle>(Oracle())));
- BOOST_TEST(o6);
- BOOST_TEST(o6->s == sMoveConstructed);
-
- optional<Oracle> o7(o6); // does copy ctor from non-const lvalue compile?
- }
- void test_move_assign_from_U()
- {
- optional<Oracle> o1 = boost::none; // test if additional ctors didn't break it
- o1 = boost::none; // test if additional assignments didn't break it
- o1 = OracleVal();
- BOOST_TEST(o1);
-
- BOOST_TEST(o1->s == sValueMoveConstructed);
-
- o1 = OracleVal();
- BOOST_TEST(o1);
- BOOST_TEST(o1->s == sMoveAssigned);
-
- OracleVal v1;
- optional<Oracle> o2;
- o2 = v1;
- BOOST_TEST(o2);
- BOOST_TEST(o2->s == sValueCopyConstructed);
- BOOST_TEST(v1.s == sIntConstructed);
- o2 = v1;
- BOOST_TEST(o2);
- BOOST_TEST(o2->s == sCopyAssigned || o2->s == sMoveAssigned);
- BOOST_TEST(v1.s == sIntConstructed);
-
- optional<Oracle> o3;
- o3 = boost::move(v1);
- BOOST_TEST(o3);
- BOOST_TEST(o3->s == sValueMoveConstructed);
- BOOST_TEST(v1.s == sMovedFrom);
- }
- void test_move_assign_from_T()
- {
- optional<Oracle> o1;
- o1 = Oracle();
- BOOST_TEST(o1);
- BOOST_TEST(o1->s == sMoveConstructed);
-
- o1 = Oracle();
- BOOST_TEST(o1);
- BOOST_TEST(o1->s == sMoveAssigned);
-
- Oracle v1;
- optional<Oracle> o2;
- o2 = v1;
- BOOST_TEST(o2);
- BOOST_TEST(o2->s == sCopyConstructed);
- BOOST_TEST(v1.s == sDefaultConstructed);
- o2 = v1;
- BOOST_TEST(o2);
- BOOST_TEST(o2->s == sCopyAssigned);
- BOOST_TEST(v1.s == sDefaultConstructed);
-
- optional<Oracle> o3;
- o3 = boost::move(v1);
- BOOST_TEST(o3);
- BOOST_TEST(o3->s == sMoveConstructed);
- BOOST_TEST(v1.s == sMovedFrom);
- }
- void test_move_assign_from_optional_T()
- {
- optional<Oracle> o1;
- optional<Oracle> o2;
- o1 = optional<Oracle>();
- BOOST_TEST(!o1);
- optional<Oracle> o3((Oracle()));
- o1 = o3;
- BOOST_TEST(o3);
- BOOST_TEST(o3->s == sMoveConstructed);
- BOOST_TEST(o1);
- BOOST_TEST(o1->s == sCopyConstructed);
-
- o2 = boost::move(o3);
- BOOST_TEST(o3);
- BOOST_TEST(o3->s == sMovedFrom);
- BOOST_TEST(o2);
- BOOST_TEST(o2->s == sMoveConstructed);
-
- o2 = optional<Oracle>((Oracle()));
- BOOST_TEST(o2);
- BOOST_TEST(o2->s == sMoveAssigned);
- }
- class MoveOnly
- {
- public:
- int val;
- MoveOnly(int v) : val(v) {}
- MoveOnly(MoveOnly&& rhs) : val(rhs.val) { rhs.val = 0; }
- void operator=(MoveOnly&& rhs) {val = rhs.val; rhs.val = 0; }
-
- private:
- MoveOnly(MoveOnly const&);
- void operator=(MoveOnly const&);
-
- friend class MoveOnlyB;
- };
- void test_with_move_only()
- {
- optional<MoveOnly> o1;
- optional<MoveOnly> o2((MoveOnly(1)));
- BOOST_TEST(o2);
- BOOST_TEST(o2->val == 1);
- optional<MoveOnly> o3 (boost::move(o1));
- BOOST_TEST(!o3);
- optional<MoveOnly> o4 (boost::move(o2));
- BOOST_TEST(o4);
- BOOST_TEST(o4->val == 1);
- BOOST_TEST(o2);
- BOOST_TEST(o2->val == 0);
-
- o3 = boost::move(o4);
- BOOST_TEST(o3);
- BOOST_TEST(o3->val == 1);
- BOOST_TEST(o4);
- BOOST_TEST(o4->val == 0);
- }
- class MoveOnlyB
- {
- public:
- int val;
- MoveOnlyB(int v) : val(v) {}
- MoveOnlyB(MoveOnlyB&& rhs) : val(rhs.val) { rhs.val = 0; }
- void operator=(MoveOnlyB&& rhs) {val = rhs.val; rhs.val = 0; }
- MoveOnlyB(MoveOnly&& rhs) : val(rhs.val) { rhs.val = 0; }
- void operator=(MoveOnly&& rhs) {val = rhs.val; rhs.val = 0; }
-
- private:
- MoveOnlyB(MoveOnlyB const&);
- void operator=(MoveOnlyB const&);
- MoveOnlyB(MoveOnly const&);
- void operator=(MoveOnly const&);
- };
- void test_move_assign_from_optional_U()
- {
- optional<MoveOnly> a((MoveOnly(2)));
- optional<MoveOnlyB> b1;
- b1 = boost::move(a);
-
- BOOST_TEST(b1);
- BOOST_TEST(b1->val == 2);
- BOOST_TEST(a);
- BOOST_TEST(a->val == 0);
-
- b1 = MoveOnly(4);
-
- BOOST_TEST(b1);
- BOOST_TEST(b1->val == 4);
- }
- void test_move_ctor_from_optional_U()
- {
- optional<MoveOnly> a((MoveOnly(2)));
- optional<MoveOnlyB> b1(boost::move(a));
-
- BOOST_TEST(b1);
- BOOST_TEST(b1->val == 2);
- BOOST_TEST(a);
- BOOST_TEST(a->val == 0);
-
- optional<MoveOnlyB> b2(( optional<MoveOnly>(( MoveOnly(4) )) ));
-
- BOOST_TEST(b2);
- BOOST_TEST(b2->val == 4);
- }
- void test_swap()
- {
- optional<MoveOnly> a((MoveOnly(2)));
- optional<MoveOnly> b((MoveOnly(3)));
- swap(a, b);
-
- BOOST_TEST(a->val == 3);
- BOOST_TEST(b->val == 2);
- }
- void test_optional_ref_to_movables()
- {
- MoveOnly m(3);
- optional<MoveOnly&> orm = m;
- orm->val = 2;
- BOOST_TEST(m.val == 2);
-
- optional<MoveOnly&> orm2 = orm;
- orm2->val = 1;
- BOOST_TEST(m.val == 1);
- BOOST_TEST(orm->val == 1);
-
- optional<MoveOnly&> orm3 = boost::move(orm);
- orm3->val = 4;
- BOOST_TEST(m.val == 4);
- BOOST_TEST(orm->val == 4);
- BOOST_TEST(orm2->val == 4);
- }
- #endif
- int main()
- {
- #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
- test_move_ctor_from_U();
- test_move_ctor_form_T();
- test_move_ctor_from_optional_T();
- test_move_ctor_from_optional_U();
- test_move_assign_from_U();
- test_move_assign_from_T();
- test_move_assign_from_optional_T();
- test_move_assign_from_optional_U();
- test_with_move_only();
- test_optional_ref_to_movables();
- test_swap();
- #endif
- return boost::report_errors();
- }
|