Sequoia
Loading...
Searching...
No Matches
MoveOnlyAllocationCheckers.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
17namespace sequoia::testing
18{
20 {
22 mutation_prediction mutationPrediction,
23 move_prediction m={})
24 : para_move{paraMovePrediction}
25 , mutation{mutationPrediction}
26 , move{m}
27 {}
28
29 para_move_prediction para_move{};
30 mutation_prediction mutation{};
31 move_prediction move{};
32 };
33
35 {
37 move_assign_prediction pureMove={})
38 : move_without_propagation{moveWithoutPropagation}
39 , move{pureMove}
40 {}
41
42 move_assign_no_prop_prediction move_without_propagation{};
44 };
45
46 template<class T>
47 [[nodiscard]]
49 const alloc_prediction_shifter<T>& shifter)
50 {
51 return {shifter.shift(predictions.para_move, container_tag::y),
52 shifter.shift(predictions.mutation),
53 shifter.shift(predictions.move)};
54 }
55
56 template<class T>
57 [[nodiscard]]
58 constexpr assignment_move_only_allocation_predictions shift(const assignment_move_only_allocation_predictions& predictions,
59 const alloc_prediction_shifter<T>& shifter)
60 {
61 return {shifter.shift(predictions.move_without_propagation),
62 shifter.shift(predictions.move)};
63 }
64
65 template<top_level TopLevel>
67 {
68 public:
72
73 requires (TopLevel == top_level::yes)
74 : m_x{x}
75 , m_y{y}
76 , m_Assign_y_to_x{assignYtoX}
77 {}
78
82 container_counts counts)
83 requires (TopLevel == top_level::no)
85 , m_x{x}
86 , m_y{y}
87 , m_Assign_y_to_x{assignYtoX}
88 {}
89
90 [[nodiscard]]
91 constexpr mutation_prediction mutation_allocs() const noexcept { return m_y.mutation; }
92
93 [[nodiscard]]
94 constexpr para_move_prediction para_move_x_allocs() const noexcept { return m_x; }
95
96 [[nodiscard]]
97 constexpr para_move_prediction para_move_y_allocs() const noexcept { return m_y.para_move; }
98
99 [[nodiscard]]
100 constexpr move_prediction move_allocs() const noexcept { return m_y.move; }
101
102 [[nodiscard]]
103 constexpr move_assign_no_prop_prediction move_assign_no_prop_allocs() const noexcept
104 {
105 return m_Assign_y_to_x.move_without_propagation;
106 }
107
108 [[nodiscard]]
109 constexpr move_assign_prediction move_assign_allocs() const noexcept
110 {
111 return m_Assign_y_to_x.move;
112 }
113
114 [[nodiscard]]
115 constexpr para_move_prediction x() const noexcept { return m_x; }
116
117 [[nodiscard]]
118 constexpr const individual_move_only_allocation_predictions& y() const noexcept { return m_y; }
119
120 [[nodiscard]]
121 constexpr const assignment_move_only_allocation_predictions& assign_y_to_x() const noexcept { return m_Assign_y_to_x; }
122
123 template<class T>
124 [[nodiscard]]
125 constexpr basic_move_only_allocation_predictions shift(const alloc_prediction_shifter<T>& shifter) const
126 {
127 auto shifted{*this};
128
129 shifted.m_x = shifter.shift(m_x, container_tag::x);
130 shifted.m_y = testing::shift(m_y, shifter);
131 shifted.m_Assign_y_to_x = testing::shift(m_Assign_y_to_x, shifter);
132
133 return shifted;
134 }
135 private:
139 };
140
141 [[nodiscard]]
143 to_top_level(const basic_move_only_allocation_predictions<top_level::no>& predictions) noexcept
144 {
145 return {predictions.x(), predictions.y(), predictions.assign_y_to_x()};
146 }
147
148 using move_only_allocation_predictions = basic_move_only_allocation_predictions<top_level::yes>;
149 using move_only_inner_allocation_predictions = basic_move_only_allocation_predictions<top_level::no>;
150
151 template<class T>
152 constexpr move_only_allocation_predictions shift(const move_only_allocation_predictions& predictions)
153 {
154 const alloc_prediction_shifter<T> shifter{{1_containers, 1_containers, 0_postmutation}, top_level::yes};
155 return predictions.shift(shifter);
156 }
157
158 template<class T>
159 [[nodiscard]]
160 constexpr move_only_inner_allocation_predictions shift(const move_only_inner_allocation_predictions& predictions)
161 {
162 const alloc_prediction_shifter<T> shifter{predictions.containers(), top_level::no};
163 return predictions.shift(shifter);
164 }
165
166 template<moveonly T>
168 {
171 };
172
173 template<test_mode Mode, moveonly T, class U, std::invocable<T&> Mutator, alloc_getter<T>... Getters>
174 requires checkable_against_for_semantics<Mode, T, U> && (!std::totally_ordered<T>) && (sizeof...(Getters) > 0)
175 void check_semantics(std::string description,
176 test_logger<Mode>& logger,
177 T&& x,
178 T&& y,
179 const U& xEquivalent,
180 const U& yEquivalent,
181 optional_ref<const U> movedFromPostConstruction,
182 optional_ref<const U> movedFromPostAssignment,
183 Mutator m,
184 const allocation_info<T, Getters>&... info)
185 {
186 impl::check_semantics(std::move(description),
187 logger,
189 std::forward<T>(x),
190 std::forward<T>(y),
191 xEquivalent,
192 yEquivalent,
193 movedFromPostConstruction,
194 movedFromPostAssignment,
195 std::move(m),
196 info...);
197 }
198
199 template<test_mode Mode, moveonly T, class U, std::invocable<T&> Mutator, alloc_getter<T>... Getters>
200 requires checkable_against_for_semantics<Mode, T, U> && std::totally_ordered<T> && (sizeof...(Getters) > 0)
201 void check_semantics(std::string description,
202 test_logger<Mode>& logger,
203 T&& x,
204 T&& y,
205 const U& xEquivalent,
206 const U& yEquivalent,
207 optional_ref<const U> movedFromPostConstruction,
208 optional_ref<const U> movedFromPostAssignment,
209 std::weak_ordering order,
210 Mutator m,
211 const allocation_info<T, Getters>&... info)
212 {
213 impl::check_semantics(std::move(description),
214 logger,
215 impl::move_only_allocation_actions<T>{order},
216 std::forward<T>(x),
217 std::forward<T>(y),
218 xEquivalent,
219 yEquivalent,
220 movedFromPostConstruction,
221 movedFromPostAssignment,
222 std::move(m),
223 info...);
224 }
225
226 template
227 <
228 test_mode Mode,
229 moveonly T,
230 regular_invocable_r<T> xMaker,
231 regular_invocable_r<T> yMaker,
232 std::invocable<T&> Mutator,
233 alloc_getter<T>... Getters
234 >
235 requires (!std::totally_ordered<T> && (sizeof...(Getters) > 0))
236 std::pair<T,T> check_semantics(std::string description,
237 test_logger<Mode>& logger,
238 xMaker xFn,
239 yMaker yFn,
240 optional_ref<const T> movedFromPostConstruction,
241 optional_ref<const T> movedFromPostAssignment,
242 Mutator m,
243 const allocation_info<T, Getters>&... info)
244 {
245 return impl::check_semantics(std::move(description),
246 logger,
247 impl::move_only_allocation_actions<T>{},
248 std::move(xFn),
249 std::move(yFn),
250 movedFromPostConstruction,
251 movedFromPostAssignment,
252 std::move(m),
253 info...);
254 }
255
256 template
257 <
258 test_mode Mode,
259 moveonly T,
260 regular_invocable_r<T> xMaker,
261 regular_invocable_r<T> yMaker,
262 std::invocable<T&> Mutator,
263 alloc_getter<T>... Getters
264 >
265 requires (std::totally_ordered<T> && (sizeof...(Getters) > 0))
266 std::pair<T,T> check_semantics(std::string description,
267 test_logger<Mode>& logger,
268 xMaker xFn,
269 yMaker yFn,
270 optional_ref<const T> movedFromPostConstruction,
271 optional_ref<const T> movedFromPostAssignment,
272 std::weak_ordering order,
273 Mutator m,
274 const allocation_info<T, Getters>&... info)
275 {
276 return impl::check_semantics(std::move(description),
277 logger,
278 impl::move_only_allocation_actions<T>{order},
279 std::move(xFn),
280 std::move(yFn),
281 movedFromPostConstruction,
282 movedFromPostAssignment,
283 std::move(m),
284 info...);
285 }
286}
Client-facing utilities for performing allocation checks.
Implementation details specific to allocation checks for move-only types.
class template for shifting allocation predictions, especially for MSVC debug builds.
Definition: AllocationCheckers.hpp:217
Class for use with a container possessing a (shared counting) allocator.
Definition: AllocationCheckers.hpp:425
Definition: MoveOnlyAllocationCheckers.hpp:67
Definition: AllocationCheckers.hpp:575
Definition: TestLogger.hpp:183
Definition: MoveOnlyAllocationCheckers.hpp:35
Definition: AllocationCheckers.hpp:152
Definition: MoveOnlyAllocationCheckersDetails.hpp:23
Definition: MoveOnlyAllocationCheckers.hpp:20
Definition: AllocationCheckers.hpp:351