Sequoia
Loading...
Searching...
No Matches
MoveOnlyTestDiagnosticsUtilities.hpp
Go to the documentation of this file.
1
2// Copyright Oliver J. Rosten 2020. //
3// Distributed under the GNU GENERAL PUBLIC LICENSE, Version 3.0. //
4// (See accompanying file LICENSE.md or copy at //
5// https://www.gnu.org/licenses/gpl-3.0.en.html) //
7
8#pragma once
9
13
14namespace sequoia::testing
15{
16 template<enable_serialization EnableSerialization>
18 {
19 public:
20 resource_binder() = default;
21
22 explicit resource_binder(int i)
23 : m_Index{i}
24 {}
25
26 resource_binder(resource_binder&& other) noexcept
27 : m_Index{std::exchange(other.m_Index, 0)}
28 {}
29
30 resource_binder& operator=(resource_binder&& other) noexcept
31 {
32 std::ranges::swap(m_Index, other.m_Index);
33 return *this;
34 }
35
36 [[nodiscard]]
37 int index() const noexcept
38 {
39 return m_Index;
40 }
41
42 [[nodiscard]]
43 friend bool operator==(const resource_binder&, const resource_binder&) = default;
44
45 template<class Stream>
46 requires (EnableSerialization == enable_serialization::yes)
47 friend Stream& operator<<(Stream& s, const resource_binder& b)
48 {
49 s << b.index();
50 return s;
51 }
52
53 template<class Stream>
54 requires (EnableSerialization == enable_serialization::yes)
55 friend Stream& operator>>(Stream& s, resource_binder& b)
56 {
57 s >> b.m_Index;
58 return s;
59 }
60 private:
61 int m_Index{-1};
62 };
63
64 template<class T=int, class Allocator=std::allocator<int>>
66 {
67 using value_type = T;
68 using allocator_type = Allocator;
69
70 move_only_beast(std::initializer_list<T> list) : x{list} {}
71
72 move_only_beast(std::initializer_list<T> list, const allocator_type& a) : x(list, a) {}
73
74 move_only_beast(const allocator_type& a) : x(a) {}
75
76 move_only_beast(const move_only_beast&) = delete;
77
78 move_only_beast(move_only_beast&&) noexcept = default;
79
80 move_only_beast(move_only_beast&& other, const allocator_type& a) : x(std::move(other.x), a) {}
81
82 move_only_beast& operator=(const move_only_beast&) = delete;
83
84 move_only_beast& operator=(move_only_beast&&) = default;
85
86 void swap(move_only_beast& other) noexcept(noexcept(std::ranges::swap(this->x, other.x)))
87 {
88 std::ranges::swap(x, other.x);
89 }
90
91 friend void swap(move_only_beast& lhs, move_only_beast& rhs)
92 noexcept(noexcept(lhs.swap(rhs)))
93 {
94 lhs.swap(rhs);
95 }
96
97 std::vector<T, Allocator> x{};
98
99 [[nodiscard]]
100 friend bool operator==(const move_only_beast&, const move_only_beast&) noexcept = default;
101
102 template<class Stream>
103 friend Stream& operator<<(Stream& s, const move_only_beast& b)
104 {
105 for(const auto& i : b.x) s << i << '\n';
106 return s;
107 }
108 };
109
110 template<class T, class Allocator>
111 struct value_tester<move_only_beast<T, Allocator>> : beast_equivalence_tester<move_only_beast<T, Allocator>> {};
112
113 template<class T = int, class Allocator = std::allocator<int>>
115 {
116 using value_type = T;
117 using allocator_type = Allocator;
118
119 move_only_specified_moved_from_beast(std::initializer_list<T> list) : x{list} {}
120
121 move_only_specified_moved_from_beast(std::initializer_list<T> list, const allocator_type& a) : x(list, a) {}
122
123 move_only_specified_moved_from_beast(const allocator_type& a) : x(a) {}
124
126
128 : x{std::move(other.x)}
129 {
130 other.x.clear();
131 }
132
133 move_only_specified_moved_from_beast(move_only_specified_moved_from_beast&& other, const allocator_type& a) : x(std::move(other.x), a) {}
134
136
138 {
139 x = std::move(other.x);
140 other.x.clear();
141
142 return *this;
143 }
144
145 void swap(move_only_specified_moved_from_beast& other) noexcept(noexcept(std::ranges::swap(this->x, other.x)))
146 {
147 std::ranges::swap(x, other.x);
148 }
149
151 noexcept(noexcept(lhs.swap(rhs)))
152 {
153 lhs.swap(rhs);
154 }
155
156 std::vector<T, Allocator> x{};
157
158 [[nodiscard]]
159 friend bool operator==(const move_only_specified_moved_from_beast&, const move_only_specified_moved_from_beast&) noexcept = default;
160
161 template<class Stream>
162 friend Stream& operator<<(Stream& s, const move_only_specified_moved_from_beast& b)
163 {
164 for(const auto& i : b.x) s << i << '\n';
165 return s;
166 }
167 };
168
169 template<class T, class Allocator>
170 struct value_tester<move_only_specified_moved_from_beast<T, Allocator>> : beast_equivalence_tester<move_only_specified_moved_from_beast<T, Allocator>> {};
171
172 template<class T=int, class Allocator=std::allocator<int>>
174 {
175 using value_type = T;
176 using allocator_type = Allocator;
177
178 move_only_broken_equality(std::initializer_list<T> list) : x{list} {}
179
180 move_only_broken_equality(std::initializer_list<T> list, const allocator_type& a) : x(list, a) {}
181
183
185
186 move_only_broken_equality(move_only_broken_equality&& other, const allocator_type& a) : x(std::move(other.x), a) {}
187
188 move_only_broken_equality& operator=(const move_only_broken_equality&) = delete;
189
191
192 friend void swap(move_only_broken_equality& lhs, move_only_broken_equality& rhs)
193 {
194 std::ranges::swap(lhs.x, rhs.x);
195 }
196
197 std::vector<T, Allocator> x{};
198
199 [[nodiscard]]
200 friend bool operator==(const move_only_broken_equality& lhs, const move_only_broken_equality& rhs) noexcept
201 {
202 return lhs.x != rhs.x;
203 }
204
205 [[nodiscard]]
206 friend bool operator!=(const move_only_broken_equality& lhs, const move_only_broken_equality& rhs) noexcept
207 {
208 return lhs.x != rhs.x;
209 }
210
211 template<class Stream>
212 friend Stream& operator<<(Stream& s, const move_only_broken_equality& b)
213 {
214 for(auto i : b.x) s << i << ' ';
215 return s;
216 }
217 };
218
219 template<class T, class Allocator>
220 struct value_tester<move_only_broken_equality<T, Allocator>> : beast_equivalence_tester<move_only_broken_equality<T, Allocator>> {};
221
222 template<class T=int, class Allocator=std::allocator<int>>
224 {
225 using value_type = T;
226 using allocator_type = Allocator;
227
228 move_only_broken_inequality(std::initializer_list<T> list) : x{list} {}
229
230 move_only_broken_inequality(std::initializer_list<T> list, const allocator_type& a) : x(list, a) {}
231
233
235
236 move_only_broken_inequality(move_only_broken_inequality&& other, const allocator_type& a) : x(std::move(other.x), a) {}
237
239
241
243 {
244 std::ranges::swap(lhs.x, rhs.x);
245 }
246
247 std::vector<T, Allocator> x{};
248
249 [[nodiscard]]
250 friend bool operator==(const move_only_broken_inequality& lhs, const move_only_broken_inequality& rhs) noexcept
251 {
252 return lhs.x != rhs.x;
253 }
254
255 [[nodiscard]]
256 friend bool operator!=(const move_only_broken_inequality& lhs, const move_only_broken_inequality& rhs) noexcept
257 {
258 return lhs.x == rhs.x;
259 }
260
261 template<class Stream>
262 friend Stream& operator<<(Stream& s, const move_only_broken_inequality& b)
263 {
264 for(auto i : b.x) s << i << ' ';
265 return s;
266 }
267 };
268
269 template<class T, class Allocator>
270 struct value_tester<move_only_broken_inequality<T, Allocator>> : beast_equivalence_tester<move_only_broken_inequality<T, Allocator>> {};
271
272 template<class T=int, class Allocator=std::allocator<int>>
274 {
275 using value_type = T;
276 using allocator_type = Allocator;
277
278 move_only_broken_move(std::initializer_list<T> list) : x{list} {}
279
280 move_only_broken_move(std::initializer_list<T> list, const allocator_type& a) : x(list, a) {}
281
283
285 {
286 // Do nothing
287 }
288
289 move_only_broken_move(move_only_broken_move&& other, const allocator_type& a) : x(std::move(other.x), a)
290 {}
291
292 move_only_broken_move& operator=(const move_only_broken_move&) = delete;
293
294 move_only_broken_move& operator=(move_only_broken_move&&) = default;
295
296 friend void swap(move_only_broken_move& lhs, move_only_broken_move& rhs)
297 {
298 std::ranges::swap(lhs.x, rhs.x);
299 }
300
301 std::vector<T, Allocator> x{};
302
303 [[nodiscard]]
304 friend bool operator==(const move_only_broken_move& lhs, const move_only_broken_move& rhs) noexcept
305 {
306 return lhs.x == rhs.x;
307 }
308
309 [[nodiscard]]
310 friend bool operator!=(const move_only_broken_move& lhs, const move_only_broken_move& rhs) noexcept
311 {
312 return !(lhs == rhs);
313 }
314
315 template<class Stream>
316 friend Stream& operator<<(Stream& s, const move_only_broken_move& b)
317 {
318 for(auto i : b.x) s << i << ' ';
319 return s;
320 }
321 };
322
323 template<class T, class Allocator>
324 struct value_tester<move_only_broken_move<T, Allocator>> : beast_equivalence_tester<move_only_broken_move<T, Allocator>> {};
325
326 template<class T=int, class Allocator=std::allocator<int>>
328 {
329 using value_type = T;
330 using allocator_type = Allocator;
331
332 move_only_broken_move_assignment(std::initializer_list<T> list) : x{list} {}
333
334 move_only_broken_move_assignment(std::initializer_list<T> list, const allocator_type& a) : x(list, a) {}
335
337
339
340 move_only_broken_move_assignment(move_only_broken_move_assignment&& other, const allocator_type& a) : x(std::move(other.x), a) {}
341
343
345 {
346 return *this;
347 }
348
350 {
351 std::ranges::swap(lhs.x, rhs.x);
352 }
353
354 std::vector<T, Allocator> x{};
355
356 [[nodiscard]]
357 friend bool operator==(const move_only_broken_move_assignment& lhs, const move_only_broken_move_assignment& rhs) noexcept
358 {
359 return lhs.x == rhs.x;
360 }
361
362 [[nodiscard]]
363 friend bool operator!=(const move_only_broken_move_assignment& lhs, const move_only_broken_move_assignment& rhs) noexcept
364 {
365 return !(lhs == rhs);
366 }
367
368 template<class Stream>
369 friend Stream& operator<<(Stream& s, const move_only_broken_move_assignment& b)
370 {
371 for(auto i : b.x) s << i << ' ';
372 return s;
373 }
374 };
375
376 template<class T, class Allocator>
378 : beast_equivalence_tester<move_only_broken_move_assignment<T, Allocator>>
379 {};
380
381 template<class T=int, class Allocator=std::allocator<int>>
383 {
384 using value_type = T;
385 using allocator_type = Allocator;
386
387 move_only_broken_swap(std::initializer_list<T> list) : x{list} {}
388
389 move_only_broken_swap(std::initializer_list<T> list, const allocator_type& a) : x(list, a) {}
390
392
393 move_only_broken_swap(move_only_broken_swap&&) noexcept = default;
394
395 move_only_broken_swap(move_only_broken_swap&& other, const allocator_type& a) : x(std::move(other.x), a) {}
396
397 move_only_broken_swap& operator=(const move_only_broken_swap&) = delete;
398
399 move_only_broken_swap& operator=(move_only_broken_swap&&) = default;
400
401 friend void swap(move_only_broken_swap&, move_only_broken_swap&) noexcept
402 {
403 // do nothing
404 }
405
406 std::vector<T, Allocator> x{};
407
408 [[nodiscard]]
409 friend bool operator==(const move_only_broken_swap& lhs, const move_only_broken_swap& rhs) noexcept
410 {
411 return lhs.x == rhs.x;
412 }
413
414 [[nodiscard]]
415 friend bool operator!=(const move_only_broken_swap& lhs, const move_only_broken_swap& rhs) noexcept
416 {
417 return !(lhs == rhs);
418 }
419
420 template<class Stream>
421 friend Stream& operator<<(Stream& s, const move_only_broken_swap& b)
422 {
423 for(auto i : b.x) s << i << ' ';
424 return s;
425 }
426 };
427
428 template<class T, class Allocator>
429 struct value_tester<move_only_broken_swap<T, Allocator>> : beast_equivalence_tester<move_only_broken_swap<T, Allocator>> {};
430
431 template<class T=int, class Allocator=std::allocator<int>>
433 {
434 using value_type = T;
435 using allocator_type = Allocator;
436
437 move_only_inefficient_move(std::initializer_list<T> list) : x{list} {}
438
439 move_only_inefficient_move(std::initializer_list<T> list, const allocator_type& a) : x(list, a) {}
440
441 move_only_inefficient_move(const allocator_type& a) : x(a) {}
442
444
445 move_only_inefficient_move(move_only_inefficient_move&& other) : x{std::move(other.x)}
446 {
447 x.reserve(x.capacity() + 10);
448 }
449
450 move_only_inefficient_move(move_only_inefficient_move&& other, const allocator_type& a) : x(std::move(other.x), a) {}
451
452 move_only_inefficient_move& operator=(const move_only_inefficient_move&) = delete;
453
455
456 void swap(move_only_inefficient_move& other) noexcept(noexcept(std::ranges::swap(this->x, other.x)))
457 {
458 std::ranges::swap(x, other.x);
459 }
460
461 friend void swap(move_only_inefficient_move& lhs, move_only_inefficient_move& rhs)
462 noexcept(noexcept(lhs.swap(rhs)))
463 {
464 lhs.swap(rhs);
465 }
466
467 std::vector<T, Allocator> x{};
468
469 [[nodiscard]]
470 friend bool operator==(const move_only_inefficient_move& lhs, const move_only_inefficient_move& rhs) noexcept
471 {
472 return lhs.x == rhs.x;
473 }
474
475 [[nodiscard]]
476 friend bool operator!=(const move_only_inefficient_move& lhs, const move_only_inefficient_move& rhs) noexcept
477 {
478 return !(lhs == rhs);
479 }
480
481 template<class Stream>
482 friend Stream& operator<<(Stream& s, const move_only_inefficient_move& b)
483 {
484 for(auto i : b.x) s << i << ' ';
485 return s;
486 }
487 };
488
489 template<class T, class Allocator>
490 struct value_tester<move_only_inefficient_move<T, Allocator>> : beast_equivalence_tester<move_only_inefficient_move<T, Allocator>> {};
491
492 template<class T=int, class Allocator=std::allocator<int>>
494 {
495 using value_type = T;
496 using allocator_type = Allocator;
497
498 move_only_inefficient_move_assignment(std::initializer_list<T> list) : x{list} {}
499
500 move_only_inefficient_move_assignment(std::initializer_list<T> list, const allocator_type& a)
501 : x(list, a)
502 {}
503
504 move_only_inefficient_move_assignment(const allocator_type& a) : x(a) {}
505
507
509
510 move_only_inefficient_move_assignment(move_only_inefficient_move_assignment&& other, const allocator_type& a) : x(std::move(other.x), a) {}
511
513
515 {
516 x = std::move(other.x);
517 x.reserve(x.capacity() + 1);
518
519 return *this;
520 }
521
522 void swap(move_only_inefficient_move_assignment& other) noexcept(noexcept(std::ranges::swap(this->x, other.x)))
523 {
524 std::ranges::swap(x, other.x);
525 }
526
528 noexcept(noexcept(lhs.swap(rhs)))
529 {
530 lhs.swap(rhs);
531 }
532
533 std::vector<T, Allocator> x{};
534
535 [[nodiscard]]
536 friend bool operator==(const move_only_inefficient_move_assignment& lhs, const move_only_inefficient_move_assignment& rhs) noexcept
537 {
538 return lhs.x == rhs.x;
539 }
540
541 [[nodiscard]]
542 friend bool operator!=(const move_only_inefficient_move_assignment& lhs, const move_only_inefficient_move_assignment& rhs) noexcept
543 {
544 return !(lhs == rhs);
545 }
546
547 template<class Stream>
548 friend Stream& operator<<(Stream& s, const move_only_inefficient_move_assignment& b)
549 {
550 for(auto i : b.x) s << i << ' ';
551 return s;
552 }
553 };
554
555 template<class T, class Allocator>
557 : beast_equivalence_tester<move_only_inefficient_move_assignment<T, Allocator>>
558 {};
559}
Definition: MoveOnlyTestDiagnosticsUtilities.hpp:18
Definition: SemanticsTestDiagnosticsUtilities.hpp:20
Definition: MoveOnlyTestDiagnosticsUtilities.hpp:66
Definition: MoveOnlyTestDiagnosticsUtilities.hpp:174
Definition: MoveOnlyTestDiagnosticsUtilities.hpp:224
Definition: MoveOnlyTestDiagnosticsUtilities.hpp:328
Definition: MoveOnlyTestDiagnosticsUtilities.hpp:274
Definition: MoveOnlyTestDiagnosticsUtilities.hpp:383
Definition: MoveOnlyTestDiagnosticsUtilities.hpp:494
Definition: MoveOnlyTestDiagnosticsUtilities.hpp:433
Definition: MoveOnlyTestDiagnosticsUtilities.hpp:115
class template, specializations of which implement various comparisons for the specified type.
Definition: FreeCheckers.hpp:78