/*! \file pivariantsimple.h * \ingroup Core * \brief * \~english Variant simple type * \~russian Простой вариативный тип */ /* PIP - Platform Independent Primitives Variant simple type Ivan Pelipenko peri4ko@yandex.ru This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #ifndef PIVARIANTSIMPLE_H #define PIVARIANTSIMPLE_H #include "pistring.h" #include #ifdef MICRO_PIP #include "pivariant.h" #endif class __VariantFunctionsBase__ { public: virtual __VariantFunctionsBase__ * instance() {return 0;} virtual PIString typeName() const {return PIString();} virtual uint hash() const {return 0;} virtual void newT(void *& ptr, const void * value) {;} virtual void newNullT(void *& ptr) {;} virtual void assignT(void *& ptr, const void * value) {;} virtual void deleteT(void *& ptr) {;} }; template class __VariantFunctions__: public __VariantFunctionsBase__ { public: __VariantFunctionsBase__ * instance() final {static __VariantFunctions__ ret; return &ret;} #ifdef MICRO_PIP PIString typeName() const final {static PIString ret(PIVariant(T()).typeName()); return ret;} #else PIString typeName() const final {static PIString ret(typeid(T).name()); return ret;} #endif uint hash() const final {static uint ret = typeName().hash(); return ret;} void newT(void *& ptr, const void * value) final {ptr = (void*)(new T(*(const T*)value));} void newNullT(void *& ptr) final {ptr = (void*)(new T());} void assignT(void *& ptr, const void * value) final {*(T*)ptr = *(const T*)value;} void deleteT(void *& ptr) final {delete (T*)(ptr);} }; class PIVariantSimple { public: PIVariantSimple() {ptr = 0; f = 0;} PIVariantSimple(const PIVariantSimple & v) { ptr = 0; f = v.f; if (f && v.ptr) f->newT(ptr, v.ptr); } ~PIVariantSimple() {destroy();} PIVariantSimple & operator=(const PIVariantSimple & v) { destroy(); f = v.f; if (f && v.ptr) f->newT(ptr, v.ptr); return *this; } template void setValue(const T & v) { if (f) { if (isMyType()) { f->assignT(ptr, (const void *)&v); return; } } destroy(); f = __VariantFunctions__().instance(); f->newT(ptr, (const void *)&v); } template T value() const { if (!f) return T(); if (!isMyType()) return T(); return *(T*)(ptr); } template static PIVariantSimple fromValue(const T & v) { PIVariantSimple ret; ret.setValue(v); return ret; } private: template bool isMyType() const { if (!f) return false; uint mh = f->hash(), th = __VariantFunctions__().instance()->hash(); if (mh == 0 || th == 0) return false; return mh == th; } void destroy() { if (ptr && f) f->deleteT(ptr); ptr = 0; f = 0; } void * ptr; __VariantFunctionsBase__ * f; }; #define REGISTER_PIVARIANTSIMPLE(Type) \ template<> \ class __VariantFunctions__: public __VariantFunctionsBase__ { \ public: \ __VariantFunctionsBase__ * instance() final {static __VariantFunctions__ ret; return &ret;} \ PIString typeName() const final {static PIString ret(#Type); return ret;} \ uint hash() const final {static uint ret = typeName().hash(); return ret;} \ void newT(void *& ptr, const void * value) final {ptr = (void*)(new Type(*(const Type *)value));} \ void newNullT(void *& ptr) final {ptr = (void*)(new Type());} \ void assignT(void *& ptr, const void * value) final {*(Type *)ptr = *(const Type *)value;} \ void deleteT(void *& ptr) final {delete (Type *)(ptr);} \ }; REGISTER_PIVARIANTSIMPLE(std::function) #endif // PIVARIANTSIMPLE_H