Sequoia
Loading...
Searching...
No Matches
RegularAllocationCheckers.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
17
18namespace sequoia::testing
19{
21 {
22 constexpr individual_allocation_predictions(copy_prediction copyPrediction, mutation_prediction mutationPrediction)
23 : copy{copyPrediction}
24 , mutation{mutationPrediction}
25 , para_copy{convert<construction_allocation_event::para_copy>(copyPrediction)}
26 , para_move{convert<construction_allocation_event::para_move>(copyPrediction)}
27 {}
28
30 mutation_prediction mutationPrediction,
31 para_copy_prediction paraCopyPrediction)
32 : copy{copyPrediction}
33 , mutation{mutationPrediction}
34 , para_copy{paraCopyPrediction}
35 , para_move{convert<construction_allocation_event::para_move>(copyPrediction)}
36 {}
37
39 mutation_prediction mutationPrediction,
40 para_copy_prediction paraCopyPrediction,
41 para_move_prediction paraMovePrediction,
42 move_prediction m={})
43 : copy{copyPrediction}
44 , mutation{mutationPrediction}
45 , para_copy{paraCopyPrediction}
46 , para_move{paraMovePrediction}
47 , move{m}
48 {}
49
50 copy_prediction copy{};
51 mutation_prediction mutation{};
52 para_copy_prediction para_copy{};
53 para_move_prediction para_move{};
54 move_prediction move{};
55 };
56
58 {
59 constexpr assignment_allocation_predictions(assign_no_prop_prediction withoutPropagation, assign_prediction withPropagation)
60 : without_propagation{withoutPropagation}
61 , with_propagation{withPropagation}
62 , move_without_propagation{convert<assignment_allocation_event::move_assign_no_prop>(without_propagation)}
63 {}
64
66 assign_prediction withPropagation,
67 move_assign_no_prop_prediction moveWithoutPropagation,
69 : without_propagation{withoutPropagation}
70 , with_propagation{withPropagation}
71 , move_without_propagation{moveWithoutPropagation}
72 , move{pureMove}
73 {}
74
75 assign_no_prop_prediction without_propagation{};
76 assign_prediction with_propagation{};
77 move_assign_no_prop_prediction move_without_propagation{};
79 };
80
81
82 template<class T>
83 [[nodiscard]]
85 const alloc_prediction_shifter<T>& shifter)
86 {
87 return {shifter.shift(predictions.copy, container_tag::y),
88 shifter.shift(predictions.mutation),
89 shifter.shift(predictions.para_copy),
90 shifter.shift(predictions.para_move, container_tag::y),
91 shifter.shift(predictions.move)};
92 }
93
94 template<class T>
95 [[nodiscard]]
96 constexpr assignment_allocation_predictions shift(const assignment_allocation_predictions& predictions,
97 const alloc_prediction_shifter<T>& shifter)
98 {
99 return {shifter.shift(predictions.without_propagation),
100 shifter.shift(predictions.with_propagation),
101 shifter.shift(predictions.move_without_propagation),
102 shifter.shift(predictions.move)};
103 }
104
105 template<top_level TopLevel>
107 {
108 public:
112 requires (TopLevel == top_level::yes)
113 : m_x{x}
114 , m_y{y}
115 , m_Assign_y_to_x{assignYtoX}
116 {}
117
121 container_counts counts)
122
123 requires (TopLevel == top_level::no)
125 , m_x{x}
126 , m_y{y}
127 , m_Assign_y_to_x{assignYtoX}
128 {}
129
130 [[nodiscard]]
131 constexpr para_move_prediction para_move_y_allocs() const noexcept { return m_y.para_move; }
132
133 [[nodiscard]]
134 constexpr move_assign_no_prop_prediction move_assign_no_prop_allocs() const noexcept
135 {
136 return m_Assign_y_to_x.move_without_propagation;
137 }
138
139 [[nodiscard]]
140 constexpr move_assign_prediction move_assign_allocs() const noexcept
141 {
142 return m_Assign_y_to_x.move;
143 }
144
145 [[nodiscard]]
146 constexpr mutation_prediction mutation_allocs() const noexcept { return m_y.mutation; }
147
148 [[nodiscard]]
149 constexpr move_prediction move_allocs() const noexcept { return m_y.move; }
150
151 [[nodiscard]]
152 constexpr copy_prediction x() const noexcept { return m_x; }
153
154 [[nodiscard]]
155 constexpr const individual_allocation_predictions& y() const noexcept { return m_y; }
156
157 [[nodiscard]]
158 constexpr const assignment_allocation_predictions& assign_y_to_x() const noexcept { return m_Assign_y_to_x; }
159
160 template<class T>
161 [[nodiscard]]
162 constexpr basic_allocation_predictions shift(const alloc_prediction_shifter<T>& shifter) const
163 {
164 auto shifted{*this};
165
166 shifted.m_x = shifter.shift(m_x, container_tag::x);
167 shifted.m_y = testing::shift(m_y, shifter);
168 shifted.m_Assign_y_to_x = testing::shift(m_Assign_y_to_x, shifter);
169
170 return shifted;
171 }
172 private:
173 copy_prediction m_x{};
175 assignment_allocation_predictions m_Assign_y_to_x;
176 };
177
178 [[nodiscard]]
180 to_top_level(const basic_allocation_predictions<top_level::no>& predictions) noexcept
181 {
182 return {predictions.x(), predictions.y(), predictions.assign_y_to_x()};
183 }
184
185 using allocation_predictions = basic_allocation_predictions<top_level::yes>;
186 using inner_allocation_predictions = basic_allocation_predictions<top_level::no>;
187
188 template<class T>
189 [[nodiscard]]
190 constexpr allocation_predictions shift(const allocation_predictions& predictions)
191 {
192 const alloc_prediction_shifter<T> shifter{{1_containers, 1_containers, 0_postmutation}, top_level::yes};
193 return predictions.shift(shifter);
194 }
195
196 template<class T>
197 [[nodiscard]]
198 constexpr inner_allocation_predictions shift(const inner_allocation_predictions& predictions)
199 {
200 const alloc_prediction_shifter<T> shifter{predictions.containers(), top_level::no};
201 return predictions.shift(shifter);
202 }
203
204 template<pseudoregular T>
205 struct type_to_allocation_predictions<T>
206 {
207 using predictions_type = allocation_predictions;
208 using inner_predictions_type = inner_allocation_predictions;
209 };
210
211 template<test_mode Mode, pseudoregular T, std::invocable<T&> Mutator, alloc_getter<T>... Getters>
212 requires (!std::totally_ordered<T> && (sizeof...(Getters) > 0))
213 void check_semantics(std::string description, test_logger<Mode>& logger, const T& x, const T& y, Mutator yMutator, const allocation_info<T, Getters>&... info)
214 {
215 impl::check_semantics(std::move(description), logger, impl::regular_allocation_actions<T>{}, x, y, std::move(yMutator), info...);
216 }
217
218 template<test_mode Mode, pseudoregular T, std::invocable<T&> Mutator, alloc_getter<T>... Getters>
219 requires (std::totally_ordered<T> && (sizeof...(Getters) > 0))
220 void check_semantics(std::string description, test_logger<Mode>& logger, const T& x, const T& y, std::weak_ordering order, Mutator yMutator, const allocation_info<T, Getters>&... info)
221 {
222 impl::check_semantics(std::move(description), logger, impl::regular_allocation_actions<T>{order}, x, y, std::move(yMutator), info...);
223 }
224
225 template
226 <
227 test_mode Mode,
228 pseudoregular T,
229 invocable_r<T> xMaker,
230 invocable_r<T> yMaker,
231 std::invocable<T&> Mutator,
232 alloc_getter<T>... Getters
233 >
234 requires (!std::totally_ordered<T> && sizeof...(Getters) > 0)
235 std::pair<T, T> check_semantics(std::string description, test_logger<Mode>& logger, xMaker xFn, yMaker yFn, Mutator yMutator, const allocation_info<T, Getters>&... info)
236 {
237 return impl::check_semantics(std::move(description), logger, impl::regular_allocation_actions<T>{}, std::move(xFn), std::move(yFn), std::move(yMutator), info...);
238 }
239
240 template
241 <
242 test_mode Mode,
243 pseudoregular T,
244 invocable_r<T> xMaker,
245 invocable_r<T> yMaker,
246 std::invocable<T&> Mutator,
247 alloc_getter<T>... Getters
248 >
249 requires (std::totally_ordered<T> && sizeof...(Getters) > 0)
250 std::pair<T, T> check_semantics(std::string description, test_logger<Mode>& logger, xMaker xFn, yMaker yFn, std::weak_ordering order, Mutator yMutator, const allocation_info<T, Getters>&... info)
251 {
252 return impl::check_semantics(std::move(description), logger, impl::regular_allocation_actions<T>{order}, std::move(xFn), std::move(yFn), std::move(yMutator), info...);
253 }
254}
Client-facing utilities for performing allocation checks.
Implementation details for allocation checks of regular types.
class template for shifting allocation predictions, especially for MSVC debug builds.
Definition: AllocationCheckers.hpp:217
Definition: RegularAllocationCheckers.hpp:107
Definition: AllocationCheckers.hpp:575
Definition: RegularAllocationCheckers.hpp:58
Definition: AllocationCheckers.hpp:152
Definition: RegularAllocationCheckers.hpp:21