Skip to content

Commit f00392d

Browse files
committed
replace deprecated std::aligned_storage with custom sbo buffer
1 parent 0eb1274 commit f00392d

File tree

1 file changed

+33
-9
lines changed

1 file changed

+33
-9
lines changed

api/util/delegate.hpp

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <type_traits>
2222
#include <functional>
2323
#include <memory>
24+
#include <new> // std::launder
2425

2526
// ----- SYNOPSIS -----
2627

@@ -68,6 +69,20 @@ class empty_delegate_error : public std::bad_function_call
6869
}
6970
};
7071

72+
template<std::size_t Size, std::size_t Align>
73+
struct sbo_storage {
74+
alignas(Align) std::byte data[Size];
75+
76+
template<class T>
77+
constexpr T& as() noexcept {
78+
return *std::launder(reinterpret_cast<T*>(data));
79+
}
80+
template<class T>
81+
constexpr const T& as() const noexcept {
82+
return *std::launder(reinterpret_cast<const T*>(data));
83+
}
84+
};
85+
7186
// ----- IMPLEMENTATION -----
7287

7388
namespace detail
@@ -163,7 +178,7 @@ template<
163178
> class inplace_triv
164179
{
165180
public:
166-
using storage_t = std::aligned_storage_t<size, align>;
181+
using storage_t = sbo_storage<size, align>;
167182
using invoke_ptr_t = R(*)(storage_t&, Args&&...);
168183

169184
explicit inplace_triv() noexcept :
@@ -178,7 +193,10 @@ template<
178193
> explicit inplace_triv(T&& closure) :
179194
invoke_ptr_{ static_cast<invoke_ptr_t>(
180195
[](storage_t& storage, Args&&... args) -> R
181-
{ return reinterpret_cast<C&>(storage)(std::forward<Args>(args)...); }
196+
{
197+
auto& closure = storage.template as<C>();
198+
return closure(std::forward<Args>(args)...);
199+
}
182200
)}
183201
{
184202
static_assert(sizeof(C) <= size,
@@ -211,12 +229,12 @@ template<
211229

212230
bool empty() const noexcept
213231
{
214-
return reinterpret_cast<std::nullptr_t&>(storage_) == nullptr;
232+
return storage_.template as <std::nullptr_t&>() == nullptr;
215233
}
216234

217235
template<typename T> T* target() const noexcept
218236
{
219-
return reinterpret_cast<T*>(&storage_);
237+
return &storage_.template as<T*>();
220238
}
221239

222240
private:
@@ -233,7 +251,7 @@ template<
233251
> class inplace
234252
{
235253
public:
236-
using storage_t = std::aligned_storage_t<size, align>;
254+
using storage_t = sbo_storage<size, align>;
237255

238256
using invoke_ptr_t = R(*)(storage_t&, Args&&...);
239257
using copy_ptr_t = void(*)(storage_t&, storage_t&);
@@ -251,12 +269,18 @@ template<
251269
> explicit inplace(T&& closure) noexcept :
252270
invoke_ptr_{ static_cast<invoke_ptr_t>(
253271
[](storage_t& storage, Args&&... args) -> R
254-
{ return reinterpret_cast<C&>(storage)(std::forward<Args>(args)...); }
272+
{
273+
auto& closure = storage.template as<C>();
274+
return closure(std::forward<Args>(args)...);
275+
}
255276
) },
256277
copy_ptr_{ copy_op<C, storage_t>() },
257278
destructor_ptr_{ static_cast<destructor_ptr_t>(
258279
[](storage_t& storage) noexcept -> void
259-
{ reinterpret_cast<C&>(storage).~C(); }
280+
{
281+
auto& closure = storage.template as<C>();
282+
closure.~C();
283+
}
260284
) }
261285
{
262286
static_assert(sizeof(C) <= size,
@@ -337,7 +361,7 @@ template<
337361

338362
template<typename T> T* target() const noexcept
339363
{
340-
return reinterpret_cast<T*>(&storage_);
364+
return &storage_.template as <T>();
341365
}
342366

343367
private:
@@ -357,7 +381,7 @@ template<
357381
{
358382
return [](S& dst, S& src) noexcept -> void
359383
{
360-
new(&dst)T{ reinterpret_cast<T&>(src) };
384+
new(&dst)T{ src.template as<T>() };
361385
};
362386
}
363387

0 commit comments

Comments
 (0)