1 | // Copyright 2017, 2021, 2022 Peter Dimov. |
2 | // Distributed under the Boost Software License, Version 1.0. |
3 | // https://www.boost.org/LICENSE_1_0.txt |
4 | |
5 | #include <boost/system/result.hpp> |
6 | #include <boost/core/lightweight_test.hpp> |
7 | #include <cerrno> |
8 | |
9 | using namespace boost::system; |
10 | |
11 | struct X |
12 | { |
13 | static int instances; |
14 | |
15 | int v_; |
16 | |
17 | explicit X( int v ): v_( v ) { ++instances; } |
18 | |
19 | X( int v1, int v2 ): v_( v1+v2 ) { ++instances; } |
20 | X( int v1, int v2, int v3 ): v_( v1+v2+v3 ) { ++instances; } |
21 | |
22 | X( X const& ) = delete; |
23 | X& operator=( X const& ) = delete; |
24 | |
25 | ~X() { --instances; } |
26 | }; |
27 | |
28 | int X::instances = 0; |
29 | |
30 | struct Y |
31 | { |
32 | static int instances; |
33 | |
34 | Y() noexcept { ++instances; } |
35 | |
36 | Y( Y const& ) noexcept { ++instances; } |
37 | |
38 | Y& operator=( Y const& ) = default; |
39 | |
40 | ~Y() { --instances; } |
41 | }; |
42 | |
43 | int Y::instances = 0; |
44 | |
45 | int main() |
46 | { |
47 | { |
48 | result<int> r; |
49 | |
50 | BOOST_TEST( r.has_value() ); |
51 | |
52 | r.emplace( a: 1 ); |
53 | |
54 | BOOST_TEST( r.has_value() ); |
55 | BOOST_TEST_EQ( r.value(), 1 ); |
56 | } |
57 | |
58 | { |
59 | result<int> r( ENOENT, generic_category() ); |
60 | |
61 | BOOST_TEST( !r.has_value() ); |
62 | |
63 | r.emplace( a: 1 ); |
64 | |
65 | BOOST_TEST( r.has_value() ); |
66 | BOOST_TEST_EQ( r.value(), 1 ); |
67 | } |
68 | |
69 | BOOST_TEST_EQ( X::instances, 0 ); |
70 | |
71 | { |
72 | result<X> r( 0 ); |
73 | |
74 | BOOST_TEST( r.has_value() ); |
75 | BOOST_TEST_EQ( r.value().v_, 0 ); |
76 | BOOST_TEST_EQ( X::instances, 1 ); |
77 | |
78 | r.emplace( a: 1 ); |
79 | BOOST_TEST( r.has_value() ); |
80 | BOOST_TEST_EQ( r.value().v_, 1 ); |
81 | BOOST_TEST_EQ( X::instances, 1 ); |
82 | |
83 | r.emplace( a: 1, a: 2 ); |
84 | BOOST_TEST( r.has_value() ); |
85 | BOOST_TEST_EQ( r.value().v_, 1+2 ); |
86 | BOOST_TEST_EQ( X::instances, 1 ); |
87 | |
88 | r.emplace( a: 1, a: 2, a: 3 ); |
89 | BOOST_TEST( r.has_value() ); |
90 | BOOST_TEST_EQ( r.value().v_, 1+2+3 ); |
91 | BOOST_TEST_EQ( X::instances, 1 ); |
92 | } |
93 | |
94 | BOOST_TEST_EQ( X::instances, 0 ); |
95 | |
96 | { |
97 | result<X> r( ENOENT, generic_category() ); |
98 | |
99 | BOOST_TEST( !r.has_value() ); |
100 | BOOST_TEST_EQ( X::instances, 0 ); |
101 | |
102 | r.emplace( a: 1, a: 2 ); |
103 | BOOST_TEST( r.has_value() ); |
104 | BOOST_TEST_EQ( r.value().v_, 1+2 ); |
105 | BOOST_TEST_EQ( X::instances, 1 ); |
106 | } |
107 | |
108 | BOOST_TEST_EQ( X::instances, 0 ); |
109 | BOOST_TEST_EQ( Y::instances, 0 ); |
110 | |
111 | { |
112 | result<int, Y> r( Y{} ); |
113 | |
114 | BOOST_TEST( !r.has_value() ); |
115 | BOOST_TEST_EQ( Y::instances, 1 ); |
116 | |
117 | r.emplace( a: 1 ); |
118 | BOOST_TEST( r.has_value() ); |
119 | BOOST_TEST_EQ( *r, 1 ); |
120 | BOOST_TEST_EQ( Y::instances, 0 ); |
121 | } |
122 | |
123 | BOOST_TEST_EQ( X::instances, 0 ); |
124 | BOOST_TEST_EQ( Y::instances, 0 ); |
125 | |
126 | { |
127 | result<X, Y> r( in_place_error ); |
128 | |
129 | BOOST_TEST( !r.has_value() ); |
130 | BOOST_TEST_EQ( X::instances, 0 ); |
131 | BOOST_TEST_EQ( Y::instances, 1 ); |
132 | |
133 | r.emplace( a: 1, a: 2, a: 3 ); |
134 | |
135 | BOOST_TEST( r.has_value() ); |
136 | BOOST_TEST_EQ( r->v_, 1+2+3 ); |
137 | BOOST_TEST_EQ( X::instances, 1 ); |
138 | BOOST_TEST_EQ( Y::instances, 0 ); |
139 | } |
140 | |
141 | BOOST_TEST_EQ( X::instances, 0 ); |
142 | BOOST_TEST_EQ( Y::instances, 0 ); |
143 | |
144 | { |
145 | result<void> r; |
146 | |
147 | BOOST_TEST( r.has_value() ); |
148 | |
149 | r.emplace(); |
150 | BOOST_TEST( r.has_value() ); |
151 | } |
152 | |
153 | { |
154 | result<void> r( ENOENT, generic_category() ); |
155 | |
156 | BOOST_TEST( !r.has_value() ); |
157 | |
158 | r.emplace(); |
159 | BOOST_TEST( r.has_value() ); |
160 | } |
161 | |
162 | BOOST_TEST_EQ( Y::instances, 0 ); |
163 | |
164 | { |
165 | result<void, Y> r( in_place_error ); |
166 | |
167 | BOOST_TEST( !r.has_value() ); |
168 | BOOST_TEST_EQ( Y::instances, 1 ); |
169 | |
170 | r.emplace(); |
171 | BOOST_TEST( r.has_value() ); |
172 | BOOST_TEST_EQ( Y::instances, 0 ); |
173 | } |
174 | |
175 | { |
176 | int x1 = 1; |
177 | result<int&> r( x1 ); |
178 | |
179 | BOOST_TEST( r.has_value() ); |
180 | BOOST_TEST_EQ( r.value(), 1 ); |
181 | |
182 | int x2 = 2; |
183 | r.emplace( a&: x2 ); |
184 | |
185 | BOOST_TEST( r.has_value() ); |
186 | BOOST_TEST_EQ( r.value(), 2 ); |
187 | } |
188 | |
189 | { |
190 | result<int&> r( ENOENT, generic_category() ); |
191 | |
192 | BOOST_TEST( !r.has_value() ); |
193 | |
194 | int x2 = 2; |
195 | r.emplace( a&: x2 ); |
196 | |
197 | BOOST_TEST( r.has_value() ); |
198 | BOOST_TEST_EQ( r.value(), 2 ); |
199 | } |
200 | |
201 | BOOST_TEST_EQ( Y::instances, 0 ); |
202 | |
203 | { |
204 | result<int&, Y> r( in_place_error ); |
205 | |
206 | BOOST_TEST( !r.has_value() ); |
207 | BOOST_TEST_EQ( Y::instances, 1 ); |
208 | |
209 | int x2 = 2; |
210 | r.emplace( a&: x2 ); |
211 | |
212 | BOOST_TEST( r.has_value() ); |
213 | BOOST_TEST_EQ( *r, 2 ); |
214 | BOOST_TEST_EQ( Y::instances, 0 ); |
215 | } |
216 | |
217 | return boost::report_errors(); |
218 | } |
219 | |