]>
Commit | Line | Data |
---|---|---|
82b2e4f8 JW |
1 | // { dg-do run { target c++23 } } |
2 | ||
3 | #include <optional> | |
4 | #include <testsuite_hooks.h> | |
5 | ||
6 | constexpr bool | |
7 | test_or_else() | |
8 | { | |
9 | std::optional<int> o; | |
10 | auto&& r = o.or_else([]() -> std::optional<int> { return {303}; }); | |
11 | VERIFY( !o ); | |
12 | VERIFY( *r == 303 ); | |
13 | static_assert( std::is_same_v<decltype(r), std::optional<int>&&> ); | |
14 | ||
15 | o = 808; | |
16 | const std::optional<int> tr = 909; | |
17 | auto&& r2 = o.or_else([&]() -> const auto& { return tr; }); | |
18 | static_assert( std::is_same_v<decltype(r2), std::optional<int>&&> ); | |
19 | VERIFY( r2 == o ); | |
20 | ||
21 | return true; | |
22 | } | |
23 | ||
24 | static_assert( test_or_else() ); | |
25 | ||
26 | constexpr bool | |
27 | test_move() | |
28 | { | |
29 | struct X | |
30 | { | |
31 | constexpr X() { } | |
32 | constexpr X(const X&) { copied = true; } | |
33 | constexpr X(X&& x) { moved = true; x.gone = true; } | |
34 | ||
35 | bool copied = false; | |
36 | bool moved = false; | |
37 | bool gone = false; | |
38 | }; | |
39 | ||
40 | std::optional<X> o(std::in_place); | |
41 | ||
42 | auto f = []{ return std::optional<X>{}; }; | |
43 | VERIFY( o.or_else(f)->copied ); | |
44 | VERIFY( ! o->gone ); | |
45 | ||
46 | VERIFY( std::move(o).or_else(f)->moved ); | |
47 | VERIFY( o->gone ); | |
48 | ||
49 | struct move_only | |
50 | { | |
51 | constexpr move_only() { } | |
52 | constexpr move_only(move_only&&) { } | |
53 | }; | |
54 | ||
55 | std::optional<move_only> mo; | |
56 | // doesn't require copy | |
57 | std::move(mo).or_else([] { return std::optional<move_only>{}; }); | |
58 | ||
59 | return true; | |
60 | } | |
61 | ||
62 | static_assert( test_move() ); | |
63 | ||
64 | constexpr bool | |
65 | test_call() | |
66 | { | |
67 | struct F | |
68 | { | |
69 | constexpr std::optional<int> operator()() & { return {1}; } | |
70 | constexpr std::optional<int> operator()() && { return {2}; } | |
71 | constexpr std::optional<int> operator()() const & { return {3}; }; | |
72 | constexpr std::optional<int> operator()() const && { return {4}; } | |
73 | }; | |
74 | ||
75 | std::optional<int> o; | |
76 | F f; | |
77 | ||
78 | VERIFY( *o.or_else(f) == 1 ); | |
79 | VERIFY( *std::move(o).or_else(f) == 1 ); | |
80 | ||
81 | VERIFY( *o.or_else(std::move(f)) == 2 ); | |
82 | VERIFY( *std::move(o).or_else(std::move(f)) == 2 ); | |
83 | ||
84 | const F& cf = f; | |
85 | ||
86 | VERIFY( *o.or_else(cf) == 3 ); | |
87 | VERIFY( *std::move(o).or_else(cf) == 3 ); | |
88 | ||
89 | VERIFY( *o.or_else(std::move(cf)) == 4 ); | |
90 | VERIFY( *std::move(o).or_else(std::move(cf)) == 4 ); | |
91 | ||
92 | return true; | |
93 | } | |
94 | ||
95 | static_assert( test_call() ); | |
96 | ||
97 | int main() | |
98 | { | |
99 | test_or_else(); | |
100 | test_move(); | |
101 | test_call(); | |
102 | } |