/*! \file pivariantsimple.h * \brief Variant simple type * * This file declares PIVariantSimple */ /* 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 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) {;} //virtual PIByteArray toData(const void * ptr) const {return PIByteArray();} //virtual void fromData(void *& ptr, PIByteArray ba) {;} static PIMap & registered() {static PIMap ret; return ret;} }; template class __VariantFunctions__: public __VariantFunctionsBase__ { public: __VariantFunctionsBase__ * instance() final {static __VariantFunctions__ ret; return &ret;} PIString typeName() const final {static PIString ret(typeid(T).name()); return ret;} 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)); /*printf(" * new\n")*/;} void newNullT(void *& ptr) final {ptr = (void*)(new T());/* printf(" * new null\n")*/;} void assignT(void *& ptr, const void * value) final {*(T*)ptr = *(const T*)value; /*printf(" * =\n")*/;} void deleteT(void *& ptr) final {delete (T*)(ptr); /*printf(" * del\n")*/;} //PIByteArray toData(const void * ptr) const final {PIByteArray ret; ret << (*(const T* &)ptr); return ret;} //void fromData(void *& ptr, PIByteArray ba) final {ba >> *(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; } /* PIByteArray save() const { if (!ptr || !f) return PIByteArray(); PIByteArray ret; ret << f->hash(); ret.append(f->toData(ptr)); return ret; } bool load(PIByteArray ba) { if (ba.size_s() < 4) return false; uint h(0); ba >> h; destroy(); f = __VariantFunctionsBase__::registered().value(h, 0); if (!f) return false; f->newNullT(ptr); f->fromData(ptr, ba); return true; } */ private: template bool isMyType() const { 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_STREAM(Type) \ STATIC_INITIALIZER_BEGIN() \ __VariantFunctionsBase__ * f = __VariantFunctions__().instance(); \ __VariantFunctionsBase__::registered()[f->hash()] = f; \ STATIC_INITIALIZER_END() #endif // PIVARIANTSIMPLE_H