From 298765b7d8788624ca551da973db453384a6cf73 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Thu, 1 Oct 2020 21:50:41 +0300 Subject: [PATCH] new class PIVariantSimple PIObject::CONNECTU_QUEUED moved to PIVariantSimple static_assert on undeclared operators PIByteArray << and >> with complex types --- libs/main/core/pibytearray.h | 28 ++---- libs/main/core/piobject.cpp | 14 +-- libs/main/core/piobject.h | 83 ++++++++-------- libs/main/core/piobject_macros.h | 24 ++--- libs/main/core/pivariantsimple.h | 158 +++++++++++++++++++++++++++++ libs/main/math/pimathcomplex.h | 8 +- main.cpp | 165 +++++++++++++++++-------------- 7 files changed, 321 insertions(+), 159 deletions(-) create mode 100644 libs/main/core/pivariantsimple.h diff --git a/libs/main/core/pibytearray.h b/libs/main/core/pibytearray.h index 76e3e6b0..7db8b7b5 100644 --- a/libs/main/core/pibytearray.h +++ b/libs/main/core/pibytearray.h @@ -444,26 +444,16 @@ inline PIByteArray & operator >>(PIByteArray & s, PIMap & v) { template::value, int>::type = 0> -inline PIByteArray & operator <<(PIByteArray & s, const T & ) {piCout << "[PIByteArray] Warning: using undeclared operator <::value, int>::type = 0> -inline PIByteArray & operator >>(PIByteArray & s, T & ) {piCout << "[PIByteArray] Warning: using undeclared operator >>!"; return s;} +inline PIByteArray & operator <<(PIByteArray & s, const T & ) { + static_assert(std::is_trivially_copyable::value, "[PIByteArray] Error: using undeclared operator << for complex type!"); + return s; +} -/* -__PIBYTEARRAY_SIMPLE_TYPE__(bool) -__PIBYTEARRAY_SIMPLE_TYPE__(char) -__PIBYTEARRAY_SIMPLE_TYPE__(short) -__PIBYTEARRAY_SIMPLE_TYPE__(ushort) -__PIBYTEARRAY_SIMPLE_TYPE__(int) -__PIBYTEARRAY_SIMPLE_TYPE__(uint) -__PIBYTEARRAY_SIMPLE_TYPE__(long) -__PIBYTEARRAY_SIMPLE_TYPE__(ulong) -__PIBYTEARRAY_SIMPLE_TYPE__(llong) -__PIBYTEARRAY_SIMPLE_TYPE__(ullong) -__PIBYTEARRAY_SIMPLE_TYPE__(float) -__PIBYTEARRAY_SIMPLE_TYPE__(double) -__PIBYTEARRAY_SIMPLE_TYPE__(ldouble) -__PIBYTEARRAY_SIMPLE_TYPE__(PIChar) -*/ +template::value, int>::type = 0> +inline PIByteArray & operator >>(PIByteArray & s, T & ) { + static_assert(std::is_trivially_copyable::value, "[PIByteArray] Error: using undeclared operator >> for complex type!"); + return s; +} template<> inline uint piHash(const PIByteArray & ba) {return ba.hash();} template<> inline void piSwap(PIByteArray & f, PIByteArray & s) {f.swap(s);} diff --git a/libs/main/core/piobject.cpp b/libs/main/core/piobject.cpp index fa04cd78..06fe88d9 100644 --- a/libs/main/core/piobject.cpp +++ b/libs/main/core/piobject.cpp @@ -105,7 +105,7 @@ PIMap PIObject::properties() const { -bool PIObject::execute(const PIString & method, const PIVector & vl) { +bool PIObject::execute(const PIString & method, const PIVector & vl) { if (method.isEmpty()) return false; if (!isPIObject()) { piCout << "Error: \"execute(" << method << ")\":" << (void*)this << "is not PIObject!"; @@ -121,7 +121,7 @@ bool PIObject::execute(const PIString & method, const PIVector & vl) } -bool PIObject::executeQueued(PIObject * performer, const PIString & method, const PIVector & vl) { +bool PIObject::executeQueued(PIObject * performer, const PIString & method, const PIVector & vl) { if (!isPIObject()) { piCout << "Error: \"executeQueued(" << method << ")\": this(" << (void*)this << ") is not PIObject!"; return false; @@ -535,14 +535,14 @@ PIMutex & PIObject::mutexObjects() { } -void PIObject::callAddrV(void * slot, void * obj, int args, const PIVector & vl) { +void PIObject::callAddrV(void * slot, void * obj, int args, const PIVector & vl) { args = piMini(args, vl.size_s()); switch (args) { case 0: ((void(*)(void *))slot)(obj); break; - case 1: ((void(*)(void * , const PIVariant & ))slot)(obj, vl[0]); break; - case 2: ((void(*)(void * , const PIVariant & , const PIVariant & ))slot)(obj, vl[0], vl[1]); break; - case 3: ((void(*)(void * , const PIVariant & , const PIVariant & , const PIVariant & ))slot)(obj, vl[0], vl[1], vl[2]); break; - case 4: ((void(*)(void * , const PIVariant & , const PIVariant & , const PIVariant & , const PIVariant & ))slot)(obj, vl[0], vl[1], vl[2], vl[3]); break; + case 1: ((void(*)(void * , const PIVariantSimple & ))slot)(obj, vl[0]); break; + case 2: ((void(*)(void * , const PIVariantSimple & , const PIVariantSimple & ))slot)(obj, vl[0], vl[1]); break; + case 3: ((void(*)(void * , const PIVariantSimple & , const PIVariantSimple & , const PIVariantSimple & ))slot)(obj, vl[0], vl[1], vl[2]); break; + case 4: ((void(*)(void * , const PIVariantSimple & , const PIVariantSimple & , const PIVariantSimple & , const PIVariantSimple & ))slot)(obj, vl[0], vl[1], vl[2], vl[3]); break; default: break; } } diff --git a/libs/main/core/piobject.h b/libs/main/core/piobject.h index abfb5436..e85b30c0 100644 --- a/libs/main/core/piobject.h +++ b/libs/main/core/piobject.h @@ -27,6 +27,7 @@ #include "piinit.h" #include "pivariant.h" +#include "pivariantsimple.h" #include "pimutex.h" #include "piset.h" #include "piqueue.h" @@ -101,33 +102,33 @@ public: void setThreadSafe(bool yes) {thread_safe_ = yes;} bool isThreadSafe() const {return thread_safe_;} - bool execute(const PIString & method, const PIVector & vl); - bool execute(const PIString & method) {return execute(method, PIVector());} - bool execute(const PIString & method, const PIVariant & v0) {return execute(method, PIVector() << v0);} - bool execute(const PIString & method, const PIVariant & v0, const PIVariant & v1) {return execute(method, PIVector() << v0 << v1);} - bool execute(const PIString & method, const PIVariant & v0, const PIVariant & v1, const PIVariant & v2) {return execute(method, PIVector() << v0 << v1 << v2);} - bool execute(const PIString & method, const PIVariant & v0, const PIVariant & v1, const PIVariant & v2, const PIVariant & v3) {return execute(method, PIVector() << v0 << v1 << v2 << v3);} + bool execute(const PIString & method, const PIVector & vl); + bool execute(const PIString & method) {return execute(method, PIVector());} + bool execute(const PIString & method, const PIVariantSimple & v0) {return execute(method, PIVector() << v0);} + bool execute(const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1) {return execute(method, PIVector() << v0 << v1);} + bool execute(const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2) {return execute(method, PIVector() << v0 << v1 << v2);} + bool execute(const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2, const PIVariantSimple & v3) {return execute(method, PIVector() << v0 << v1 << v2 << v3);} - bool executeQueued(PIObject * performer, const PIString & method, const PIVector & vl); - bool executeQueued(PIObject * performer, const PIString & method) {return executeQueued(performer, method, PIVector());} - bool executeQueued(PIObject * performer, const PIString & method, const PIVariant & v0) {return executeQueued(performer, method, PIVector() << v0);} - bool executeQueued(PIObject * performer, const PIString & method, const PIVariant & v0, const PIVariant & v1) {return executeQueued(performer, method, PIVector() << v0 << v1);} - bool executeQueued(PIObject * performer, const PIString & method, const PIVariant & v0, const PIVariant & v1, const PIVariant & v2) {return executeQueued(performer, method, PIVector() << v0 << v1 << v2);} - bool executeQueued(PIObject * performer, const PIString & method, const PIVariant & v0, const PIVariant & v1, const PIVariant & v2, const PIVariant & v3) {return executeQueued(performer, method, PIVector() << v0 << v1 << v2 << v3);} + bool executeQueued(PIObject * performer, const PIString & method, const PIVector & vl); + bool executeQueued(PIObject * performer, const PIString & method) {return executeQueued(performer, method, PIVector());} + bool executeQueued(PIObject * performer, const PIString & method, const PIVariantSimple & v0) {return executeQueued(performer, method, PIVector() << v0);} + bool executeQueued(PIObject * performer, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1) {return executeQueued(performer, method, PIVector() << v0 << v1);} + bool executeQueued(PIObject * performer, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2) {return executeQueued(performer, method, PIVector() << v0 << v1 << v2);} + bool executeQueued(PIObject * performer, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2, const PIVariantSimple & v3) {return executeQueued(performer, method, PIVector() << v0 << v1 << v2 << v3);} - static bool execute(PIObject * o, const PIString & method, const PIVector & vl) {return o->execute(method, vl);} - static bool execute(PIObject * o, const PIString & method) {return execute(o, method, PIVector());} - static bool execute(PIObject * o, const PIString & method, const PIVariant & v0) {return execute(o, method, PIVector() << v0);} - static bool execute(PIObject * o, const PIString & method, const PIVariant & v0, const PIVariant & v1) {return execute(o, method, PIVector() << v0 << v1);} - static bool execute(PIObject * o, const PIString & method, const PIVariant & v0, const PIVariant & v1, const PIVariant & v2) {return execute(o, method, PIVector() << v0 << v1 << v2);} - static bool execute(PIObject * o, const PIString & method, const PIVariant & v0, const PIVariant & v1, const PIVariant & v2, const PIVariant & v3) {return execute(o, method, PIVector() << v0 << v1 << v2 << v3);} + static bool execute(PIObject * o, const PIString & method, const PIVector & vl) {return o->execute(method, vl);} + static bool execute(PIObject * o, const PIString & method) {return execute(o, method, PIVector());} + static bool execute(PIObject * o, const PIString & method, const PIVariantSimple & v0) {return execute(o, method, PIVector() << v0);} + static bool execute(PIObject * o, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1) {return execute(o, method, PIVector() << v0 << v1);} + static bool execute(PIObject * o, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2) {return execute(o, method, PIVector() << v0 << v1 << v2);} + static bool execute(PIObject * o, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2, const PIVariantSimple & v3) {return execute(o, method, PIVector() << v0 << v1 << v2 << v3);} - static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVector & vl) {return o->executeQueued(performer, method, vl);} - static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method) {return executeQueued(o, performer, method, PIVector());} - static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVariant & v0) {return executeQueued(o, performer, method, PIVector() << v0);} - static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVariant & v0, const PIVariant & v1) {return executeQueued(o, performer, method, PIVector() << v0 << v1);} - static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVariant & v0, const PIVariant & v1, const PIVariant & v2) {return executeQueued(o, performer, method, PIVector() << v0 << v1 << v2);} - static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVariant & v0, const PIVariant & v1, const PIVariant & v2, const PIVariant & v3) {return executeQueued(o, performer, method, PIVector() << v0 << v1 << v2 << v3);} + static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVector & vl) {return o->executeQueued(performer, method, vl);} + static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method) {return executeQueued(o, performer, method, PIVector());} + static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVariantSimple & v0) {return executeQueued(o, performer, method, PIVector() << v0);} + static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1) {return executeQueued(o, performer, method, PIVector() << v0 << v1);} + static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2) {return executeQueued(o, performer, method, PIVector() << v0 << v1 << v2);} + static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2, const PIVariantSimple & v3) {return executeQueued(o, performer, method, PIVector() << v0 << v1 << v2 << v3);} void dump(const PIString & line_prefix = PIString()) const; @@ -201,8 +202,8 @@ public: (*((std::function*)i.functor))(v0); } else { if (i.performer) { - PIVector vl; - if (i.args_count > 0) vl << PIVariant::fromValue(v0); + PIVector vl; + if (i.args_count > 0) vl << PIVariantSimple::fromValue(v0); i.performer->postQueuedEvent(__QueuedEvent(i.slot, i.dest, i.dest_o, sender, vl)); } else { bool ts = sender->thread_safe_; @@ -232,9 +233,9 @@ public: (*((std::function*)i.functor))(v0, v1); } else { if (i.performer) { - PIVector vl; - if (i.args_count > 0) vl << PIVariant::fromValue(v0); - if (i.args_count > 1) vl << PIVariant::fromValue(v1); + PIVector vl; + if (i.args_count > 0) vl << PIVariantSimple::fromValue(v0); + if (i.args_count > 1) vl << PIVariantSimple::fromValue(v1); i.performer->postQueuedEvent(__QueuedEvent(i.slot, i.dest, i.dest_o, sender, vl)); } else { bool ts = sender->thread_safe_; @@ -267,10 +268,10 @@ public: (*((std::function*)i.functor))(v0, v1, v2); } else { if (i.performer) { - PIVector vl; - if (i.args_count > 0) vl << PIVariant::fromValue(v0); - if (i.args_count > 1) vl << PIVariant::fromValue(v1); - if (i.args_count > 2) vl << PIVariant::fromValue(v2); + PIVector vl; + if (i.args_count > 0) vl << PIVariantSimple::fromValue(v0); + if (i.args_count > 1) vl << PIVariantSimple::fromValue(v1); + if (i.args_count > 2) vl << PIVariantSimple::fromValue(v2); i.performer->postQueuedEvent(__QueuedEvent(i.slot, i.dest, i.dest_o, sender, vl)); } else { bool ts = sender->thread_safe_; @@ -304,11 +305,11 @@ public: (*((std::function*)i.functor))(v0, v1, v2, v3); } else { if (i.performer) { - PIVector vl; - if (i.args_count > 0) vl << PIVariant::fromValue(v0); - if (i.args_count > 1) vl << PIVariant::fromValue(v1); - if (i.args_count > 2) vl << PIVariant::fromValue(v2); - if (i.args_count > 3) vl << PIVariant::fromValue(v3); + PIVector vl; + if (i.args_count > 0) vl << PIVariantSimple::fromValue(v0); + if (i.args_count > 1) vl << PIVariantSimple::fromValue(v1); + if (i.args_count > 2) vl << PIVariantSimple::fromValue(v2); + if (i.args_count > 3) vl << PIVariantSimple::fromValue(v3); i.performer->postQueuedEvent(__QueuedEvent(i.slot, i.dest, i.dest_o, sender, vl)); } else { bool ts = sender->thread_safe_; @@ -452,7 +453,7 @@ private: }; struct __QueuedEvent { - __QueuedEvent(void * sl = 0, void * d = 0, PIObject * d_o = 0, PIObject * s = 0, const PIVector & v = PIVector()) { + __QueuedEvent(void * sl = 0, void * d = 0, PIObject * d_o = 0, PIObject * s = 0, const PIVector & v = PIVector()) { slot = sl; dest = d; dest_o = d_o; @@ -463,7 +464,7 @@ private: void * dest; PIObject * dest_o; PIObject * src; - PIVector values; + PIVector values; }; class Deleter { @@ -496,7 +497,7 @@ private: static PIVector & objects(); static PIMutex & mutexObjects(); - static void callAddrV(void * slot, void * obj, int args, const PIVector & vl); + static void callAddrV(void * slot, void * obj, int args, const PIVector & vl); PIVector<__Connection> connections; diff --git a/libs/main/core/piobject_macros.h b/libs/main/core/piobject_macros.h index c4c5da43..261c4531 100644 --- a/libs/main/core/piobject_macros.h +++ b/libs/main/core/piobject_macros.h @@ -269,7 +269,7 @@ PIMutexLocker ml(__meta_mutex()); \ __MetaData & eh(__meta_data()[__classNameIDS()]); \ void * fp = (void*)(ret(*)(void*, a0))__stat_eh_##name##__; \ - void * fpV = (void*)(ret(*)(void*, const PIVariant &))__stat_eh_v_##name##__; \ + void * fpV = (void*)(ret(*)(void*, const PIVariantSimple &))__stat_eh_v_##name##__; \ if (eh.eh_set[fp]) return; \ eh.eh_set << fp; \ __MetaFunc & f(eh.eh_func[fp]); \ @@ -287,7 +287,7 @@ PIMutexLocker ml(__meta_mutex()); \ __MetaData & eh(__meta_data()[__classNameIDS()]); \ void * fp = (void*)(ret(*)(void*, a0, a1))__stat_eh_##name##__; \ - void * fpV = (void*)(ret(*)(void*, const PIVariant &, const PIVariant &))__stat_eh_v_##name##__; \ + void * fpV = (void*)(ret(*)(void*, const PIVariantSimple &, const PIVariantSimple &))__stat_eh_v_##name##__; \ if (eh.eh_set[fp]) return; \ eh.eh_set << fp; \ __MetaFunc & f(eh.eh_func[fp]); \ @@ -305,7 +305,7 @@ PIMutexLocker ml(__meta_mutex()); \ __MetaData & eh(__meta_data()[__classNameIDS()]); \ void * fp = (void*)(ret(*)(void*, a0, a1, a2))__stat_eh_##name##__; \ - void * fpV = (void*)(ret(*)(void*, const PIVariant &, const PIVariant &, const PIVariant &))__stat_eh_v_##name##__; \ + void * fpV = (void*)(ret(*)(void*, const PIVariantSimple &, const PIVariantSimple &, const PIVariantSimple &))__stat_eh_v_##name##__; \ if (eh.eh_set[fp]) return; \ eh.eh_set << fp; \ __MetaFunc & f(eh.eh_func[fp]); \ @@ -323,7 +323,7 @@ PIMutexLocker ml(__meta_mutex()); \ __MetaData & eh(__meta_data()[__classNameIDS()]); \ void * fp = (void*)(ret(*)(void*, a0, a1, a2, a3))__stat_eh_##name##__; \ - void * fpV = (void*)(ret(*)(void*, const PIVariant &, const PIVariant &, const PIVariant &, const PIVariant &))__stat_eh_v_##name##__; \ + void * fpV = (void*)(ret(*)(void*, const PIVariantSimple &, const PIVariantSimple &, const PIVariantSimple &, const PIVariantSimple &))__stat_eh_v_##name##__; \ if (eh.eh_set[fp]) return; \ eh.eh_set << fp; \ __MetaFunc & f(eh.eh_func[fp]); \ @@ -345,7 +345,7 @@ #define EVENT_HANDLER1(ret, name, a0, n0) \ EH_INIT1(ret, name, a0, n0) \ static ret __stat_eh_##name##__(void * __o__, a0 n0) {return ((__PIObject__*)__o__)->name(n0);} \ - static ret __stat_eh_v_##name##__(void * __o__, const PIVariant & v0) { \ + static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0) { \ __PTYPE(a0) tv0 = __VVALUE(a0, v0); \ return ((__PIObject__*)__o__)->name(tv0);} \ ret name(a0 n0) @@ -353,7 +353,7 @@ #define EVENT_HANDLER2(ret, name, a0, n0, a1, n1) \ EH_INIT2(ret, name, a0, n0, a1, n1) \ static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1) {return ((__PIObject__*)__o__)->name(n0, n1);} \ - static ret __stat_eh_v_##name##__(void * __o__, const PIVariant & v0, const PIVariant & v1) { \ + static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0, const PIVariantSimple & v1) { \ __PTYPE(a0) tv0 = __VVALUE(a0, v0); \ __PTYPE(a1) tv1 = __VVALUE(a1, v1); \ return ((__PIObject__*)__o__)->name(tv0, tv1);} \ @@ -362,7 +362,7 @@ #define EVENT_HANDLER3(ret, name, a0, n0, a1, n1, a2, n2) \ EH_INIT3(ret, name, a0, n0, a1, n1, a2, n2) \ static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1, a2 n2) {return ((__PIObject__*)__o__)->name(n0, n1, n2);} \ - static ret __stat_eh_v_##name##__(void * __o__, const PIVariant & v0, const PIVariant & v1, const PIVariant & v2) { \ + static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2) { \ __PTYPE(a0) tv0 = __VVALUE(a0, v0); \ __PTYPE(a1) tv1 = __VVALUE(a1, v1); \ __PTYPE(a2) tv2 = __VVALUE(a2, v2); \ @@ -372,7 +372,7 @@ #define EVENT_HANDLER4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) \ EH_INIT4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) \ static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1, a2 n2, a3 n3) {return ((__PIObject__*)__o__)->name(n0, n1, n2, n3);} \ - static ret __stat_eh_v_##name##__(void * __o__, const PIVariant & v0, const PIVariant & v1, const PIVariant & v2, const PIVariant & v3) { \ + static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2, const PIVariantSimple & v3) { \ __PTYPE(a0) tv0 = __VVALUE(a0, v0); \ __PTYPE(a1) tv1 = __VVALUE(a1, v1); \ __PTYPE(a2) tv2 = __VVALUE(a2, v2); \ @@ -391,25 +391,25 @@ #define EVENT_VHANDLER1(ret, name, a0, n0) \ EH_INIT1(ret, name, a0, n0) \ static ret __stat_eh_##name##__(void * __o__, a0 n0) {return ((__PIObject__*)__o__)->name(n0);} \ - static ret __stat_eh_v_##name##__(void * __o__, const PIVariant & v0) {return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0));} \ + static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0) {return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0));} \ virtual ret name(a0 n0) #define EVENT_VHANDLER2(ret, name, a0, n0, a1, n1) \ EH_INIT2(ret, name, a0, n0, a1, n1) \ static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1) {return ((__PIObject__*)__o__)->name(n0, n1);} \ - static ret __stat_eh_v_##name##__(void * __o__, const PIVariant & v0, const PIVariant & v1) {return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1));} \ + static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0, const PIVariantSimple & v1) {return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1));} \ virtual ret name(a0 n0, a1 n1) #define EVENT_VHANDLER3(ret, name, a0, n0, a1, n1, a2, n2) \ EH_INIT3(ret, name, a0, n0, a1, n1, a2, n2) \ static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1, a2 n2) {return ((__PIObject__*)__o__)->name(n0, n1, n2);} \ - static ret __stat_eh_v_##name##__(void * __o__, const PIVariant & v0, const PIVariant & v1, const PIVariant & v2) {return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1), __VVALUE(a2, v2));} \ + static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2) {return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1), __VVALUE(a2, v2));} \ virtual ret name(a0 n0, a1 n1, a2 n2) #define EVENT_VHANDLER4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) \ EH_INIT4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) \ static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1, a2 n2, a3 n3) {return ((__PIObject__*)__o__)->name(n0, n1, n2, n3);} \ - static ret __stat_eh_v_##name##__(void * __o__, const PIVariant & v0, const PIVariant & v1, const PIVariant & v2, const PIVariant & v3) {return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1), __VVALUE(a2, v2), __VVALUE(a3, v3));} \ + static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2, const PIVariantSimple & v3) {return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1), __VVALUE(a2, v2), __VVALUE(a3, v3));} \ virtual ret name(a0 n0, a1 n1, a2 n2, a3 n3) #define EVENT_VHANDLER EVENT_VHANDLER0 diff --git a/libs/main/core/pivariantsimple.h b/libs/main/core/pivariantsimple.h new file mode 100644 index 00000000..ba2d2e9e --- /dev/null +++ b/libs/main/core/pivariantsimple.h @@ -0,0 +1,158 @@ +/*! \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 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) {;} + 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 {static PIString ret(typeid(T).name()); return ret;} + 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;} +}; + +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->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); + } + + 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 diff --git a/libs/main/math/pimathcomplex.h b/libs/main/math/pimathcomplex.h index 9d428d56..79e651d5 100644 --- a/libs/main/math/pimathcomplex.h +++ b/libs/main/math/pimathcomplex.h @@ -46,13 +46,7 @@ const complexd complexd_1(1.); const complexld complexld_i(0., 1.); const complexld complexld_0(0.); const complexld complexld_1(1.); -/* -__PIBYTEARRAY_SIMPLE_TYPE__(complexi) -__PIBYTEARRAY_SIMPLE_TYPE__(complexs) -__PIBYTEARRAY_SIMPLE_TYPE__(complexf) -__PIBYTEARRAY_SIMPLE_TYPE__(complexd) -__PIBYTEARRAY_SIMPLE_TYPE__(complexld) -*/ + inline complexd sign(const complexd & x) {return complexd(sign(x.real()), sign(x.imag()));} inline complexd round(const complexd & c) {return complexd(piRound(c.real()), piRound(c.imag()));} diff --git a/main.cpp b/main.cpp index d27a590f..28bd520d 100644 --- a/main.cpp +++ b/main.cpp @@ -1,80 +1,99 @@ #include "pip.h" +#include "pivariantsimple.h" -struct A { - double x1; - //PIString str; + +template +struct __VariantTypeInfo__ { + typedef T PureType; + typedef const T ConstPureType; + typedef T * PointerType; + typedef const T * ConstPointerType; + typedef T & ReferenceType; + typedef const T & ConstReferenceType; }; -//inline PIByteArray & operator <<(PIByteArray & s, const A & a) {s << a.x1/* << a.x2*/; return s;} -//inline PIByteArray & operator >>(PIByteArray & s, A & a) {s >> a.x1/* >> a.x2*/; return s;} -struct B { - B() { - x1=0; +#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 &) + + + +struct SwitchChannel { + SwitchChannel(bool on_ = true, float dur_ = 10.f, int m_count = 0, short unrely = -1) { + on = on_ ? 1 : 0; + duration = dur_; + max_count = m_count; + overload[0] = overload[1] = false; + unreliability = unrely; } - B(const B & b) = default; - //B & operator =(const B & b) {x1=b.x1; return *this;} - //A aa; - double x1; + uchar on; + short unreliability; + float duration; + int max_count; + bool overload[2]; }; -//__PIVECTOR_SIMPLE_TYPE__(B) - -#include "piconditionvar.h" -int main() { - PIByteArray ba; ba.reserve(100*100*16); - - PITimeMeasurer tm; - PIVector2D vx; - PIVector2D vd; - ba << vx; - ba >> vx; - vd.resize(100, 100); - vx = vd; - tm.reset(); - for(int i=0; i<1000; ++i) { - vx.clear(); - vx = vd; - ba << vx; - ba >> vd; - } - piCout << tm.elapsed_m(); - - PIVector2D ax; - PIVector2D ad; - ad.resize(100, 100); - ax = ad; - tm.reset(); - for(int i=0; i<1000; ++i) { - ax.clear(); - ax = ad; - ba << ax; - ba >> ad; - } - piCout << tm.elapsed_m(); - - PIVector2D bx; - PIVector2D bd; - bd.resize(100, 100); - bx = bd; - tm.reset(); - for(int i=0; i<1000; ++i) { - bx.clear(); - bx = bd; - ba << bx; - ba >> bd; - } - piCout << tm.elapsed_m(); - - PIVector2D cx; - PIVector2D cd; - cd.resize(100, 100); - cx = cd; - tm.reset(); - for(int i=0; i<1000; ++i) { - cx.clear(); - cx = cd; - ba << cx; - ba >> cd; - } - piCout << tm.elapsed_m(); - return 0; +/* +inline PIByteArray & operator <<(PIByteArray & ba, const SwitchChannel & v) { + PIChunkStream cs; + cs << cs.chunk(1, v.on) + << cs.chunk(2, v.duration) + << cs.chunk(3, v.max_count) + << cs.chunk(4, v.unreliability); + ba << cs.data(); + return ba; +} +inline PIByteArray & operator >>(PIByteArray & ba, SwitchChannel & v) { + PIByteArray src; ba >> src; PIChunkStream cs(src); + while (!cs.atEnd()) { + switch (cs.read()) { + case 1: cs.get(v.on); break; + case 2: cs.get(v.duration); break; + case 3: cs.get(v.max_count); break; + case 4: cs.get(v.unreliability); break; + } + } + return ba; +}*/ +inline PICout operator <<(PICout c, const SwitchChannel & v) { + c << v.on << v.duration << v.max_count << v.unreliability; + return c; +} + + + +int Acnt = 0; + +class A { +public: + A() {moved = false; i = "constructor"; piCout << "A()"; ++Acnt;} + A(const PIString & s): i(s) {moved = false; piCout << "A(String)"; ++Acnt;} + A(const A & a): i(a.i) {moved = false; piCout << "copy A(&)"; ++Acnt;} + A(A && a): i(std::move(a.i)) {moved = false; a.moved = true; piCout << "copy A(&&)"; ++Acnt;} + ~A() {piCout << "~A()" << moved; --Acnt;} + void swap(A & a) {piCout << "swap A()"; piSwap(i, a.i);} + A & operator =(const A & a) {i = a.i; piCout << "= A&"; return *this;} + A & operator =(A && a) {piSwap(i, a.i); a.moved = true; piCout << "= A&&)"; return *this;} + PIString i; + bool moved; + static void F(int) {} +}; +PIByteArray & operator <<(PIByteArray & ba, const A & v) {ba << v.i; return ba;} +PIByteArray & operator >>(PIByteArray & ba, A & v) {ba >> v.i; return ba;} + + +int main() { + A a; + PIByteArray ba; + ba >> a; }