Skip to content

Commit 8ad5ed0

Browse files
committed
refactor(allocation-value): reduce duplication
1 parent eb852c8 commit 8ad5ed0

File tree

2 files changed

+95
-94
lines changed

2 files changed

+95
-94
lines changed

include/stdsharp/memory/allocation_value.h

Lines changed: 51 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@ namespace stdsharp::details
1818
using ctor = allocator_traits::constructor;
1919
using dtor = allocator_traits::destructor;
2020

21-
static constexpr auto data = allocation_traits::template data<T>;
22-
static constexpr auto get = allocation_traits::template get<T>;
23-
2421
template<typename>
2522
struct forward_value;
2623

@@ -39,7 +36,7 @@ namespace stdsharp::details
3936
template<typename Allocation>
4037
using forward_value_t = forward_value<Allocation>::type;
4138

42-
constexpr void size_validate(this const auto& t, const auto&... allocations) noexcept
39+
static constexpr void size_validate(const auto& t, const auto&... allocations) noexcept
4340
{
4441
( //
4542
Expects(
@@ -50,6 +47,19 @@ namespace stdsharp::details
5047
);
5148
}
5249

50+
[[nodiscard]] constexpr auto data(this const auto& t, const auto& allocation) noexcept
51+
{
52+
size_validate(t, allocation);
53+
return allocation_traits::template data<T>(allocation);
54+
}
55+
56+
[[nodiscard]] constexpr decltype(auto) get(this const auto& t, const auto& allocation) //
57+
noexcept
58+
{
59+
size_validate(t, allocation);
60+
return allocation_traits::template get<T>(allocation);
61+
}
62+
5363
static constexpr struct default_construct_t
5464
{
5565
} default_construct{};
@@ -61,15 +71,13 @@ namespace stdsharp
6171
template<allocator_req Allocator, typename T = Allocator::value_type>
6272
struct allocation_value : private details::allocation_value<Allocator, T>
6373
{
74+
private:
6475
using m_base = details::allocation_value<Allocator, T>;
6576

77+
friend m_base;
78+
6679
public:
67-
using typename m_base::allocation_traits;
68-
using typename m_base::allocator_traits;
6980
using typename m_base::allocator_type;
70-
using typename m_base::size_type;
71-
using typename m_base::default_construct_t;
72-
using m_base::default_construct;
7381
using m_base::data;
7482
using m_base::get;
7583

@@ -85,25 +93,21 @@ namespace stdsharp
8593
private:
8694
using typename m_base::ctor;
8795
using typename m_base::dtor;
88-
using m_base::size_validate;
8996

9097
template<typename Allocation>
91-
[[nodiscard]] constexpr decltype(auto) forward_value(const Allocation& src_allocation
92-
) const noexcept
98+
[[nodiscard]] constexpr decltype(auto) forward_value(const Allocation& src) const noexcept
9399
{
94-
size_validate(src_allocation);
95-
return static_cast<forward_value_t<Allocation>>(get(src_allocation));
100+
return static_cast<forward_value_t<Allocation>>(get(src));
96101
}
97102

98103
public:
99104
constexpr void operator()(
100105
allocator_type& allocator,
101106
const allocation<Allocator> auto& allocation,
102-
const default_construct_t /*unused*/
107+
const m_base::default_construct_t /*unused*/
103108
) const noexcept(nothrow_invocable<ctor, allocator_type&, T*>)
104109
requires std::invocable<ctor, allocator_type&, T*>
105110
{
106-
size_validate(allocation);
107111
ctor{}(allocator, data(allocation));
108112
}
109113

@@ -115,7 +119,6 @@ namespace stdsharp
115119
const allocation<Allocator> auto& dst_allocation
116120
) const noexcept(nothrow_invocable<ctor, allocator_type&, T*, Value>)
117121
{
118-
size_validate(dst_allocation);
119122
ctor{}(allocator, data(dst_allocation), forward_value(src_allocation));
120123
}
121124

@@ -126,7 +129,6 @@ namespace stdsharp
126129
) const noexcept(nothrow_assignable_from<T&, Value>)
127130
requires std::assignable_from<T&, Value>
128131
{
129-
size_validate(dst_allocation);
130132
get(dst_allocation) = forward_value(src_allocation);
131133
}
132134

