35 const void *(*get)(
const void *src);
42template<
typename ExtraInfo,
typename T>
46 +[](
void *dst,
const void *src) {
new (dst)
T(*
static_cast<const T *
>(src)); },
49 +[](
void *dst,
void *src) {
new (dst)
T(std::move(*
static_cast<T *
>(src))); },
52 +[](
void *src) { std::destroy_at((
static_cast<T *
>(src))); },
54 ExtraInfo::template get<T>()};
60template<
typename T>
using Ptr = std::unique_ptr<T>;
61template<
typename ExtraInfo,
typename T>
63 [](
void *dst,
const void *src) {
new (dst)
Ptr<T>(
new T(**(
const Ptr<T> *)src)); },
64 [](
void *dst,
void *src) {
new (dst)
Ptr<T>(
new T(std::move(**(
Ptr<T> *)src))); },
65 [](
void *src) { std::destroy_at((
Ptr<T> *)src); },
66 [](
const void *src) ->
const void * {
return &**(
const Ptr<T> *)src; },
67 ExtraInfo::template get<T>()};
87 typename ExtraInfo = void,
92 size_t InlineBufferCapacity = 8,
101 using RealExtraInfo =
104 static constexpr size_t RealInlineBufferCapacity = std::max(InlineBufferCapacity,
105 sizeof(std::unique_ptr<int>));
117 const Info *info_ =
nullptr;
121 template<
typename T>
static constexpr bool is_allowed_v = std::is_copy_constructible_v<T>;
128 static constexpr bool is_inline_v = std::is_nothrow_move_constructible_v<T> &&
129 sizeof(
T) <= InlineBufferCapacity &&
alignof(
T) <= Alignment;
135 template<
typename T>
static constexpr bool is_same_any_v = std::is_same_v<std::decay_t<T>,
Any>;
138 template<
typename T>
const Info &get_info()
const
140 using DecayT = std::decay_t<T>;
143 return detail::template info_for_inline<RealExtraInfo, DecayT>;
146 return detail::template info_for_unique_ptr<RealExtraInfo, DecayT>;
153 Any(
const Any &other) : info_(other.info_)
155 if (info_ !=
nullptr) {
156 if (info_->copy_construct !=
nullptr) {
157 info_->copy_construct(&buffer_, &other.buffer_);
160 std::copy_n(
static_cast<const std::byte *
>(other.buffer_.
ptr()),
161 RealInlineBufferCapacity,
162 static_cast<std::byte *
>(buffer_.ptr()));
171 Any(
Any &&other) noexcept : info_(other.info_)
173 if (info_ !=
nullptr) {
174 if (info_->move_construct !=
nullptr) {
175 info_->move_construct(&buffer_, &other.buffer_);
178 std::copy_n(
static_cast<const std::byte *
>(other.buffer_.ptr()),
179 RealInlineBufferCapacity,
180 static_cast<std::byte *
>(buffer_.ptr()));
189 template<
typename T,
typename... Args>
explicit Any(std::in_place_type_t<T>, Args &&...args)
197 template<
typename T, BLI_ENABLE_IF((!is_same_any_v<T>))>
198 Any(
T &&value) :
Any(std::in_place_type<
T>, std::forward<
T>(value))
204 if (info_ !=
nullptr) {
205 if (info_->destruct !=
nullptr) {
206 info_->destruct(&buffer_);
216 if (
this == &other) {
220 new (
this)
Any(other);
228 if (
this == &other) {
233 new (
this)
Any(std::forward<T>(other));
240 if (info_ !=
nullptr) {
241 if (info_->destruct !=
nullptr) {
242 info_->destruct(&buffer_);
248 operator bool()
const
255 return info_ !=
nullptr;
258 template<
typename T,
typename... Args> std::decay_t<T> &
emplace(Args &&...args)
261 new (
this)
Any(std::in_place_type<T>, std::forward<Args>(args)...);
268 using DecayT = std::decay_t<T>;
270 info_ = &this->
template get_info<DecayT>();
273 DecayT *stored_value =
new (&buffer_) DecayT(std::forward<Args>(args)...);
274 return *stored_value;
279 std::unique_ptr<DecayT> *stored_value =
new (&buffer_)
280 std::unique_ptr<DecayT>(
new DecayT(std::forward<Args>(args)...));
281 return **stored_value;
303 info_ = &this->
template get_info<T>();
305 return buffer_.ptr();
309 T *value =
static_cast<T *
>(::operator
new(
sizeof(
T)));
310 new (&buffer_) std::unique_ptr<T>(value);
316 template<
typename T>
bool is()
const
318 return info_ == &this->
template get_info<T>();
325 if (info_->get !=
nullptr) {
326 return const_cast<void *
>(info_->get(&buffer_));
335 if (info_->get !=
nullptr) {
336 return info_->get(&buffer_);
348 return const_cast<T &
>(
const_cast<const Any *
>(
this)->get<
T>());
355 template<
typename T>
const T &
get()
const
365 buffer = info_->get(&buffer_);
367 return *
static_cast<const T *
>(buffer);
376 return info_->extra_info;
static constexpr bool is_same_any_v
Any(std::in_place_type_t< T >, Args &&...args)
Any & operator=(T &&other)
std::decay_t< T > & emplace(Args &&...args)
std::decay_t< T > & emplace_on_empty(Args &&...args)
const RealExtraInfo & extra_info() const
static constexpr bool is_inline_v
void * allocate_on_empty()
Any(Any &&other) noexcept
static constexpr bool is_allowed_v
Any & operator=(const Any &other)
constexpr AnyTypeInfo< ExtraInfo > info_for_inline
constexpr AnyTypeInfo< ExtraInfo > info_for_unique_ptr
constexpr bool is_trivially_move_constructible_extended_v
constexpr bool is_trivially_destructible_extended_v
constexpr bool is_trivially_copy_constructible_extended_v
void(* move_construct)(void *dst, void *src)
void(* destruct)(void *src)
void(* copy_construct)(void *dst, const void *src)