forked from Bananymous/banan-os
BAN: Variant with reference now supports copy/assign
This commit is contained in:
parent
06916f56be
commit
2c52e0aad8
|
@ -4,6 +4,8 @@
|
||||||
#include <BAN/Math.h>
|
#include <BAN/Math.h>
|
||||||
#include <BAN/Move.h>
|
#include <BAN/Move.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
namespace BAN
|
namespace BAN
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -53,7 +55,10 @@ namespace BAN
|
||||||
void move_construct(size_t index, uint8_t* source, uint8_t* target)
|
void move_construct(size_t index, uint8_t* source, uint8_t* target)
|
||||||
{
|
{
|
||||||
if (index == 0)
|
if (index == 0)
|
||||||
|
if constexpr(!is_lvalue_reference_v<T>)
|
||||||
new (target) T(move(*reinterpret_cast<T*>(source)));
|
new (target) T(move(*reinterpret_cast<T*>(source)));
|
||||||
|
else
|
||||||
|
memcpy(target, source, sizeof(remove_reference_t<T>*));
|
||||||
else if constexpr(sizeof...(Ts) > 0)
|
else if constexpr(sizeof...(Ts) > 0)
|
||||||
move_construct<Ts...>(index - 1, source, target);
|
move_construct<Ts...>(index - 1, source, target);
|
||||||
else
|
else
|
||||||
|
@ -64,7 +69,10 @@ namespace BAN
|
||||||
void copy_construct(size_t index, const uint8_t* source, uint8_t* target)
|
void copy_construct(size_t index, const uint8_t* source, uint8_t* target)
|
||||||
{
|
{
|
||||||
if (index == 0)
|
if (index == 0)
|
||||||
|
if constexpr(!is_lvalue_reference_v<T>)
|
||||||
new (target) T(*reinterpret_cast<const T*>(source));
|
new (target) T(*reinterpret_cast<const T*>(source));
|
||||||
|
else
|
||||||
|
memcpy(target, source, sizeof(remove_reference_t<T>*));
|
||||||
else if constexpr(sizeof...(Ts) > 0)
|
else if constexpr(sizeof...(Ts) > 0)
|
||||||
copy_construct<Ts...>(index - 1, source, target);
|
copy_construct<Ts...>(index - 1, source, target);
|
||||||
else
|
else
|
||||||
|
@ -75,7 +83,10 @@ namespace BAN
|
||||||
void move_assign(size_t index, uint8_t* source, uint8_t* target)
|
void move_assign(size_t index, uint8_t* source, uint8_t* target)
|
||||||
{
|
{
|
||||||
if (index == 0)
|
if (index == 0)
|
||||||
|
if constexpr(!is_lvalue_reference_v<T>)
|
||||||
*reinterpret_cast<T*>(target) = move(*reinterpret_cast<T*>(source));
|
*reinterpret_cast<T*>(target) = move(*reinterpret_cast<T*>(source));
|
||||||
|
else
|
||||||
|
memcpy(target, source, sizeof(remove_reference_t<T>*));
|
||||||
else if constexpr(sizeof...(Ts) > 0)
|
else if constexpr(sizeof...(Ts) > 0)
|
||||||
move_assign<Ts...>(index - 1, source, target);
|
move_assign<Ts...>(index - 1, source, target);
|
||||||
else
|
else
|
||||||
|
@ -86,7 +97,10 @@ namespace BAN
|
||||||
void copy_assign(size_t index, const uint8_t* source, uint8_t* target)
|
void copy_assign(size_t index, const uint8_t* source, uint8_t* target)
|
||||||
{
|
{
|
||||||
if (index == 0)
|
if (index == 0)
|
||||||
|
if constexpr(!is_lvalue_reference_v<T>)
|
||||||
*reinterpret_cast<T*>(target) = *reinterpret_cast<const T*>(source);
|
*reinterpret_cast<T*>(target) = *reinterpret_cast<const T*>(source);
|
||||||
|
else
|
||||||
|
memcpy(target, source, sizeof(remove_reference_t<T>*));
|
||||||
else if constexpr(sizeof...(Ts) > 0)
|
else if constexpr(sizeof...(Ts) > 0)
|
||||||
copy_assign<Ts...>(index - 1, source, target);
|
copy_assign<Ts...>(index - 1, source, target);
|
||||||
else
|
else
|
||||||
|
@ -142,9 +156,7 @@ namespace BAN
|
||||||
Variant& operator=(Variant&& other)
|
Variant& operator=(Variant&& other)
|
||||||
{
|
{
|
||||||
if (m_index == other.m_index)
|
if (m_index == other.m_index)
|
||||||
{
|
|
||||||
detail::move_assign<Ts...>(m_index, other.m_storage, m_storage);
|
detail::move_assign<Ts...>(m_index, other.m_storage, m_storage);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
|
@ -158,9 +170,7 @@ namespace BAN
|
||||||
Variant& operator=(const Variant& other)
|
Variant& operator=(const Variant& other)
|
||||||
{
|
{
|
||||||
if (m_index == other.m_index)
|
if (m_index == other.m_index)
|
||||||
{
|
|
||||||
detail::copy_assign<Ts...>(m_index, other.m_storage, m_storage);
|
detail::copy_assign<Ts...>(m_index, other.m_storage, m_storage);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
|
@ -173,14 +183,28 @@ namespace BAN
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Variant& operator=(T&& value) requires (can_have<T>() && !is_lvalue_reference_v<T>)
|
Variant& operator=(T&& value) requires (can_have<T>() && !is_lvalue_reference_v<T>)
|
||||||
{
|
{
|
||||||
*this = Variant(move(value));
|
if (size_t index = detail::index<T, Ts...>(); index == m_index)
|
||||||
|
get<T>() = move(value);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
new (m_storage) T(move(value));
|
||||||
|
m_index = index;
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Variant& operator=(const T& value) requires (can_have<T>() && !is_lvalue_reference_v<T>)
|
Variant& operator=(const T& value) requires (can_have<T>() && !is_lvalue_reference_v<T>)
|
||||||
{
|
{
|
||||||
*this = Variant(value);
|
if (size_t index = detail::index<T, Ts...>(); index == m_index)
|
||||||
|
get<T>() = value;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
new (m_storage) T(value);
|
||||||
|
m_index = index;
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue