1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <memory>
6
7 #include <lib/fit/nullable.h>
8 #include <unittest/unittest.h>
9
10 namespace {
11
12 struct null_comparable_struct {
13 int value = 0;
14
operator ==__anon7307f0470111::null_comparable_struct15 constexpr bool operator==(decltype(nullptr)) const { return value == -1; }
16 };
17
18 struct nullable_struct {
19 int value = 0;
20
21 constexpr nullable_struct() = default;
nullable_struct__anon7307f0470111::nullable_struct22 constexpr nullable_struct(int value)
23 : value(value) {}
nullable_struct__anon7307f0470111::nullable_struct24 constexpr explicit nullable_struct(decltype(nullptr))
25 : value(-1) {}
26 nullable_struct(const nullable_struct& other) = default;
27 nullable_struct(nullable_struct&& other) = default;
28
get__anon7307f0470111::nullable_struct29 constexpr int get() const { return value; }
increment__anon7307f0470111::nullable_struct30 constexpr int increment() { return ++value; }
31
operator ==__anon7307f0470111::nullable_struct32 constexpr bool operator==(decltype(nullptr)) const { return value == -1; }
operator ==__anon7307f0470111::nullable_struct33 constexpr bool operator==(const nullable_struct& other) const { return value == other.value; }
operator !=__anon7307f0470111::nullable_struct34 constexpr bool operator!=(const nullable_struct& other) const { return value != other.value; }
35
36 nullable_struct& operator=(const nullable_struct& other) = default;
37 nullable_struct& operator=(nullable_struct&& other) = default;
operator =__anon7307f0470111::nullable_struct38 nullable_struct& operator=(decltype(nullptr)) {
39 value = -1;
40 return *this;
41 }
42 };
43
44 struct non_nullable_struct_missing_constructor {
45 int value = 0;
46
47 constexpr non_nullable_struct_missing_constructor() = default;
operator =__anon7307f0470111::non_nullable_struct_missing_constructor48 constexpr non_nullable_struct_missing_constructor& operator=(decltype(nullptr)) {
49 value = -1;
50 return *this;
51 }
52
operator ==__anon7307f0470111::non_nullable_struct_missing_constructor53 constexpr bool operator==(decltype(nullptr)) const { return value == -1; }
54 };
55
56 struct non_nullable_struct_missing_assignment {
57 int value = 0;
58
59 constexpr non_nullable_struct_missing_assignment() = default;
non_nullable_struct_missing_assignment__anon7307f0470111::non_nullable_struct_missing_assignment60 constexpr explicit non_nullable_struct_missing_assignment(decltype(nullptr))
61 : value(-1) {}
62
operator ==__anon7307f0470111::non_nullable_struct_missing_assignment63 constexpr bool operator==(decltype(nullptr)) const { return value == -1; }
64 };
65
66 struct non_nullable_struct_missing_comparator {
67 int value = 0;
68
69 constexpr non_nullable_struct_missing_comparator() = default;
non_nullable_struct_missing_comparator__anon7307f0470111::non_nullable_struct_missing_comparator70 constexpr explicit non_nullable_struct_missing_comparator(decltype(nullptr))
71 : value(-1) {}
72
operator =__anon7307f0470111::non_nullable_struct_missing_comparator73 non_nullable_struct_missing_comparator& operator=(decltype(nullptr)) {
74 value = -1;
75 return *this;
76 }
77 };
78
79 struct non_nullable_struct {
80 int value = 0;
81
82 constexpr non_nullable_struct() = default;
non_nullable_struct__anon7307f0470111::non_nullable_struct83 constexpr non_nullable_struct(int value)
84 : value(value) {}
85 non_nullable_struct(const non_nullable_struct& other) = default;
86 non_nullable_struct(non_nullable_struct&& other) = default;
87
get__anon7307f0470111::non_nullable_struct88 constexpr int get() const { return value; }
increment__anon7307f0470111::non_nullable_struct89 constexpr int increment() { return ++value; }
90
operator ==__anon7307f0470111::non_nullable_struct91 constexpr bool operator==(const non_nullable_struct& other) const { return value == other.value; }
operator !=__anon7307f0470111::non_nullable_struct92 constexpr bool operator!=(const non_nullable_struct& other) const { return value != other.value; }
93
94 non_nullable_struct& operator=(const non_nullable_struct& other) = default;
95 non_nullable_struct& operator=(non_nullable_struct&& other) = default;
96 };
97
98 struct non_nullable_struct_with_non_bool_comparator {
99 int value = 0;
100
operator ==__anon7307f0470111::non_nullable_struct_with_non_bool_comparator101 constexpr void operator==(decltype(nullptr)) const {}
102 };
103
104 // Some values of type void* that we can compare.
105 int item_a = 0;
106 int item_b = 0;
107 constexpr void* void_a = &item_a;
108 constexpr void* void_b = &item_b;
109 constexpr void* void_null = nullptr;
110
111 // Function and lambda types are never nullable.
function(float,bool)112 void function(float, bool) {}
__anon7307f0470202(float, bool) 113 auto lambda = [](float, bool) { return 0; };
114
115 // Test is_comparable_with_null.
116 static_assert(!fit::is_comparable_with_null<void>::value, "");
117 static_assert(!fit::is_comparable_with_null<int>::value, "");
118 static_assert(!fit::is_comparable_with_null<non_nullable_struct>::value, "");
119 static_assert(!fit::is_comparable_with_null<non_nullable_struct_missing_comparator>::value, "");
120 static_assert(fit::is_comparable_with_null<decltype(nullptr)>::value, "");
121 static_assert(fit::is_comparable_with_null<void*>::value, "");
122 static_assert(fit::is_comparable_with_null<null_comparable_struct>::value, "");
123 static_assert(fit::is_comparable_with_null<nullable_struct>::value, "");
124 static_assert(fit::is_comparable_with_null<fit::nullable<int>>::value, "");
125 static_assert(fit::is_comparable_with_null<fit::nullable<void*>>::value, "");
126 static_assert(fit::is_comparable_with_null<std::unique_ptr<int>>::value, "");
127 static_assert(fit::is_comparable_with_null<decltype(function)>::value, "");
128 static_assert(fit::is_comparable_with_null<decltype(&function)>::value, "");
129 static_assert(fit::is_comparable_with_null<decltype(lambda)>::value, "");
130 static_assert(fit::is_comparable_with_null<decltype(&lambda)>::value, "");
131
132 // Test is_nullable.
133 static_assert(!fit::is_nullable<void>::value, "");
134 static_assert(!fit::is_nullable<int>::value, "");
135 static_assert(!fit::is_nullable<non_nullable_struct>::value, "");
136 static_assert(!fit::is_nullable<non_nullable_struct_missing_constructor>::value, "");
137 static_assert(!fit::is_nullable<non_nullable_struct_missing_assignment>::value, "");
138 static_assert(!fit::is_nullable<non_nullable_struct_missing_comparator>::value, "");
139 static_assert(!fit::is_nullable<null_comparable_struct>::value, "");
140 static_assert(fit::is_nullable<decltype(nullptr)>::value, "");
141 static_assert(fit::is_nullable<void*>::value, "");
142 static_assert(fit::is_nullable<nullable_struct>::value, "");
143 static_assert(fit::is_nullable<fit::nullable<int>>::value, "");
144 static_assert(fit::is_nullable<fit::nullable<void*>>::value, "");
145 static_assert(fit::is_nullable<std::unique_ptr<int>>::value, "");
146 static_assert(!fit::is_nullable<decltype(function)>::value, "");
147 static_assert(fit::is_nullable<decltype(&function)>::value, "");
148 static_assert(!fit::is_nullable<decltype(lambda)>::value, "");
149 static_assert(fit::is_nullable<decltype(&lambda)>::value, "");
150
151 // Test is_null.
152 static_assert(fit::is_null(nullptr), "");
153 static_assert(fit::is_null(void_null), "");
154 static_assert(fit::is_null(fit::nullable<void*>(nullptr)), "");
155 static_assert(!fit::is_null(void_a), "");
156 static_assert(!fit::is_null(fit::nullable<void*>(void_a)), "");
157 static_assert(!fit::is_null(5), "");
158 static_assert(!fit::is_null(function), "");
159 static_assert(!fit::is_null(&function), "");
160 static_assert(!fit::is_null(lambda), "");
161 static_assert(!fit::is_null(&lambda), "");
162
163 // Test nullable::value_type.
164 static_assert(std::is_same<int, fit::nullable<int>::value_type>::value, "");
165 static_assert(std::is_same<void*, fit::nullable<void*>::value_type>::value, "");
166 static_assert(std::is_same<decltype(&function),
167 fit::nullable<decltype(&function)>::value_type>::value,
168 "");
169
170 // Test constexpr comparators for nullable.
171 static_assert(!fit::nullable<void*>(), "");
172 static_assert(!fit::nullable<void*>().has_value(), "");
173 static_assert(fit::nullable<void*>() == nullptr, "");
174 static_assert(!fit::nullable<void*>(nullptr), "");
175 static_assert(!fit::nullable<void*>(nullptr).has_value(), "");
176 static_assert(!fit::nullable<void*>(void_null), "");
177 static_assert(!fit::nullable<void*>(void_null).has_value(), "");
178 static_assert(fit::nullable<void*>(void_a), "");
179 static_assert(fit::nullable<void*>(void_a).has_value(), "");
180
181 static_assert(fit::nullable<void*>(void_null) == nullptr, "");
182 static_assert(nullptr == fit::nullable<void*>(void_null), "");
183 static_assert(!(fit::nullable<void*>(void_a) == nullptr), "");
184 static_assert(!(nullptr == fit::nullable<void*>(void_a)), "");
185
186 static_assert(!(fit::nullable<void*>(void_null) != nullptr), "");
187 static_assert(!(nullptr != fit::nullable<void*>(void_null)), "");
188 static_assert(fit::nullable<void*>(void_a) != nullptr, "");
189 static_assert(nullptr != fit::nullable<void*>(void_a), "");
190
191 static_assert(fit::nullable<void*>(void_a) == fit::nullable<void*>(void_a), "");
192 static_assert(fit::nullable<void*>(void_null) == fit::nullable<void*>(void_null), "");
193 static_assert(!(fit::nullable<void*>(void_a) == fit::nullable<void*>(void_b)), "");
194 static_assert(!(fit::nullable<void*>(void_a) == fit::nullable<void*>(void_null)), "");
195 static_assert(!(fit::nullable<void*>(void_null) == fit::nullable<void*>(void_a)), "");
196
197 static_assert(!(fit::nullable<void*>(void_a) != fit::nullable<void*>(void_a)), "");
198 static_assert(!(fit::nullable<void*>(void_null) != fit::nullable<void*>(void_null)), "");
199 static_assert(fit::nullable<void*>(void_a) != fit::nullable<void*>(void_b), "");
200 static_assert(fit::nullable<void*>(void_a) != fit::nullable<void*>(void_null), "");
201 static_assert(fit::nullable<void*>(void_null) != fit::nullable<void*>(void_a), "");
202
203 static_assert(fit::nullable<void*>(void_a) == void_a, "");
204 static_assert(fit::nullable<void*>(void_null) == void_null, "");
205 static_assert(!(fit::nullable<void*>(void_a) == void_b), "");
206 static_assert(!(fit::nullable<void*>(void_a) == void_null), "");
207 static_assert(!(fit::nullable<void*>(void_null) == void_a), "");
208
209 static_assert(void_a == fit::nullable<void*>(void_a), "");
210 static_assert(void_null == fit::nullable<void*>(void_null), "");
211 static_assert(!(void_a == fit::nullable<void*>(void_b)), "");
212 static_assert(!(void_a == fit::nullable<void*>(void_null)), "");
213 static_assert(!(void_null == fit::nullable<void*>(void_a)), "");
214
215 static_assert(!(fit::nullable<void*>(void_a) != void_a), "");
216 static_assert(!(fit::nullable<void*>(void_null) != void_null), "");
217 static_assert(fit::nullable<void*>(void_a) != void_b, "");
218 static_assert(fit::nullable<void*>(void_a) != void_null, "");
219 static_assert(fit::nullable<void*>(void_null) != void_a, "");
220
221 static_assert(!(void_a != fit::nullable<void*>(void_a)), "");
222 static_assert(!(void_null != fit::nullable<void*>(void_null)), "");
223 static_assert(void_a != fit::nullable<void*>(void_b), "");
224 static_assert(void_a != fit::nullable<void*>(void_null), "");
225 static_assert(void_null != fit::nullable<void*>(void_a), "");
226
227 // TODO(US-90): Unfortunately fit::optional is not a literal type unlike
228 // std::optional so values of type fit::nullable<T> when T is not nullable
229 // are also not literal. Once we fix fit::optional to allow literal types,
230 // we can add constexpr tests for those types.
231 // e.g. fit::nullable<int>.
232
is_null()233 bool is_null() {
234 BEGIN_TEST;
235
236 EXPECT_TRUE(fit::is_null(nullptr));
237
238 null_comparable_struct ncf;
239 EXPECT_FALSE(fit::is_null(ncf));
240
241 null_comparable_struct nct{-1};
242 EXPECT_TRUE(fit::is_null(nct));
243
244 nullable_struct nf;
245 EXPECT_FALSE(fit::is_null(nf));
246
247 nullable_struct nt(nullptr);
248 EXPECT_TRUE(fit::is_null(nt));
249
250 fit::nullable<int> nif(1);
251 EXPECT_FALSE(fit::is_null(nif));
252
253 fit::nullable<int> nit(nullptr);
254 EXPECT_TRUE(fit::is_null(nit));
255
256 fit::nullable<void*> npf(&nit);
257 EXPECT_FALSE(fit::is_null(npf));
258
259 fit::nullable<void*> npt(nullptr);
260 EXPECT_TRUE(fit::is_null(npt));
261
262 non_nullable_struct nn;
263 EXPECT_FALSE(fit::is_null(nn));
264
265 non_nullable_struct_with_non_bool_comparator nbn;
266 EXPECT_FALSE(fit::is_null(nbn));
267
268 END_TEST;
269 }
270
271 template <typename T>
272 struct traits;
273
274 template <>
275 struct traits<nullable_struct> {
276 static constexpr nullable_struct a{42};
277 static constexpr nullable_struct b{55};
278 static constexpr nullable_struct null{-1};
279 };
280
281 template <>
282 struct traits<non_nullable_struct> {
283 static constexpr non_nullable_struct a{42};
284 static constexpr non_nullable_struct b{55};
285 static constexpr nullptr_t null = nullptr;
286 };
287
288 template <typename T>
construct_without_value()289 bool construct_without_value() {
290 BEGIN_TEST;
291
292 fit::nullable<T> opt;
293 EXPECT_FALSE(opt.has_value());
294 EXPECT_FALSE(!!opt);
295
296 EXPECT_EQ(42, opt.value_or(traits<T>::a).value);
297
298 opt.reset();
299 EXPECT_FALSE(opt.has_value());
300
301 END_TEST;
302 }
303
304 template <typename T>
construct_with_value()305 bool construct_with_value() {
306 BEGIN_TEST;
307
308 fit::nullable<T> opt(traits<T>::a);
309 EXPECT_TRUE(opt.has_value());
310 EXPECT_TRUE(!!opt);
311
312 EXPECT_EQ(42, opt.value().value);
313 EXPECT_EQ(42, opt.value_or(traits<T>::b).value);
314
315 EXPECT_EQ(42, opt->get());
316 EXPECT_EQ(43, opt->increment());
317 EXPECT_EQ(43, opt->get());
318
319 opt.reset();
320 EXPECT_FALSE(opt.has_value());
321
322 END_TEST;
323 }
324
325 template <typename T>
construct_copy()326 bool construct_copy() {
327 BEGIN_TEST;
328
329 fit::nullable<T> a(traits<T>::a);
330 fit::nullable<T> b(a);
331 fit::nullable<T> c;
332 fit::nullable<T> d(c);
333 fit::nullable<T> e(traits<T>::null);
334 EXPECT_TRUE(a.has_value());
335 EXPECT_EQ(42, a.value().value);
336 EXPECT_TRUE(b.has_value());
337 EXPECT_EQ(42, b.value().value);
338 EXPECT_FALSE(c.has_value());
339 EXPECT_FALSE(d.has_value());
340 EXPECT_FALSE(e.has_value());
341
342 END_TEST;
343 }
344
345 template <typename T>
construct_move()346 bool construct_move() {
347 BEGIN_TEST;
348
349 fit::nullable<T> a(traits<T>::a);
350 fit::nullable<T> b(std::move(a));
351 fit::nullable<T> c;
352 fit::nullable<T> d(std::move(c));
353 EXPECT_FALSE(a.has_value());
354 EXPECT_TRUE(b.has_value());
355 EXPECT_EQ(42, b.value().value);
356 EXPECT_FALSE(c.has_value());
357 EXPECT_FALSE(d.has_value());
358
359 END_TEST;
360 }
361
362 template <typename T>
accessors()363 bool accessors() {
364 BEGIN_TEST;
365
366 fit::nullable<T> a(traits<T>::a);
367 T& value = a.value();
368 EXPECT_EQ(42, value.value);
369
370 const T& const_value = const_cast<const decltype(a)&>(a).value();
371 EXPECT_EQ(42, const_value.value);
372
373 T rvalue = fit::nullable<T>(traits<T>::a).value();
374 EXPECT_EQ(42, rvalue.value);
375
376 T const_rvalue = const_cast<const fit::nullable<T>&&>(
377 fit::nullable<T>(traits<T>::a))
378 .value();
379 EXPECT_EQ(42, const_rvalue.value);
380
381 END_TEST;
382 }
383
384 template <typename T>
assign()385 bool assign() {
386 BEGIN_TEST;
387
388 fit::nullable<T> a(traits<T>::a);
389 EXPECT_TRUE(a.has_value());
390 EXPECT_EQ(42, a.value().value);
391
392 a = traits<T>::b;
393 EXPECT_TRUE(a.has_value());
394 EXPECT_EQ(55, a.value().value);
395
396 a.reset();
397 EXPECT_FALSE(a.has_value());
398
399 a = traits<T>::a;
400 EXPECT_TRUE(a.has_value());
401 EXPECT_EQ(42, a.value().value);
402
403 a = nullptr;
404 EXPECT_FALSE(a.has_value());
405
406 a = traits<T>::a;
407 a = traits<T>::null;
408 EXPECT_FALSE(a.has_value());
409
410 END_TEST;
411 }
412
413 template <typename T>
assign_copy()414 bool assign_copy() {
415 BEGIN_TEST;
416
417 fit::nullable<T> a(traits<T>::a);
418 fit::nullable<T> b(traits<T>::b);
419 fit::nullable<T> c;
420 EXPECT_TRUE(a.has_value());
421 EXPECT_EQ(42, a.value().value);
422 EXPECT_TRUE(b.has_value());
423 EXPECT_EQ(55, b.value().value);
424 EXPECT_FALSE(c.has_value());
425
426 a = b;
427 EXPECT_TRUE(a.has_value());
428 EXPECT_EQ(55, b.value().value);
429 EXPECT_TRUE(b.has_value());
430 EXPECT_EQ(55, b.value().value);
431
432 b = c;
433 EXPECT_FALSE(b.has_value());
434 EXPECT_FALSE(c.has_value());
435
436 b = a;
437 EXPECT_TRUE(b.has_value());
438 EXPECT_EQ(55, b.value().value);
439 EXPECT_TRUE(a.has_value());
440 EXPECT_EQ(55, b.value().value);
441
442 #ifdef __clang__
443 #pragma clang diagnostic push
444 #pragma clang diagnostic ignored "-Wself-assign-overloaded"
445 #endif
446
447 b = b;
448 EXPECT_TRUE(b.has_value());
449 EXPECT_EQ(55, b.value().value);
450
451 c = c;
452 EXPECT_FALSE(c.has_value());
453
454 #ifdef __clang__
455 #pragma clang diagnostic pop
456 #endif
457
458 b = traits<T>::null;
459 EXPECT_FALSE(b.has_value());
460
461 END_TEST;
462 }
463
464 template <typename T>
assign_move()465 bool assign_move() {
466 BEGIN_TEST;
467
468 fit::nullable<T> a(traits<T>::a);
469 fit::nullable<T> b(traits<T>::b);
470 fit::nullable<T> c;
471 EXPECT_TRUE(a.has_value());
472 EXPECT_EQ(42, a.value().value);
473 EXPECT_TRUE(b.has_value());
474 EXPECT_EQ(55, b.value().value);
475 EXPECT_FALSE(c.has_value());
476
477 a = std::move(b);
478 EXPECT_TRUE(a.has_value());
479 EXPECT_EQ(55, a.value().value);
480 EXPECT_FALSE(b.has_value());
481
482 b = std::move(c);
483 EXPECT_FALSE(b.has_value());
484 EXPECT_FALSE(c.has_value());
485
486 c = std::move(b);
487 EXPECT_FALSE(c.has_value());
488 EXPECT_FALSE(b.has_value());
489
490 b = std::move(a);
491 EXPECT_TRUE(b.has_value());
492 EXPECT_EQ(55, b.value().value);
493 EXPECT_FALSE(a.has_value());
494
495 b = std::move(b);
496 EXPECT_TRUE(b.has_value());
497 EXPECT_EQ(55, b.value().value);
498
499 a = std::move(a);
500 EXPECT_FALSE(a.has_value());
501
502 END_TEST;
503 }
504
505 template <typename T>
invoke()506 bool invoke() {
507 BEGIN_TEST;
508
509 fit::nullable<T> a(traits<T>::a);
510 EXPECT_EQ(42, a->get());
511 EXPECT_EQ(43, a->increment());
512 EXPECT_EQ(43, (*a).value);
513
514 END_TEST;
515 }
516
517 template <typename T>
comparisons()518 bool comparisons() {
519 BEGIN_TEST;
520
521 fit::nullable<T> a(traits<T>::a);
522 fit::nullable<T> b(traits<T>::b);
523 fit::nullable<T> c(traits<T>::a);
524 fit::nullable<T> d;
525 fit::nullable<T> e(traits<T>::null);
526
527 EXPECT_FALSE(a == b);
528 EXPECT_TRUE(a == c);
529 EXPECT_FALSE(a == d);
530 EXPECT_TRUE(d == e);
531 EXPECT_FALSE(d == a);
532
533 EXPECT_FALSE(a == nullptr);
534 EXPECT_FALSE(nullptr == a);
535 EXPECT_TRUE(a == traits<T>::a);
536 EXPECT_TRUE(traits<T>::a == a);
537 EXPECT_FALSE(a == traits<T>::b);
538 EXPECT_FALSE(traits<T>::b == a);
539 EXPECT_FALSE(d == traits<T>::a);
540 EXPECT_FALSE(traits<T>::b == d);
541 EXPECT_TRUE(d == nullptr);
542 EXPECT_TRUE(nullptr == d);
543
544 EXPECT_TRUE(a != b);
545 EXPECT_FALSE(a != c);
546 EXPECT_TRUE(a != d);
547 EXPECT_FALSE(d != e);
548 EXPECT_TRUE(d != a);
549
550 EXPECT_TRUE(a != nullptr);
551 EXPECT_TRUE(nullptr != a);
552 EXPECT_FALSE(a != traits<T>::a);
553 EXPECT_FALSE(traits<T>::a != a);
554 EXPECT_TRUE(a != traits<T>::b);
555 EXPECT_TRUE(traits<T>::b != a);
556 EXPECT_TRUE(d != traits<T>::a);
557 EXPECT_TRUE(traits<T>::a != d);
558 EXPECT_FALSE(d != nullptr);
559 EXPECT_FALSE(nullptr != d);
560
561 END_TEST;
562 }
563
564 template <typename T>
swapping()565 bool swapping() {
566 BEGIN_TEST;
567
568 fit::nullable<T> a(traits<T>::a);
569 fit::nullable<T> b(traits<T>::b);
570 fit::nullable<T> c;
571 fit::nullable<T> d;
572
573 swap(a, b);
574 EXPECT_TRUE(a.has_value());
575 EXPECT_EQ(55, a.value().value);
576 EXPECT_TRUE(b.has_value());
577 EXPECT_EQ(42, b.value().value);
578
579 swap(a, c);
580 EXPECT_FALSE(a.has_value());
581 EXPECT_TRUE(c.has_value());
582 EXPECT_EQ(55, c.value().value);
583
584 swap(d, c);
585 EXPECT_FALSE(c.has_value());
586 EXPECT_TRUE(d.has_value());
587 EXPECT_EQ(55, d.value().value);
588
589 swap(c, a);
590 EXPECT_FALSE(c.has_value());
591 EXPECT_FALSE(a.has_value());
592
593 swap(a, a);
594 EXPECT_FALSE(a.has_value());
595
596 swap(d, d);
597 EXPECT_TRUE(d.has_value());
598 EXPECT_EQ(55, d.value().value);
599
600 END_TEST;
601 }
602
603 } // namespace
604
605 BEGIN_TEST_CASE(nullable_tests)
606 RUN_TEST(is_null)
607 RUN_TEST(construct_without_value<nullable_struct>)
608 RUN_TEST(construct_without_value<non_nullable_struct>)
609 RUN_TEST(construct_with_value<nullable_struct>)
610 RUN_TEST(construct_with_value<non_nullable_struct>)
611 RUN_TEST(construct_copy<nullable_struct>)
612 RUN_TEST(construct_copy<non_nullable_struct>)
613 RUN_TEST(construct_move<nullable_struct>)
614 RUN_TEST(construct_move<non_nullable_struct>)
615 RUN_TEST(accessors<nullable_struct>)
616 RUN_TEST(accessors<non_nullable_struct>)
617 RUN_TEST(assign<nullable_struct>)
618 RUN_TEST(assign<non_nullable_struct>)
619 RUN_TEST(assign_copy<nullable_struct>)
620 RUN_TEST(assign_copy<non_nullable_struct>)
621 RUN_TEST(assign_move<nullable_struct>)
622 RUN_TEST(assign_move<non_nullable_struct>)
623 RUN_TEST(invoke<nullable_struct>)
624 RUN_TEST(invoke<non_nullable_struct>)
625 RUN_TEST(comparisons<nullable_struct>)
626 RUN_TEST(comparisons<non_nullable_struct>)
627 RUN_TEST(swapping<nullable_struct>)
628 RUN_TEST(swapping<non_nullable_struct>)
629 END_TEST_CASE(nullable_tests)
630