diff options
Diffstat (limited to 'src/CommonAPI/SerializableVariant.hpp')
-rw-r--r-- | src/CommonAPI/SerializableVariant.hpp | 80 |
1 files changed, 49 insertions, 31 deletions
diff --git a/src/CommonAPI/SerializableVariant.hpp b/src/CommonAPI/SerializableVariant.hpp index 3760118..2919638 100644 --- a/src/CommonAPI/SerializableVariant.hpp +++ b/src/CommonAPI/SerializableVariant.hpp @@ -15,6 +15,35 @@ namespace CommonAPI { +template<class Variant, typename ... _Types> +struct ApplyVoidIndexVisitor; + +template<class Variant> +struct ApplyVoidIndexVisitor<Variant> { + static const uint8_t index = 0; + + static + void visit(Variant&, uint8_t&) { + //won't be called + assert(false); + } +}; + +template<class Variant, typename _Type, typename ... _Types> +struct ApplyVoidIndexVisitor<Variant, _Type, _Types...> { + static const uint8_t index = ApplyVoidIndexVisitor<Variant, + _Types...>::index + 1; + + static void visit(Variant& var, uint8_t& ind) { + if (ind == index) { + new (&var.valueStorage_) _Type(); + var.valueType_ = index; + } else { + ApplyVoidIndexVisitor<Variant, _Types...>::visit(var, ind); + } + } +}; + template<class Visitor, class Variant, typename ... _Types> struct ApplyVoidVisitor; @@ -87,7 +116,7 @@ struct ApplyBoolVisitor<Visitor, Variant, _Type, _Types...> { } }; -/*template<uint8_t size> +template<uint8_t size> struct DeleteVisitor { public: DeleteVisitor(typename std::aligned_storage<size>::type& storage) : @@ -96,31 +125,11 @@ public: template<typename _Type> void operator()(const _Type&) const { - _Type thing = (reinterpret_cast<const _Type&>(storage_)); - thing.~_Type(); + (reinterpret_cast<const _Type *>(&storage_))->~_Type(); } private: typename std::aligned_storage<size>::type& storage_; -};*/ - -template<uint8_t size, typename ... _Types> -struct DeleteVisitor { -public: - DeleteVisitor(Variant<_Types ...>& storage) : - storage_(storage) - { - - } - - template<typename _Type> - void operator()(const _Type& value) const { - value.~_Type(); - //storage_.get<_Type>().~_Type(); - } - -private: - Variant<_Types...>& storage_; }; struct TypeOutputStreamWriteVisitor { @@ -326,6 +335,7 @@ struct TypeIndex<_Type, _Types...> { template<typename ... _Types> Variant<_Types...>::Variant() : valueType_(TypesTupleSize::value) { + ApplyVoidIndexVisitor<Variant<_Types...>, _Types...>::visit(*this, valueType_); } template<typename ... _Types> @@ -335,24 +345,32 @@ Variant<_Types...>::Variant(const Variant& fromVariant) { } template<typename ... _Types> -Variant<_Types...>::Variant(Variant&& fromVariant) { +Variant<_Types...>::Variant(Variant&& fromVariant) +{ AssignmentVisitor<_Types...> visitor(*this, false); ApplyVoidVisitor<AssignmentVisitor<_Types...> , Variant<_Types...>, _Types...>::visit(visitor, fromVariant); } +/*template<typename ... _Types> +Variant<_Types...>::Variant(Variant&& fromVariant) : + valueType_(std::move(fromVariant.valueType_)), + valueStorage_(std::move(fromVariant.valueStorage_)) +{ +}*/ + template<typename ... _Types> Variant<_Types...>::~Variant() { if (hasValue()) { - DeleteVisitor<maxSize, _Types...> visitor(*this); - ApplyVoidVisitor<DeleteVisitor<maxSize, _Types...>, Variant<_Types...>, _Types...>::visit(visitor, *this); + DeleteVisitor<maxSize> visitor(valueStorage_); + ApplyVoidVisitor<DeleteVisitor<maxSize>, Variant<_Types...>, _Types...>::visit(visitor, *this); } } template<typename ... _Types> void Variant<_Types...>::readFromInputStream(const uint8_t typeIndex, InputStream& inputStream) { if(hasValue()) { - DeleteVisitor<maxSize, _Types...> visitor(*this); - ApplyVoidVisitor<DeleteVisitor<maxSize, _Types...>, Variant<_Types...>, _Types...>::visit(visitor, *this); + DeleteVisitor<maxSize> visitor(valueStorage_); + ApplyVoidVisitor<DeleteVisitor<maxSize>, Variant<_Types...>, _Types...>::visit(visitor, *this); } valueType_ = typeIndex; InputStreamReadVisitor<_Types...> visitor(*this, inputStream); @@ -447,8 +465,8 @@ void Variant<_Types...>::set(const _U& value, const bool clear) { typedef typename TypeSelector<_U, _Types...>::type selected_type_t; if (clear) { - DeleteVisitor<maxSize, _Types...> visitor(*this); - ApplyVoidVisitor<DeleteVisitor<maxSize, _Types...>, Variant<_Types...>, _Types...>::visit(visitor, *this); + DeleteVisitor<maxSize> visitor(valueStorage_); + ApplyVoidVisitor<DeleteVisitor<maxSize>, Variant<_Types...>, _Types...>::visit(visitor, *this); } new (&valueStorage_) selected_type_t(std::move(value)); valueType_ = TypeIndex<_Types...>::template get<selected_type_t>(); @@ -462,8 +480,8 @@ void Variant<_Types...>::set(_U&& value, const bool clear) { selected_type_t&& any_container_value = std::move(value); if(clear) { - DeleteVisitor<maxSize, _Types...> visitor(*this); - ApplyVoidVisitor<DeleteVisitor<maxSize, _Types...>, Variant<_Types...>, _Types...>::visit(visitor, *this); + DeleteVisitor<maxSize> visitor(valueStorage_); + ApplyVoidVisitor<DeleteVisitor<maxSize>, Variant<_Types...>, _Types...>::visit(visitor, *this); } else { new (&valueStorage_) selected_type_t(std::move(any_container_value)); } |