summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohannes Schanda <schanda@itestra.de>2013-01-16 13:42:26 +0100
committerJohannes Schanda <schanda@itestra.de>2013-01-16 13:42:26 +0100
commit49ccab312bb195eaffe13f905400ceba4276ba3d (patch)
treecd5cb2c2351d29babcf549203fd553c45d83561b /src
parentdfee05eeb1c8976d35aa802e91c56b34a78ce588 (diff)
downloadgenivi-common-api-runtime-49ccab312bb195eaffe13f905400ceba4276ba3d.tar.gz
Variant with working output stream
Diffstat (limited to 'src')
-rw-r--r--src/CommonAPI/OutputStream.h5
-rw-r--r--src/CommonAPI/SerializableVariant.h423
-rw-r--r--src/CommonAPI/SerializableVariant.ipp465
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