X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fcore%2Fvariant.h;h=fccf891850f8045a528ad723b7fd781c7df72c09;hb=83fcabb1fc1acff5d115f07253f801fc3f7cca9a;hp=04c372b54ef305205e6f38e661a408eab75d18d6;hpb=e42c69a8d3416be5071637cd4e241593458cb941;p=libs%2Fcore.git diff --git a/source/core/variant.h b/source/core/variant.h index 04c372b..fccf891 100644 --- a/source/core/variant.h +++ b/source/core/variant.h @@ -5,17 +5,18 @@ #include #include #include "meta.h" +#include "mspcore_api.h" namespace Msp { -class type_mismatch: public std::runtime_error +class MSPCORE_API type_mismatch: public std::runtime_error { public: type_mismatch(const std::type_info &, const std::type_info &); }; -class Variant +class MSPCORE_API Variant { public: static constexpr unsigned INTERNAL_SIZE = 2*sizeof(void *); @@ -37,13 +38,15 @@ public: template Variant(const T &v) { assign(v); } Variant(const Variant &v) { copy_from(v); } - ~Variant() { if(funcs) funcs->destroy(storage); } + ~Variant() { clear(); } template Variant &operator=(const T &v) { assign(v); return *this; } Variant &operator=(const Variant &v) { if(&v!=this) copy_from(v); return *this; } + void clear(); + private: template void assign(const T &); @@ -61,9 +64,14 @@ public: const T &value() const { return const_cast(this)->get(); } template - bool check_type() const { return funcs==get_functions::type>(); } + bool has_type() const { return type_equals(funcs, get_functions::type>()); } + + bool has_same_type(const Variant &v) const { return type_equals(funcs, v.funcs); } - bool check_same_type(const Variant &v) const { return (funcs && funcs==v.funcs); } + template + DEPRECATED bool check_type() const { return has_type(); } + + DEPRECATED bool check_same_type(const Variant &v) const { return has_same_type(v); } bool operator==(const Variant &v) const { return (has_same_type(v) && funcs->compare(storage, v.storage)); } bool operator!=(const Variant &v) const { return !(operator==(v)); } @@ -72,6 +80,8 @@ public: operator T() const { return value(); } private: + static bool type_equals(const Functions *, const Functions *); + template static constexpr bool is_small() { return (sizeof(T)<=INTERNAL_SIZE && alignof(T)<=alignof(void *)); } @@ -125,23 +135,25 @@ private: }; -template -inline void Variant::assign(const T &value) +inline void Variant::clear() { if(funcs) funcs->destroy(storage); + funcs = nullptr; +} +template +inline void Variant::assign(const T &v) +{ + clear(); funcs = get_functions::type>(); - create(storage, value); + create(storage, v); } inline void Variant::copy_from(const Variant &v) { - if(funcs) - funcs->destroy(storage); - - funcs = v.funcs; - if(funcs) + clear(); + if((funcs = v.funcs)) funcs->clone(storage, v.storage); } @@ -157,6 +169,16 @@ inline T &Variant::get() return **reinterpret_cast(storage); } +inline bool Variant::type_equals(const Functions *funcs1, const Functions *funcs2) +{ + if(!funcs1 || !funcs2) + return false; + else if(funcs1==funcs2) + return true; + else + return funcs1->get_type()==funcs2->get_type(); +} + template inline const Variant::Functions *Variant::get_functions() {