Sequoia
Loading...
Searching...
No Matches
RegularCheckersDetails.hpp
Go to the documentation of this file.
1
2// Copyright Oliver J. Rosten 2019. //
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
16
18{
19 template<class Actions, class... Args>
20 inline constexpr bool has_post_copy_action
21 = requires (std::remove_cvref_t<Actions> actions, std::remove_cvref_t<Args>&... args) {
22 actions.post_copy_action(args...);
23 };
24
25 template<class Actions, class... Args>
26 inline constexpr bool has_post_copy_assign_action
27 = requires (std::remove_cvref_t<Actions> actions, std::remove_cvref_t<Args>&... args) {
28 actions.post_copy_assign_action(args...);
29 };
30
31 template<test_mode Mode, class Actions, pseudoregular T, class... Args>
32 bool do_check_copy_assign(test_logger<Mode>& logger, [[maybe_unused]] const Actions& actions, T& z, const T& y, const Args&... args)
33 {
34 z = y;
35 if(check(equality, "Inconsistent copy assignment (from y)", logger, z, y))
36 {
37 if constexpr(has_post_copy_assign_action<Actions, test_logger<Mode>, T, T, Args...>)
38 {
39 actions.post_copy_assign_action(logger, z, y, args...);
40 }
41
42 auto& w{z};
43 z = w;
44 return check(equality, "Inconsistent self copy assignment", logger, z, y);
45 }
46
47 return false;
48 }
49
50 template<test_mode Mode, class Actions, pseudoregular T>
51 bool check_copy_assign(test_logger<Mode>& logger, const Actions& actions, T& z, const T& y)
52 {
53 return do_check_copy_assign(logger, actions, z, y);
54 }
55
56 template<test_mode Mode, class Actions, pseudoregular T, class U, std::invocable<T&> Mutator, class... Args>
57 bool check_semantics(test_logger<Mode>& logger,
58 const Actions& actions,
59 const T& x,
60 const T& y,
61 optional_ref<const U> movedFromPostConstruction,
62 optional_ref<const U> movedFromPostAssignment,
63 Mutator yMutator,
64 const Args&... args)
65 {
66 sentinel<Mode> sentry{logger, ""};
67
68 if(!check_prerequisites(logger, actions, x, y, args...))
69 return false;
70
71 T z{x};
72 const bool consistentCopy{check(equality, "Inconsistent copy constructor (x)", logger, z, x)};
73
74 if constexpr(has_post_copy_action<Actions, test_logger<Mode>, T, T, Args...>)
75 {
76 if(consistentCopy)
77 {
78 actions.post_copy_action(logger, z, T{y}, args...);
79 }
80 }
81
82 const bool consistentCopyAssign{check_copy_assign(logger, actions, z, y, args...)};
83 // z == y, if copy assign is consistent, even if copy construction is not
84
85 if(consistentCopyAssign)
86 {
87 check_move_construction(logger, actions, std::move(z), y, movedFromPostConstruction, args...);
88 }
89
90 if(!consistentCopy)
91 return false;
92
93 T w{x};
94 check_move_assign(logger, actions, w, T{y}, y, movedFromPostAssignment, yMutator, args...);
95
96 if constexpr (do_swap<Args...>::value)
97 {
98 check_swap(logger, actions, T{x}, T{y}, x, y, yMutator, args...);
99 }
100
101 if constexpr(!std::is_same_v<std::remove_cvref_t<Mutator>, null_mutator>)
102 {
103 if(consistentCopy && consistentCopyAssign)
104 {
105 T v{y};
106 yMutator(v);
107
108 if(check(
109 "Either mutation is not doing anything following copy construction"
110 " or value semantics are broken, with mutation of an object also changing"
111 " the object from which it was copied", logger, v != y))
112 {
113 v = y;
114 if(check(equality, "Inconsistent copy assignment (from mutated y)", logger, v, y))
115 {
116 yMutator(v);
117
118 check(
119 "Either mutation is not doing anything following copy assignment"
120 " or value semantics are broken, with mutation of an object also changing"
121 " the object from which it was assigned", logger, v != y);
122 }
123 }
124 }
125 }
126
127 if constexpr (serializable_to<T, std::stringstream> && deserializable_from<T, std::stringstream>)
128 {
129 check_serialization(logger, actions, T{x}, y, args...);
130 }
131
132 return !sentry.failure_detected();
133 }
134}
bool check(CheckType flavour, std::string description, test_logger< Mode > &logger, Iter first, Sentinel last, PredictionIter predictionFirst, PredictionSentinel predictionLast, tutor< Advisor > advisor={})
The workhorse for comparing the contents of ranges.
Definition: FreeCheckers.hpp:377
Implementation details for semantics checks that cleanly supports types which do/do not have allocato...
Condition for applying a container check.
Definition: AllocationCheckersDetails.cpp:15
bool check_copy_assign(test_logger< Mode > &logger, const Actions &actions, T &z, const T &y, const dual_allocation_checker< T, Getters > &... checkers)
Definition: RegularAllocationCheckersDetails.hpp:51