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;
} }
@ -188,31 +186,41 @@ namespace BAN
template<typename T> template<typename T>
void set(T&& value) requires (can_have<T>()) void set(T&& value) requires (can_have<T>())
{ {
clear(); if (has<T>())
m_index = detail::index<T, Ts...>(); get<T>() = move(value);
new (m_storage) T(move(value)); else
{
clear();
m_index = detail::index<T, Ts...>();
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>())
{ {
clear(); if (has<T>())
m_index = detail::index<T, Ts...>(); get<T>() = value;
new (m_storage) T(value); else
{
clear();
m_index = detail::index<T, Ts...>();
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()