diff --git a/alib2std/src/extensions/variant.hpp b/alib2std/src/extensions/variant.hpp index 1eaa450bf974ca287fb8aa0ea036dc246413d801..d17a87320340709285062b7ba0539bf7503cc036 100644 --- a/alib2std/src/extensions/variant.hpp +++ b/alib2std/src/extensions/variant.hpp @@ -27,47 +27,63 @@ struct static_max<arg1, arg2, others...> { static_max<arg2, others...>::value; }; +struct type_id_hash_code { + size_t m_hash_code; + + type_id_hash_code ( size_t hash_code ) : m_hash_code ( hash_code ) { + } + + friend bool operator == ( const type_id_hash_code & first, const type_id_hash_code & second ) { + return first.m_hash_code == second.m_hash_code; + } + + friend bool operator != ( const type_id_hash_code & first, const type_id_hash_code & second ) { + return first.m_hash_code != second.m_hash_code; + } + +}; + template<typename... Ts> struct variant_helper; template<typename F, typename... Ts> struct variant_helper<F, Ts...> { - inline static void destroy(size_t id, void * data) { + inline static void destroy(type_id_hash_code id, void * data) { if (id == typeid(F).hash_code()) reinterpret_cast<F*>(data)->~F(); else variant_helper<Ts...>::destroy(id, data); } - inline static void copy(size_t old_t, const void * old_v, void * new_v) { + inline static void copy(type_id_hash_code old_t, const void * old_v, void * new_v) { if (old_t == typeid(F).hash_code()) new (new_v) F(*reinterpret_cast<const F*>(old_v)); else variant_helper<Ts...>::copy(old_t, old_v, new_v); } - inline static void move(size_t old_t, void * old_v, void * new_v) { + inline static void move(type_id_hash_code 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))); else variant_helper<Ts...>::move(old_t, old_v, new_v); } - inline static void print(ostream& out, const size_t id, const void* data) { + inline static void print(ostream& out, type_id_hash_code id, const void* data) { if (id == typeid(F).hash_code()) out << *reinterpret_cast<const F*>(data); else variant_helper<Ts...>::print(out, id, data); } - inline static std::string string(const size_t id, const void* data) { + inline static std::string string(type_id_hash_code id, const void* data) { if (id == typeid(F).hash_code()) return (std::string) *reinterpret_cast<const F*>(data); else return variant_helper<Ts...>::string(id, data); } - inline static int compareHelper(size_t this_t, const void * this_v, size_t other_t, const void * other_v) { + inline static int compareHelper(type_id_hash_code this_t, const void * this_v, type_id_hash_code other_t, const void * other_v) { if (this_t == typeid(F).hash_code() && other_t != typeid(F).hash_code()) return -1; if (this_t != typeid(F).hash_code() && other_t == typeid(F).hash_code()) return 1; @@ -81,36 +97,36 @@ struct variant_helper<F, Ts...> { template<typename... Ts> struct variant_helper<void, Ts...> { - inline static void destroy(size_t id, void * data) { + inline static void destroy(type_id_hash_code id, void * data) { if (id != typeid(void).hash_code()) variant_helper<Ts...>::destroy(id, data); } - inline static void copy(size_t old_t, const void * old_v, void * new_v) { + inline static void copy(type_id_hash_code old_t, const void * old_v, void * new_v) { if (old_t != typeid(void).hash_code()) variant_helper<Ts...>::copy(old_t, old_v, new_v); } - inline static void move(size_t old_t, void * old_v, void * new_v) { + inline static void move(type_id_hash_code old_t, void * old_v, void * new_v) { if (old_t != typeid(void).hash_code()) variant_helper<Ts...>::move(old_t, old_v, new_v); } - inline static void print(ostream& out, const size_t id, const void* data) { + inline static void print(ostream& out, type_id_hash_code id, const void* data) { if (id == typeid(void).hash_code()) out << "void"; else variant_helper<Ts...>::print(out, id, data); } - inline static std::string string(const size_t id, const void* data) { + inline static std::string string(type_id_hash_code id, const void* data) { if (id == typeid(void).hash_code()) return "void"; else return variant_helper<Ts...>::string(id, data); } - inline static int compareHelper(size_t this_t, const void * this_v, size_t other_t, const void * other_v) { + inline static int compareHelper(type_id_hash_code this_t, const void * this_v, type_id_hash_code other_t, const void * other_v) { if (this_t == typeid(void).hash_code() && other_t != typeid(void).hash_code()) return -1; if (this_t != typeid(void).hash_code() && other_t == typeid(void).hash_code()) return 1; @@ -122,12 +138,12 @@ struct variant_helper<void, Ts...> { }; template<> struct variant_helper<> { -inline static void destroy(size_t, void *) { } -inline static void copy(size_t, const void *, void *) { } -inline static void move(size_t, void *, void *) { } -inline static void print(ostream&, const size_t, const void *) {} -inline static std::string string(const size_t, const void *) { return ""; } -inline static int compareHelper(size_t, const void *, size_t, const void *) { return 0; } +inline static void destroy(type_id_hash_code, void *) { } +inline static void copy(type_id_hash_code, const void *, void *) { } +inline static void move(type_id_hash_code, void *, void *) { } +inline static void print(ostream&, type_id_hash_code, const void *) {} +inline static std::string string(type_id_hash_code, const void *) { return ""; } +inline static int compareHelper(type_id_hash_code, const void *, type_id_hash_code, const void *) { return 0; } }; template<typename ST, typename AT, typename... Ts> @@ -141,10 +157,10 @@ class variant_base<ST, AT> { using data_t = typename std::aligned_storage<data_size, data_align>::type; protected: - size_t type_id; + type_id_hash_code type_id; data_t data; - variant_base( size_t id ) : type_id ( id ) { } + variant_base( type_id_hash_code id ) : type_id ( id ) { } }; template<typename ST, typename AT, typename F, typename... Ts> @@ -152,11 +168,11 @@ class variant_base<ST, AT, F, Ts...> : public variant_base<ST, AT, Ts...> { using variant_base<ST, AT, Ts...>::variant_base; protected: - variant_base( size_t type_id ) : variant_base<ST, AT, Ts...>::variant_base ( type_id ) { } + variant_base( type_id_hash_code type_id ) : variant_base<ST, AT, Ts...>::variant_base ( type_id ) { } public: - variant_base(const F& value) : variant_base<ST, AT, Ts...>::variant_base ( typeid(F).hash_code() ) { new (&this->data) F(value); } - variant_base(F&& value) : variant_base<ST, AT, Ts...>::variant_base ( typeid(F).hash_code() ) { new (&this->data) F(std::move(value)); } + variant_base(const F& value) : variant_base<ST, AT, Ts...>::variant_base ( type_id_hash_code ( typeid(F).hash_code() ) ) { new (&this->data) F(value); } + variant_base(F&& value) : variant_base<ST, AT, Ts...>::variant_base ( type_id_hash_code ( typeid(F).hash_code() ) ) { new (&this->data) F(std::move(value)); } variant_base() : variant_base<ST, AT, Ts ... >::variant_base ( ) { } }; @@ -166,10 +182,10 @@ class variant_base<ST, AT, void, Ts...> : public variant_base<ST, AT, Ts...> { using variant_base<ST, AT, Ts...>::variant_base; protected: - variant_base( size_t type_id ) : variant_base<ST, AT, Ts...>::variant_base ( type_id ) { } + variant_base( type_id_hash_code type_id ) : variant_base<ST, AT, Ts...>::variant_base ( type_id ) { } public: - variant_base() : variant_base<ST, AT, Ts...>::variant_base ( typeid(void).hash_code() ) { } + variant_base() : variant_base<ST, AT, Ts...>::variant_base ( type_id_hash_code ( typeid(void).hash_code() ) ) { } }; template<class T> diff --git a/alib2std/test-src/extensions/VariantTest.cpp b/alib2std/test-src/extensions/VariantTest.cpp index 93fd9a0c6a41d03abda992e600c8ff4e602ec140..6d7372f346c3f613164add922599603378e79840 100644 --- a/alib2std/test-src/extensions/VariantTest.cpp +++ b/alib2std/test-src/extensions/VariantTest.cpp @@ -158,3 +158,13 @@ void VariantTest::testVariantSameTypes() { CPPUNIT_ASSERT ( v1.is < int > ( ) ); } + +void VariantTest::testSizeT() { + std::variant < size_t, int, void > a ( ( size_t ) 1 ); + std::variant < size_t, int, void > b ( 1 ); + std::variant < size_t, int, void > c; + + CPPUNIT_ASSERT ( a.is < size_t > ( ) ); + CPPUNIT_ASSERT ( b.is < int > ( ) ); + CPPUNIT_ASSERT ( c.is < void > ( ) ); +} diff --git a/alib2std/test-src/extensions/VariantTest.h b/alib2std/test-src/extensions/VariantTest.h index f7804de2cc61eaec3638e060eee8e59994b50166..c4f07ed6f19b3d608ccc069922d1ea4b74a3a96d 100644 --- a/alib2std/test-src/extensions/VariantTest.h +++ b/alib2std/test-src/extensions/VariantTest.h @@ -13,6 +13,7 @@ class VariantTest : public CppUnit::TestFixture CPPUNIT_TEST( testVariantVoid ); CPPUNIT_TEST( testVariantDefault ); CPPUNIT_TEST( testVariantSameTypes ); + CPPUNIT_TEST( testSizeT ); CPPUNIT_TEST_SUITE_END(); public: @@ -74,6 +75,7 @@ public: void testVariantVoid(); void testVariantDefault(); void testVariantSameTypes(); + void testSizeT(); }; namespace std {