1 // Copyright (c) 2018-2020 Emil Dotchevski and Reverge Studios, Inc.
2
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6 #include <boost/leaf/detail/config.hpp>
7 #include <boost/leaf/detail/optional.hpp>
8 #include "lightweight_test.hpp"
9
10 namespace leaf = boost::leaf;
11
12 int object_count=0;
13 int value_count=0;
14
15 class my_info
16 {
17 my_info & operator=( my_info const & ) = delete;
18
19 public:
20
21 int value;
22
my_info(int value)23 explicit my_info( int value ):
24 value(value)
25 {
26 BOOST_TEST(++object_count>0);
27 BOOST_TEST(++value_count>0);
28 }
29
my_info(my_info const & x)30 my_info( my_info const & x ):
31 value(x.value)
32 {
33 BOOST_TEST(++object_count>0);
34 BOOST_TEST(++value_count>0);
35 }
36
my_info(my_info && x)37 my_info( my_info && x ):
38 value(x.value)
39 {
40 x.value=-1;
41 BOOST_TEST(++object_count>0);
42 }
~my_info()43 ~my_info()
44 {
45 BOOST_TEST(--object_count>=0);
46 if( value!=-1 )
47 BOOST_TEST(--value_count>=0);
48 }
49 };
50
51 #ifndef BOOST_LEAF_NO_EXCEPTIONS
52 class throws_on_copy
53 {
54 throws_on_copy & operator=( throws_on_copy const & )=delete;
55
56 public:
57
58 int value;
59
throws_on_copy()60 throws_on_copy()
61 {
62 BOOST_TEST(++object_count>0);
63 }
64
throws_on_copy(throws_on_copy const &)65 throws_on_copy( throws_on_copy const & )
66 {
67 throw std::exception();
68 }
69
throws_on_copy(throws_on_copy &&)70 throws_on_copy( throws_on_copy && )
71 {
72 BOOST_TEST(++object_count>0);
73 }
74
~throws_on_copy()75 ~throws_on_copy()
76 {
77 BOOST_TEST(--object_count>=0);
78 }
79 };
80 #endif
81
run_tests()82 void run_tests()
83 {
84 using leaf::leaf_detail::optional;
85 {
86 optional<my_info> x;
87 BOOST_TEST(x.empty());
88 }
89 BOOST_TEST(!object_count);
90 BOOST_TEST(!value_count);
91 {
92 my_info a(42);
93 BOOST_TEST_EQ(object_count, 1);
94 BOOST_TEST_EQ(value_count, 1);
95 optional<my_info> x(10, a);
96 BOOST_TEST_EQ(object_count, 2);
97 BOOST_TEST_EQ(value_count, 2);
98 BOOST_TEST(!x.empty());
99 BOOST_TEST(x.has_value(10));
100 BOOST_TEST(!x.has_value(11));
101 BOOST_TEST_EQ(x.value(10).value, 42);
102 }
103 BOOST_TEST(!object_count);
104 BOOST_TEST(!value_count);
105 #ifndef BOOST_LEAF_NO_EXCEPTIONS
106 {
107 throws_on_copy a;
108 BOOST_TEST_EQ(object_count, 1);
109 try
110 {
111 optional<throws_on_copy> x(10, a);
112 BOOST_TEST(false);
113 }
114 catch( std::exception & )
115 {
116 }
117 }
118 #endif
119 BOOST_TEST(!object_count);
120 BOOST_TEST(!value_count);
121 {
122 my_info a(42);
123 BOOST_TEST_EQ(object_count, 1);
124 BOOST_TEST_EQ(value_count, 1);
125 optional<my_info> x(10, std::move(a));
126 BOOST_TEST_EQ(object_count, 2);
127 BOOST_TEST_EQ(value_count, 1);
128 BOOST_TEST(!x.empty());
129 BOOST_TEST(x.has_value(10));
130 BOOST_TEST(!x.has_value(11));
131 BOOST_TEST_EQ(x.value(10).value, 42);
132 }
133 BOOST_TEST(!object_count);
134 BOOST_TEST(!value_count);
135 {
136 optional<my_info> x(10, my_info(42));
137 BOOST_TEST_EQ(object_count, 1);
138 BOOST_TEST_EQ(value_count, 1);
139 BOOST_TEST(!x.empty());
140 BOOST_TEST(x.has_value(10));
141 BOOST_TEST(!x.has_value(11));
142 BOOST_TEST_EQ(x.value(10).value, 42);
143 optional<my_info> y(x);
144 BOOST_TEST_EQ(object_count, 2);
145 BOOST_TEST_EQ(value_count, 2);
146 BOOST_TEST(!x.empty());
147 BOOST_TEST(x.has_value(10));
148 BOOST_TEST(!x.has_value(11));
149 BOOST_TEST_EQ(x.value(10).value, 42);
150 BOOST_TEST(!y.empty());
151 BOOST_TEST(y.has_value(10));
152 BOOST_TEST(!y.has_value(11));
153 BOOST_TEST_EQ(y.value(10).value, 42);
154 }
155 BOOST_TEST(!object_count);
156 BOOST_TEST(!value_count);
157 {
158 optional<my_info> x(10, my_info(42));
159 BOOST_TEST_EQ(object_count, 1);
160 BOOST_TEST_EQ(value_count, 1);
161 BOOST_TEST(!x.empty());
162 BOOST_TEST(x.has_value(10));
163 BOOST_TEST(!x.has_value(11));
164 BOOST_TEST_EQ(x.value(10).value, 42);
165 optional<my_info> y(std::move(x));
166 BOOST_TEST_EQ(object_count, 1);
167 BOOST_TEST_EQ(value_count, 1);
168 BOOST_TEST(x.empty());
169 BOOST_TEST(!x.has_value(10));
170 BOOST_TEST(!y.empty());
171 BOOST_TEST(y.has_value(10));
172 BOOST_TEST(!y.has_value(11));
173 BOOST_TEST_EQ(y.value(10).value, 42);
174 }
175 BOOST_TEST(!object_count);
176 BOOST_TEST(!value_count);
177 {
178 optional<my_info> x(10, my_info(42));
179 BOOST_TEST_EQ(object_count, 1);
180 BOOST_TEST_EQ(value_count, 1);
181 BOOST_TEST(!x.empty());
182 BOOST_TEST(x.has_value(10));
183 BOOST_TEST(!x.has_value(11));
184 BOOST_TEST_EQ(x.value(10).value, 42);
185 optional<my_info> y;
186 BOOST_TEST(y.empty());
187 BOOST_TEST_EQ(&(y=x), &y);
188 BOOST_TEST_EQ(object_count, 2);
189 BOOST_TEST_EQ(value_count, 2);
190 BOOST_TEST(!x.empty());
191 BOOST_TEST(x.has_value(10));
192 BOOST_TEST(!x.has_value(11));
193 BOOST_TEST_EQ(x.value(10).value, 42);
194 BOOST_TEST(!y.empty());
195 BOOST_TEST(y.has_value(10));
196 BOOST_TEST(!y.has_value(11));
197 BOOST_TEST_EQ(y.value(10).value, 42);
198 }
199 BOOST_TEST(!object_count);
200 BOOST_TEST(!value_count);
201 {
202 optional<my_info> x(10, my_info(42));
203 BOOST_TEST_EQ(object_count, 1);
204 BOOST_TEST_EQ(value_count, 1);
205 BOOST_TEST(!x.empty());
206 BOOST_TEST(x.has_value(10));
207 BOOST_TEST(!x.has_value(11));
208 BOOST_TEST_EQ(x.value(10).value, 42);
209 optional<my_info> y(11, my_info(43));
210 BOOST_TEST_EQ(object_count, 2);
211 BOOST_TEST_EQ(value_count, 2);
212 BOOST_TEST(!y.empty());
213 BOOST_TEST_EQ(&(y=x), &y);
214 BOOST_TEST_EQ(object_count, 2);
215 BOOST_TEST_EQ(value_count, 2);
216 BOOST_TEST(!x.empty());
217 BOOST_TEST(x.has_value(10));
218 BOOST_TEST(!x.has_value(11));
219 BOOST_TEST_EQ(x.value(10).value, 42);
220 BOOST_TEST(!y.empty());
221 BOOST_TEST(y.has_value(10));
222 BOOST_TEST(!y.has_value(11));
223 BOOST_TEST_EQ(y.value(10).value, 42);
224 }
225 BOOST_TEST(!object_count);
226 BOOST_TEST(!value_count);
227 #ifndef BOOST_LEAF_NO_EXCEPTIONS
228 {
229 optional<throws_on_copy> x(10, throws_on_copy());
230 BOOST_TEST_EQ(object_count, 1);
231 BOOST_TEST(!x.empty());
232 BOOST_TEST(x.has_value(10));
233 BOOST_TEST(!x.has_value(11));
234 optional<throws_on_copy> y;
235 try
236 {
237 (void) (y=x);
238 }
239 catch( std::exception & )
240 {
241 }
242 BOOST_TEST_EQ(object_count, 1);
243 BOOST_TEST(!x.empty());
244 BOOST_TEST(x.has_value(10));
245 BOOST_TEST(!x.has_value(11));
246 BOOST_TEST(y.empty());
247 BOOST_TEST(!y.has_value(10));
248 }
249 #endif
250 BOOST_TEST(!object_count);
251 BOOST_TEST(!value_count);
252 {
253 optional<my_info> x(10, my_info(42));
254 BOOST_TEST_EQ(object_count, 1);
255 BOOST_TEST_EQ(value_count, 1);
256 BOOST_TEST(!x.empty());
257 BOOST_TEST(x.has_value(10));
258 BOOST_TEST_EQ(x.value(10).value, 42);
259 optional<my_info> y;
260 BOOST_TEST_EQ(&(y=std::move(x)), &y);
261 BOOST_TEST_EQ(object_count, 1);
262 BOOST_TEST_EQ(value_count, 1);
263 BOOST_TEST(x.empty());
264 BOOST_TEST(!x.has_value(10));
265 BOOST_TEST(!y.empty());
266 BOOST_TEST(y.has_value(10));
267 BOOST_TEST(!y.has_value(11));
268 BOOST_TEST_EQ(y.value(10).value, 42);
269 }
270 BOOST_TEST(!object_count);
271 BOOST_TEST(!value_count);
272 {
273 optional<my_info> x(10, my_info(42));
274 BOOST_TEST_EQ(object_count, 1);
275 BOOST_TEST_EQ(value_count, 1);
276 BOOST_TEST(!x.empty());
277 BOOST_TEST(x.has_value(10));
278 BOOST_TEST(!x.has_value(11));
279 BOOST_TEST_EQ(x.value(10).value, 42);
280 optional<my_info> y(11, my_info(43));
281 BOOST_TEST_EQ(object_count, 2);
282 BOOST_TEST_EQ(value_count, 2);
283 BOOST_TEST(!y.empty());
284 BOOST_TEST_EQ(&(y=std::move(x)), &y);
285 BOOST_TEST_EQ(object_count, 1);
286 BOOST_TEST_EQ(value_count, 1);
287 BOOST_TEST(x.empty());
288 BOOST_TEST(!x.has_value(10));
289 BOOST_TEST(!y.empty());
290 BOOST_TEST(y.has_value(10));
291 BOOST_TEST(!y.has_value(11));
292 BOOST_TEST_EQ(y.value(10).value, 42);
293 }
294 BOOST_TEST(!object_count);
295 BOOST_TEST(!value_count);
296 {
297 optional<my_info> x;
298 my_info a(42);
299 x.put(10, a);
300 BOOST_TEST_EQ(object_count, 2);
301 BOOST_TEST_EQ(value_count, 2);
302 BOOST_TEST(!x.empty());
303 BOOST_TEST(x.has_value(10));
304 BOOST_TEST(!x.has_value(11));
305 BOOST_TEST_EQ(x.value(10).value, 42);
306 }
307 BOOST_TEST(!object_count);
308 BOOST_TEST(!value_count);
309 {
310 optional<my_info> x(10, my_info(43));
311 BOOST_TEST(!x.empty());
312 BOOST_TEST_EQ(object_count, 1);
313 BOOST_TEST_EQ(value_count, 1);
314 my_info a(42);
315 x.put(10, a);
316 BOOST_TEST_EQ(object_count, 2);
317 BOOST_TEST_EQ(value_count, 2);
318 BOOST_TEST(!x.empty());
319 BOOST_TEST(x.has_value(10));
320 BOOST_TEST(!x.has_value(11));
321 BOOST_TEST_EQ(x.value(10).value, 42);
322 }
323 BOOST_TEST(!object_count);
324 BOOST_TEST(!value_count);
325 {
326 optional<my_info> x;
327 BOOST_TEST(x.empty());
328 x.put(10, my_info(42));
329 BOOST_TEST_EQ(object_count, 1);
330 BOOST_TEST_EQ(value_count, 1);
331 BOOST_TEST(!x.empty());
332 BOOST_TEST(x.has_value(10));
333 BOOST_TEST(!x.has_value(11));
334 BOOST_TEST_EQ(x.value(10).value, 42);
335 }
336 BOOST_TEST(!object_count);
337 BOOST_TEST(!value_count);
338 {
339 optional<my_info> x(11, my_info(43));
340 BOOST_TEST(!x.empty());
341 BOOST_TEST_EQ(object_count, 1);
342 BOOST_TEST_EQ(value_count, 1);
343 x.put(10, my_info(42));
344 BOOST_TEST(!x.empty());
345 BOOST_TEST_EQ(object_count, 1);
346 BOOST_TEST_EQ(value_count, 1);
347 BOOST_TEST(x.has_value(10));
348 BOOST_TEST(!x.has_value(11));
349 BOOST_TEST_EQ(x.value(10).value, 42);
350 }
351 BOOST_TEST(!object_count);
352 BOOST_TEST(!value_count);
353 {
354 optional<my_info> x(10, my_info(42));
355 BOOST_TEST_EQ(object_count, 1);
356 BOOST_TEST_EQ(value_count, 1);
357 BOOST_TEST(!x.empty());
358 my_info a = std::move(x).value(10);
359 BOOST_TEST_EQ(object_count, 1);
360 BOOST_TEST_EQ(value_count, 1);
361 BOOST_TEST(x.empty());
362 BOOST_TEST(!x.has_value(10));
363 BOOST_TEST_EQ(a.value, 42);
364 }
365 BOOST_TEST(!object_count);
366 BOOST_TEST(!value_count);
367 {
368 optional<my_info> x(10, my_info(42));
369 BOOST_TEST_EQ(object_count, 1);
370 BOOST_TEST_EQ(value_count, 1);
371 BOOST_TEST(!x.empty());
372 BOOST_TEST(x.has_value(10));
373 BOOST_TEST(!x.has_value(11));
374 x.reset();
375 BOOST_TEST(x.empty());
376 BOOST_TEST(!x.has_value(10));
377 }
378 BOOST_TEST(!object_count);
379 BOOST_TEST(!value_count);
380 }
381
main()382 int main()
383 {
384 run_tests();
385 return boost::report_errors();
386 }
387