1 // Copyright (C) 2014 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
14 #ifdef __BORLANDC__
15 #pragma hdrstop
16 #endif
17
18 #include "boost/core/lightweight_test.hpp"
19 #include "boost/none.hpp"
20
21 //#ifndef BOOST_OPTIONAL_NO_CONVERTING_ASSIGNMENT
22 //#ifndef BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR
23
24 using boost::optional;
25 using boost::none;
26 using boost::in_place_init;
27 using boost::in_place_init_if;
28
29 #if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
30
31 class Guard
32 {
33 public:
34 int which_ctor;
Guard()35 Guard () : which_ctor(0) { }
Guard(int &,double &&)36 Guard (int&, double&&) : which_ctor(1) { }
Guard(int &&,double &)37 Guard (int&&, double&) : which_ctor(2) { }
Guard(int &&,double &&)38 Guard (int&&, double&&) : which_ctor(3) { }
Guard(int &,double &)39 Guard (int&, double&) : which_ctor(4) { }
Guard(std::string const &)40 Guard (std::string const&) : which_ctor(5) { }
Guard(std::string &)41 Guard (std::string &) : which_ctor(6) { }
Guard(std::string &&)42 Guard (std::string &&) : which_ctor(7) { }
43 private:
44 Guard(Guard&&);
45 Guard(Guard const&);
46 void operator=(Guard &&);
47 void operator=(Guard const&);
48 };
49
50
test_emplace()51 void test_emplace()
52 {
53 int i = 0;
54 double d = 0.0;
55 const std::string cs;
56 std::string ms;
57 optional<Guard> o;
58
59 o.emplace();
60 BOOST_TEST(o);
61 BOOST_TEST(0 == o->which_ctor);
62
63 o.emplace(i, 2.0);
64 BOOST_TEST(o);
65 BOOST_TEST(1 == o->which_ctor);
66
67 o.emplace(1, d);
68 BOOST_TEST(o);
69 BOOST_TEST(2 == o->which_ctor);
70
71 o.emplace(1, 2.0);
72 BOOST_TEST(o);
73 BOOST_TEST(3 == o->which_ctor);
74
75 o.emplace(i, d);
76 BOOST_TEST(o);
77 BOOST_TEST(4 == o->which_ctor);
78
79 o.emplace(cs);
80 BOOST_TEST(o);
81 BOOST_TEST(5 == o->which_ctor);
82
83 o.emplace(ms);
84 BOOST_TEST(o);
85 BOOST_TEST(6 == o->which_ctor);
86
87 o.emplace(std::string());
88 BOOST_TEST(o);
89 BOOST_TEST(7 == o->which_ctor);
90 }
91
test_in_place_ctor()92 void test_in_place_ctor()
93 {
94 int i = 0;
95 double d = 0.0;
96 const std::string cs;
97 std::string ms;
98
99 {
100 optional<Guard> o (in_place_init);
101 BOOST_TEST(o);
102 BOOST_TEST(0 == o->which_ctor);
103 }
104 {
105 optional<Guard> o (in_place_init, i, 2.0);
106 BOOST_TEST(o);
107 BOOST_TEST(1 == o->which_ctor);
108 }
109 {
110 optional<Guard> o (in_place_init, 1, d);
111 BOOST_TEST(o);
112 BOOST_TEST(2 == o->which_ctor);
113 }
114 {
115 optional<Guard> o (in_place_init, 1, 2.0);
116 BOOST_TEST(o);
117 BOOST_TEST(3 == o->which_ctor);
118 }
119 {
120 optional<Guard> o (in_place_init, i, d);
121 BOOST_TEST(o);
122 BOOST_TEST(4 == o->which_ctor);
123 }
124 {
125 optional<Guard> o (in_place_init, cs);
126 BOOST_TEST(o);
127 BOOST_TEST(5 == o->which_ctor);
128 }
129 {
130 optional<Guard> o (in_place_init, ms);
131 BOOST_TEST(o);
132 BOOST_TEST(6 == o->which_ctor);
133 }
134 {
135 optional<Guard> o (in_place_init, std::string());
136 BOOST_TEST(o);
137 BOOST_TEST(7 == o->which_ctor);
138 }
139 }
140
test_in_place_if_ctor()141 void test_in_place_if_ctor()
142 {
143 int i = 0;
144 double d = 0.0;
145 const std::string cs;
146 std::string ms;
147
148 {
149 optional<Guard> o (in_place_init_if, true);
150 BOOST_TEST(o);
151 BOOST_TEST(0 == o->which_ctor);
152 }
153 {
154 optional<Guard> o (in_place_init_if, true, i, 2.0);
155 BOOST_TEST(o);
156 BOOST_TEST(1 == o->which_ctor);
157 }
158 {
159 optional<Guard> o (in_place_init_if, true, 1, d);
160 BOOST_TEST(o);
161 BOOST_TEST(2 == o->which_ctor);
162 }
163 {
164 optional<Guard> o (in_place_init_if, true, 1, 2.0);
165 BOOST_TEST(o);
166 BOOST_TEST(3 == o->which_ctor);
167 }
168 {
169 optional<Guard> o (in_place_init_if, true, i, d);
170 BOOST_TEST(o);
171 BOOST_TEST(4 == o->which_ctor);
172 }
173 {
174 optional<Guard> o (in_place_init_if, true, cs);
175 BOOST_TEST(o);
176 BOOST_TEST(5 == o->which_ctor);
177 }
178 {
179 optional<Guard> o (in_place_init_if, true, ms);
180 BOOST_TEST(o);
181 BOOST_TEST(6 == o->which_ctor);
182 }
183 {
184 optional<Guard> o (in_place_init_if, true, std::string());
185 BOOST_TEST(o);
186 BOOST_TEST(7 == o->which_ctor);
187 }
188
189 {
190 optional<Guard> o (in_place_init_if, false, 1, 2.0);
191 BOOST_TEST(!o);
192 }
193 }
194
195
196 #endif
197
198 #if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
199
200
201 struct ThrowOnMove
202 {
ThrowOnMoveThrowOnMove203 ThrowOnMove(ThrowOnMove&&) { throw int(); }
ThrowOnMoveThrowOnMove204 ThrowOnMove(ThrowOnMove const&) { throw int(); }
ThrowOnMoveThrowOnMove205 ThrowOnMove(int){}
206 };
207
208
test_no_moves_on_emplacement()209 void test_no_moves_on_emplacement()
210 {
211 try {
212 optional<ThrowOnMove> o;
213 o.emplace(1);
214 BOOST_TEST(o);
215 }
216 catch (...) {
217 BOOST_TEST(false);
218 }
219 }
220
test_no_moves_on_in_place_ctor()221 void test_no_moves_on_in_place_ctor()
222 {
223 try {
224 optional<ThrowOnMove> o (in_place_init, 1);
225 BOOST_TEST(o);
226
227 optional<ThrowOnMove> p (in_place_init_if, true, 1);
228 BOOST_TEST(p);
229
230 optional<ThrowOnMove> q (in_place_init_if, false, 1);
231 BOOST_TEST(!q);
232 }
233 catch (...) {
234 BOOST_TEST(false);
235 }
236 }
237
238 #endif
239
240 struct Thrower
241 {
ThrowerThrower242 Thrower(bool throw_) { if (throw_) throw int(); }
243
244 private:
245 Thrower(Thrower const&);
246 #if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
247 Thrower(Thrower&&);
248 #endif
249 };
250
test_clear_on_throw()251 void test_clear_on_throw()
252 {
253 optional<Thrower> ot;
254 try {
255 ot.emplace(false);
256 BOOST_TEST(ot);
257 } catch(...) {
258 BOOST_TEST(false);
259 }
260
261 try {
262 ot.emplace(true);
263 BOOST_TEST(false);
264 } catch(...) {
265 BOOST_TEST(!ot);
266 }
267 }
268
test_no_assignment_on_emplacement()269 void test_no_assignment_on_emplacement()
270 {
271 optional<const std::string> os, ot;
272 BOOST_TEST(!os);
273 os.emplace("wow");
274 BOOST_TEST(os);
275 BOOST_TEST_EQ(*os, "wow");
276
277 BOOST_TEST(!ot);
278 ot.emplace();
279 BOOST_TEST(ot);
280 BOOST_TEST_EQ(*ot, "");
281 }
282
283 namespace no_rvalue_refs {
284
285 class Guard
286 {
287 public:
288 int which_ctor;
Guard()289 Guard () : which_ctor(0) { }
Guard(std::string const &)290 Guard (std::string const&) : which_ctor(5) { }
Guard(std::string &)291 Guard (std::string &) : which_ctor(6) { }
292 private:
293 Guard(Guard const&);
294 void operator=(Guard const&);
295 };
296
test_emplace()297 void test_emplace()
298 {
299 const std::string cs;
300 std::string ms;
301 optional<Guard> o;
302
303 o.emplace();
304 BOOST_TEST(o);
305 BOOST_TEST(0 == o->which_ctor);
306
307 o.emplace(cs);
308 BOOST_TEST(o);
309 BOOST_TEST(5 == o->which_ctor);
310
311 o.emplace(ms);
312 BOOST_TEST(o);
313 BOOST_TEST(6 == o->which_ctor);
314 }
315
test_in_place_ctor()316 void test_in_place_ctor()
317 {
318 const std::string cs;
319 std::string ms;
320
321 {
322 optional<Guard> o (in_place_init);
323 BOOST_TEST(o);
324 BOOST_TEST(0 == o->which_ctor);
325 }
326 {
327 optional<Guard> o (in_place_init, cs);
328 BOOST_TEST(o);
329 BOOST_TEST(5 == o->which_ctor);
330 }
331 {
332 optional<Guard> o (in_place_init, ms);
333 BOOST_TEST(o);
334 BOOST_TEST(6 == o->which_ctor);
335 }
336 }
337
test_in_place_if_ctor()338 void test_in_place_if_ctor()
339 {
340 const std::string cs;
341 std::string ms;
342
343 {
344 optional<Guard> n (in_place_init_if, false);
345 BOOST_TEST(!n);
346
347 optional<Guard> o (in_place_init_if, true);
348 BOOST_TEST(o);
349 BOOST_TEST(0 == o->which_ctor);
350 }
351 {
352 optional<Guard> n (in_place_init_if, false, cs);
353 BOOST_TEST(!n);
354
355 optional<Guard> o (in_place_init_if, true, cs);
356 BOOST_TEST(o);
357 BOOST_TEST(5 == o->which_ctor);
358 }
359 {
360 optional<Guard> n (in_place_init_if, false, ms);
361 BOOST_TEST(!n);
362
363 optional<Guard> o (in_place_init_if, true, ms);
364 BOOST_TEST(o);
365 BOOST_TEST(6 == o->which_ctor);
366 }
367 }
368
369 } // namespace no_rvalue_ref
370
main()371 int main()
372 {
373 #if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
374 test_emplace();
375 test_in_place_ctor();
376 test_in_place_if_ctor();
377 #endif
378 #if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
379 test_no_moves_on_emplacement();
380 test_no_moves_on_in_place_ctor();
381 #endif
382 test_clear_on_throw();
383 test_no_assignment_on_emplacement();
384 no_rvalue_refs::test_emplace();
385 no_rvalue_refs::test_in_place_ctor();
386 no_rvalue_refs::test_in_place_if_ctor();
387
388 return boost::report_errors();
389 }
390