From f5f6e9979f080383fd8d5e86f9150641258c96e5 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Mon, 3 Mar 2014 11:19:15 +0100 Subject: [PATCH] finishing variant --- alib/src/std/variant.hpp | 50 ++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/alib/src/std/variant.hpp b/alib/src/std/variant.hpp index f8f60c88ff..fa8a96c626 100644 --- a/alib/src/std/variant.hpp +++ b/alib/src/std/variant.hpp @@ -2,7 +2,7 @@ * https://gist.github.com/tibordp/6909880 * Created on: Feb 28, 2014 * Author: Tibor Djurica Potpara - * Modified: Jan Travnicek + * Modified: Jan Travnicek */ #ifndef VATIANT_HPP_ @@ -43,7 +43,7 @@ struct variant_helper<F, Ts...> { variant_helper<Ts...>::destroy(id, data); } - inline static void move(size_t old_t, void * old_v, void * new_v) + inline static bool move(size_t old_t, void * old_v, void * new_v) { if (old_t == typeid(F).hash_code()) { new (new_v) F(std::move(*reinterpret_cast<F*>(old_v))); @@ -72,7 +72,7 @@ struct variant_helper<F, Ts...> { { if (this_t == typeid(F).hash_code() && other_t != typeid(F).hash_code()) return true; if (this_t != typeid(F).hash_code() && other_t == typeid(F).hash_code()) return false; - + if (this_t == typeid(F).hash_code() && other_t == typeid(F).hash_code()) return *(reinterpret_cast<const F*>(this_v)) < *(reinterpret_cast<const F*>(other_v)); else @@ -91,20 +91,20 @@ inline static bool compareLess(size_t this_t, const void * this_v, size_t other_ template<typename F, typename... Ts> struct variant { -private: +private: static const size_t data_size = static_max<sizeof(F), sizeof(Ts)...>::value; static const size_t data_align = static_max<alignof(F), alignof(Ts)...>::value; - + using data_t = typename std::aligned_storage<data_size, data_align>::type; - + using helper_t = variant_helper<F, Ts...>; - + size_t type_id; data_t data; public: //default constructor - variant() : type_id(typeid(F).hash_code()) { new (&data) F(); } - + variant() : type_id(typeid(F).hash_code()) { new (&data) F(); } + //copy consructor variant(const variant<F, Ts...>& old) : type_id(old.type_id) { @@ -115,23 +115,17 @@ public: variant(variant<F, Ts...>&& old) : type_id(old.type_id) { helper_t::move(old.type_id, &old.data, &data); + + new (&old.data) F(); + old.type_id = typeid(F).hash_code(); } - + //assignment operator variant<F, Ts...>& operator= (variant<F, Ts...> old) { std::swap(type_id, old.type_id); std::swap(data, old.data); - - return *this; - } - //move assignment operator - variant<F, Ts...>& operator= (variant<F, Ts...>&& old) - { - std::swap(type_id, std::move(old.type_id)); - std::swap(data, std::move(old.data)); - return *this; } @@ -140,7 +134,7 @@ public: { return helper_t::compareEq(type_id, &data, other.type_id, &other.data); } - + bool operator< (const variant<F, Ts...>& other) const { return helper_t::compareLess(type_id, &data, other.type_id, &other.data); @@ -150,12 +144,12 @@ public: bool is() const { return (type_id == typeid(T).hash_code()); } - + template<typename T> void set(T&& value) { if(std::is_base_of_any<T, F, Ts...>::value) { - helper_t::destroy(type_id, &data); + helper_t::destroy(type_id, &data); new (&data) T(value); type_id = typeid(T).hash_code(); } else @@ -163,10 +157,10 @@ public: } template<typename T> - void set(T& value) + void set(const T& value) { if(std::is_base_of_any<T, F, Ts...>::value) { - helper_t::destroy(type_id, &data); + helper_t::destroy(type_id, &data); new (&data) T(value); type_id = typeid(T).hash_code(); } else @@ -181,8 +175,8 @@ public: return *reinterpret_cast<T*>(&data); else throw std::bad_cast(); - } - + } + template<typename T> const T& get() const { @@ -191,8 +185,8 @@ public: return *reinterpret_cast<const T*>(&data); else throw std::bad_cast(); - } - + } + ~variant() { helper_t::destroy(type_id, &data); } -- GitLab