]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/optional/test/optional_test_move.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / optional / test / optional_test_move.cpp
1 // Copyright (C) 2014 - 2015 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
13 #include "boost/optional/optional.hpp"
14
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18
19 #include "boost/core/lightweight_test.hpp"
20
21 using boost::optional;
22 using boost::none;
23
24 //#ifndef BOOST_OPTIONAL_NO_CONVERTING_ASSIGNMENT
25 //#ifndef BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR
26
27 #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
28
29 enum State
30 {
31 sDefaultConstructed,
32 sValueCopyConstructed,
33 sValueMoveConstructed,
34 sCopyConstructed,
35 sMoveConstructed,
36 sMoveAssigned,
37 sCopyAssigned,
38 sValueCopyAssigned,
39 sValueMoveAssigned,
40 sMovedFrom,
41 sIntConstructed
42 };
43
44 struct OracleVal
45 {
46 State s;
47 int i;
48 OracleVal(int i = 0) : s(sIntConstructed), i(i) {}
49 };
50
51
52 struct Oracle
53 {
54 State s;
55 OracleVal val;
56
57 Oracle() : s(sDefaultConstructed) {}
58 Oracle(const OracleVal& v) : s(sValueCopyConstructed), val(v) {}
59 Oracle(OracleVal&& v) : s(sValueMoveConstructed), val(std::move(v)) {v.s = sMovedFrom;}
60 Oracle(const Oracle& o) : s(sCopyConstructed), val(o.val) {}
61 Oracle(Oracle&& o) : s(sMoveConstructed), val(std::move(o.val)) {o.s = sMovedFrom;}
62
63 Oracle& operator=(const OracleVal& v) { s = sValueCopyAssigned; val = v; return *this; }
64 Oracle& operator=(OracleVal&& v) { s = sValueMoveAssigned; val = std::move(v); v.s = sMovedFrom; return *this; }
65 Oracle& operator=(const Oracle& o) { s = sCopyAssigned; val = o.val; return *this; }
66 Oracle& operator=(Oracle&& o) { s = sMoveAssigned; val = std::move(o.val); o.s = sMovedFrom; return *this; }
67 };
68
69 bool operator==( Oracle const& a, Oracle const& b ) { return a.val.i == b.val.i; }
70 bool operator!=( Oracle const& a, Oracle const& b ) { return a.val.i != b.val.i; }
71
72
73 void test_move_ctor_from_U()
74 {
75 optional<Oracle> o1 ((OracleVal()));
76 BOOST_TEST(o1);
77 BOOST_TEST(o1->s == sValueMoveConstructed || o1->s == sMoveConstructed);
78
79 OracleVal v1;
80 optional<Oracle> o2 (v1);
81 BOOST_TEST(o2);
82 BOOST_TEST(o2->s == sValueCopyConstructed || o2->s == sCopyConstructed || o2->s == sMoveConstructed );
83 BOOST_TEST(v1.s == sIntConstructed);
84
85 optional<Oracle> o3 (boost::move(v1));
86 BOOST_TEST(o3);
87 BOOST_TEST(o3->s == sValueMoveConstructed || o3->s == sMoveConstructed);
88 BOOST_TEST(v1.s == sMovedFrom);
89 }
90
91 void test_move_ctor_form_T()
92 {
93 optional<Oracle> o1 ((Oracle()));
94 BOOST_TEST(o1);
95 BOOST_TEST(o1->s == sMoveConstructed);
96
97 Oracle v1;
98 optional<Oracle> o2 (v1);
99 BOOST_TEST(o2);
100 BOOST_TEST(o2->s == sCopyConstructed);
101 BOOST_TEST(v1.s == sDefaultConstructed);
102
103 optional<Oracle> o3 (boost::move(v1));
104 BOOST_TEST(o3);
105 BOOST_TEST(o3->s == sMoveConstructed);
106 BOOST_TEST(v1.s == sMovedFrom);
107 }
108
109 void test_move_ctor_from_optional_T()
110 {
111 optional<Oracle> o1;
112 optional<Oracle> o2(boost::move(o1));
113
114 BOOST_TEST(!o1);
115 BOOST_TEST(!o2);
116
117 optional<Oracle> o3((Oracle()));
118 optional<Oracle> o4(boost::move(o3));
119 BOOST_TEST(o3);
120 BOOST_TEST(o4);
121 BOOST_TEST(o3->s == sMovedFrom);
122 BOOST_TEST(o4->s == sMoveConstructed);
123
124 optional<Oracle> o5((optional<Oracle>()));
125 BOOST_TEST(!o5);
126
127 optional<Oracle> o6((optional<Oracle>(Oracle())));
128 BOOST_TEST(o6);
129 BOOST_TEST(o6->s == sMoveConstructed);
130
131 optional<Oracle> o7(o6); // does copy ctor from non-const lvalue compile?
132 }
133
134 void test_move_assign_from_U()
135 {
136 optional<Oracle> o1 = boost::none; // test if additional ctors didn't break it
137 o1 = boost::none; // test if additional assignments didn't break it
138 o1 = OracleVal();
139 BOOST_TEST(o1);
140
141 BOOST_TEST(o1->s == sValueMoveConstructed);
142
143 o1 = OracleVal();
144 BOOST_TEST(o1);
145 BOOST_TEST(o1->s == sMoveAssigned);
146
147 OracleVal v1;
148 optional<Oracle> o2;
149 o2 = v1;
150 BOOST_TEST(o2);
151 BOOST_TEST(o2->s == sValueCopyConstructed);
152 BOOST_TEST(v1.s == sIntConstructed);
153 o2 = v1;
154 BOOST_TEST(o2);
155 BOOST_TEST(o2->s == sCopyAssigned || o2->s == sMoveAssigned);
156 BOOST_TEST(v1.s == sIntConstructed);
157
158 optional<Oracle> o3;
159 o3 = boost::move(v1);
160 BOOST_TEST(o3);
161 BOOST_TEST(o3->s == sValueMoveConstructed);
162 BOOST_TEST(v1.s == sMovedFrom);
163 }
164
165 void test_move_assign_from_T()
166 {
167 optional<Oracle> o1;
168 o1 = Oracle();
169 BOOST_TEST(o1);
170 BOOST_TEST(o1->s == sMoveConstructed);
171
172 o1 = Oracle();
173 BOOST_TEST(o1);
174 BOOST_TEST(o1->s == sMoveAssigned);
175
176 Oracle v1;
177 optional<Oracle> o2;
178 o2 = v1;
179 BOOST_TEST(o2);
180 BOOST_TEST(o2->s == sCopyConstructed);
181 BOOST_TEST(v1.s == sDefaultConstructed);
182 o2 = v1;
183 BOOST_TEST(o2);
184 BOOST_TEST(o2->s == sCopyAssigned);
185 BOOST_TEST(v1.s == sDefaultConstructed);
186
187 optional<Oracle> o3;
188 o3 = boost::move(v1);
189 BOOST_TEST(o3);
190 BOOST_TEST(o3->s == sMoveConstructed);
191 BOOST_TEST(v1.s == sMovedFrom);
192 }
193
194 void test_move_assign_from_optional_T()
195 {
196 optional<Oracle> o1;
197 optional<Oracle> o2;
198 o1 = optional<Oracle>();
199 BOOST_TEST(!o1);
200 optional<Oracle> o3((Oracle()));
201 o1 = o3;
202 BOOST_TEST(o3);
203 BOOST_TEST(o3->s == sMoveConstructed);
204 BOOST_TEST(o1);
205 BOOST_TEST(o1->s == sCopyConstructed);
206
207 o2 = boost::move(o3);
208 BOOST_TEST(o3);
209 BOOST_TEST(o3->s == sMovedFrom);
210 BOOST_TEST(o2);
211 BOOST_TEST(o2->s == sMoveConstructed);
212
213 o2 = optional<Oracle>((Oracle()));
214 BOOST_TEST(o2);
215 BOOST_TEST(o2->s == sMoveAssigned);
216 }
217
218 class MoveOnly
219 {
220 public:
221 int val;
222 MoveOnly(int v) : val(v) {}
223 MoveOnly(MoveOnly&& rhs) : val(rhs.val) { rhs.val = 0; }
224 void operator=(MoveOnly&& rhs) {val = rhs.val; rhs.val = 0; }
225
226 private:
227 MoveOnly(MoveOnly const&);
228 void operator=(MoveOnly const&);
229
230 friend class MoveOnlyB;
231 };
232
233 void test_with_move_only()
234 {
235 optional<MoveOnly> o1;
236 optional<MoveOnly> o2((MoveOnly(1)));
237 BOOST_TEST(o2);
238 BOOST_TEST(o2->val == 1);
239 optional<MoveOnly> o3 (boost::move(o1));
240 BOOST_TEST(!o3);
241 optional<MoveOnly> o4 (boost::move(o2));
242 BOOST_TEST(o4);
243 BOOST_TEST(o4->val == 1);
244 BOOST_TEST(o2);
245 BOOST_TEST(o2->val == 0);
246
247 o3 = boost::move(o4);
248 BOOST_TEST(o3);
249 BOOST_TEST(o3->val == 1);
250 BOOST_TEST(o4);
251 BOOST_TEST(o4->val == 0);
252 }
253
254 class MoveOnlyB
255 {
256 public:
257 int val;
258 MoveOnlyB(int v) : val(v) {}
259 MoveOnlyB(MoveOnlyB&& rhs) : val(rhs.val) { rhs.val = 0; }
260 void operator=(MoveOnlyB&& rhs) {val = rhs.val; rhs.val = 0; }
261 MoveOnlyB(MoveOnly&& rhs) : val(rhs.val) { rhs.val = 0; }
262 void operator=(MoveOnly&& rhs) {val = rhs.val; rhs.val = 0; }
263
264 private:
265 MoveOnlyB(MoveOnlyB const&);
266 void operator=(MoveOnlyB const&);
267 MoveOnlyB(MoveOnly const&);
268 void operator=(MoveOnly const&);
269 };
270
271 void test_move_assign_from_optional_U()
272 {
273 optional<MoveOnly> a((MoveOnly(2)));
274 optional<MoveOnlyB> b1;
275 b1 = boost::move(a);
276
277 BOOST_TEST(b1);
278 BOOST_TEST(b1->val == 2);
279 BOOST_TEST(a);
280 BOOST_TEST(a->val == 0);
281
282 b1 = MoveOnly(4);
283
284 BOOST_TEST(b1);
285 BOOST_TEST(b1->val == 4);
286 }
287
288 void test_move_ctor_from_optional_U()
289 {
290 optional<MoveOnly> a((MoveOnly(2)));
291 optional<MoveOnlyB> b1(boost::move(a));
292
293 BOOST_TEST(b1);
294 BOOST_TEST(b1->val == 2);
295 BOOST_TEST(a);
296 BOOST_TEST(a->val == 0);
297
298 optional<MoveOnlyB> b2(( optional<MoveOnly>(( MoveOnly(4) )) ));
299
300 BOOST_TEST(b2);
301 BOOST_TEST(b2->val == 4);
302 }
303
304 void test_swap()
305 {
306 optional<MoveOnly> a((MoveOnly(2)));
307 optional<MoveOnly> b((MoveOnly(3)));
308 swap(a, b);
309
310 BOOST_TEST(a->val == 3);
311 BOOST_TEST(b->val == 2);
312 }
313
314 void test_optional_ref_to_movables()
315 {
316 MoveOnly m(3);
317 optional<MoveOnly&> orm = m;
318 orm->val = 2;
319 BOOST_TEST(m.val == 2);
320
321 optional<MoveOnly&> orm2 = orm;
322 orm2->val = 1;
323 BOOST_TEST(m.val == 1);
324 BOOST_TEST(orm->val == 1);
325
326 optional<MoveOnly&> orm3 = boost::move(orm);
327 orm3->val = 4;
328 BOOST_TEST(m.val == 4);
329 BOOST_TEST(orm->val == 4);
330 BOOST_TEST(orm2->val == 4);
331 }
332
333 #endif
334
335 int main()
336 {
337 #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
338 test_move_ctor_from_U();
339 test_move_ctor_form_T();
340 test_move_ctor_from_optional_T();
341 test_move_ctor_from_optional_U();
342 test_move_assign_from_U();
343 test_move_assign_from_T();
344 test_move_assign_from_optional_T();
345 test_move_assign_from_optional_U();
346 test_with_move_only();
347 test_optional_ref_to_movables();
348 test_swap();
349 #endif
350
351 return boost::report_errors();
352 }