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...);
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...);
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)
35 if(
check(equality,
"Inconsistent copy assignment (from y)", logger, z, y))
37 if constexpr(has_post_copy_assign_action<Actions, test_logger<Mode>, T, T, Args...>)
39 actions.post_copy_assign_action(logger, z, y, args...);
44 return check(equality,
"Inconsistent self copy assignment", logger, z, y);
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)
53 return do_check_copy_assign(logger, actions, z, y);
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,
61 optional_ref<const U> movedFromPostConstruction,
62 optional_ref<const U> movedFromPostAssignment,
66 sentinel<Mode> sentry{logger,
""};
68 if(!check_prerequisites(logger, actions, x, y, args...))
72 const bool consistentCopy{
check(equality,
"Inconsistent copy constructor (x)", logger, z, x)};
74 if constexpr(has_post_copy_action<Actions, test_logger<Mode>, T, T, Args...>)
78 actions.post_copy_action(logger, z, T{y}, args...);
82 const bool consistentCopyAssign{
check_copy_assign(logger, actions, z, y, args...)};
85 if(consistentCopyAssign)
87 check_move_construction(logger, actions, std::move(z), y, movedFromPostConstruction, args...);
94 check_move_assign(logger, actions, w, T{y}, y, movedFromPostAssignment, yMutator, args...);
96 if constexpr (do_swap<Args...>::value)
98 check_swap(logger, actions, T{x}, T{y}, x, y, yMutator, args...);
101 if constexpr(!std::is_same_v<std::remove_cvref_t<Mutator>, null_mutator>)
103 if(consistentCopy && consistentCopyAssign)
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))
114 if(
check(equality,
"Inconsistent copy assignment (from mutated y)", logger, v, y))
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);
127 if constexpr (serializable_to<T, std::stringstream> && deserializable_from<T, std::stringstream>)
129 check_serialization(logger, actions, T{x}, y, args...);
132 return !sentry.failure_detected();
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