Remove polymorphic_storage helper
This commit is contained in:
parent
a1cf646633
commit
cb468aa675
1 changed files with 0 additions and 155 deletions
|
|
@ -1,155 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
#include <algorithm>
|
||||
|
||||
namespace psemek::util
|
||||
{
|
||||
|
||||
template <typename I, std::size_t Size = sizeof(I)>
|
||||
struct polymorhpic_storage
|
||||
{
|
||||
static constexpr std::size_t align = std::max(alignof(I*), alignof(I));
|
||||
static constexpr std::size_t size = std::max(sizeof(I*), std::max(sizeof(I), Size));
|
||||
|
||||
polymorhpic_storage() noexcept = default;
|
||||
|
||||
polymorhpic_storage(polymorhpic_storage && other) noexcept;
|
||||
polymorhpic_storage & operator = (polymorhpic_storage && other) noexcept;
|
||||
|
||||
polymorhpic_storage(polymorhpic_storage const &) = delete;
|
||||
polymorhpic_storage & operator = (polymorhpic_storage const &) = delete;
|
||||
|
||||
template <typename T, typename ... Args>
|
||||
void emplace(Args && ... args);
|
||||
|
||||
I * get() const noexcept;
|
||||
|
||||
void reset() noexcept;
|
||||
|
||||
~polymorhpic_storage() noexcept
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
explicit operator bool() const
|
||||
{
|
||||
return static_cast<bool>(manager_);
|
||||
}
|
||||
|
||||
private:
|
||||
std::aligned_storage_t<size, align> storage_;
|
||||
|
||||
using manager = void*(*)(void *, void *, int);
|
||||
manager manager_ = nullptr;
|
||||
|
||||
static constexpr int op_get = 1;
|
||||
static constexpr int op_move = 2;
|
||||
static constexpr int op_destroy = 3;
|
||||
};
|
||||
|
||||
template <typename I, std::size_t Size>
|
||||
polymorhpic_storage<I, Size>::polymorhpic_storage(polymorhpic_storage && other) noexcept
|
||||
{
|
||||
manager_ = other.manager_;
|
||||
if (manager_)
|
||||
{
|
||||
manager_(&other.storage_, &storage_, op_move);
|
||||
}
|
||||
|
||||
other.reset();
|
||||
}
|
||||
|
||||
template <typename I, std::size_t Size>
|
||||
polymorhpic_storage<I, Size> & polymorhpic_storage<I, Size>::operator = (polymorhpic_storage && other) noexcept
|
||||
{
|
||||
if (this == &other)
|
||||
return *this;
|
||||
|
||||
reset();
|
||||
manager_ = other.manager_;
|
||||
if (manager_)
|
||||
{
|
||||
manager_(&other.storage_, &storage_, op_move);
|
||||
}
|
||||
|
||||
other.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename I, std::size_t Size>
|
||||
template <typename T, typename ... Args>
|
||||
void polymorhpic_storage<I, Size>::emplace(Args && ... args)
|
||||
{
|
||||
constexpr bool static_storage = true
|
||||
&& (sizeof(T) <= size)
|
||||
&& (alignof(T) <= align)
|
||||
&& ((align % alignof(T)) == 0)
|
||||
&& std::is_nothrow_move_constructible_v<T>
|
||||
;
|
||||
|
||||
reset();
|
||||
if constexpr (static_storage)
|
||||
{
|
||||
static_assert(sizeof(T) <= size);
|
||||
new (reinterpret_cast<T *>(&storage_)) T(std::forward<Args>(args)...);
|
||||
manager_ = [](void * src, void * dst, int op) -> void*
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case op_get:
|
||||
return src;
|
||||
case op_move:
|
||||
new (reinterpret_cast<T *>(dst)) T(std::move(*reinterpret_cast<T *>(src)));
|
||||
break;
|
||||
case op_destroy:
|
||||
reinterpret_cast<T *>(src)->~T();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
*reinterpret_cast<T**>(&storage_) = new T(std::forward<Args>(args)...);
|
||||
manager_ = [](void * src, void * dst, int op) -> void*
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case op_get:
|
||||
return *reinterpret_cast<T**>(src);
|
||||
case op_move:
|
||||
*reinterpret_cast<T**>(dst) = *reinterpret_cast<T**>(src);
|
||||
*reinterpret_cast<T**>(src) = nullptr;
|
||||
break;
|
||||
case op_destroy:
|
||||
delete *reinterpret_cast<T**>(src);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
template <typename I, std::size_t Size>
|
||||
I * polymorhpic_storage<I, Size>::get() const noexcept
|
||||
{
|
||||
if (!manager_) return nullptr;
|
||||
return static_cast<I *>(manager_(const_cast<void *>(static_cast<void const *>(&storage_)), nullptr, op_get));
|
||||
}
|
||||
|
||||
template <typename I, std::size_t Size>
|
||||
void polymorhpic_storage<I, Size>::reset() noexcept
|
||||
{
|
||||
if (!manager_) return;
|
||||
manager_(&storage_, nullptr, op_destroy);
|
||||
manager_ = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue