Sequoia
Loading...
Searching...
No Matches
RegularAllocationCheckersDetails.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
16
18{
20 template<pseudoregular T>
22 {
23 using allocation_actions<T>::allocation_actions;
24
25 template<test_mode Mode, alloc_getter<T>... Getters>
26 static void post_copy_action(test_logger<Mode>& logger, const T& xCopy, const T& yCopy, const dual_allocation_checker<T, Getters>&... checkers)
27 {
28 check_copy_x_allocation(logger, xCopy, allocation_checker{checkers.info(), checkers.first_count()}...);
29
30 check_copy_y_allocation(logger, yCopy, allocation_checker{checkers.info(), checkers.second_count()}...);
31 }
32
33 template<test_mode Mode, alloc_getter<T>... Getters>
34 static void post_copy_assign_action(test_logger<Mode>& logger, const T& lhs, const T& rhs, const dual_allocation_checker<T, Getters>&... checkers)
35 {
36 check_copy_assign_allocation(logger, lhs, rhs, checkers...);
37 }
38
39 template<test_mode Mode, std::invocable<T&> Mutator, alloc_getter<T>... Getters>
40 static void post_swap_action(test_logger<Mode>& logger, T& x, const T& y, const T& yEquivalent, Mutator yMutator, const dual_allocation_checker<T, Getters>&... checkers)
41 {
42 allocation_actions<T>::post_swap_action(logger, x, y, yEquivalent, checkers...);
43 check_mutation_after_swap(logger, x, y, yEquivalent, std::move(yMutator), checkers...);
44 }
45 };
46
50 template<test_mode Mode, class Actions, pseudoregular T, alloc_getter<T>... Getters>
51 bool check_copy_assign(test_logger<Mode>& logger, const Actions& actions, T& z, const T& y, const dual_allocation_checker<T, Getters>&... checkers)
52 {
53 return do_check_copy_assign(logger, actions, z, y, dual_allocation_checker{checkers.info(), z, y}...);
54 }
55
56 template<test_mode Mode, pseudoregular T, std::invocable<T&> Mutator, alloc_getter<T>... Getters>
57 void check_para_constructor_allocations(test_logger<Mode>& logger, const T& y, Mutator yMutator, const allocation_info<T, Getters>&... info)
58 {
59 auto make{
60 [&logger, &y](auto&... info){
61 T u{y, info.make_allocator()...};
62 if(check(equality, "Inconsistent para-copy construction", logger, u, y))
63 {
64 check_para_copy_y_allocation(logger, u, std::tuple_cat(make_allocation_checkers(info)...));
65 return std::optional<T>{u};
66 }
67 return std::optional<T>{};
68 }
69 };
70
71 if(auto c{make(info...)}; c)
72 {
73 T v{std::move(*c), info.make_allocator()...};
74
75 if(check(equality, "Inconsistent para-move construction", logger, v, y))
76 {
77 using ctag = container_tag_constant<container_tag::y>;
78 check_para_move_allocation(logger, ctag{}, v, std::tuple_cat(make_allocation_checkers(info)...));
79 check_mutation_after_move("para-move", logger, v, std::move(yMutator), std::tuple_cat(make_allocation_checkers(info, v)...));
80 }
81 }
82 }
83
84 template
85 <
86 test_mode Mode,
87 class Actions,
88 pseudoregular T,
89 std::invocable<T&> Mutator,
90 alloc_getter<T>... Getters
91 >
92 bool check_swap(test_logger<Mode>& logger, const Actions& actions, T&& x, T&& y, const T& xEquivalent, const T& yEquivalent, Mutator yMutator, const dual_allocation_checker<T, Getters>&... checkers)
93 {
94 return do_check_swap(logger, actions, std::move(x), std::move(y), xEquivalent, yEquivalent, std::move(yMutator), dual_allocation_checker{checkers.info(), x, y}...);
95 }
96
97 template<test_mode Mode, class Actions, pseudoregular T, std::invocable<T&> Mutator, alloc_getter<T>... Getters>
98 requires (sizeof...(Getters) > 0)
99 void check_semantics(std::string description, test_logger<Mode>& logger, const Actions& actions, const T& x, const T& y, Mutator yMutator, const allocation_info<T, Getters>&... info)
100 {
101 const auto message{!description.empty() ? add_type_info<T>(std::move(description)).append("\n") : ""};
102 sentinel<Mode> sentry{logger, message};
103
104 if(check_semantics(logger, actions, x, y, yMutator, std::tuple_cat(make_dual_allocation_checkers(info, x, y)...)))
105 {
106 check_para_constructor_allocations(logger, y, yMutator, info...);
107 }
108 }
109
110 template
111 <
112 test_mode Mode,
113 class Actions,
114 pseudoregular T,
115 invocable_r<T> xMaker,
116 invocable_r<T> yMaker,
117 std::invocable<T&> Mutator,
118 alloc_getter<T>... Getters
119 >
120 requires (sizeof...(Getters) > 0)
121 std::pair<T, T> check_semantics(std::string description, test_logger<Mode>& logger, const Actions& actions, xMaker xFn, yMaker yFn, Mutator yMutator, const allocation_info<T, Getters>&... info)
122 {
123 sentinel<Mode> sentry{logger, add_type_info<T>(std::move(description)).append("\n")};
124
125 auto x{xFn()};
126 auto y{yFn()};
127
128 check_initialization_allocations(logger, x, y, info...);
129 check_semantics("", logger, actions, x, y, std::move(yMutator), info...);
130
131 return {std::move(x), std::move(y)};
132 }
133
135 template
136 <
137 test_mode Mode,
138 class Actions,
139 pseudoregular T,
140 std::invocable<T&> Mutator,
141 alloc_getter<T>... Getters
142 >
143 bool check_semantics(test_logger<Mode>& logger, const Actions& actions, const T& x, const T& y, Mutator yMutator, std::tuple<dual_allocation_checker<T, Getters>...> checkers)
144 {
145 auto fn{
146 [&logger, &actions, &x, &y, m{std::move(yMutator)}](auto&&... checkers){
147 return check_semantics(logger,
148 actions,
149 x,
150 y,
151 optional_ref<const T>{},
152 optional_ref<const T>{},
153 m,
154 std::forward<decltype(checkers)>(checkers)...);
155 }
156 };
157
158 return std::apply(fn, checkers);
159 }
160}
Implementation details for allocation checks.
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 checking regular semantics.
Class for use with a container possessing a (shared counting) allocator.
Definition: AllocationCheckers.hpp:425
Wraps allocation_info, together with the prior allocation count.
Definition: AllocationCheckersDetails.hpp:187
Wraps allocation_info, together with two prior allocation counts.
Definition: AllocationCheckersDetails.hpp:60
Definition: TestLogger.hpp:183
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
actions common to both move-only and regular types.
Definition: AllocationCheckersDetails.hpp:603
Extends allocation_actions for types with copy semantics.
Definition: RegularAllocationCheckersDetails.hpp:22