• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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