#include "pip.h" PIMap results; template struct __VariantTypeInfo__ { typedef T PureType; typedef const T ConstPureType; typedef T * PointerType; typedef const T * ConstPointerType; typedef T & ReferenceType; typedef const T & ConstReferenceType; }; #define __TYPEINFO_SINGLE(PT, T) \ template<> struct __PIVariantTypeInfo__ { \ typedef PT PureType; \ typedef const PT ConstPureType; \ typedef PT * PointerType; \ typedef const PT * ConstPointerType; \ typedef PT & ReferenceType; \ typedef const PT & ConstReferenceType; \ }; #define REGISTER_VARIANT_TYPEINFO(T) \ __TYPEINFO_SINGLE(T, T &) \ __TYPEINFO_SINGLE(T, const T) \ __TYPEINFO_SINGLE(T, const T &) 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 equalT(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) {;} //template static PIByteArray castHelper(PIByteArray ba) {return PIByteArray();} //template static C castVariant(const T & v) {return C();} static PIMap & registered() {static PIMap ret; return ret;} }; template class __VariantFunctions__: public __VariantFunctionsBase__ { public: __VariantFunctionsBase__ * instance() override {static __VariantFunctions__ ret; return &ret;} PIString typeName() const override {return PIString();} uint hash() const override {static uint ret = typeName().hash(); return ret;} void newT(void *& ptr, const void * value) override {ptr = (void*)(new T(*(const T*)value)); printf(" * new\n");} void newNullT(void *& ptr) override {ptr = (void*)(new T()); printf(" * new null\n");} void equalT(void *& ptr, const void * value) override {*(T*)ptr = *(const T*)value; printf(" * =\n");} void deleteT(void *& ptr) override {delete (T*)(ptr); printf(" * del\n");} PIByteArray toData(const void * ptr) const override {PIByteArray ret; ret << (*(const T* &)ptr); return ret;} void fromData(void *& ptr, PIByteArray ba) override {ba >> *(T*)ptr;} template static PIByteArray castHelper(PIByteArray ba) {return PIByteArray();} template static C castVariant(const T & v) {return C();} }; class Variant { public: Variant() {ptr = 0; f = 0;} Variant(const Variant & v) { ptr = 0; f = v.f; if (f && v.ptr) f->newT(ptr, v.ptr); } ~Variant() {destroy();} Variant & operator=(const Variant & 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->equalT(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); } 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 {return f->hash() == __VariantFunctions__().instance()->hash();} void destroy() { if (ptr && f) f->deleteT(ptr); ptr = 0; f = 0; } void * ptr; __VariantFunctionsBase__ * f; }; int Acnt = 0; class A { public: A() {i = "constructor"; /*piCout << "A()";*/ ++Acnt;} A(const A & a): i(a.i) {/*piCout << "copy A()";*/ ++Acnt;} ~A() {/*piCout << "~A()";*/ --Acnt;} A & operator =(const A & a) {i = a.i; /*piCout << "= A()";*/ return *this;} PIString i; }; PIByteArray & operator <<(PIByteArray & ba, const A & v) {ba << v.i; return ba;} PIByteArray & operator >>(PIByteArray & ba, A & v) {ba >> v.i; return ba;} template <> PIString __VariantFunctions__::typeName() const {static PIString ret("int"); return ret;} class _VariantRegistrator_int__ { public: _VariantRegistrator_int__() { __VariantFunctionsBase__ * f = __VariantFunctions__().instance(); __VariantFunctionsBase__::registered()[f->hash()] = f; } }; _VariantRegistrator_int__ __reg_int__; template <> PIString __VariantFunctions__::typeName() const {static PIString ret("A"); return ret;} class _VariantRegistrator_A__ { public: _VariantRegistrator_A__() { __VariantFunctionsBase__ * f = __VariantFunctions__().instance(); __VariantFunctionsBase__::registered()[f->hash()] = f; } }; _VariantRegistrator_A__ __reg_A__; int main() { { Variant v, v2; /*{ A a, ra; a.i = "main"; v.setValue(a); ra = v.value(); piCout << " 1 A.i =" << ra.i; a.i = "main second"; v.setValue(a); ra = v.value(); piCout << " 2 A.i =" << ra.i; piCout << "Acnt" << Acnt; } piCout << "Acnt" << Acnt; v2 = v; PIString ra = v2.value(); piCout << " 3 A.i =" << ra;*/ A a, ra; a.i = "main"; v.setValue(a); PIByteArray ba = v.save(); piCout << v2.load(ba); piCout << v2.value().i; } piCout << "Acnt" << Acnt; //__VariantFunctionsBase__ * f = __VariantFunctions__().instance(); //piCout << f->typeName(); //f = __VariantFunctions__().instance(); //piCout << f->typeName(); } /* template void test_var(const char * Tname) { piCout << Tname << "..."; ullong cnt = 0; PIVariant _v; PITimeMeasurer tm1s; while (tm1s.elapsed_m() < 500.) { ++cnt; for (int j = 0; j < 1000; ++j) { PIVariant v; v = T(); v.setValue(T(j)); _v = v; } } PIVariant v; results[Tname] = cnt; } #define TEST_VAR(T) test_var(#T) int main() { TEST_VAR(int); TEST_VAR(float); TEST_VAR(ullong); TEST_VAR(PIString); int sz = 0; auto i = results.makeIterator(); while (i.next()) sz = piMaxi(sz, i.key().length()); i.reset(); while (i.next()) piCout << i.key().expandedLeftTo(sz, ' ') << ":" << i.value(); } */