summaryrefslogtreecommitdiff
path: root/src/CommonAPI/SerializableVariant.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/CommonAPI/SerializableVariant.hpp')
-rw-r--r--src/CommonAPI/SerializableVariant.hpp80
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));
}