From e474c5a8de1b27fb5057a6344dcb4312aa65405a Mon Sep 17 00:00:00 2001 From: andrey Date: Mon, 28 Sep 2020 15:38:45 +0300 Subject: [PATCH 1/4] remove __PICONTAINERS_SIMPLE_TYPE__ --- libs/main/containers/pideque.h | 115 +++++++++++++++++--------- libs/main/containers/pimap.h | 3 - libs/main/containers/pivector.h | 114 +++++++++++++++++--------- libs/main/containers/pivector2d.h | 25 ++---- libs/main/core/pibytearray.h | 1 - libs/main/math/pimathcomplex.h | 10 --- main.cpp | 131 ++++++++++++++++-------------- 7 files changed, 227 insertions(+), 172 deletions(-) diff --git a/libs/main/containers/pideque.h b/libs/main/containers/pideque.h index dd62b501..82d00b45 100644 --- a/libs/main/containers/pideque.h +++ b/libs/main/containers/pideque.h @@ -209,7 +209,22 @@ public: inline T * data(size_t index = 0) {return &(pid_data[pid_start + index]);} inline const T * data(size_t index = 0) const {return &(pid_data[pid_start + index]);} - inline PIDeque & clear() {resize(0); return *this;} + template::value + , int>::type = 0> + inline PIDeque & clear() { + resize(0); + return *this; + } + template::value + , int>::type = 0> + inline PIDeque & clear() { + PIINTROSPECTION_CONTAINER_UNUSED(T, pid_size) + pid_size = 0; + return *this; + } + inline PIDeque & fill(const T & f = T()) { deleteT(pid_data + pid_start, pid_size); PIINTROSPECTION_CONTAINER_USED(T, pid_size) @@ -218,10 +233,20 @@ public: return *this; } inline PIDeque & assign(const T & f = T()) {return fill(f);} + template::value + , int>::type = 0> inline PIDeque & assign(size_t new_size, const T & f) { resize(new_size); return fill(f); } + template::value + , int>::type = 0> + inline PIDeque & assign(size_t new_size, const T & f) { + _resizeRaw(new_size); + return fill(f); + } inline PIDeque & resize(size_t new_size, const T & f = T()) { if (new_size < pid_size) { @@ -236,9 +261,18 @@ public: } return *this; } + + template::value + , int>::type = 0> inline PIDeque & _resizeRaw(size_t new_size) { - piCout << "Error, \"resizeRaw()\" only allowed for simple type declared with __PIDEQUE_SIMPLE_TYPE__ macro!"; - assert(0); + if (new_size > pid_size) { + PIINTROSPECTION_CONTAINER_USED(T, (new_size-pid_size)); + } + if (new_size < pid_size) { + PIINTROSPECTION_CONTAINER_UNUSED(T, (pid_size-new_size)); + } + alloc(new_size, true); return *this; } @@ -437,11 +471,24 @@ private: ++t; return (1 << t); } + template::value + , int>::type = 0> inline void newT(T * dst, const T * src, size_t s) { PIINTROSPECTION_CONTAINER_USED(T, s) for (size_t i = 0; i < s; ++i) elementNew(dst + i, src[i]); } + template::value + , int>::type = 0> + inline void newT(T * dst, const T * src, size_t s) { + PIINTROSPECTION_CONTAINER_USED(T, s) + memcpy((void*)(dst), (const void*)(src), s * sizeof(T)); + } + template::value + , int>::type = 0> inline void deleteT(T * d, size_t sz) { PIINTROSPECTION_CONTAINER_UNUSED(T, sz) if ((uchar*)d != 0) { @@ -449,9 +496,36 @@ private: elementDelete(d[i]); } } + template::value + , int>::type = 0> + inline void deleteT(T * d, size_t sz) { + PIINTROSPECTION_CONTAINER_UNUSED(T, sz) + } + template::value + , int>::type = 0> inline void elementNew(T * to, const T & from) {new(to)T(from);} + template::value + , int>::type = 0> inline void elementNew(T * to, T && from) {new(to)T(std::move(from));} + template::value + , int>::type = 0> + inline void elementNew(T1 * to, const T & from) {(*to) = from;} + template::value + , int>::type = 0> + inline void elementNew(T * to, T && from) {(*to) = std::move(from);} + template::value + , int>::type = 0> inline void elementDelete(T & from) {from.~T();} + template::value + , int>::type = 0> + inline void elementDelete(T & from) {} inline void dealloc() { if ((uchar*)pid_data != 0) free((uchar*)pid_data); pid_data = 0; @@ -520,41 +594,6 @@ private: ssize_t pid_start; }; -#define __PIDEQUE_SIMPLE_TYPE__(T) \ - template<> inline void PIDeque::newT(T * dst, const T * src, size_t s) {PIINTROSPECTION_CONTAINER_USED(T, s); memcpy((void*)(dst), (const void*)(src), s * sizeof(T));} \ - template<> inline void PIDeque::deleteT(T *, size_t sz) {PIINTROSPECTION_CONTAINER_UNUSED(T, sz);} \ - template<> inline void PIDeque::elementNew(T * to, const T & from) {(*to) = from;} \ - template<> inline void PIDeque::elementNew(T * to, T && from) {(*to) = std::move(from);} \ - template<> inline void PIDeque::elementDelete(T &) {;} \ - template<> inline PIDeque & PIDeque::_resizeRaw(size_t new_size) { \ - if (new_size > pid_size) { \ - PIINTROSPECTION_CONTAINER_USED(T, (new_size-pid_size)); \ - } \ - if (new_size < pid_size) { \ - PIINTROSPECTION_CONTAINER_UNUSED(T, (pid_size-new_size)); \ - } \ - alloc(new_size, true); \ - return *this; \ - } \ - template<> inline PIDeque & PIDeque::clear() {PIINTROSPECTION_CONTAINER_UNUSED(T, pid_size); pid_size = 0; return *this;} \ - template<> inline PIDeque & PIDeque::assign(size_t new_size, const T & f) {_resizeRaw(new_size); return fill(f);} - - -__PIDEQUE_SIMPLE_TYPE__(bool) -__PIDEQUE_SIMPLE_TYPE__(char) -__PIDEQUE_SIMPLE_TYPE__(uchar) -__PIDEQUE_SIMPLE_TYPE__(short) -__PIDEQUE_SIMPLE_TYPE__(ushort) -__PIDEQUE_SIMPLE_TYPE__(int) -__PIDEQUE_SIMPLE_TYPE__(uint) -__PIDEQUE_SIMPLE_TYPE__(long) -__PIDEQUE_SIMPLE_TYPE__(ulong) -__PIDEQUE_SIMPLE_TYPE__(llong) -__PIDEQUE_SIMPLE_TYPE__(ullong) -__PIDEQUE_SIMPLE_TYPE__(float) -__PIDEQUE_SIMPLE_TYPE__(double) -__PIDEQUE_SIMPLE_TYPE__(ldouble) - #ifdef PIP_STD_IOSTREAM template diff --git a/libs/main/containers/pimap.h b/libs/main/containers/pimap.h index 38339dd7..ab4c6007 100644 --- a/libs/main/containers/pimap.h +++ b/libs/main/containers/pimap.h @@ -28,9 +28,6 @@ #include "pivector.h" #include "pideque.h" #include "pipair.h" -# define __PICONTAINERS_SIMPLE_TYPE__(T) \ -__PIDEQUE_SIMPLE_TYPE__(T)\ -__PIVECTOR_SIMPLE_TYPE__(T) template diff --git a/libs/main/containers/pivector.h b/libs/main/containers/pivector.h index 73f4d572..e7a3bd48 100644 --- a/libs/main/containers/pivector.h +++ b/libs/main/containers/pivector.h @@ -210,7 +210,22 @@ public: inline T * data(size_t index = 0) {return &(piv_data[index]);} inline const T * data(size_t index = 0) const {return &(piv_data[index]);} - inline PIVector & clear() {resize(0); return *this;} + template::value + , int>::type = 0> + inline PIVector & clear() { + resize(0); + return *this; + } + template::value + , int>::type = 0> + inline PIVector & clear() { + PIINTROSPECTION_CONTAINER_UNUSED(T, piv_size) + piv_size = 0; + return *this; + } + inline PIVector & fill(const T & f = T()) { deleteT(piv_data, piv_size); PIINTROSPECTION_CONTAINER_USED(T, piv_size) @@ -219,10 +234,20 @@ public: return *this; } inline PIVector & assign(const T & f = T()) {return fill(f);} + template::value + , int>::type = 0> inline PIVector & assign(size_t new_size, const T & f) { resize(new_size); return fill(f); } + template::value + , int>::type = 0> + inline PIVector & assign(size_t new_size, const T & f) { + _resizeRaw(new_size); + return fill(f); + } inline PIVector & resize(size_t new_size, const T & f = T()) { if (new_size < piv_size) { @@ -239,9 +264,17 @@ public: } return *this; } + template::value + , int>::type = 0> inline PIVector & _resizeRaw(size_t new_size) { - piCout << "Error, \"resizeRaw()\" only allowed for simple type declared with __PIVECTOR_SIMPLE_TYPE__ macro!"; - assert(0); + if (new_size > piv_size) { + PIINTROSPECTION_CONTAINER_USED(T, (new_size-piv_size)); + } + if (new_size < piv_size) { + PIINTROSPECTION_CONTAINER_UNUSED(T, (piv_size-new_size)); + } + alloc(new_size); return *this; } inline void _copyRaw(T * dst, const T * src, size_t size) { @@ -425,11 +458,24 @@ private: while (s_ >> t) ++t; return (1 << t); } + template::value + , int>::type = 0> inline void newT(T * dst, const T * src, size_t s) { PIINTROSPECTION_CONTAINER_USED(T, s) for (size_t i = 0; i < s; ++i) elementNew(dst + i, src[i]); } + template::value + , int>::type = 0> + inline void newT(T * dst, const T * src, size_t s) { + PIINTROSPECTION_CONTAINER_USED(T, s) + memcpy((void*)(dst), (const void*)(src), s * sizeof(T)); + } + template::value + , int>::type = 0> inline void deleteT(T * d, size_t sz) { PIINTROSPECTION_CONTAINER_UNUSED(T, sz) if ((uchar*)d != 0) { @@ -437,9 +483,36 @@ private: elementDelete(d[i]); } } + template::value + , int>::type = 0> + inline void deleteT(T * d, size_t sz) { + PIINTROSPECTION_CONTAINER_UNUSED(T, sz) + } + template::value + , int>::type = 0> inline void elementNew(T * to, const T & from) {new(to)T(from);} + template::value + , int>::type = 0> inline void elementNew(T * to, T && from) {new(to)T(std::move(from));} + template::value + , int>::type = 0> + inline void elementNew(T1 * to, const T & from) {(*to) = from;} + template::value + , int>::type = 0> + inline void elementNew(T * to, T && from) {(*to) = std::move(from);} + template::value + , int>::type = 0> inline void elementDelete(T & from) {from.~T();} + template::value + , int>::type = 0> + inline void elementDelete(T & from) {} inline void dealloc() { if ((uchar*)piv_data != 0) free((uchar*)piv_data); piv_data = 0; @@ -464,41 +537,6 @@ private: }; -#define __PIVECTOR_SIMPLE_TYPE__(T) \ - template<> inline void PIVector::newT(T * dst, const T * src, size_t s) {PIINTROSPECTION_CONTAINER_USED(T, s); memcpy((void*)(dst), (const void*)(src), s * sizeof(T));} \ - template<> inline void PIVector::deleteT(T *, size_t sz) {PIINTROSPECTION_CONTAINER_UNUSED(T, sz);} \ - template<> inline void PIVector::elementNew(T * to, const T & from) {(*to) = from;} \ - template<> inline void PIVector::elementNew(T * to, T && from) {(*to) = std::move(from);} \ - template<> inline void PIVector::elementDelete(T &) {;} \ - template<> inline PIVector & PIVector::_resizeRaw(size_t new_size) { \ - if (new_size > piv_size) { \ - PIINTROSPECTION_CONTAINER_USED(T, (new_size-piv_size)); \ - } \ - if (new_size < piv_size) { \ - PIINTROSPECTION_CONTAINER_UNUSED(T, (piv_size-new_size)); \ - } \ - alloc(new_size); \ - return *this; \ - } \ - template<> inline PIVector & PIVector::clear() {PIINTROSPECTION_CONTAINER_UNUSED(T, piv_size); piv_size = 0; return *this;} \ - template<> inline PIVector & PIVector::assign(size_t new_size, const T & f) {_resizeRaw(new_size); return fill(f);} - - -__PIVECTOR_SIMPLE_TYPE__(bool) -__PIVECTOR_SIMPLE_TYPE__(char) -__PIVECTOR_SIMPLE_TYPE__(uchar) -__PIVECTOR_SIMPLE_TYPE__(short) -__PIVECTOR_SIMPLE_TYPE__(ushort) -__PIVECTOR_SIMPLE_TYPE__(int) -__PIVECTOR_SIMPLE_TYPE__(uint) -__PIVECTOR_SIMPLE_TYPE__(long) -__PIVECTOR_SIMPLE_TYPE__(ulong) -__PIVECTOR_SIMPLE_TYPE__(llong) -__PIVECTOR_SIMPLE_TYPE__(ullong) -__PIVECTOR_SIMPLE_TYPE__(float) -__PIVECTOR_SIMPLE_TYPE__(double) -__PIVECTOR_SIMPLE_TYPE__(ldouble) - #ifdef PIP_STD_IOSTREAM template diff --git a/libs/main/containers/pivector2d.h b/libs/main/containers/pivector2d.h index f573439f..ad9b1ea3 100644 --- a/libs/main/containers/pivector2d.h +++ b/libs/main/containers/pivector2d.h @@ -251,9 +251,13 @@ public: piSwap(cols_, other.cols_); } + template::value + , int>::type = 0> inline PIVector2D & _resizeRaw(size_t r, size_t c) { - piCout << "Error, \"resizeRaw()\" only allowed for simple type declared with __PIVECTOR_SIMPLE_TYPE__ macro!"; - assert(0); + rows_ = r; + cols_ = c; + mat._resizeRaw(r*c); return *this; } @@ -287,22 +291,5 @@ inline PICout operator <<(PICout s, const PIVector2D & v) { return s; } -#define __PIVECTOR2D_SIMPLE_TYPE__(T) \ - template<> inline PIVector2D & PIVector2D::_resizeRaw(size_t r, size_t c) {rows_ = r; cols_ = c; mat._resizeRaw(r*c); return *this;} - -__PIVECTOR2D_SIMPLE_TYPE__(bool) -__PIVECTOR2D_SIMPLE_TYPE__(char) -__PIVECTOR2D_SIMPLE_TYPE__(uchar) -__PIVECTOR2D_SIMPLE_TYPE__(short) -__PIVECTOR2D_SIMPLE_TYPE__(ushort) -__PIVECTOR2D_SIMPLE_TYPE__(int) -__PIVECTOR2D_SIMPLE_TYPE__(uint) -__PIVECTOR2D_SIMPLE_TYPE__(long) -__PIVECTOR2D_SIMPLE_TYPE__(ulong) -__PIVECTOR2D_SIMPLE_TYPE__(llong) -__PIVECTOR2D_SIMPLE_TYPE__(ullong) -__PIVECTOR2D_SIMPLE_TYPE__(float) -__PIVECTOR2D_SIMPLE_TYPE__(double) -__PIVECTOR2D_SIMPLE_TYPE__(ldouble) #endif // PIVECTOR2D_H diff --git a/libs/main/core/pibytearray.h b/libs/main/core/pibytearray.h index d3d532b4..9c6bb60e 100644 --- a/libs/main/core/pibytearray.h +++ b/libs/main/core/pibytearray.h @@ -28,7 +28,6 @@ #include "pimap.h" #include "pivector2d.h" -__PICONTAINERS_SIMPLE_TYPE__(PIChar) #define __PIBYTEARRAY_SIMPLE_TYPE__(T) \ template<> \ diff --git a/libs/main/math/pimathcomplex.h b/libs/main/math/pimathcomplex.h index 268e7daf..e633b5c4 100644 --- a/libs/main/math/pimathcomplex.h +++ b/libs/main/math/pimathcomplex.h @@ -47,16 +47,6 @@ const complexld complexld_i(0., 1.); const complexld complexld_0(0.); const complexld complexld_1(1.); -__PICONTAINERS_SIMPLE_TYPE__(complexi) -__PICONTAINERS_SIMPLE_TYPE__(complexs) -__PICONTAINERS_SIMPLE_TYPE__(complexf) -__PICONTAINERS_SIMPLE_TYPE__(complexd) -__PICONTAINERS_SIMPLE_TYPE__(complexld) -__PIVECTOR2D_SIMPLE_TYPE__(complexi) -__PIVECTOR2D_SIMPLE_TYPE__(complexs) -__PIVECTOR2D_SIMPLE_TYPE__(complexf) -__PIVECTOR2D_SIMPLE_TYPE__(complexd) -__PIVECTOR2D_SIMPLE_TYPE__(complexld) __PIBYTEARRAY_SIMPLE_TYPE__(complexi) __PIBYTEARRAY_SIMPLE_TYPE__(complexs) __PIBYTEARRAY_SIMPLE_TYPE__(complexf) diff --git a/main.cpp b/main.cpp index 1165af51..070f9cdc 100644 --- a/main.cpp +++ b/main.cpp @@ -1,79 +1,84 @@ #include "pip.h" - -#define REGISTER_CNT (__COUNTER__) -#define REGISTER_V_STREAM_INTERNAL(T, C) \ - class _VariantRegistrator_##C##__ { \ - public: \ - _VariantRegistrator_##C##__() { \ - __VariantFunctionsBase__ * f = __VariantFunctions__().instance(); \ - __VariantFunctionsBase__::registered()[f->hash()] = f; \ - } \ - }; \ - _VariantRegistrator_##C##__ __registrator_##C##__; - - -#define REGISTER_V_STREAM_INTERNAL_W(T, C) REGISTER_V_STREAM_INTERNAL(T, C) -#define REGISTER_V_STREAM(T) REGISTER_V_STREAM_INTERNAL_W(T, __COUNTER__) - - - - -class Send: public PIObject { - PIOBJECT(Send) -public: - Send() {piCout << "Send";} - ~Send() {piCout << "~Send";} - EVENT1(ev, PIObject * , o); +struct A { + double x1; + //double x2; }; +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;} - -class Recv: public PIObject { - PIOBJECT(Recv) -public: - Recv() {piCout << "Recv";} - ~Recv() {piCout << "~Recv";} - EVENT_HANDLER1(void, eh, PIObject * , o) { - piCout << "eh ..." << o; - o->deleteLater(); - piMSleep(1000); - piCout << "eh ok"; +struct B { + B() { + x1=0; + //x2=0; } + B(const B & b) = default; + B & operator =(const B & b) {x1=b.x1; return *this;} + double x1; + //double x2; }; +inline PIByteArray & operator <<(PIByteArray & s, const B & a) {s << a.x1/* << a.x2*/; return s;} +inline PIByteArray & operator >>(PIByteArray & s, B & a) {s >> a.x1/* >> a.x2*/; return s;} - -Send * s = new Send(); -Recv * r = new Recv(); +//__PIVECTOR_SIMPLE_TYPE__(B) #include "piconditionvar.h" int main() { + PITimeMeasurer tm; + PIByteArray ba; ba.reserve(100*100*16); - CONNECTU(s, ev, r, eh); - s->ev(r); - r->deleteLater(); - s->deleteLater(); - piMSleep(1500); - //s->deleteLater(); - //delete o; - //eth.dump(); - //versionCompare("",""); - //PICloudServer s("127.0.0.1:10101"); - //s.startThreadedRead(); - piMSleep(10); + 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(); - /*PIMutex m; - PIConditionVariable var; + 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(); - PIThread::runOnce([&](){ - piCout << "wait ..."; - m.lock(); - var.wait(m); - m.unlock(); - piCout << "wait done"; - }); - - piMSleep(100); - var.notifyAll();*/ + 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; } -- 2.43.0 From 2ca8db70f3a5dbe1ae8c641e99f49860cdaaf56a Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Thu, 1 Oct 2020 19:04:10 +0300 Subject: [PATCH 2/4] pibytearray patch, now automatic supports all simple types --- libs/main/core/pibytearray.h | 373 +++++++++++++++++++++++---------- libs/main/core/pichar.h | 4 +- libs/main/math/pimathcomplex.h | 4 +- main.cpp | 16 +- 4 files changed, 268 insertions(+), 129 deletions(-) diff --git a/libs/main/core/pibytearray.h b/libs/main/core/pibytearray.h index 9c6bb60e..76e3e6b0 100644 --- a/libs/main/core/pibytearray.h +++ b/libs/main/core/pibytearray.h @@ -28,22 +28,6 @@ #include "pimap.h" #include "pivector2d.h" - -#define __PIBYTEARRAY_SIMPLE_TYPE__(T) \ -template<> \ -inline PIByteArray & operator <<(PIByteArray & s, const PIVector & v) {s << int(v.size_s()); int os = s.size_s(); s.enlarge(v.size_s()*sizeof(T)); memcpy(s.data(os), v.data(), v.size_s()*sizeof(T)); return s;} \ -template<> \ -inline PIByteArray & operator >>(PIByteArray & s, PIVector & v) {assert(s.size_s() >= 4); int sz; s >> sz; v._resizeRaw(sz); if (sz > 0) memcpy(v.data(), s.data(), sz*sizeof(T)); s.remove(0, sz*sizeof(T)); return s;} \ -template<> \ -inline PIByteArray & operator <<(PIByteArray & s, const PIDeque & v) {s << int(v.size_s()); int os = s.size_s(); s.enlarge(v.size_s()*sizeof(T)); memcpy(s.data(os), v.data(), v.size_s()*sizeof(T)); return s;} \ -template<> \ -inline PIByteArray & operator >>(PIByteArray & s, PIDeque & v) {assert(s.size_s() >= 4); int sz; s >> sz; v._resizeRaw(sz); if (sz > 0) memcpy(v.data(), s.data(), sz*sizeof(T)); s.remove(0, sz*sizeof(T)); return s;} \ -template<> \ -inline PIByteArray & operator <<(PIByteArray & s, const PIVector2D & v) {s << int(v.rows()) << int(v.cols()); int os = s.size_s(); s.enlarge(v.size_s()*sizeof(T)); memcpy(s.data(os), v.data(), v.size_s()*sizeof(T)); return s;} \ -template<> \ -inline PIByteArray & operator >>(PIByteArray & s, PIVector2D & v) {assert(s.size_s() >= 8); int r, c; s >> r >> c; v._resizeRaw(r, c); int sz = r*c; if (sz > 0) memcpy(v.data(), s.data(), sz*sizeof(T)); s.remove(0, sz*sizeof(T)); return s;} - - class PIString; class PIByteArray; @@ -137,7 +121,36 @@ public: static PIByteArray fromBase64(const PIString & base64); }; -inline bool operator <(const PIByteArray & v0, const PIByteArray & v1) {if (v0.size() == v1.size()) {for (uint i = 0; i < v0.size(); ++i) if (v0[i] != v1[i]) return v0[i] < v1[i]; return false;} return v0.size() < v1.size();} +//! \relatesalso PIByteArray \brief Byte arrays compare operator +inline bool operator <(const PIByteArray & v0, const PIByteArray & v1) { + if (v0.size() == v1.size()) { + for (uint i = 0; i < v0.size(); ++i) + if (v0[i] != v1[i]) + return v0[i] < v1[i]; + return false; + } + return v0.size() < v1.size(); +} + +//! \relatesalso PIByteArray \brief Byte arrays compare operator +inline bool operator ==(PIByteArray & f, PIByteArray & s) { + if (f.size_s() != s.size_s()) + return false; + for (int i = 0; i < f.size_s(); ++i) + if (f[i] != s[i]) + return false; + return true; +} + +//! \relatesalso PIByteArray \brief Byte arrays compare operator +inline bool operator !=(PIByteArray & f, PIByteArray & s) { + if (f.size_s() != s.size_s()) + return true; + for (int i = 0; i < f.size_s(); ++i) + if (f[i] != s[i]) + return true; + return false; +} #ifdef PIP_STD_IOSTREAM //! \relatesalso PIByteArray \brief Output to std::ostream operator @@ -147,114 +160,260 @@ inline std::ostream & operator <<(std::ostream & s, const PIByteArray & ba); //! \relatesalso PIByteArray \brief Output to PICout operator PIP_EXPORT PICout operator <<(PICout s, const PIByteArray & ba); + + + +// store operators for basic types + + #define PBA_OPERATOR_TO int os = s.size_s(); s.enlarge(sizeof(v)); memcpy(s.data(os), &v, sizeof(v)); +//! \relatesalso PIByteArray \brief Store operator +inline PIByteArray & operator <<(PIByteArray & s, const bool v) {s.push_back(v); return s;} //! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, bool v) {s.push_back(v); return s;} +inline PIByteArray & operator <<(PIByteArray & s, const char v) {s.push_back(v); return s;} + //! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, char v) {s.push_back(v); return s;} +inline PIByteArray & operator <<(PIByteArray & s, const uchar v) {s.push_back(v); return s;} + //! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, uchar v) {s.push_back(v); return s;} -//! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, const short v) {PBA_OPERATOR_TO return s;} -//! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, const int v) {PBA_OPERATOR_TO return s;} -//! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, const long & v) {PBA_OPERATOR_TO return s;} -//! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, const llong & v) {PBA_OPERATOR_TO return s;} -//! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, const ushort v) {PBA_OPERATOR_TO return s;} -//! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, const uint v) {PBA_OPERATOR_TO return s;} -//! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, const ulong & v) {PBA_OPERATOR_TO return s;} -//! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, const ullong & v) {PBA_OPERATOR_TO return s;} -//! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, const float v) {PBA_OPERATOR_TO return s;} -//! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, const double & v) {PBA_OPERATOR_TO return s;} -//! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, const ldouble & v) {PBA_OPERATOR_TO return s;} +inline PIByteArray & operator <<(PIByteArray & s, const PIChar & v) {PBA_OPERATOR_TO return s;} + //! \relatesalso PIByteArray \brief Store operator template inline PIByteArray & operator <<(PIByteArray & s, const PIFlags & v) {PBA_OPERATOR_TO return s;} + +//! \relatesalso PIByteArray \brief Store operator for any trivial copyable type +template::value, int>::type = 0> +inline PIByteArray & operator <<(PIByteArray & s, const T & v) {PBA_OPERATOR_TO return s;} + //! \relatesalso PIByteArray \brief Store operator, see \ref PIByteArray_sec1 for details -inline PIByteArray & operator <<(PIByteArray & s, const PIByteArray & v) {s << int(v.size_s()); int os = s.size_s(); s.enlarge(v.size_s()); if (v.size_s() > 0) memcpy(s.data(os), v.data(), v.size()); return s;} +inline PIByteArray & operator <<(PIByteArray & s, const PIByteArray & v) { + s << int(v.size_s()); + int os = s.size_s(); + if (v.size_s() > 0) { + s.enlarge(v.size_s()); + memcpy(s.data(os), v.data(), v.size()); + } + return s; +} + //! \relatesalso PIByteArray \brief Store operator, see \ref PIByteArray_sec1 for details -inline PIByteArray & operator <<(PIByteArray & s, const PIByteArray::RawData & v) {int os = s.size_s(); s.enlarge(v.s); if (v.s > 0) memcpy(s.data(os), v.d, v.s); return s;} +inline PIByteArray & operator <<(PIByteArray & s, const PIByteArray::RawData & v) { + int os = s.size_s(); + if (v.s > 0) { + s.enlarge(v.s); + memcpy(s.data(os), v.d, v.s); + } + return s; +} + +//! \relatesalso PIByteArray \brief Store operator for PIVector of any trivial copyable type +template::value, int>::type = 0> +inline PIByteArray & operator <<(PIByteArray & s, const PIVector & v) { + s << int(v.size_s()); + int os = s.size_s(); + if (v.size_s() > 0) { + s.enlarge(v.size_s()*sizeof(T)); + memcpy(s.data(os), v.data(), v.size_s()*sizeof(T)); + } + return s; +} + +//! \relatesalso PIByteArray \brief Store operator for PIDeque of any trivial copyable type +template::value, int>::type = 0> +inline PIByteArray & operator <<(PIByteArray & s, const PIDeque & v) { + s << int(v.size_s()); + int os = s.size_s(); + if (v.size_s() > 0) { + s.enlarge(v.size_s()*sizeof(T)); + memcpy(s.data(os), v.data(), v.size_s()*sizeof(T)); + } + return s; +} + +//! \relatesalso PIByteArray \brief Store operator for PIVector2D of any trivial copyable type +template::value, int>::type = 0> +inline PIByteArray & operator <<(PIByteArray & s, const PIVector2D & v) { + s << int(v.rows()) << int(v.cols()); + int os = s.size_s(); + if (v.size_s() > 0) { + s.enlarge(v.size_s()*sizeof(T)); + memcpy(s.data(os), v.data(), v.size_s()*sizeof(T)); + } + return s; +} + +//! \relatesalso PIByteArray \brief Store operator +inline PIByteArray & operator <<(PIByteArray & s, const PIBitArray & v) {s << v.size_ << v.data_; return s;} + +//! \relatesalso PIPair \brief Store operator +template +inline PIByteArray & operator <<(PIByteArray & s, const PIPair & v) {s << v.first << v.second; return s;} #undef PBA_OPERATOR_TO + + + + +// restore operators for basic types + + #define PBA_OPERATOR_FROM memcpy((void*)(&v), s.data(), sizeof(v)); s.remove(0, sizeof(v)); //! \relatesalso PIByteArray \brief Restore operator inline PIByteArray & operator >>(PIByteArray & s, bool & v) {assert(s.size() >= 1u); v = s.take_front(); return s;} + //! \relatesalso PIByteArray \brief Restore operator inline PIByteArray & operator >>(PIByteArray & s, char & v) {assert(s.size() >= 1u); v = s.take_front(); return s;} + //! \relatesalso PIByteArray \brief Restore operator inline PIByteArray & operator >>(PIByteArray & s, uchar & v) {assert(s.size() >= 1u); v = s.take_front(); return s;} + //! \relatesalso PIByteArray \brief Restore operator -inline PIByteArray & operator >>(PIByteArray & s, short & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;} -//! \relatesalso PIByteArray \brief Restore operator -inline PIByteArray & operator >>(PIByteArray & s, int & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;} -//! \relatesalso PIByteArray \brief Restore operator -inline PIByteArray & operator >>(PIByteArray & s, long & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;} -//! \relatesalso PIByteArray \brief Restore operator -inline PIByteArray & operator >>(PIByteArray & s, llong & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;} -//! \relatesalso PIByteArray \brief Restore operator -inline PIByteArray & operator >>(PIByteArray & s, ushort & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;} -//! \relatesalso PIByteArray \brief Restore operator -inline PIByteArray & operator >>(PIByteArray & s, uint & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;} -//! \relatesalso PIByteArray \brief Restore operator -inline PIByteArray & operator >>(PIByteArray & s, ulong & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;} -//! \relatesalso PIByteArray \brief Restore operator -inline PIByteArray & operator >>(PIByteArray & s, ullong & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;} -//! \relatesalso PIByteArray \brief Restore operator -inline PIByteArray & operator >>(PIByteArray & s, float & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;} -//! \relatesalso PIByteArray \brief Restore operator -inline PIByteArray & operator >>(PIByteArray & s, double & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;} -//! \relatesalso PIByteArray \brief Restore operator -inline PIByteArray & operator >>(PIByteArray & s, ldouble & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;} +inline PIByteArray & operator >>(PIByteArray & s, PIChar & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;} + +//! \relatesalso PIByteArray \brief Restore operator for any trivial copyable type +template::value, int>::type = 0> +inline PIByteArray & operator >>(PIByteArray & s, T & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;} + //! \relatesalso PIByteArray \brief Restore operator template inline PIByteArray & operator >>(PIByteArray & s, PIFlags & v) {PBA_OPERATOR_FROM return s;} + //! \relatesalso PIByteArray \brief Restore operator, see \ref PIByteArray_sec1 for details PIP_EXPORT PIByteArray & operator >>(PIByteArray & s, PIByteArray & v); + //! \relatesalso PIByteArray \brief Restore operator, see \ref PIByteArray_sec1 for details -inline PIByteArray & operator >>(PIByteArray & s, PIByteArray::RawData v) {assert(s.size_s() >= v.s); if (v.s > 0) memcpy((void*)(v.d), s.data(), v.s); s.remove(0, v.s); return s;} +inline PIByteArray & operator >>(PIByteArray & s, PIByteArray::RawData v) { + assert(s.size_s() >= v.s); + if (v.s > 0) { + memcpy((void*)(v.d), s.data(), v.s); + s.remove(0, v.s); + } + return s; +} + +//! \relatesalso PIByteArray \brief Restore operator for PIVector of any trivial copyable type +template::value, int>::type = 0> +inline PIByteArray & operator >>(PIByteArray & s, PIVector & v) { + assert(s.size_s() >= 4); + int sz; s >> sz; + v._resizeRaw(sz); + if (sz > 0) { + memcpy(v.data(), s.data(), sz*sizeof(T)); + s.remove(0, sz*sizeof(T)); + } + return s; +} + +//! \relatesalso PIByteArray \brief Restore operator for PIDeque of any trivial copyable type +template::value, int>::type = 0> +inline PIByteArray & operator >>(PIByteArray & s, PIDeque & v) { + assert(s.size_s() >= 4); + int sz; s >> sz; + v._resizeRaw(sz); + if (sz > 0) { + memcpy(v.data(), s.data(), sz*sizeof(T)); + s.remove(0, sz*sizeof(T)); + } + return s; +} + +//! \relatesalso PIByteArray \brief Restore operator for PIVector2D of any trivial copyable type +template::value, int>::type = 0> +inline PIByteArray & operator >>(PIByteArray & s, PIVector2D & v) { + assert(s.size_s() >= 8); + int r, c; s >> r >> c; + v._resizeRaw(r, c); + int sz = r*c; + if (sz > 0) { + memcpy(v.data(), s.data(), sz*sizeof(T)); + s.remove(0, sz*sizeof(T)); + } + return s; +} + +//! \relatesalso PIByteArray \brief Restore operator +inline PIByteArray & operator >>(PIByteArray & s, PIBitArray & v) {assert(s.size_s() >= 8); s >> v.size_ >> v.data_; return s;} + +//! \relatesalso PIPair \brief Restore operator +template +inline PIByteArray & operator >>(PIByteArray & s, PIPair & v) {s >> v.first >> v.second; return s;} #undef PBA_OPERATOR_FROM -template inline PIByteArray & operator <<(PIByteArray & s, const PIPair & v); -//! \relatesalso PIByteArray \brief Store operator -template inline PIByteArray & operator <<(PIByteArray & s, const PIVector & v); -//! \relatesalso PIByteArray \brief Store operator -template inline PIByteArray & operator <<(PIByteArray & s, const PIDeque & v); - //! \relatesalso PIByteArray \brief Store operator -template inline PIByteArray & operator <<(PIByteArray & s, const PIMap & v); -//! Write operator to \c PIByteArray -inline PIByteArray & operator <<(PIByteArray & s, const PIChar & v) {s << v.ch; return s;} - -//! \relatesalso PIByteArray \brief Restore operator -template inline PIByteArray & operator >>(PIByteArray & s, PIPair & v); -//! \relatesalso PIByteArray \brief Restore operator -template inline PIByteArray & operator >>(PIByteArray & s, PIVector & v); -//! \relatesalso PIByteArray \brief Restore operator -template inline PIByteArray & operator >>(PIByteArray & s, PIDeque & v); - //! \relatesalso PIByteArray \brief Restore operator -template inline PIByteArray & operator >>(PIByteArray & s, PIMap & v); -//! Read operator from \c PIByteArray -inline PIByteArray & operator >>(PIByteArray & s, PIChar & v) {s >> v.ch; return s;} -//! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, const PIBitArray & v) {s << v.size_ << v.data_; return s;} -template -inline PIByteArray & operator <<(PIByteArray & s, const PIPair & v) {s << v.first << v.second; return s;} -template -inline PIByteArray & operator <<(PIByteArray & s, const PIVector & v) {s << int(v.size_s()); for (uint i = 0; i < v.size(); ++i) s << v[i]; return s;} -template -inline PIByteArray & operator <<(PIByteArray & s, const PIDeque & v) {s << int(v.size_s()); for (uint i = 0; i < v.size(); ++i) s << v[i]; return s;} + +// store operators for complex types + + +//! \relatesalso PIByteArray \brief Store operator for PIVector of any non-trivial copyable type +template::value, int>::type = 0> +inline PIByteArray & operator <<(PIByteArray & s, const PIVector & v) { + s << int(v.size_s()); + for (uint i = 0; i < v.size(); ++i) s << v[i]; + return s; +} + +//! \relatesalso PIByteArray \brief Store operator for PIDeque of any non-trivial copyable type +template::value, int>::type = 0> +inline PIByteArray & operator <<(PIByteArray & s, const PIDeque & v) { + s << int(v.size_s()); + for (uint i = 0; i < v.size(); ++i) s << v[i]; + return s; +} + +//! \relatesalso PIByteArray \brief Store operator for PIVector2D of any non-trivial copyable type +template::value, int>::type = 0> +inline PIByteArray & operator <<(PIByteArray & s, const PIVector2D & v) { + s << int(v.rows()) << int(v.cols()) << v.toPlainVector(); + return s; +} + + + + +// restore operators for complex types + + +//! \relatesalso PIByteArray \brief Restore operator for PIVector of any non-trivial copyable type +template::value, int>::type = 0> +inline PIByteArray & operator >>(PIByteArray & s, PIVector & v) { + assert(s.size_s() >= 4); + int sz; s >> sz; + v.resize(sz); + for (int i = 0; i < sz; ++i) s >> v[i]; + return s; +} + +//! \relatesalso PIByteArray \brief Restore operator for PIDeque of any non-trivial copyable type +template::value, int>::type = 0> +inline PIByteArray & operator >>(PIByteArray & s, PIDeque & v) { + assert(s.size_s() >= 4); + int sz; s >> sz; + v.resize(sz); + for (int i = 0; i < sz; ++i) s >> v[i]; + return s; +} + +//! \relatesalso PIByteArray \brief Restore operator for PIVector2D of any non-trivial copyable type +template::value, int>::type = 0> +inline PIByteArray & operator >>(PIByteArray & s, PIVector2D & v) { + assert(s.size_s() >= 8); + int r,c; + PIVector tmp; + s >> r >> c >> tmp; + v = PIVector2D(r, c, tmp); + return s; +} + + + + +// other types + + template inline PIByteArray & operator <<(PIByteArray & s, const PIMap & v) { s << int(v.pim_index.size_s()); @@ -263,18 +422,8 @@ inline PIByteArray & operator <<(PIByteArray & s, const PIMap & v) { s << v.pim_content; return s; } -template -inline PIByteArray & operator <<(PIByteArray & s, const PIVector2D & v) {s << int(v.rows()) << int(v.cols()) << v.toPlainVector(); return s;} -//! \relatesalso PIByteArray \brief Restore operator -inline PIByteArray & operator >>(PIByteArray & s, PIBitArray & v) {assert(s.size_s() >= 8); s >> v.size_ >> v.data_; return s;} -template -inline PIByteArray & operator >>(PIByteArray & s, PIPair & v) {s >> v.first >> v.second; return s;} -template -inline PIByteArray & operator >>(PIByteArray & s, PIVector & v) {assert(s.size_s() >= 4); int sz; s >> sz; v.resize(sz); for (int i = 0; i < sz; ++i) s >> v[i]; return s;} -template -inline PIByteArray & operator >>(PIByteArray & s, PIDeque & v) {assert(s.size_s() >= 4); int sz; s >> sz; v.resize(sz); for (int i = 0; i < sz; ++i) s >> v[i]; return s;} template inline PIByteArray & operator >>(PIByteArray & s, PIMap & v) { assert(s.size_s() >= 4); @@ -291,21 +440,15 @@ inline PIByteArray & operator >>(PIByteArray & s, PIMap & v) { } return s; } -template -inline PIByteArray & operator >>(PIByteArray & s, PIVector2D & v) {assert(s.size_s() >= 8); int r,c; PIVector tmp; s >> r >> c >> tmp; v = PIVector2D(r, c, tmp); return s;} -template + +template::value, int>::type = 0> inline PIByteArray & operator <<(PIByteArray & s, const T & ) {piCout << "[PIByteArray] Warning: using undeclared operator < +template::value, int>::type = 0> inline PIByteArray & operator >>(PIByteArray & s, T & ) {piCout << "[PIByteArray] Warning: using undeclared operator >>!"; return s;} - -//! \relatesalso PIByteArray \brief Byte arrays compare operator -inline bool operator ==(PIByteArray & f, PIByteArray & s) {if (f.size_s() != s.size_s()) return false; for (int i = 0; i < f.size_s(); ++i) if (f[i] != s[i]) return false; return true;} -//! \relatesalso PIByteArray \brief Byte arrays compare operator -inline bool operator !=(PIByteArray & f, PIByteArray & s) {if (f.size_s() != s.size_s()) return true; for (int i = 0; i < f.size_s(); ++i) if (f[i] != s[i]) return true; return false;} - +/* __PIBYTEARRAY_SIMPLE_TYPE__(bool) __PIBYTEARRAY_SIMPLE_TYPE__(char) __PIBYTEARRAY_SIMPLE_TYPE__(short) @@ -320,7 +463,7 @@ __PIBYTEARRAY_SIMPLE_TYPE__(float) __PIBYTEARRAY_SIMPLE_TYPE__(double) __PIBYTEARRAY_SIMPLE_TYPE__(ldouble) __PIBYTEARRAY_SIMPLE_TYPE__(PIChar) - +*/ 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/pichar.h b/libs/main/core/pichar.h index 5b18db41..a01b07ce 100644 --- a/libs/main/core/pichar.h +++ b/libs/main/core/pichar.h @@ -34,7 +34,7 @@ class PIP_EXPORT PIChar friend class PIString; friend PIByteArray & operator <<(PIByteArray & s, const PIChar & v); friend PIByteArray & operator >>(PIByteArray & s, PIChar & v); - friend PICout operator <<(PICout s, const PIChar & v); + friend PICout PIP_EXPORT operator <<(PICout s, const PIChar & v); public: //! Contructs ascii symbol PIChar(const char c) {ch = c; ch &= 0xFF;} @@ -135,7 +135,7 @@ private: }; //! Output operator to \a PICout -PICout operator <<(PICout s, const PIChar & v); +PICout PIP_EXPORT operator <<(PICout s, const PIChar & v); //! Compare operator inline bool operator ==(const char v, const PIChar & c) {return (PIChar(v) == c);} diff --git a/libs/main/math/pimathcomplex.h b/libs/main/math/pimathcomplex.h index e633b5c4..9d428d56 100644 --- a/libs/main/math/pimathcomplex.h +++ b/libs/main/math/pimathcomplex.h @@ -46,13 +46,13 @@ 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 070f9cdc..d27a590f 100644 --- a/main.cpp +++ b/main.cpp @@ -2,31 +2,27 @@ struct A { double x1; - //double x2; + //PIString str; }; -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;} +//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; - //x2=0; } B(const B & b) = default; - B & operator =(const B & b) {x1=b.x1; return *this;} + //B & operator =(const B & b) {x1=b.x1; return *this;} + //A aa; double x1; - //double x2; }; -inline PIByteArray & operator <<(PIByteArray & s, const B & a) {s << a.x1/* << a.x2*/; return s;} -inline PIByteArray & operator >>(PIByteArray & s, B & a) {s >> a.x1/* >> a.x2*/; return s;} - //__PIVECTOR_SIMPLE_TYPE__(B) #include "piconditionvar.h" int main() { - PITimeMeasurer tm; PIByteArray ba; ba.reserve(100*100*16); + PITimeMeasurer tm; PIVector2D vx; PIVector2D vd; ba << vx; -- 2.43.0 From 298765b7d8788624ca551da973db453384a6cf73 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Thu, 1 Oct 2020 21:50:41 +0300 Subject: [PATCH 3/4] 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; } -- 2.43.0 From f3d673986919b9801ac72a16e6f02474956cba8e Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Fri, 2 Oct 2020 11:11:55 +0300 Subject: [PATCH 4/4] code brush --- libs/main/core/pibytearray.h | 20 ++++++-------------- libs/main/core/pivariantsimple.h | 22 +++++++++++----------- libs/main/io_devices/pifile.cpp | 10 ++++++---- libs/main/io_devices/pifile.h | 2 +- 4 files changed, 24 insertions(+), 30 deletions(-) diff --git a/libs/main/core/pibytearray.h b/libs/main/core/pibytearray.h index 7db8b7b5..a5e9488d 100644 --- a/libs/main/core/pibytearray.h +++ b/libs/main/core/pibytearray.h @@ -166,8 +166,6 @@ PIP_EXPORT PICout operator <<(PICout s, const PIByteArray & ba); // store operators for basic types -#define PBA_OPERATOR_TO int os = s.size_s(); s.enlarge(sizeof(v)); memcpy(s.data(os), &v, sizeof(v)); - //! \relatesalso PIByteArray \brief Store operator inline PIByteArray & operator <<(PIByteArray & s, const bool v) {s.push_back(v); return s;} @@ -178,14 +176,14 @@ inline PIByteArray & operator <<(PIByteArray & s, const char v) {s.push_back(v); inline PIByteArray & operator <<(PIByteArray & s, const uchar v) {s.push_back(v); return s;} //! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, const PIChar & v) {PBA_OPERATOR_TO return s;} +inline PIByteArray & operator <<(PIByteArray & s, const PIChar & v) {int os = s.size_s(); s.enlarge(sizeof(v)); memcpy(s.data(os), &v, sizeof(v)); return s;} //! \relatesalso PIByteArray \brief Store operator -template inline PIByteArray & operator <<(PIByteArray & s, const PIFlags & v) {PBA_OPERATOR_TO return s;} +template inline PIByteArray & operator <<(PIByteArray & s, const PIFlags & v) {int os = s.size_s(); s.enlarge(sizeof(v)); memcpy(s.data(os), &v, sizeof(v)); return s;} //! \relatesalso PIByteArray \brief Store operator for any trivial copyable type template::value, int>::type = 0> -inline PIByteArray & operator <<(PIByteArray & s, const T & v) {PBA_OPERATOR_TO return s;} +inline PIByteArray & operator <<(PIByteArray & s, const T & v) {int os = s.size_s(); s.enlarge(sizeof(v)); memcpy(s.data(os), &v, sizeof(v)); return s;} //! \relatesalso PIByteArray \brief Store operator, see \ref PIByteArray_sec1 for details inline PIByteArray & operator <<(PIByteArray & s, const PIByteArray & v) { @@ -251,16 +249,12 @@ inline PIByteArray & operator <<(PIByteArray & s, const PIBitArray & v) {s << v. template inline PIByteArray & operator <<(PIByteArray & s, const PIPair & v) {s << v.first << v.second; return s;} -#undef PBA_OPERATOR_TO - // restore operators for basic types -#define PBA_OPERATOR_FROM memcpy((void*)(&v), s.data(), sizeof(v)); s.remove(0, sizeof(v)); - //! \relatesalso PIByteArray \brief Restore operator inline PIByteArray & operator >>(PIByteArray & s, bool & v) {assert(s.size() >= 1u); v = s.take_front(); return s;} @@ -271,14 +265,14 @@ inline PIByteArray & operator >>(PIByteArray & s, char & v) {assert(s.size() >= inline PIByteArray & operator >>(PIByteArray & s, uchar & v) {assert(s.size() >= 1u); v = s.take_front(); return s;} //! \relatesalso PIByteArray \brief Restore operator -inline PIByteArray & operator >>(PIByteArray & s, PIChar & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;} +inline PIByteArray & operator >>(PIByteArray & s, PIChar & v) {assert(s.size() >= sizeof(v)); memcpy((void*)(&v), s.data(), sizeof(v)); s.remove(0, sizeof(v)); return s;} //! \relatesalso PIByteArray \brief Restore operator for any trivial copyable type template::value, int>::type = 0> -inline PIByteArray & operator >>(PIByteArray & s, T & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;} +inline PIByteArray & operator >>(PIByteArray & s, T & v) {assert(s.size() >= sizeof(v)); memcpy((void*)(&v), s.data(), sizeof(v)); s.remove(0, sizeof(v)); return s;} //! \relatesalso PIByteArray \brief Restore operator -template inline PIByteArray & operator >>(PIByteArray & s, PIFlags & v) {PBA_OPERATOR_FROM return s;} +template inline PIByteArray & operator >>(PIByteArray & s, PIFlags & v) {memcpy((void*)(&v), s.data(), sizeof(v)); s.remove(0, sizeof(v)); return s;} //! \relatesalso PIByteArray \brief Restore operator, see \ref PIByteArray_sec1 for details PIP_EXPORT PIByteArray & operator >>(PIByteArray & s, PIByteArray & v); @@ -340,8 +334,6 @@ inline PIByteArray & operator >>(PIByteArray & s, PIBitArray & v) {assert(s.size template inline PIByteArray & operator >>(PIByteArray & s, PIPair & v) {s >> v.first >> v.second; return s;} -#undef PBA_OPERATOR_FROM - diff --git a/libs/main/core/pivariantsimple.h b/libs/main/core/pivariantsimple.h index ba2d2e9e..64114a4e 100644 --- a/libs/main/core/pivariantsimple.h +++ b/libs/main/core/pivariantsimple.h @@ -36,7 +36,7 @@ public: 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 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) {;} @@ -47,15 +47,15 @@ public: 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;} + __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 { @@ -81,7 +81,7 @@ public: void setValue(const T & v) { if (f) { if (isMyType()) { - f->equalT(ptr, (const void *)&v); + f->assignT(ptr, (const void *)&v); return; } } diff --git a/libs/main/io_devices/pifile.cpp b/libs/main/io_devices/pifile.cpp index 8f598b05..c8754a08 100644 --- a/libs/main/io_devices/pifile.cpp +++ b/libs/main/io_devices/pifile.cpp @@ -124,10 +124,12 @@ PIString PIFile::FileInfo::extension() const { PIString PIFile::FileInfo::dir() const { if (path.isEmpty()) return PIString(); - PIString ret = path.mid(0, path.findLast(PIDir::separator)); - if (ret.isEmpty()) ret = PIDir::separator; - if (!PIDir(ret).isExists()) return (PIStringAscii(".") + PIDir::separator); - return ret; + int ind = path.findLast(PIDir::separator); + PIString ret; + if (ind >= 0) + ret = path.mid(0, ind); + if (ret.isEmpty()) ret = "."; + return ret + PIDir::separator; } diff --git a/libs/main/io_devices/pifile.h b/libs/main/io_devices/pifile.h index 56b1df6f..a84cd63d 100644 --- a/libs/main/io_devices/pifile.h +++ b/libs/main/io_devices/pifile.h @@ -36,7 +36,7 @@ public: explicit PIFile(); struct PIP_EXPORT FileInfo { - FileInfo() {size = 0; id_group = id_user = 0;} + FileInfo(const PIString & path_ = PIString()) {path = path_; size = 0; id_group = id_user = 0;} enum Flag { File = 0x01, -- 2.43.0