]>
Commit | Line | Data |
---|---|---|
92f5a8d4 TL |
1 | // Copyright (C) 2018 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 | // akrzemi1@gmail.com | |
11 | ||
12 | #include "boost/optional/optional.hpp" | |
13 | ||
20effc67 | 14 | #ifdef BOOST_BORLANDC |
92f5a8d4 TL |
15 | #pragma hdrstop |
16 | #endif | |
17 | ||
18 | #include "boost/core/ignore_unused.hpp" | |
19 | #include "boost/core/is_same.hpp" | |
20 | #include "boost/core/lightweight_test.hpp" | |
21 | #include "boost/core/lightweight_test_trait.hpp" | |
22 | ||
23 | ||
24 | using boost::optional; | |
25 | using boost::make_optional; | |
26 | using boost::core::is_same; | |
27 | ||
28 | template <typename Expected, typename Deduced> | |
29 | void verify_type(Deduced) | |
30 | { | |
31 | BOOST_TEST_TRAIT_TRUE(( is_same<Expected, Deduced> )); | |
32 | } | |
33 | ||
34 | #if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) | |
35 | struct MoveOnly | |
36 | { | |
37 | int value; | |
38 | explicit MoveOnly(int i) : value(i) {} | |
39 | MoveOnly(MoveOnly && r) : value(r.value) { r.value = 0; } | |
40 | MoveOnly& operator=(MoveOnly && r) { value = r.value; r.value = 0; return *this; } | |
41 | ||
42 | private: | |
43 | MoveOnly(MoveOnly const&); | |
44 | void operator=(MoveOnly const&); | |
45 | }; | |
46 | ||
47 | MoveOnly makeMoveOnly(int i) | |
48 | { | |
49 | return MoveOnly(i); | |
50 | } | |
51 | ||
52 | optional<MoveOnly> makeOptMoveOnly(int i) | |
53 | { | |
54 | return optional<MoveOnly>(MoveOnly(i)); | |
55 | } | |
56 | ||
57 | int get_val(MoveOnly m) | |
58 | { | |
59 | return m.value; | |
60 | } | |
61 | ||
62 | void test_map_move_only() | |
63 | { | |
64 | optional<MoveOnly> om (makeMoveOnly(7)), om2 (makeMoveOnly(8)); | |
65 | verify_type<optional<int> >(boost::move(om).map(get_val)); | |
66 | optional<int> oi = boost::move(om2).map(get_val); | |
67 | BOOST_TEST(bool(oi)); | |
68 | BOOST_TEST_EQ(8, *oi); | |
69 | ||
70 | optional<int> oj = makeOptMoveOnly(4).map(get_val); | |
71 | BOOST_TEST(bool(oj)); | |
72 | BOOST_TEST_EQ(4, *oj); | |
73 | ||
74 | optional<MoveOnly> o_; | |
75 | optional<int> oi_ = boost::move(o_).map(get_val); | |
76 | BOOST_TEST(!oi_); | |
77 | } | |
78 | ||
79 | #endif // no rvalue refs | |
80 | ||
81 | struct Int | |
82 | { | |
83 | int i; | |
84 | explicit Int(int i_) : i(i_) {} | |
85 | }; | |
86 | ||
87 | struct convert_t | |
88 | { | |
89 | typedef Int result_type; | |
90 | Int operator()(int i) { return Int(i); } | |
91 | }; | |
92 | ||
93 | int& get_int_ref(Int& i) | |
94 | { | |
95 | return i.i; | |
96 | } | |
97 | ||
98 | struct get_ref | |
99 | { | |
100 | typedef int& result_type; | |
101 | int& operator()(int& i) { return i; } | |
102 | }; | |
103 | ||
104 | void test_map() | |
105 | { | |
106 | optional<int> oi (1); | |
107 | verify_type<optional<Int> >(oi.map(convert_t())); | |
108 | optional<Int> oI = oi.map(convert_t()); | |
109 | BOOST_TEST(bool(oI)); | |
110 | BOOST_TEST_EQ(1, oI->i); | |
111 | ||
112 | optional<Int> o_ = optional<int>().map(convert_t()); | |
113 | BOOST_TEST(!o_); | |
114 | } | |
115 | ||
116 | optional<Int> make_opt_int(int i) | |
117 | { | |
118 | if (i != 0) | |
119 | return Int(i); | |
120 | else | |
121 | return boost::none; | |
122 | } | |
123 | ||
124 | void test_map_optional() | |
125 | { | |
126 | optional<int> o9 (9), o0 (0), o_; | |
127 | verify_type<optional<optional<Int> > >(o9.map(make_opt_int)); | |
128 | optional<optional<Int> > oo9 = o9.map(make_opt_int); | |
129 | BOOST_TEST(bool(oo9)); | |
130 | BOOST_TEST(bool(*oo9)); | |
131 | BOOST_TEST_EQ(9, (**oo9).i); | |
132 | ||
133 | optional<optional<Int> > oo0 = o0.map(make_opt_int); | |
134 | BOOST_TEST(bool(oo0)); | |
135 | BOOST_TEST(!*oo0); | |
136 | ||
137 | optional<optional<Int> > oo_ = o_.map(make_opt_int); | |
138 | BOOST_TEST(!oo_); | |
139 | } | |
140 | ||
141 | void test_map_with_lambda() | |
142 | { | |
143 | #if !defined BOOST_NO_CXX11_LAMBDAS && !defined BOOST_NO_CXX11_DECLTYPE_N3276 | |
144 | optional<int> oi (1), oj(2); | |
145 | verify_type<optional<bool> >(oi.map([](int i){ return i == 1; })); | |
146 | optional<bool> ob = oi.map([](int i){ return i == 1; }); | |
147 | optional<bool> oc = oj.map([](int i){ return i == 1; }); | |
148 | BOOST_TEST(bool(ob)); | |
149 | BOOST_TEST_EQ(true, *ob); | |
150 | BOOST_TEST(bool(oc)); | |
151 | BOOST_TEST_EQ(false, *oc); | |
152 | #endif // lambdas | |
153 | } | |
154 | ||
155 | void test_map_to_ref() | |
156 | { | |
157 | optional<int> oi (2); | |
158 | verify_type<optional<int&> >(oi.map(get_ref())); | |
159 | optional<int&> ori = oi.map(get_ref()); | |
160 | BOOST_TEST(bool(ori)); | |
161 | *ori = 3; | |
162 | BOOST_TEST(bool(oi)); | |
163 | BOOST_TEST_EQ(3, *oi); | |
164 | BOOST_TEST_EQ(3, *ori); | |
165 | } | |
166 | ||
167 | void test_map_optional_ref() | |
168 | { | |
169 | Int I (5); | |
170 | optional<Int&> ori (I); | |
171 | verify_type<optional<int&> >(ori.map(get_int_ref)); | |
172 | optional<int&> orii = ori.map(get_int_ref); | |
173 | BOOST_TEST(bool(orii)); | |
174 | BOOST_TEST_EQ(5, *orii); | |
175 | *orii = 6; | |
176 | BOOST_TEST_EQ(6, I.i); | |
177 | } | |
178 | ||
179 | int main() | |
180 | { | |
181 | #if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) | |
182 | test_map_move_only(); | |
183 | #endif | |
184 | test_map_with_lambda(); | |
185 | test_map(); | |
186 | test_map_optional(); | |
187 | test_map_to_ref(); | |
188 | test_map_optional(); | |
189 | test_map_optional_ref(); | |
190 | ||
191 | return boost::report_errors(); | |
192 | } |