4
4
#include " allocation_traits.h"
5
5
#include " launder_iterator.h"
6
6
7
- namespace stdsharp
7
+ namespace stdsharp ::details
8
8
{
9
- template <allocator_req Allocator, typename T = Allocator::value_type >
9
+ template <typename Allocator, typename T>
10
10
struct allocation_value
11
11
{
12
12
using allocation_traits = allocation_traits<Allocator>;
13
13
using allocator_traits = allocation_traits::allocator_traits;
14
14
using allocator_type = allocation_traits::allocator_type;
15
15
using size_type = allocator_traits::size_type;
16
16
17
- static constexpr auto always_equal = true ;
18
-
19
- [[nodiscard]] static constexpr auto value_size () noexcept { return sizeof (T); }
20
-
21
- [[nodiscard]] bool operator ==(const allocation_value&) const = default ;
17
+ using ctor = allocator_traits::constructor;
18
+ using dtor = allocator_traits::destructor;
22
19
23
20
static constexpr auto data = allocation_traits::template data<T>;
24
21
static constexpr auto get = allocation_traits::template get<T>;
25
22
26
- private:
27
- using ctor = allocator_traits::constructor;
28
- using dtor = allocator_traits::destructor;
29
-
30
- constexpr void size_validate (const auto & allocation) const noexcept
23
+ constexpr void size_validate (this const auto & t, const auto & allocation) noexcept
31
24
{
32
25
Expects (
33
- allocation.size () * sizeof (typename allocation_traits::value_type) >= value_size ()
26
+ allocation.size () * sizeof (typename allocation_traits::value_type) >= t. value_size ()
34
27
);
35
28
}
36
29
37
- constexpr void
38
- size_validate (const auto & src_allocation, const auto & dst_allocation) const noexcept
30
+ constexpr void size_validate (
31
+ this const auto & t,
32
+ const auto & src_allocation,
33
+ const auto & dst_allocation
34
+ ) noexcept
39
35
{
40
- size_validate (src_allocation);
41
- size_validate (dst_allocation);
36
+ t. size_validate (src_allocation);
37
+ t. size_validate (dst_allocation);
42
38
}
43
39
44
- public:
45
40
static constexpr struct default_construct_t
46
41
{
47
42
} default_construct{};
43
+ };
44
+ }
48
45
46
+ namespace stdsharp
47
+ {
48
+ template <allocator_req Allocator, typename T = Allocator::value_type>
49
+ struct allocation_value : private details ::allocation_value<Allocator, T>
50
+ {
51
+ using m_base = details::allocation_value<Allocator, T>;
52
+
53
+ public:
54
+ using typename m_base::allocation_traits;
55
+ using typename m_base::allocator_traits;
56
+ using typename m_base::allocator_type;
57
+ using typename m_base::size_type;
58
+ using typename m_base::default_construct_t ;
59
+ using m_base::default_construct;
60
+ using m_base::data;
61
+ using m_base::get;
62
+
63
+ static constexpr auto always_equal = true ;
64
+
65
+ [[nodiscard]] static constexpr auto value_size () noexcept { return sizeof (T); }
66
+
67
+ [[nodiscard]] bool operator ==(const allocation_value&) const = default ;
68
+
69
+ private:
70
+ using typename m_base::ctor;
71
+ using typename m_base::dtor;
72
+
73
+ public:
49
74
constexpr void operator ()(
50
75
allocator_type& allocator,
51
76
const allocation<Allocator> auto & allocation,
52
77
const default_construct_t /* unused*/
53
78
) const noexcept (nothrow_invocable<ctor, allocator_type&, T*>)
54
79
requires std::invocable<ctor, allocator_type&, T*>
55
80
{
56
- size_validate (allocation);
81
+ this -> size_validate (allocation);
57
82
ctor{}(allocator, data (allocation));
58
83
}
59
84
@@ -64,7 +89,7 @@ namespace stdsharp
64
89
) const noexcept (nothrow_invocable<ctor, allocator_type&, T*, const T&>)
65
90
requires std::invocable<ctor, allocator_type&, T*, const T&>
66
91
{
67
- size_validate (src_allocation, dst_allocation);
92
+ this -> size_validate (src_allocation, dst_allocation);
68
93
ctor{}(allocator, data (dst_allocation), get (src_allocation));
69
94
}
70
95
@@ -75,7 +100,7 @@ namespace stdsharp
75
100
) const noexcept (nothrow_invocable<ctor, allocator_type&, T*, T>)
76
101
requires std::invocable<ctor, allocator_type&, T*, T>
77
102
{
78
- size_validate (src_allocation, dst_allocation);
103
+ this -> size_validate (src_allocation, dst_allocation);
79
104
ctor{}(allocator, data (dst_allocation), cpp_move (get (src_allocation)));
80
105
}
81
106
@@ -85,7 +110,7 @@ namespace stdsharp
85
110
) const noexcept (nothrow_copy_assignable<T>)
86
111
requires copy_assignable<T>
87
112
{
88
- size_validate (src_allocation, dst_allocation);
113
+ this -> size_validate (src_allocation, dst_allocation);
89
114
get (dst_allocation) = get (src_allocation);
90
115
}
91
116
@@ -95,7 +120,7 @@ namespace stdsharp
95
120
) const noexcept (nothrow_move_assignable<T>)
96
121
requires move_assignable<T>
97
122
{
98
- size_validate (src_allocation, dst_allocation);
123
+ this -> size_validate (src_allocation, dst_allocation);
99
124
get (dst_allocation) = cpp_move (get (src_allocation));
100
125
}
101
126
@@ -104,44 +129,34 @@ namespace stdsharp
104
129
const allocation<Allocator> auto & allocation
105
130
) const noexcept
106
131
{
107
- size_validate (allocation);
132
+ this -> size_validate (allocation);
108
133
dtor{}(allocator, data (allocation));
109
134
}
110
135
};
111
136
112
137
template <allocator_req Allocator, typename T>
113
- struct allocation_value <Allocator, T[]> // NOLINT(*-c-arrays)
138
+ struct allocation_value <Allocator, T[]> :// NOLINT(*-c-arrays)
139
+ private details::allocation_value<Allocator, T>
114
140
{
115
- public:
116
- using allocation_traits = allocation_traits<Allocator>;
117
- using allocator_traits = allocation_traits::allocator_traits;
118
- using allocator_type = allocation_traits::allocator_type;
119
- using size_type = allocator_traits::size_type;
141
+ using m_base = details::allocation_value<Allocator, T>;
120
142
121
- static constexpr auto data = allocation_traits::template data<T>;
122
- static constexpr auto get = allocation_traits::template get<T>;
143
+ public:
144
+ using typename m_base::allocation_traits;
145
+ using typename m_base::allocator_traits;
146
+ using typename m_base::allocator_type;
147
+ using typename m_base::size_type;
148
+ using typename m_base::default_construct_t ;
149
+ using m_base::default_construct;
150
+ using m_base::data;
151
+ using m_base::get;
123
152
124
153
private:
125
- using ctor = allocator_traits::constructor ;
126
- using dtor = allocator_traits::destructor ;
154
+ using typename m_base::ctor ;
155
+ using typename m_base::dtor ;
127
156
using size_t = std::size_t ;
128
157
129
158
size_t size_;
130
159
131
- constexpr void size_validate (const auto & allocation) const noexcept
132
- {
133
- Expects (
134
- allocation.size () * sizeof (typename allocation_traits::value_type) >= value_size ()
135
- );
136
- }
137
-
138
- constexpr void
139
- size_validate (const auto & src_allocation, const auto & dst_allocation) const noexcept
140
- {
141
- size_validate (src_allocation);
142
- size_validate (dst_allocation);
143
- }
144
-
145
160
[[nodiscard]] constexpr auto launder_begin (const auto & allocation) const noexcept
146
161
{
147
162
return launder_iterator{data (allocation)};
@@ -161,20 +176,16 @@ namespace stdsharp
161
176
162
177
[[nodiscard]] bool operator ==(const allocation_value&) const = default ;
163
178
164
- static constexpr struct default_construct_t
165
- {
166
- } default_construct{};
167
-
168
179
constexpr void operator ()(
169
180
allocator_type& allocator,
170
181
const allocation<Allocator> auto & allocation,
171
182
const default_construct_t /* unused*/
172
183
) const noexcept (nothrow_invocable<ctor, allocator_type&, T*>)
173
184
requires std::invocable<ctor, allocator_type&, T*>
174
185
{
175
- size_validate (allocation);
186
+ this -> size_validate (allocation);
176
187
177
- auto p = data (allocation);
188
+ auto && p = data (allocation);
178
189
const auto count = size ();
179
190
for (size_t i = 0 ; i < count; ++i, ++p) ctor{}(allocator, p);
180
191
}
@@ -186,9 +197,9 @@ namespace stdsharp
186
197
) const noexcept (nothrow_invocable<ctor, allocator_type&, T*, const T&>)
187
198
requires std::invocable<ctor, allocator_type&, T*, const T&>
188
199
{
189
- size_validate (src_allocation, dst_allocation);
200
+ this -> size_validate (src_allocation, dst_allocation);
190
201
191
- auto dst_begin = data (dst_allocation);
202
+ auto && dst_begin = data (dst_allocation);
192
203
const auto & src_begin = launder_begin (src_allocation);
193
204
const auto count = size ();
194
205
@@ -203,9 +214,9 @@ namespace stdsharp
203
214
) const noexcept (nothrow_invocable<ctor, allocator_type&, T*, T>)
204
215
requires std::invocable<ctor, allocator_type&, T*, T>
205
216
{
206
- size_validate (src_allocation, dst_allocation);
217
+ this -> size_validate (src_allocation, dst_allocation);
207
218
208
- auto dst_begin = data (dst_allocation);
219
+ auto && dst_begin = data (dst_allocation);
209
220
const auto & src_begin = launder_begin (src_allocation);
210
221
const auto count = size ();
211
222
@@ -219,7 +230,7 @@ namespace stdsharp
219
230
) const noexcept (nothrow_copy_assignable<T>)
220
231
requires copy_assignable<T>
221
232
{
222
- size_validate (src_allocation, dst_allocation);
233
+ this -> size_validate (src_allocation, dst_allocation);
223
234
std::ranges::copy_n ( //
224
235
launder_begin (src_allocation),
225
236
size (),
@@ -233,7 +244,7 @@ namespace stdsharp
233
244
) const noexcept (nothrow_move_assignable<T>)
234
245
requires move_assignable<T>
235
246
{
236
- size_validate (src_allocation, dst_allocation);
247
+ this -> size_validate (src_allocation, dst_allocation);
237
248
move_n (launder_begin (src_allocation), size (), launder_begin (dst_allocation));
238
249
}
239
250
@@ -242,9 +253,9 @@ namespace stdsharp
242
253
const allocation<Allocator> auto & allocation
243
254
) const noexcept
244
255
{
245
- size_validate (allocation);
256
+ this -> size_validate (allocation);
246
257
247
- auto iter = launder_begin (allocation);
258
+ auto && iter = launder_begin (allocation);
248
259
const auto count = size ();
249
260
for (size_t i = 0 ; i < count; ++i, ++iter) dtor{}(allocator, iter.data ());
250
261
}
0 commit comments