diff options
author | Johannes Schanda <schanda@itestra.de> | 2013-01-16 13:42:26 +0100 |
---|---|---|
committer | Johannes Schanda <schanda@itestra.de> | 2013-01-16 13:42:26 +0100 |
commit | 49ccab312bb195eaffe13f905400ceba4276ba3d (patch) | |
tree | cd5cb2c2351d29babcf549203fd553c45d83561b /src | |
parent | dfee05eeb1c8976d35aa802e91c56b34a78ce588 (diff) | |
download | genivi-common-api-runtime-49ccab312bb195eaffe13f905400ceba4276ba3d.tar.gz |
Variant with working output stream
Diffstat (limited to 'src')
-rw-r--r-- | src/CommonAPI/OutputStream.h | 5 | ||||
-rw-r--r-- | src/CommonAPI/SerializableVariant.h | 423 | ||||
-rw-r--r-- | src/CommonAPI/SerializableVariant.ipp | 465 |
3 files changed, 491 insertions, 402 deletions
diff --git a/src/CommonAPI/OutputStream.h b/src/CommonAPI/OutputStream.h index d3d62f0..1f33de9 100644 --- a/src/CommonAPI/OutputStream.h +++ b/src/CommonAPI/OutputStream.h @@ -22,6 +22,7 @@ namespace CommonAPI { +class SerializableVariant; class TypeOutputStream { public: @@ -223,7 +224,7 @@ inline static void writeType(TypeOutputStream& typeStream) { template<typename _Type, bool _IsVariantType = false> -struct VariantTypeWriter: public StructTypeWriter<_Type, std::is_base_of<CommonAPI::SerializableStruct, _Type>::value> { +struct VariantTypeWriter: public StructTypeWriter<_Type, std::is_base_of<SerializableStruct, _Type>::value> { }; template<typename _Type> @@ -235,7 +236,7 @@ inline static void writeType(TypeOutputStream& typeStream) { template<typename _Type> -struct TypeWriter: public VariantTypeWriter<_Type, std::is_base_of<CommonAPI::SerializableVariant, _Type>::value>{}; +struct TypeWriter: public VariantTypeWriter<_Type, std::is_base_of<SerializableVariant, _Type>::value>{}; diff --git a/src/CommonAPI/SerializableVariant.h b/src/CommonAPI/SerializableVariant.h index 39b6ddf..92d6114 100644 --- a/src/CommonAPI/SerializableVariant.h +++ b/src/CommonAPI/SerializableVariant.h @@ -39,224 +39,6 @@ public: }; template<typename ... _Types> -struct AssignmentVisitor; - -template<typename _Type> -struct TypeEqualsVisitor; - -template<typename ... _Types> -struct PartialEqualsVisitor; - -template<class Visitor, class Variant, typename ... _Types> -struct ApplyVoidVisitor; - -template<class Visitor, class Variant> -struct ApplyVoidVisitor<Visitor, Variant> { - static const uint8_t index = 0; - - static - void visit(Visitor&, Variant&) { - //won't be called - assert(false); - } - - static - void visit(Visitor&, const Variant&) { - //won't be called - assert(false); - } -}; - -template<class Visitor, class Variant, typename _Type, typename ... _Types> -struct ApplyVoidVisitor<Visitor, Variant, _Type, _Types...> { - static const uint8_t index = ApplyVoidVisitor<Visitor, Variant, - _Types...>::index + 1; - - static - void visit(Visitor& visitor, Variant& var) { - if (var.getValueType() == index) { - bool b; - visitor(var.template get<_Type>(b)); - } else { - ApplyVoidVisitor<Visitor, Variant, _Types...>::visit(visitor, var); - } - } - - static - void visit(Visitor& visitor, const Variant& var) { - if (var.getValueType() == index) { - bool b; - visitor(var.template get<_Type>(b)); - } else { - ApplyVoidVisitor<Visitor, Variant, _Types...>::visit(visitor, var); - } - } -}; - -template<class Visitor, class Variant, typename ... _Types> -struct ApplyBoolVisitor -; - -template<class Visitor, class Variant> -struct ApplyBoolVisitor<Visitor, Variant> { - static const uint8_t index = 0; - - static bool visit(Visitor&, Variant&) { - //won't be called - assert(false); - } -}; - -template<class Visitor, class Variant, typename _Type, typename ... _Types> -struct ApplyBoolVisitor<Visitor, Variant, _Type, _Types...> { - static const uint8_t index = ApplyBoolVisitor<Visitor, Variant, - _Types...>::index + 1; - - static bool visit(Visitor& visitor, Variant& var) { - if (var.getValueType() == index) { - bool b; - return visitor(var.template get<_Type>(b)); - } else { - return ApplyBoolVisitor<Visitor, Variant, _Types...>::visit(visitor, - var); - } - } -}; - -template<uint8_t size> -struct DeleteVisitor { -public: - DeleteVisitor(typename std::aligned_storage<size>::type& storage) : - storage_(storage) { - } - - template<typename _Type> - void operator()(const _Type&) const { - (reinterpret_cast<const _Type *>(&storage_))->~_Type(); - } - -private: - typename std::aligned_storage<size>::type& storage_; -}; - -struct TypeOutputStreamWriteVisitor { -public: - TypeOutputStreamWriteVisitor(TypeOutputStream& typeStream): typeStream_(typeStream) { - } - - template<typename _Type> - void operator()(const _Type&) const { - TypeWriter<_Type>::writeType(typeStream_); - } - -private: - TypeOutputStream& typeStream_; -}; - -struct OutputStreamWriteVisitor { -public: - OutputStreamWriteVisitor(OutputStream& outputStream): outputStream_(outputStream) { - } - - template<typename _Type> - void operator()(const _Type& value) const { - outputStream_ << value; - } - -private: - OutputStream& outputStream_; -}; - -template<typename _U, typename ... _Types> -struct TypeSelector; - -template<typename _U> -struct TypeSelector<_U> { -}; - -//_U == _Type -template<typename _Type, typename ... _Types> -struct TypeSelector<_Type, _Type, _Types...> { - typedef _Type type; -}; - -//_U& == _Type -template<typename _Type, typename ... _Types> -struct TypeSelector<_Type, _Type&, _Types...> { - typedef _Type& type; -}; - -//_U == _Type& -template<typename _Type, typename ... _Types> -struct TypeSelector<_Type&, _Type, _Types...> { - typedef _Type type; -}; - -//const _U& == _Type -template<typename _Type, typename ... _Types> -struct TypeSelector<_Type, const _Type&, _Types...> { - typedef const _Type& type; -}; - -//_U == const _Type& -template<typename _Type, typename ... _Types> -struct TypeSelector<const _Type&, _Type, _Types...> { - typedef _Type type; -}; - -//_U == X* -//_Type == const X* -template<typename _Type, typename ... _Types> -struct TypeSelector<_Type*, const _Type*, _Types...> { - typedef const _Type* type; -}; - -//_U == X& -//_Type == const X& -template<typename _Type, typename ... _Types> -struct TypeSelector<_Type&, const _Type&, _Types...> { - typedef const _Type& type; -}; - -//_U != _Type, let's try to find _U among _Types -template<typename _U, typename _Type, typename ... _Types> -struct TypeSelector<_U, _Type, _Types...> { - typedef typename TypeSelector<_U, _Types...>::type type; -}; - -template<typename ... _Types> -struct TypeIndex; - -template<> -struct TypeIndex<> { - static const uint8_t index = 0; - - template<typename _U> - static - uint8_t get() { - return 0; - } -}; - -template<typename _Type, typename ... _Types> -struct TypeIndex<_Type, _Types...> { - static const uint8_t index = TypeIndex<_Types...>::index + 1; - - template<typename _U> - static - uint8_t get( - typename std::enable_if<std::is_same<_Type, _U>::value>::type* = 0) { - return index; - } - - template<typename _U> - static - uint8_t get(typename std::enable_if<!std::is_same<_Type, _U>::value>::type* = 0) { - return TypeIndex<_Types...>::template get<_U>(); - } -}; - -template<typename ... _Types> struct MaxSize; template<> @@ -291,136 +73,59 @@ public: static const unsigned int maxSize = MaxSize<_Types...>::value; - Variant() : - valueType_(TypesTupleSize::value) { - } + Variant(); - Variant(const Variant& fromVariant) : - valueType_(fromVariant.valueType_), - valueStorage_(fromVariant.valueStorage_) { - } + Variant(const Variant& fromVariant); - Variant(Variant&& fromVariant): - valueType_(std::move(fromVariant.valueType_)), - valueStorage_(std::move(fromVariant.valueStorage_)) { - fromVariant.valueType_ = TypesTupleSize::value; - } + Variant(Variant&& fromVariant); - ~Variant() { - if (hasValue()) { - DeleteVisitor<maxSize> visitor(valueStorage_); - ApplyVoidVisitor<DeleteVisitor<maxSize>, Variant<_Types...>, _Types...>::visit(visitor, *this); - } - } + ~Variant(); - virtual void readFromInputStream(InputStream& inputStream) { - //TODO - } + virtual void readFromInputStream(InputStream& inputStream); - virtual void writeToOutputStream(OutputStream& outputStream) const { - OutputStreamWriteVisitor visitor(outputStream); - ApplyVoidVisitor<OutputStreamWriteVisitor, Variant<_Types...>, _Types...>::visit(visitor, *this); - } + virtual void writeToOutputStream(OutputStream& outputStream) const; - virtual void writeToTypeOutputStream(TypeOutputStream& typeOutputStream) const { - TypeOutputStreamWriteVisitor visitor(typeOutputStream); - ApplyVoidVisitor<TypeOutputStreamWriteVisitor, Variant<_Types...>, _Types...>::visit(visitor, *this); - } + virtual void writeToTypeOutputStream(TypeOutputStream& typeOutputStream) const; - Variant& operator=(const Variant& rhs) - { - AssignmentVisitor<_Types...> visitor(*this); - ApplyVoidVisitor<AssignmentVisitor<_Types...>, Variant<_Types...>, _Types...>::visit(visitor, rhs); - return *this; - } + Variant& operator=(const Variant& rhs); - Variant& operator=(Variant&& rhs) { - AssignmentVisitor<_Types...> visitor(*this); - ApplyVoidVisitor<AssignmentVisitor<_Types...>, Variant<_Types...>, _Types...>::visit(visitor, rhs); - return *this; - } + Variant& operator=(Variant&& rhs); template<typename _Type> typename std::enable_if<!std::is_same<_Type, Variant<_Types...>>::value, Variant<_Types...>&>::type - operator=(const _Type& value) - { - set<typename TypeSelector<_Type, _Types...>::type>(value); - return *this; - } + operator=(const _Type& value); + + bool operator==(const Variant<_Types...>& rhs) const; + + bool operator!=(const Variant<_Types...>& rhs) const; template <typename _Type> - const bool isType() const { - typedef typename TypeSelector<_Type, _Types...>::type selected_type_t; - uint8_t cType = TypeIndex<_Types...>::template get<selected_type_t>(); - if(cType == valueType_) { - return true; - } else { - return false; - } - } + const bool isType() const; template <typename _Type> Variant(const _Type& value, typename std::enable_if<!std::is_const<_Type>::value>::type* = 0, typename std::enable_if<!std::is_reference<_Type>::value>::type* = 0, - typename std::enable_if<!std::is_same<_Type, Variant>::value>::type* = 0) { - set<typename TypeSelector<_Type, _Types...>::type>(value, false); - } + typename std::enable_if<!std::is_same<_Type, Variant>::value>::type* = 0); template <typename _Type> Variant(_Type && value, typename std::enable_if<!std::is_const<_Type>::value>::type* = 0, typename std::enable_if<!std::is_reference<_Type>::value>::type* = 0, - typename std::enable_if<!std::is_same<_Type, Variant>::value>::type* = 0) { - set2<typename TypeSelector<_Type, _Types...>::type>(std::move(value), false); - } + typename std::enable_if<!std::is_same<_Type, Variant>::value>::type* = 0); - //TODO: Return type??? template <typename _Type> - const typename VariantTypeSelector<_Type, _Types...>::type & get(bool& success) const { - typedef typename TypeSelector<_Type, _Types...>::type selected_type_t; - uint8_t cType = TypeIndex<_Types...>::template get<selected_type_t>(); - if(cType == valueType_) { - success = true; - return *(reinterpret_cast<const _Type *>(&valueStorage_)); - } else { - success = false; - return *(reinterpret_cast<const _Type *>(&valueStorage_)); - } - } + const typename VariantTypeSelector<_Type, _Types...>::type & get(bool& success) const; inline uint8_t getValueType() const { - return valueType_; + return valueType_; } template<typename _U> - void set( const _U& value, const bool clear) { - typedef typename TypeSelector<_U, _Types...>::type selected_type_t; - - const selected_type_t& type_value = value; - if(clear) { - 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>(); - } + void set( const _U& value, const bool clear); template<typename _U> - void set2( _U&& value, const bool clear) { - typedef typename TypeSelector<_U, _Types...>::type selected_type_t; - - selected_type_t&& any_container_value = std::move(value); - if(clear) - { - DeleteVisitor<maxSize> visitor(valueStorage_); - ApplyVoidVisitor<DeleteVisitor<maxSize>, Variant<_Types...>, _Types...>::visit(visitor, *this); - } else { - new (&valueStorage_) selected_type_t(std::move(any_container_value)); - } - - valueType_ = TypeIndex<_Types...>::template get<selected_type_t>(); - } + void set2( _U&& value, const bool clear); private: inline bool hasValue() const { @@ -431,90 +136,8 @@ private: typename std::aligned_storage<maxSize>::type valueStorage_; }; - -template<typename ... _Types> -bool operator==(const Variant<_Types...>& lhs, const Variant<_Types...>& rhs) - { - PartialEqualsVisitor<_Types...> visitor(lhs); - return ApplyBoolVisitor<PartialEqualsVisitor<_Types...>, const Variant<_Types...>, _Types...>::visit( - visitor, - rhs); -} - -template<typename ... _Types> -bool operator!=(const Variant<_Types...>& lhs, const Variant<_Types...>& rhs) - { - return !(lhs == rhs); -} - -template<typename _Type> -struct TypeEqualsVisitor -{ -public: - TypeEqualsVisitor(const _Type& rhs) : - rhs_(rhs) - { - } - - bool - operator()(const _Type& lhs) const - { - return lhs == rhs_; - } - - template<typename _U> - bool - operator()(const _U&) const - { - return false; - } - -private: - const _Type& rhs_; -}; - -template<typename ... _Types> -struct PartialEqualsVisitor -{ -public: - PartialEqualsVisitor(const Variant<_Types...>& lhs) : - lhs_(lhs) { - } - - template<typename _Type> - bool - operator()(const _Type& rhs) const - { - TypeEqualsVisitor<_Type> visitor(rhs); - return ApplyBoolVisitor<TypeEqualsVisitor<_Type>, const Variant<_Types...>, _Types...>::visit(visitor, lhs_); - } - -private: - const Variant<_Types...>& lhs_; -}; - -template<typename ... _Types> -struct AssignmentVisitor { -public: - AssignmentVisitor(Variant<_Types...>& lhs, const bool clear = true) : - lhs_(lhs), clear_(clear) { - } - - template<typename _Type> - void operator()(const _Type& value) const { - lhs_.template set<_Type>(value, clear_); - } - - template<typename _Type> - void operator()(_Type& value) const { - lhs_.template set<_Type>(value, clear_); - } - -private: - Variant<_Types...>& lhs_; - const bool clear_; -}; - } // namespace CommonAPI +#include "SerializableVariant.ipp" + #endif // COMMONAPI_SERIALIZABLE_VARIANT_H_ diff --git a/src/CommonAPI/SerializableVariant.ipp b/src/CommonAPI/SerializableVariant.ipp new file mode 100644 index 0000000..bab99f0 --- /dev/null +++ b/src/CommonAPI/SerializableVariant.ipp @@ -0,0 +1,465 @@ +/* Copyright (C) 2013 BMW Group + * Author: Manfred Bathelt (manfred.bathelt@bmw.de) + * Author: Juergen Gehring (juergen.gehring@bmw.de) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __VAR_IMPL__ +#define __VAR_IMPL__ + +//#include "SerializableVariant.h" +#include "OutputStream.h" + +namespace CommonAPI { + +template<typename _Type> +struct TypeWriter; + +template<typename ... _Types> +struct AssignmentVisitor; + +template<typename _Type> +struct TypeEqualsVisitor; + +template<typename ... _Types> +struct PartialEqualsVisitor; + +template<class Visitor, class Variant, typename ... _Types> +struct ApplyVoidVisitor; + +template<class Visitor, class Variant> +struct ApplyVoidVisitor<Visitor, Variant> { + static const uint8_t index = 0; + + static + void visit(Visitor&, Variant&) { + //won't be called + assert(false); + } + + static + void visit(Visitor&, const Variant&) { + //won't be called + assert(false); + } +}; + +template<class Visitor, class Variant, typename _Type, typename ... _Types> +struct ApplyVoidVisitor<Visitor, Variant, _Type, _Types...> { + static const uint8_t index = ApplyVoidVisitor<Visitor, Variant, + _Types...>::index + 1; + + static + void visit(Visitor& visitor, Variant& var) { + if (var.getValueType() == index) { + bool b; + visitor(var.template get<_Type>(b)); + } else { + ApplyVoidVisitor<Visitor, Variant, _Types...>::visit(visitor, var); + } + } + + static + void visit(Visitor& visitor, const Variant& var) { + if (var.getValueType() == index) { + bool b; + visitor(var.template get<_Type>(b)); + } else { + ApplyVoidVisitor<Visitor, Variant, _Types...>::visit(visitor, var); + } + } +}; + +template<class Visitor, class Variant, typename ... _Types> +struct ApplyBoolVisitor +; + +template<class Visitor, class Variant> +struct ApplyBoolVisitor<Visitor, Variant> { + static const uint8_t index = 0; + + static bool visit(Visitor&, Variant&) { + //won't be called + assert(false); + } +}; + +template<class Visitor, class Variant, typename _Type, typename ... _Types> +struct ApplyBoolVisitor<Visitor, Variant, _Type, _Types...> { + static const uint8_t index = ApplyBoolVisitor<Visitor, Variant, + _Types...>::index + 1; + + static bool visit(Visitor& visitor, Variant& var) { + if (var.getValueType() == index) { + bool b; + return visitor(var.template get<_Type>(b)); + } else { + return ApplyBoolVisitor<Visitor, Variant, _Types...>::visit(visitor, + var); + } + } +}; + +template<uint8_t size> +struct DeleteVisitor { +public: + DeleteVisitor(typename std::aligned_storage<size>::type& storage) : + storage_(storage) { + } + + template<typename _Type> + void operator()(const _Type&) const { + (reinterpret_cast<const _Type *>(&storage_))->~_Type(); + } + +private: + typename std::aligned_storage<size>::type& storage_; +}; + +struct TypeOutputStreamWriteVisitor { +public: + TypeOutputStreamWriteVisitor(TypeOutputStream& typeStream) : + typeStream_(typeStream) { + } + + template<typename _Type> + void operator()(const _Type&) const { + TypeWriter<_Type>::writeType(typeStream_); + } + +private: + TypeOutputStream& typeStream_; +}; + +struct OutputStreamWriteVisitor { +public: + OutputStreamWriteVisitor(OutputStream& outputStream) : + outputStream_(outputStream) { + } + + template<typename _Type> + void operator()(const _Type& value) const { + outputStream_ << value; + } + +private: + OutputStream& outputStream_; +}; + +template<typename _Type> +struct TypeEqualsVisitor +{ +public: + TypeEqualsVisitor(const _Type& rhs) : + rhs_(rhs) + { + } + + bool + operator()(const _Type& lhs) const + { + return lhs == rhs_; + } + + template<typename _U> + bool + operator()(const _U&) const + { + return false; + } + +private: + const _Type& rhs_; +}; + +template<typename ... _Types> +struct PartialEqualsVisitor +{ +public: + PartialEqualsVisitor(const Variant<_Types...>& lhs) : + lhs_(lhs) { + } + + template<typename _Type> + bool + operator()(const _Type& rhs) const + { + TypeEqualsVisitor<_Type> visitor(rhs); + return ApplyBoolVisitor<TypeEqualsVisitor<_Type>, const Variant<_Types...>, _Types...>::visit(visitor, lhs_); + } + +private: + const Variant<_Types...>& lhs_; +}; + +template<typename ... _Types> +struct AssignmentVisitor { +public: + AssignmentVisitor(Variant<_Types...>& lhs, const bool clear = true) : + lhs_(lhs), clear_(clear) { + } + + template<typename _Type> + void operator()(const _Type& value) const { + lhs_.template set<_Type>(value, clear_); + } + + template<typename _Type> + void operator()(_Type& value) const { + lhs_.template set<_Type>(value, clear_); + } + +private: + Variant<_Types...>& lhs_; + const bool clear_; +}; + +template<typename _U, typename ... _Types> +struct TypeSelector; + +template<typename _U> +struct TypeSelector<_U> { +}; + +//_U == _Type +template<typename _Type, typename ... _Types> +struct TypeSelector<_Type, _Type, _Types...> { + typedef _Type type; +}; + +//_U& == _Type +template<typename _Type, typename ... _Types> +struct TypeSelector<_Type, _Type&, _Types...> { + typedef _Type& type; +}; + +//_U == _Type& +template<typename _Type, typename ... _Types> +struct TypeSelector<_Type&, _Type, _Types...> { + typedef _Type type; +}; + +//const _U& == _Type +template<typename _Type, typename ... _Types> +struct TypeSelector<_Type, const _Type&, _Types...> { + typedef const _Type& type; +}; + +//_U == const _Type& +template<typename _Type, typename ... _Types> +struct TypeSelector<const _Type&, _Type, _Types...> { + typedef _Type type; +}; + +//_U == X* +//_Type == const X* +template<typename _Type, typename ... _Types> +struct TypeSelector<_Type*, const _Type*, _Types...> { + typedef const _Type* type; +}; + +//_U == X& +//_Type == const X& +template<typename _Type, typename ... _Types> +struct TypeSelector<_Type&, const _Type&, _Types...> { + typedef const _Type& type; +}; + +//_U != _Type, let's try to find _U among _Types +template<typename _U, typename _Type, typename ... _Types> +struct TypeSelector<_U, _Type, _Types...> { + typedef typename TypeSelector<_U, _Types...>::type type; +}; + +template<typename ... _Types> +struct TypeIndex; + +template<> +struct TypeIndex<> { + static const uint8_t index = 0; + + template<typename _U> + static uint8_t get() { + return 0; + } +}; + +template<typename _Type, typename ... _Types> +struct TypeIndex<_Type, _Types...> { + static const uint8_t index = TypeIndex<_Types...>::index + 1; + + template<typename _U> + static uint8_t get( + typename std::enable_if<std::is_same<_Type, _U>::value>::type* = 0) { + return index; + } + + template<typename _U> + static uint8_t get(typename std::enable_if<!std::is_same<_Type, _U>::value>::type* = 0) { + return TypeIndex<_Types...>::template get<_U>(); + } +}; + +template<typename ... _Types> +Variant<_Types...>::Variant() : + valueType_(TypesTupleSize::value) { +} + +template<typename ... _Types> +Variant<_Types...>::Variant(const Variant& fromVariant) : + valueType_(fromVariant.valueType_), + valueStorage_(fromVariant.valueStorage_) { +} + +template<typename ... _Types> +Variant<_Types...>::Variant(Variant&& fromVariant): +valueType_(std::move(fromVariant.valueType_)), +valueStorage_(std::move(fromVariant.valueStorage_)) { + fromVariant.valueType_ = TypesTupleSize::value; +} + +template<typename ... _Types> +Variant<_Types...>::~Variant() { + if (hasValue()) { + DeleteVisitor<maxSize> visitor(valueStorage_); + ApplyVoidVisitor<DeleteVisitor<maxSize>, Variant<_Types...>, _Types...>::visit(visitor, *this); + } +} + +template<typename ... _Types> +void Variant<_Types...>::readFromInputStream(InputStream& inputStream) { + //TODO +} + +template<typename ... _Types> +void Variant<_Types...>::writeToOutputStream(OutputStream& outputStream) const { + OutputStreamWriteVisitor visitor(outputStream); + ApplyVoidVisitor<OutputStreamWriteVisitor, Variant<_Types...>, _Types...>::visit( + visitor, *this); +} + +template<typename ... _Types> +void Variant<_Types...>::writeToTypeOutputStream(TypeOutputStream& typeOutputStream) const { + TypeOutputStreamWriteVisitor visitor(typeOutputStream); + ApplyVoidVisitor<TypeOutputStreamWriteVisitor, Variant<_Types...>, _Types...>::visit( + visitor, *this); +} + +template<typename ... _Types> +Variant<_Types...>& Variant<_Types...>::operator=(const Variant<_Types...>& rhs) { + AssignmentVisitor<_Types...> visitor(*this); + ApplyVoidVisitor<AssignmentVisitor<_Types...>, Variant<_Types...>, _Types...>::visit( + visitor, rhs); + return *this; +} + +template<typename ... _Types> +Variant<_Types...>& Variant<_Types...>::operator=(Variant<_Types...>&& rhs) { + AssignmentVisitor<_Types...> visitor(*this); + ApplyVoidVisitor<AssignmentVisitor<_Types...>, Variant<_Types...>, _Types...>::visit(visitor, rhs); + return *this; +} + +template<typename ... _Types> +template<typename _Type> +typename std::enable_if<!std::is_same<_Type, Variant<_Types...>>::value, Variant<_Types...>&>::type +Variant<_Types...>::operator=(const _Type& value) + { + set<typename TypeSelector<_Type, _Types...>::type>(value); + return *this; +} + +template<typename ... _Types> +template<typename _Type> +const bool Variant<_Types...>::isType() const { + typedef typename TypeSelector<_Type, _Types...>::type selected_type_t; + uint8_t cType = TypeIndex<_Types...>::template get<selected_type_t>(); + if (cType == valueType_) { + return true; + } else { + return false; + } +} + +template<typename ... _Types> +template<typename _Type> +Variant<_Types...>::Variant(const _Type& value, + typename std::enable_if<!std::is_const<_Type>::value>::type*, + typename std::enable_if<!std::is_reference<_Type>::value>::type*, + typename std::enable_if<!std::is_same<_Type, Variant<_Types...>>::value>::type*) { + set<typename TypeSelector<_Type, _Types...>::type>(value, false); +} + +template<typename ... _Types> +template<typename _Type> +Variant<_Types...>::Variant(_Type && value, +typename std::enable_if<!std::is_const<_Type>::value>::type*, +typename std::enable_if<!std::is_reference<_Type>::value>::type*, +typename std::enable_if<!std::is_same<_Type, Variant<_Types...>>::value>::type*) { + set2<typename TypeSelector<_Type, _Types...>::type>(std::move(value), false); +} + +template<typename ... _Types> +template<typename _Type> +const typename VariantTypeSelector<_Type, _Types...>::type & Variant<_Types...>::get(bool& success) const { + typedef typename TypeSelector<_Type, _Types...>::type selected_type_t; + uint8_t cType = TypeIndex<_Types...>::template get<selected_type_t>(); + if (cType == valueType_) { + success = true; + return *(reinterpret_cast<const _Type *>(&valueStorage_)); + } else { + success = false; + return *(reinterpret_cast<const _Type *>(&valueStorage_)); + } +} + +template<typename ... _Types> +template<typename _U> +void Variant<_Types...>::set(const _U& value, const bool clear) { + typedef typename TypeSelector<_U, _Types...>::type selected_type_t; + + const selected_type_t& type_value = value; + if (clear) { + 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>(); +} + +template<typename ... _Types> +template<typename _U> +void Variant<_Types...>::set2(_U&& value, const bool clear) { + typedef typename TypeSelector<_U, _Types...>::type selected_type_t; + + selected_type_t&& any_container_value = std::move(value); + if(clear) + { + DeleteVisitor<maxSize> visitor(valueStorage_); + ApplyVoidVisitor<DeleteVisitor<maxSize>, Variant<_Types...>, _Types...>::visit(visitor, *this); + } else { + new (&valueStorage_) selected_type_t(std::move(any_container_value)); + } + + valueType_ = TypeIndex<_Types...>::template get<selected_type_t>(); +} + +template<typename ... _Types> +bool Variant<_Types...>::operator==(const Variant<_Types...>& rhs) const + { + PartialEqualsVisitor<_Types...> visitor(*this); + return ApplyBoolVisitor<PartialEqualsVisitor<_Types...>, const Variant<_Types...>, _Types...>::visit( + visitor, + rhs); +} + +template<typename ... _Types> +bool Variant<_Types...>::operator!=(const Variant<_Types...>& rhs) const + { + return !(*this == rhs); +} + +} + +#endif |