BAN: Variant::set now copy/move assigns when possible

This commit is contained in:
Bananymous 2023-04-18 19:06:58 +03:00
parent b41a8e2829
commit c3df0bd15e
1 changed files with 21 additions and 13 deletions

View File

@ -98,9 +98,7 @@ namespace BAN
static constexpr size_t invalid_index() { return sizeof...(Ts); } static constexpr size_t invalid_index() { return sizeof...(Ts); }
public: public:
Variant() Variant() = default;
: m_index(invalid_index())
{ }
Variant(Variant&& other) Variant(Variant&& other)
: m_index(other.m_index) : m_index(other.m_index)
@ -168,14 +166,14 @@ namespace BAN
template<typename T> template<typename T>
Variant& operator=(T&& value) requires (can_have<T>()) Variant& operator=(T&& value) requires (can_have<T>())
{ {
set(move(value)); *this = Variant(move(value));
return *this; return *this;
} }
template<typename T> template<typename T>
Variant& operator=(const T& value) requires (can_have<T>()) Variant& operator=(const T& value) requires (can_have<T>())
{ {
set(value); *this = Variant(value);
return *this; return *this;
} }
@ -187,32 +185,42 @@ namespace BAN
template<typename T> template<typename T>
void set(T&& value) requires (can_have<T>()) void set(T&& value) requires (can_have<T>())
{
if (has<T>())
get<T>() = move(value);
else
{ {
clear(); clear();
m_index = detail::index<T, Ts...>(); m_index = detail::index<T, Ts...>();
new (m_storage) T(move(value)); new (m_storage) T(move(value));
} }
}
template<typename T> template<typename T>
void set(const T& value) requires (can_have<T>()) void set(const T& value) requires (can_have<T>())
{
if (has<T>())
get<T>() = value;
else
{ {
clear(); clear();
m_index = detail::index<T, Ts...>(); m_index = detail::index<T, Ts...>();
new (m_storage) T(value); new (m_storage) T(value);
} }
}
template<typename T> template<typename T>
T& get() requires (can_have<T>()) T& get() requires (can_have<T>())
{ {
ASSERT(has<T>()); ASSERT(has<T>());
return (T&)m_storage; return *reinterpret_cast<T*>(m_storage);
} }
template<typename T> template<typename T>
const T& get() const requires (can_have<T>()) const T& get() const requires (can_have<T>())
{ {
ASSERT(has<T>()); ASSERT(has<T>());
return (const T&)m_storage; return *reinterpret_cast<const T*>(m_storage);
} }
void clear() void clear()