From 2c52e0aad8a6d8c67d4f3701fb131a92c715404f Mon Sep 17 00:00:00 2001 From: Bananymous Date: Tue, 18 Apr 2023 20:21:23 +0300 Subject: [PATCH] BAN: Variant with reference now supports copy/assign --- BAN/include/BAN/Variant.h | 44 ++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/BAN/include/BAN/Variant.h b/BAN/include/BAN/Variant.h index 0522f9fe..8c7fbae2 100644 --- a/BAN/include/BAN/Variant.h +++ b/BAN/include/BAN/Variant.h @@ -4,6 +4,8 @@ #include #include +#include + namespace BAN { @@ -53,7 +55,10 @@ namespace BAN void move_construct(size_t index, uint8_t* source, uint8_t* target) { if (index == 0) - new (target) T(move(*reinterpret_cast(source))); + if constexpr(!is_lvalue_reference_v) + new (target) T(move(*reinterpret_cast(source))); + else + memcpy(target, source, sizeof(remove_reference_t*)); else if constexpr(sizeof...(Ts) > 0) move_construct(index - 1, source, target); else @@ -64,7 +69,10 @@ namespace BAN void copy_construct(size_t index, const uint8_t* source, uint8_t* target) { if (index == 0) - new (target) T(*reinterpret_cast(source)); + if constexpr(!is_lvalue_reference_v) + new (target) T(*reinterpret_cast(source)); + else + memcpy(target, source, sizeof(remove_reference_t*)); else if constexpr(sizeof...(Ts) > 0) copy_construct(index - 1, source, target); else @@ -75,7 +83,10 @@ namespace BAN void move_assign(size_t index, uint8_t* source, uint8_t* target) { if (index == 0) - *reinterpret_cast(target) = move(*reinterpret_cast(source)); + if constexpr(!is_lvalue_reference_v) + *reinterpret_cast(target) = move(*reinterpret_cast(source)); + else + memcpy(target, source, sizeof(remove_reference_t*)); else if constexpr(sizeof...(Ts) > 0) move_assign(index - 1, source, target); else @@ -86,7 +97,10 @@ namespace BAN void copy_assign(size_t index, const uint8_t* source, uint8_t* target) { if (index == 0) - *reinterpret_cast(target) = *reinterpret_cast(source); + if constexpr(!is_lvalue_reference_v) + *reinterpret_cast(target) = *reinterpret_cast(source); + else + memcpy(target, source, sizeof(remove_reference_t*)); else if constexpr(sizeof...(Ts) > 0) copy_assign(index - 1, source, target); else @@ -142,9 +156,7 @@ namespace BAN Variant& operator=(Variant&& other) { if (m_index == other.m_index) - { detail::move_assign(m_index, other.m_storage, m_storage); - } else { clear(); @@ -158,9 +170,7 @@ namespace BAN Variant& operator=(const Variant& other) { if (m_index == other.m_index) - { detail::copy_assign(m_index, other.m_storage, m_storage); - } else { clear(); @@ -173,14 +183,28 @@ namespace BAN template Variant& operator=(T&& value) requires (can_have() && !is_lvalue_reference_v) { - *this = Variant(move(value)); + if (size_t index = detail::index(); index == m_index) + get() = move(value); + else + { + clear(); + new (m_storage) T(move(value)); + m_index = index; + } return *this; } template Variant& operator=(const T& value) requires (can_have() && !is_lvalue_reference_v) { - *this = Variant(value); + if (size_t index = detail::index(); index == m_index) + get() = value; + else + { + clear(); + new (m_storage) T(value); + m_index = index; + } return *this; }