1 // Copyright (C) 2016 Andrzej Krzemienski.
2 //
3 // Use, modification, and distribution is subject to the Boost Software
4 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // See http://www.boost.org/lib/optional for documentation.
8 //
9 // You are welcome to contact the author at:
10 //  [email protected]
11 
12 
13 #include "boost/optional/optional.hpp"
14 
15 #ifdef BOOST_BORLANDC
16 #pragma hdrstop
17 #endif
18 
19 #include "boost/core/lightweight_test.hpp"
20 
21 using boost::optional;
22 using boost::none;
23 
24 struct Value
25 {
26   int val;
ValueValue27   explicit Value(int v) : val(v) {}
28 };
29 
val(int const & i)30 int val(int const& i)
31 {
32   return i;
33 }
34 
val(Value const & v)35 int val(Value const& v)
36 {
37   return v.val;
38 }
39 
40 template <typename Tref>
make_opt_ref(Tref & v)41 optional<Tref&> make_opt_ref(Tref& v)
42 {
43   return optional<Tref&>(v);
44 }
45 
46 template <typename Tval, typename Tref>
test_construct_from_optional_ref()47 void test_construct_from_optional_ref()
48 {
49     Tref v1 (1), v2 (2);
50 
51     optional<Tref&> opt_ref0;
52     optional<Tref&> opt_ref1 (v1);
53 
54     optional<Tval> opt_val0 (opt_ref0);
55     optional<Tval> opt_val1 (opt_ref1);
56     optional<Tval> opt_val2 (make_opt_ref(v2));
57 
58     BOOST_TEST (!opt_val0);
59     BOOST_TEST (opt_val1);
60     BOOST_TEST (opt_val2);
61 
62     BOOST_TEST_EQ (1, val(*opt_val1));
63     BOOST_TEST_EQ (2, val(*opt_val2));
64 
65     BOOST_TEST (boost::addressof(*opt_val1) != boost::addressof(v1));
66     BOOST_TEST (boost::addressof(*opt_val2) != boost::addressof(v2));
67 }
68 
69 template <typename Tval, typename Tref>
test_assign_from_optional_ref()70 void test_assign_from_optional_ref()
71 {
72     Tref v1 (1), v2 (2);
73 
74     optional<Tref&> opt_ref0;
75     optional<Tref&> opt_ref1 (v1);
76 
77     optional<Tval> opt_val0;
78     optional<Tval> opt_val1;
79     optional<Tval> opt_val2;
80 
81     opt_val0 = opt_ref0;
82     opt_val1 = opt_ref1;
83     opt_val2 = make_opt_ref(v2);
84 
85     BOOST_TEST (!opt_val0);
86     BOOST_TEST (opt_val1);
87     BOOST_TEST (opt_val2);
88 
89     BOOST_TEST_EQ (1, val(*opt_val1));
90     BOOST_TEST_EQ (2, val(*opt_val2));
91 
92     BOOST_TEST (boost::addressof(*opt_val1) != boost::addressof(v1));
93     BOOST_TEST (boost::addressof(*opt_val2) != boost::addressof(v2));
94 }
95 
96 
main()97 int main()
98 {
99     test_construct_from_optional_ref<int, int>();
100     test_construct_from_optional_ref<int, int const>();
101     test_construct_from_optional_ref<int const, int const>();
102     test_construct_from_optional_ref<int const, int>();
103 
104     test_construct_from_optional_ref<Value, Value>();
105     test_construct_from_optional_ref<Value, Value const>();
106     test_construct_from_optional_ref<Value const, Value const>();
107     test_construct_from_optional_ref<Value const, Value>();
108 
109     test_assign_from_optional_ref<int, int>();
110     test_assign_from_optional_ref<int, int const>();
111 
112     test_assign_from_optional_ref<Value, Value>();
113     test_assign_from_optional_ref<Value, Value const>();
114 
115     return boost::report_errors();
116 }
117