@@ -135,7 +137,6 @@ namespace stdsharp
135137
const allocation<Allocator> auto& allocation
136138
) const noexcept
137139
{
138-
size_validate(allocation);
139140
dtor{}(allocator, data(allocation));
140141
}
141142
};
@@ -144,54 +145,50 @@ namespace stdsharp
144145
struct allocation_value<Allocator, T[]> :// NOLINT(*-c-arrays)
145146
private details::allocation_value<Allocator, T>
146147
{
148+
private:
147149
using m_base = details::allocation_value<Allocator, T>;
148150

151+
friend m_base;
152+
149153
public:
150-
using typename m_base::allocation_traits;
151-
using typename m_base::allocator_traits;
152154
using typename m_base::allocator_type;
153-
using typename m_base::size_type;
154-
using typename m_base::default_construct_t;
155-
using m_base::default_construct;
156-
using m_base::data;
157-
using m_base::get;
158155

159156
private:
160157
using typename m_base::ctor;
161158
using typename m_base::dtor;
162159
using size_t = std::size_t;
163-
using m_base::size_validate;
164160

165161
size_t size_;
166162

167-
[[nodiscard]] constexpr auto launder_begin(const auto& allocation) const noexcept
163+
public:
164+
[[nodiscard]] constexpr auto data(const auto& allocation) const noexcept
168165
{
169-
size_validate(allocation);
170-
return launder_iterator{data(allocation)};
166+
return launder_iterator{m_base::data(allocation)};
171167
}
172168

173-
[[nodiscard]] constexpr auto
174-
forward_launder_begin(const callocation<Allocator> auto& allocation) const noexcept
169+
private:
170+
template<typename Allocation>
171+
using forward_value_t = m_base::template forward_value_t<Allocation>;
172+
173+
[[nodiscard]] constexpr auto forward_data(const callocation<Allocator> auto& allocation) //
174+
const noexcept
175175
{
176-
return launder_begin(allocation);
176+
return data(allocation);
177177
}
178178

179-
[[nodiscard]] constexpr auto
180-
forward_launder_begin(const allocation<Allocator> auto& allocation) const noexcept
179+
[[nodiscard]] constexpr auto forward_data(const allocation<Allocator> auto& allocation) //
180+
const noexcept
181181
{
182-
return std::move_iterator{launder_begin(allocation)};
182+
return std::move_iterator{data(allocation)};
183183
}
184184

185-
template<typename Allocation>
186-
using forward_value_t = m_base::template forward_value_t<Allocation>;
187-
188-
[[nodiscard]] constexpr auto forward_rng(const auto& allocation) const noexcept
185+
public:
186+
[[nodiscard]] constexpr auto get(const auto& allocation) const noexcept
189187
{
190-
return std::views::counted(forward_launder_begin(allocation), size());
188+
return std::views::counted(data(allocation), size());
191189
}
192190

193-
public:
194-
constexpr explicit allocation_value(const size_type size) noexcept: size_(size) {}
191+
constexpr explicit allocation_value(const m_base::size_type size) noexcept: size_(size) {}
195192

196193
[[nodiscard]] constexpr auto size() const noexcept { return size_; }
197194

@@ -202,12 +199,11 @@ namespace stdsharp
202199
constexpr void operator()(
203200
allocator_type& allocator,
204201
const allocation<Allocator> auto& allocation,
205-
const default_construct_t /*unused*/
202+
const m_base::default_construct_t /*unused*/
206203
) const noexcept(nothrow_invocable<ctor, allocator_type&, T*>)
207204
requires std::invocable<ctor, allocator_type&, T*>
208205
{
209-
size_validate(allocation);
210-
auto begin = data(allocation);
206+
auto begin = m_base::data(allocation);
211207
for(const auto end = begin + size(); begin < end; ++begin) ctor{}(allocator, begin);
212208
}
213209

@@ -219,36 +215,31 @@ namespace stdsharp
219215
) const noexcept(nothrow_invocable<ctor, allocator_type&, T*, Value>)
220216
requires std::invocable<ctor, allocator_type&, T*, Value>
221217
{
222-
size_validate(dst_allocation);
223-
224-
const auto& dst_begin = data(dst_allocation);
225-
const auto& src_begin = forward_launder_begin(src_allocation);
218+
const auto& dst_begin = m_base::data(dst_allocation);
219+
const auto& src_begin = forward_data(src_allocation);
226220
const auto count = size();
227221

228-
for(size_t i = 0; i < count; ++i) ctor{}(allocator, dst_begin[i], src_begin[i]);
222+
for(size_t i = 0; i < count; ++i) ctor{}(allocator, dst_begin + i, src_begin[i]);
229223
}
230224

231225
template<typename Allocation, typename Value = forward_value_t<Allocation>>
232226
constexpr void operator()(
233227
const Allocation& src_allocation,
234228
const allocation<Allocator> auto& dst_allocation
235-
) const noexcept(nothrow_assignable_from<T, Value>)
236-
requires std::assignable_from<T, Value>
229+
) const noexcept(nothrow_assignable_from<T&, Value>)
230+
requires std::assignable_from<T&, Value>
237231
{
238-
std::ranges::copy_n(
239-
launder_begin(src_allocation),
240-
size(),
241-
forward_launder_begin(dst_allocation)
242-
);
232+
std::ranges::copy_n(forward_data(dst_allocation), size(), data(src_allocation));
243233
}
244234

245235
constexpr void operator()(
246236
allocator_type& allocator,
247237
const allocation<Allocator> auto& allocation
248238
) const noexcept
249239
{
250-
auto&& begin = launder_begin(allocation);
251-
for(const auto& end = begin + size(); begin < end; ++begin) dtor{}(allocator, begin);
240+
auto&& begin = m_base::data(allocation);
241+
for(const auto& end = begin + size(); begin < end; ++begin)
242+
dtor{}(allocator, std::launder(begin));
252243
}
253244
};
254245
}

0 commit comments

Comments
 (0)