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..a5e9488d 100644 --- a/libs/main/core/pibytearray.h +++ b/libs/main/core/pibytearray.h @@ -28,23 +28,6 @@ #include "pimap.h" #include "pivector2d.h" -__PICONTAINERS_SIMPLE_TYPE__(PIChar) - -#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; @@ -138,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 @@ -148,114 +160,252 @@ 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); -#define PBA_OPERATOR_TO int os = s.size_s(); s.enlarge(sizeof(v)); memcpy(s.data(os), &v, sizeof(v)); + + + +// store operators for basic types //! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, bool v) {s.push_back(v); return s;} +inline PIByteArray & operator <<(PIByteArray & s, const bool 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 char 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;} +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 short 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 -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;} -//! \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) {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) {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; +} -#undef PBA_OPERATOR_TO -#define PBA_OPERATOR_FROM memcpy((void*)(&v), s.data(), sizeof(v)); s.remove(0, sizeof(v)); +//! \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 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;} -//! \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;} - -#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 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;} -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;} + + + + +// restore operators for basic types + + +//! \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, 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)); 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) {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); + +//! \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; +} + +//! \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;} + + + + +// 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()); @@ -264,18 +414,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); @@ -292,36 +432,20 @@ 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 -inline PIByteArray & operator <<(PIByteArray & s, const T & ) {piCout << "[PIByteArray] Warning: using undeclared operator < -inline PIByteArray & operator >>(PIByteArray & s, T & ) {piCout << "[PIByteArray] Warning: using undeclared operator >>!"; return s;} +template::value, int>::type = 0> +inline PIByteArray & operator <<(PIByteArray & s, const T & ) { + static_assert(std::is_trivially_copyable::value, "[PIByteArray] Error: using undeclared operator << for complex type!"); + 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) -__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/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/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..64114a4e --- /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 assignT(void *& ptr, const void * value) {;} + virtual void deleteT(void *& ptr) {;} + //virtual PIByteArray toData(const void * ptr) const {return PIByteArray();} + //virtual void fromData(void *& ptr, PIByteArray ba) {;} + static PIMap & registered() {static PIMap ret; return ret;} +}; + + +template +class __VariantFunctions__: public __VariantFunctionsBase__ { +public: + __VariantFunctionsBase__ * instance() final {static __VariantFunctions__ ret; return &ret;} + PIString typeName() const final {static PIString ret(typeid(T).name()); return ret;} + uint hash() const final {static uint ret = typeName().hash(); return ret;} + void newT(void *& ptr, const void * value) final {ptr = (void*)(new T(*(const T*)value)); /*printf(" * new\n")*/;} + void newNullT(void *& ptr) final {ptr = (void*)(new T());/* printf(" * new null\n")*/;} + void assignT(void *& ptr, const void * value) final {*(T*)ptr = *(const T*)value; /*printf(" * =\n")*/;} + void deleteT(void *& ptr) final {delete (T*)(ptr); /*printf(" * del\n")*/;} + //PIByteArray toData(const void * ptr) const final {PIByteArray ret; ret << (*(const T* &)ptr); return ret;} + //void fromData(void *& ptr, PIByteArray ba) final {ba >> *(T*)ptr;} +}; + +class PIVariantSimple { +public: + PIVariantSimple() {ptr = 0; f = 0;} + PIVariantSimple(const PIVariantSimple & v) { + ptr = 0; + f = v.f; + if (f && v.ptr) + f->newT(ptr, v.ptr); + } + ~PIVariantSimple() {destroy();} + + PIVariantSimple & operator=(const PIVariantSimple & v) { + destroy(); + f = v.f; + if (f && v.ptr) + f->newT(ptr, v.ptr); + return *this; + } + + template + void setValue(const T & v) { + if (f) { + if (isMyType()) { + f->assignT(ptr, (const void *)&v); + return; + } + } + destroy(); + f = __VariantFunctions__().instance(); + f->newT(ptr, (const void *)&v); + } + + template + T value() const { + if (!f) return T(); + if (!isMyType()) + return T(); + return *(T*)(ptr); + } + + template + static PIVariantSimple fromValue(const T & v) { + PIVariantSimple ret; + ret.setValue(v); + return ret; + } + + /* + PIByteArray save() const { + if (!ptr || !f) return PIByteArray(); + PIByteArray ret; + ret << f->hash(); + ret.append(f->toData(ptr)); + return ret; + } + + bool load(PIByteArray ba) { + if (ba.size_s() < 4) return false; + uint h(0); ba >> h; + destroy(); + f = __VariantFunctionsBase__::registered().value(h, 0); + if (!f) return false; + f->newNullT(ptr); + f->fromData(ptr, ba); + return true; + } + */ + +private: + template + bool isMyType() const { + uint mh = f->hash(), th = __VariantFunctions__().instance()->hash(); + if (mh == 0 || th == 0) return false; + return mh == th; + } + + void destroy() { + if (ptr && f) + f->deleteT(ptr); + ptr = 0; + f = 0; + } + + void * ptr; + __VariantFunctionsBase__ * f; + +}; + + +#define REGISTER_PIVARIANTSIMPLE_STREAM(Type) \ + STATIC_INITIALIZER_BEGIN() \ + __VariantFunctionsBase__ * f = __VariantFunctions__().instance(); \ + __VariantFunctionsBase__::registered()[f->hash()] = f; \ + STATIC_INITIALIZER_END() + + + +#endif // PIVARIANTSIMPLE_H 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, diff --git a/libs/main/math/pimathcomplex.h b/libs/main/math/pimathcomplex.h index 268e7daf..79e651d5 100644 --- a/libs/main/math/pimathcomplex.h +++ b/libs/main/math/pimathcomplex.h @@ -47,22 +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) -__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 1165af51..28bd520d 100644 --- a/main.cpp +++ b/main.cpp @@ -1,79 +1,99 @@ #include "pip.h" +#include "pivariantsimple.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); +template +struct __VariantTypeInfo__ { + typedef T PureType; + typedef const T ConstPureType; + typedef T * PointerType; + typedef const T * ConstPointerType; + typedef T & ReferenceType; + typedef const T & ConstReferenceType; }; +#define __TYPEINFO_SINGLE(PT, T) \ + template<> struct __PIVariantTypeInfo__ { \ + typedef PT PureType; \ + typedef const PT ConstPureType; \ + typedef PT * PointerType; \ + typedef const PT * ConstPointerType; \ + typedef PT & ReferenceType; \ + typedef const PT & ConstReferenceType; \ + }; -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"; +#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; } + uchar on; + short unreliability; + float duration; + int max_count; + bool overload[2]; }; - - -Send * s = new Send(); -Recv * r = new Recv(); - -#include "piconditionvar.h" -int main() { - - 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); - - /*PIMutex m; - PIConditionVariable var; - - PIThread::runOnce([&](){ - piCout << "wait ..."; - m.lock(); - var.wait(m); - m.unlock(); - piCout << "wait done"; - }); - - piMSleep(100); - var.notifyAll();*/ - - 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; }