remove __PICONTAINERS_SIMPLE_TYPE__ #44

Merged
peri4 merged 4 commits from experiment into master 2020-10-02 11:22:25 +03:00
14 changed files with 746 additions and 396 deletions

View File

@@ -209,7 +209,22 @@ public:
inline T * data(size_t index = 0) {return &(pid_data[pid_start + index]);} 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 const T * data(size_t index = 0) const {return &(pid_data[pid_start + index]);}
inline PIDeque<T> & clear() {resize(0); return *this;} template<typename T1 = T, typename std::enable_if<
!std::is_trivially_copyable<T1>::value
, int>::type = 0>
inline PIDeque<T> & clear() {
resize(0);
return *this;
}
template<typename T1 = T, typename std::enable_if<
std::is_trivially_copyable<T1>::value
, int>::type = 0>
inline PIDeque<T> & clear() {
PIINTROSPECTION_CONTAINER_UNUSED(T, pid_size)
pid_size = 0;
return *this;
}
inline PIDeque<T> & fill(const T & f = T()) { inline PIDeque<T> & fill(const T & f = T()) {
deleteT(pid_data + pid_start, pid_size); deleteT(pid_data + pid_start, pid_size);
PIINTROSPECTION_CONTAINER_USED(T, pid_size) PIINTROSPECTION_CONTAINER_USED(T, pid_size)
@@ -218,10 +233,20 @@ public:
return *this; return *this;
} }
inline PIDeque<T> & assign(const T & f = T()) {return fill(f);} inline PIDeque<T> & assign(const T & f = T()) {return fill(f);}
template<typename T1 = T, typename std::enable_if<
!std::is_trivially_copyable<T1>::value
, int>::type = 0>
inline PIDeque<T> & assign(size_t new_size, const T & f) { inline PIDeque<T> & assign(size_t new_size, const T & f) {
resize(new_size); resize(new_size);
return fill(f); return fill(f);
} }
template<typename T1 = T, typename std::enable_if<
std::is_trivially_copyable<T1>::value
, int>::type = 0>
inline PIDeque<T> & assign(size_t new_size, const T & f) {
_resizeRaw(new_size);
return fill(f);
}
inline PIDeque<T> & resize(size_t new_size, const T & f = T()) { inline PIDeque<T> & resize(size_t new_size, const T & f = T()) {
if (new_size < pid_size) { if (new_size < pid_size) {
@@ -236,9 +261,18 @@ public:
} }
return *this; return *this;
} }
template<typename T1 = T, typename std::enable_if<
std::is_trivially_copyable<T1>::value
, int>::type = 0>
inline PIDeque<T> & _resizeRaw(size_t new_size) { inline PIDeque<T> & _resizeRaw(size_t new_size) {
piCout << "Error, \"resizeRaw()\" only allowed for simple type declared with __PIDEQUE_SIMPLE_TYPE__ macro!"; if (new_size > pid_size) {
assert(0); 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; return *this;
} }
@@ -437,11 +471,24 @@ private:
++t; ++t;
return (1 << t); return (1 << t);
} }
template<typename T1 = T, typename std::enable_if<
!std::is_trivially_copyable<T1>::value
, int>::type = 0>
inline void newT(T * dst, const T * src, size_t s) { inline void newT(T * dst, const T * src, size_t s) {
PIINTROSPECTION_CONTAINER_USED(T, s) PIINTROSPECTION_CONTAINER_USED(T, s)
for (size_t i = 0; i < s; ++i) for (size_t i = 0; i < s; ++i)
elementNew(dst + i, src[i]); elementNew(dst + i, src[i]);
} }
template<typename T1 = T, typename std::enable_if<
std::is_trivially_copyable<T1>::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<typename T1 = T, typename std::enable_if<
!std::is_trivially_copyable<T1>::value
, int>::type = 0>
inline void deleteT(T * d, size_t sz) { inline void deleteT(T * d, size_t sz) {
PIINTROSPECTION_CONTAINER_UNUSED(T, sz) PIINTROSPECTION_CONTAINER_UNUSED(T, sz)
if ((uchar*)d != 0) { if ((uchar*)d != 0) {
@@ -449,9 +496,36 @@ private:
elementDelete(d[i]); elementDelete(d[i]);
} }
} }
template<typename T1 = T, typename std::enable_if<
std::is_trivially_copyable<T1>::value
, int>::type = 0>
inline void deleteT(T * d, size_t sz) {
PIINTROSPECTION_CONTAINER_UNUSED(T, sz)
}
template<typename T1 = T, typename std::enable_if<
!std::is_trivially_copyable<T1>::value
, int>::type = 0>
inline void elementNew(T * to, const T & from) {new(to)T(from);} inline void elementNew(T * to, const T & from) {new(to)T(from);}
template<typename T1 = T, typename std::enable_if<
!std::is_trivially_copyable<T1>::value
, int>::type = 0>
inline void elementNew(T * to, T && from) {new(to)T(std::move(from));} inline void elementNew(T * to, T && from) {new(to)T(std::move(from));}
template<typename T1 = T, typename std::enable_if<
std::is_trivially_copyable<T1>::value
, int>::type = 0>
inline void elementNew(T1 * to, const T & from) {(*to) = from;}
template<typename T1 = T, typename std::enable_if<
std::is_trivially_copyable<T1>::value
, int>::type = 0>
inline void elementNew(T * to, T && from) {(*to) = std::move(from);}
template<typename T1 = T, typename std::enable_if<
!std::is_trivially_copyable<T1>::value
, int>::type = 0>
inline void elementDelete(T & from) {from.~T();} inline void elementDelete(T & from) {from.~T();}
template<typename T1 = T, typename std::enable_if<
std::is_trivially_copyable<T1>::value
, int>::type = 0>
inline void elementDelete(T & from) {}
inline void dealloc() { inline void dealloc() {
if ((uchar*)pid_data != 0) free((uchar*)pid_data); if ((uchar*)pid_data != 0) free((uchar*)pid_data);
pid_data = 0; pid_data = 0;
@@ -520,41 +594,6 @@ private:
ssize_t pid_start; ssize_t pid_start;
}; };
#define __PIDEQUE_SIMPLE_TYPE__(T) \
template<> inline void PIDeque<T>::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<T>::deleteT(T *, size_t sz) {PIINTROSPECTION_CONTAINER_UNUSED(T, sz);} \
template<> inline void PIDeque<T>::elementNew(T * to, const T & from) {(*to) = from;} \
template<> inline void PIDeque<T>::elementNew(T * to, T && from) {(*to) = std::move(from);} \
template<> inline void PIDeque<T>::elementDelete(T &) {;} \
template<> inline PIDeque<T> & PIDeque<T>::_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<T> & PIDeque<T>::clear() {PIINTROSPECTION_CONTAINER_UNUSED(T, pid_size); pid_size = 0; return *this;} \
template<> inline PIDeque<T> & PIDeque<T>::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 #ifdef PIP_STD_IOSTREAM
template<typename T> template<typename T>

View File

@@ -28,9 +28,6 @@
#include "pivector.h" #include "pivector.h"
#include "pideque.h" #include "pideque.h"
#include "pipair.h" #include "pipair.h"
# define __PICONTAINERS_SIMPLE_TYPE__(T) \
__PIDEQUE_SIMPLE_TYPE__(T)\
__PIVECTOR_SIMPLE_TYPE__(T)
template<class T> template<class T>

View File

@@ -210,7 +210,22 @@ public:
inline T * data(size_t index = 0) {return &(piv_data[index]);} 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 const T * data(size_t index = 0) const {return &(piv_data[index]);}
inline PIVector<T> & clear() {resize(0); return *this;} template<typename T1 = T, typename std::enable_if<
!std::is_trivially_copyable<T1>::value
, int>::type = 0>
inline PIVector<T> & clear() {
resize(0);
return *this;
}
template<typename T1 = T, typename std::enable_if<
std::is_trivially_copyable<T1>::value
, int>::type = 0>
inline PIVector<T> & clear() {
PIINTROSPECTION_CONTAINER_UNUSED(T, piv_size)
piv_size = 0;
return *this;
}
inline PIVector<T> & fill(const T & f = T()) { inline PIVector<T> & fill(const T & f = T()) {
deleteT(piv_data, piv_size); deleteT(piv_data, piv_size);
PIINTROSPECTION_CONTAINER_USED(T, piv_size) PIINTROSPECTION_CONTAINER_USED(T, piv_size)
@@ -219,10 +234,20 @@ public:
return *this; return *this;
} }
inline PIVector<T> & assign(const T & f = T()) {return fill(f);} inline PIVector<T> & assign(const T & f = T()) {return fill(f);}
template<typename T1 = T, typename std::enable_if<
!std::is_trivially_copyable<T1>::value
, int>::type = 0>
inline PIVector<T> & assign(size_t new_size, const T & f) { inline PIVector<T> & assign(size_t new_size, const T & f) {
resize(new_size); resize(new_size);
return fill(f); return fill(f);
} }
template<typename T1 = T, typename std::enable_if<
std::is_trivially_copyable<T1>::value
, int>::type = 0>
inline PIVector<T> & assign(size_t new_size, const T & f) {
_resizeRaw(new_size);
return fill(f);
}
inline PIVector<T> & resize(size_t new_size, const T & f = T()) { inline PIVector<T> & resize(size_t new_size, const T & f = T()) {
if (new_size < piv_size) { if (new_size < piv_size) {
@@ -239,9 +264,17 @@ public:
} }
return *this; return *this;
} }
template<typename T1 = T, typename std::enable_if<
std::is_trivially_copyable<T1>::value
, int>::type = 0>
inline PIVector<T> & _resizeRaw(size_t new_size) { inline PIVector<T> & _resizeRaw(size_t new_size) {
piCout << "Error, \"resizeRaw()\" only allowed for simple type declared with __PIVECTOR_SIMPLE_TYPE__ macro!"; if (new_size > piv_size) {
assert(0); 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; return *this;
} }
inline void _copyRaw(T * dst, const T * src, size_t size) { inline void _copyRaw(T * dst, const T * src, size_t size) {
@@ -425,11 +458,24 @@ private:
while (s_ >> t) ++t; while (s_ >> t) ++t;
return (1 << t); return (1 << t);
} }
template<typename T1 = T, typename std::enable_if<
!std::is_trivially_copyable<T1>::value
, int>::type = 0>
inline void newT(T * dst, const T * src, size_t s) { inline void newT(T * dst, const T * src, size_t s) {
PIINTROSPECTION_CONTAINER_USED(T, s) PIINTROSPECTION_CONTAINER_USED(T, s)
for (size_t i = 0; i < s; ++i) for (size_t i = 0; i < s; ++i)
elementNew(dst + i, src[i]); elementNew(dst + i, src[i]);
} }
template<typename T1 = T, typename std::enable_if<
std::is_trivially_copyable<T1>::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<typename T1 = T, typename std::enable_if<
!std::is_trivially_copyable<T1>::value
, int>::type = 0>
inline void deleteT(T * d, size_t sz) { inline void deleteT(T * d, size_t sz) {
PIINTROSPECTION_CONTAINER_UNUSED(T, sz) PIINTROSPECTION_CONTAINER_UNUSED(T, sz)
if ((uchar*)d != 0) { if ((uchar*)d != 0) {
@@ -437,9 +483,36 @@ private:
elementDelete(d[i]); elementDelete(d[i]);
} }
} }
template<typename T1 = T, typename std::enable_if<
std::is_trivially_copyable<T1>::value
, int>::type = 0>
inline void deleteT(T * d, size_t sz) {
PIINTROSPECTION_CONTAINER_UNUSED(T, sz)
}
template<typename T1 = T, typename std::enable_if<
!std::is_trivially_copyable<T1>::value
, int>::type = 0>
inline void elementNew(T * to, const T & from) {new(to)T(from);} inline void elementNew(T * to, const T & from) {new(to)T(from);}
template<typename T1 = T, typename std::enable_if<
!std::is_trivially_copyable<T1>::value
, int>::type = 0>
inline void elementNew(T * to, T && from) {new(to)T(std::move(from));} inline void elementNew(T * to, T && from) {new(to)T(std::move(from));}
template<typename T1 = T, typename std::enable_if<
std::is_trivially_copyable<T1>::value
, int>::type = 0>
inline void elementNew(T1 * to, const T & from) {(*to) = from;}
template<typename T1 = T, typename std::enable_if<
std::is_trivially_copyable<T1>::value
, int>::type = 0>
inline void elementNew(T * to, T && from) {(*to) = std::move(from);}
template<typename T1 = T, typename std::enable_if<
!std::is_trivially_copyable<T1>::value
, int>::type = 0>
inline void elementDelete(T & from) {from.~T();} inline void elementDelete(T & from) {from.~T();}
template<typename T1 = T, typename std::enable_if<
std::is_trivially_copyable<T1>::value
, int>::type = 0>
inline void elementDelete(T & from) {}
inline void dealloc() { inline void dealloc() {
if ((uchar*)piv_data != 0) free((uchar*)piv_data); if ((uchar*)piv_data != 0) free((uchar*)piv_data);
piv_data = 0; piv_data = 0;
@@ -464,41 +537,6 @@ private:
}; };
#define __PIVECTOR_SIMPLE_TYPE__(T) \
template<> inline void PIVector<T>::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<T>::deleteT(T *, size_t sz) {PIINTROSPECTION_CONTAINER_UNUSED(T, sz);} \
template<> inline void PIVector<T>::elementNew(T * to, const T & from) {(*to) = from;} \
template<> inline void PIVector<T>::elementNew(T * to, T && from) {(*to) = std::move(from);} \
template<> inline void PIVector<T>::elementDelete(T &) {;} \
template<> inline PIVector<T> & PIVector<T>::_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<T> & PIVector<T>::clear() {PIINTROSPECTION_CONTAINER_UNUSED(T, piv_size); piv_size = 0; return *this;} \
template<> inline PIVector<T> & PIVector<T>::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 #ifdef PIP_STD_IOSTREAM
template<typename T> template<typename T>

View File

@@ -251,9 +251,13 @@ public:
piSwap<size_t>(cols_, other.cols_); piSwap<size_t>(cols_, other.cols_);
} }
template<typename T1 = T, typename std::enable_if<
std::is_trivially_copyable<T1>::value
, int>::type = 0>
inline PIVector2D<T> & _resizeRaw(size_t r, size_t c) { inline PIVector2D<T> & _resizeRaw(size_t r, size_t c) {
piCout << "Error, \"resizeRaw()\" only allowed for simple type declared with __PIVECTOR_SIMPLE_TYPE__ macro!"; rows_ = r;
assert(0); cols_ = c;
mat._resizeRaw(r*c);
return *this; return *this;
} }
@@ -287,22 +291,5 @@ inline PICout operator <<(PICout s, const PIVector2D<T> & v) {
return s; return s;
} }
#define __PIVECTOR2D_SIMPLE_TYPE__(T) \
template<> inline PIVector2D<T> & PIVector2D<T>::_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 #endif // PIVECTOR2D_H

View File

@@ -28,23 +28,6 @@
#include "pimap.h" #include "pimap.h"
#include "pivector2d.h" #include "pivector2d.h"
__PICONTAINERS_SIMPLE_TYPE__(PIChar)
#define __PIBYTEARRAY_SIMPLE_TYPE__(T) \
template<> \
inline PIByteArray & operator <<(PIByteArray & s, const PIVector<T> & 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<T> & 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<T> & 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<T> & 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<T> & 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<T> & 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 PIString;
class PIByteArray; class PIByteArray;
@@ -138,7 +121,36 @@ public:
static PIByteArray fromBase64(const PIString & base64); 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)
andrey marked this conversation as resolved
Review

надо бы заменить на memcmp

надо бы заменить на memcmp
Review

по тестам memcmp профита не даёт

по тестам memcmp профита не даёт
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)
andrey marked this conversation as resolved
Review

надо бы заменить на memcmp

надо бы заменить на memcmp
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)
andrey marked this conversation as resolved
Review

надо бы заменить на memcmp

надо бы заменить на memcmp
if (f[i] != s[i])
return true;
return false;
}
#ifdef PIP_STD_IOSTREAM #ifdef PIP_STD_IOSTREAM
//! \relatesalso PIByteArray \brief Output to std::ostream operator //! \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 //! \relatesalso PIByteArray \brief Output to PICout operator
PIP_EXPORT PICout operator <<(PICout s, const PIByteArray & ba); 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 //! \relatesalso PIByteArray \brief Store operator

а этот макрос теперь нужен вообще? он же в 1м месте только

а этот макрос теперь нужен вообще? он же в 1м месте только
Outdated
Review

в 3

в 3

у тебя на 3 строки 5 строк описания дефайна, мне это кажется нелогичным, не говоря от том что макросы нужно использовать только по необходимости, коей здесь не видно

у тебя на 3 строки 5 строк описания дефайна, мне это кажется нелогичным, не говоря от том что макросы нужно использовать только по необходимости, коей здесь не видно
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 //! \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 //! \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 //! \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 //! \relatesalso PIByteArray \brief Store operator
inline PIByteArray & operator <<(PIByteArray & s, const int v) {PBA_OPERATOR_TO return s;} template<typename T> inline PIByteArray & operator <<(PIByteArray & s, const PIFlags<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
inline PIByteArray & operator <<(PIByteArray & s, const long & v) {PBA_OPERATOR_TO return s;} //! \relatesalso PIByteArray \brief Store operator for any trivial copyable type
//! \relatesalso PIByteArray \brief Store operator template<typename T, typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0>
inline PIByteArray & operator <<(PIByteArray & s, const llong & 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
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<typename T> inline PIByteArray & operator <<(PIByteArray & s, const PIFlags<T> & v) {PBA_OPERATOR_TO return s;}
//! \relatesalso PIByteArray \brief Store operator, see \ref PIByteArray_sec1 for details //! \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 //! \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 //! \relatesalso PIByteArray \brief Store operator for PIVector of any trivial copyable type
#define PBA_OPERATOR_FROM memcpy((void*)(&v), s.data(), sizeof(v)); s.remove(0, sizeof(v)); template<typename T, typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0>
inline PIByteArray & operator <<(PIByteArray & s, const PIVector<T> & 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 //! \relatesalso PIByteArray \brief Store operator for PIDeque of any trivial copyable type
inline PIByteArray & operator >>(PIByteArray & s, bool & v) {assert(s.size() >= 1u); v = s.take_front(); return s;} template<typename T, typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0>
//! \relatesalso PIByteArray \brief Restore operator inline PIByteArray & operator <<(PIByteArray & s, const PIDeque<T> & v) {
inline PIByteArray & operator >>(PIByteArray & s, char & v) {assert(s.size() >= 1u); v = s.take_front(); return s;} s << int(v.size_s());
//! \relatesalso PIByteArray \brief Restore operator int os = s.size_s();
inline PIByteArray & operator >>(PIByteArray & s, uchar & v) {assert(s.size() >= 1u); v = s.take_front(); return s;} if (v.size_s() > 0) {
//! \relatesalso PIByteArray \brief Restore operator s.enlarge(v.size_s()*sizeof(T));
inline PIByteArray & operator >>(PIByteArray & s, short & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;} memcpy(s.data(os), v.data(), v.size_s()*sizeof(T));
//! \relatesalso PIByteArray \brief Restore operator }
inline PIByteArray & operator >>(PIByteArray & s, int & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;} 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<typename T> inline PIByteArray & operator >>(PIByteArray & s, PIFlags<T> & 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<typename Type0, typename Type1> inline PIByteArray & operator <<(PIByteArray & s, const PIPair<Type0, Type1> & v);
//! \relatesalso PIByteArray \brief Store operator
template<typename T> inline PIByteArray & operator <<(PIByteArray & s, const PIVector<T> & v);
//! \relatesalso PIByteArray \brief Store operator
template<typename T> inline PIByteArray & operator <<(PIByteArray & s, const PIDeque<T> & v);
//! \relatesalso PIByteArray \brief Store operator
template <typename Key, typename T> inline PIByteArray & operator <<(PIByteArray & s, const PIMap<Key, T> & 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<typename Type0, typename Type1> inline PIByteArray & operator >>(PIByteArray & s, PIPair<Type0, Type1> & v);
//! \relatesalso PIByteArray \brief Restore operator
template<typename T> inline PIByteArray & operator >>(PIByteArray & s, PIVector<T> & v);
//! \relatesalso PIByteArray \brief Restore operator
template<typename T> inline PIByteArray & operator >>(PIByteArray & s, PIDeque<T> & v);
//! \relatesalso PIByteArray \brief Restore operator
template <typename Key, typename T> inline PIByteArray & operator >>(PIByteArray & s, PIMap<Key, T> & v);
//! Read operator from \c PIByteArray
inline PIByteArray & operator >>(PIByteArray & s, PIChar & v) {s >> v.ch; return s;}
//! \relatesalso PIByteArray \brief Store operator for PIVector2D of any trivial copyable type
template<typename T, typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0>
inline PIByteArray & operator <<(PIByteArray & s, const PIVector2D<T> & 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 //! \relatesalso PIByteArray \brief Store operator
inline PIByteArray & operator <<(PIByteArray & s, const PIBitArray & v) {s << v.size_ << v.data_; return s;} inline PIByteArray & operator <<(PIByteArray & s, const PIBitArray & v) {s << v.size_ << v.data_; return s;}
//! \relatesalso PIPair \brief Store operator
template<typename Type0, typename Type1> template<typename Type0, typename Type1>
inline PIByteArray & operator <<(PIByteArray & s, const PIPair<Type0, Type1> & v) {s << v.first << v.second; return s;} inline PIByteArray & operator <<(PIByteArray & s, const PIPair<Type0, Type1> & v) {s << v.first << v.second; return s;}
template<typename T>
inline PIByteArray & operator <<(PIByteArray & s, const PIVector<T> & v) {s << int(v.size_s()); for (uint i = 0; i < v.size(); ++i) s << v[i]; return s;}
template<typename T>
inline PIByteArray & operator <<(PIByteArray & s, const PIDeque<T> & 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;}

этот макрос тоже теперь не нужен?

этот макрос тоже теперь не нужен?
Outdated
Review

тем более они потом undefine, в чем проблема?

тем более они потом undefine, в чем проблема?

не читаемый код получается, и к тому же кода больше чем если ты эту строку вставишь в функцию

не читаемый код получается, и к тому же кода больше чем если ты эту строку вставишь в функцию
//! \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<typename T, typename std::enable_if< std::is_trivially_copyable<T>::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<typename T> inline PIByteArray & operator >>(PIByteArray & s, PIFlags<T> & 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);
peri4 marked this conversation as resolved Outdated

а почему этот оператор не inline, а оператор << inline?

а почему этот оператор не inline, а оператор << inline?
Outdated
Review

потому что реализован в cpp, и 20 строк, большой

потому что реализован в cpp, и 20 строк, большой

оператор « маленький что ли?

оператор « маленький что ли?
s.remove(0, v.s);
}
return s;
}
//! \relatesalso PIByteArray \brief Restore operator for PIVector of any trivial copyable type
template<typename T, typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0>
inline PIByteArray & operator >>(PIByteArray & s, PIVector<T> & 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<typename T, typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0>
inline PIByteArray & operator >>(PIByteArray & s, PIDeque<T> & 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<typename T, typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0>
inline PIByteArray & operator >>(PIByteArray & s, PIVector2D<T> & 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<typename Type0, typename Type1>
inline PIByteArray & operator >>(PIByteArray & s, PIPair<Type0, Type1> & 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<typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
inline PIByteArray & operator <<(PIByteArray & s, const PIVector<T> & 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<typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
inline PIByteArray & operator <<(PIByteArray & s, const PIDeque<T> & 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<typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
inline PIByteArray & operator <<(PIByteArray & s, const PIVector2D<T> & 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<typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
inline PIByteArray & operator >>(PIByteArray & s, PIVector<T> & 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<typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
inline PIByteArray & operator >>(PIByteArray & s, PIDeque<T> & 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<typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
inline PIByteArray & operator >>(PIByteArray & s, PIVector2D<T> & v) {
assert(s.size_s() >= 8);
int r,c;
PIVector<T> tmp;
s >> r >> c >> tmp;
v = PIVector2D<T>(r, c, tmp);
return s;
}
// other types
template <typename Key, typename T> template <typename Key, typename T>
inline PIByteArray & operator <<(PIByteArray & s, const PIMap<Key, T> & v) { inline PIByteArray & operator <<(PIByteArray & s, const PIMap<Key, T> & v) {
s << int(v.pim_index.size_s()); s << int(v.pim_index.size_s());
@@ -264,18 +414,8 @@ inline PIByteArray & operator <<(PIByteArray & s, const PIMap<Key, T> & v) {
s << v.pim_content; s << v.pim_content;
return s; return s;
} }
template<typename T>
inline PIByteArray & operator <<(PIByteArray & s, const PIVector2D<T> & 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<typename Type0, typename Type1>
inline PIByteArray & operator >>(PIByteArray & s, PIPair<Type0, Type1> & v) {s >> v.first >> v.second; return s;}
template<typename T>
inline PIByteArray & operator >>(PIByteArray & s, PIVector<T> & 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<typename T>
inline PIByteArray & operator >>(PIByteArray & s, PIDeque<T> & 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 <typename Key, typename T> template <typename Key, typename T>
inline PIByteArray & operator >>(PIByteArray & s, PIMap<Key, T> & v) { inline PIByteArray & operator >>(PIByteArray & s, PIMap<Key, T> & v) {
assert(s.size_s() >= 4); assert(s.size_s() >= 4);
@@ -292,36 +432,20 @@ inline PIByteArray & operator >>(PIByteArray & s, PIMap<Key, T> & v) {
} }
return s; return s;
} }
template<typename T>
inline PIByteArray & operator >>(PIByteArray & s, PIVector2D<T> & v) {assert(s.size_s() >= 8); int r,c; PIVector<T> tmp; s >> r >> c >> tmp; v = PIVector2D<T>(r, c, tmp); return s;}
template<typename T>
inline PIByteArray & operator <<(PIByteArray & s, const T & ) {piCout << "[PIByteArray] Warning: using undeclared operator <<!"; return s;}
template<typename T>
inline PIByteArray & operator >>(PIByteArray & s, T & ) {piCout << "[PIByteArray] Warning: using undeclared operator >>!"; return s;}
template<typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
inline PIByteArray & operator <<(PIByteArray & s, const T & ) {
static_assert(std::is_trivially_copyable<T>::value, "[PIByteArray] Error: using undeclared operator << for complex type!");
return s;
}
//! \relatesalso PIByteArray \brief Byte arrays compare operator template<typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
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;} inline PIByteArray & operator >>(PIByteArray & s, T & ) {
//! \relatesalso PIByteArray \brief Byte arrays compare operator static_assert(std::is_trivially_copyable<T>::value, "[PIByteArray] Error: using undeclared operator >> for complex type!");
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;} return s;
}
andrey marked this conversation as resolved
Review

Пихать в static_assert std::is_trivially_copyable::value мне кажется лишним, другой туда не попадёт, наглядней будет static_assert(false) или static_assert(0). Ещё предлагаю в сообщение запихнуть имя типа, а то не понятно на что он сработал.

Пихать в static_assert std::is_trivially_copyable<T>::value мне кажется лишним, другой туда не попадёт, наглядней будет static_assert(false) или static_assert(0). Ещё предлагаю в сообщение запихнуть имя типа, а то не понятно на что он сработал.
Review

нет, не трогай. с false он для всех типов стреляет ассертом. имя типа как мы получим, это ж компил-тайм?

нет, не трогай. с false он для всех типов стреляет ассертом. имя типа как мы получим, это ж компил-тайм?
Review

а typeid это разве не компил тайм?

а typeid это разве не компил тайм?
Review

зачем вообще тип выводить если тебе ошибка дана на место в коде, сходи и посмотри

зачем вообще тип выводить если тебе ошибка дана на место в коде, сходи и посмотри
__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<> inline uint piHash(const PIByteArray & ba) {return ba.hash();} template<> inline uint piHash(const PIByteArray & ba) {return ba.hash();}
template<> inline void piSwap(PIByteArray & f, PIByteArray & s) {f.swap(s);} template<> inline void piSwap(PIByteArray & f, PIByteArray & s) {f.swap(s);}

View File

@@ -34,7 +34,7 @@ class PIP_EXPORT PIChar
friend class PIString; friend class PIString;
friend PIByteArray & operator <<(PIByteArray & s, const PIChar & v); friend PIByteArray & operator <<(PIByteArray & s, const PIChar & v);
friend PIByteArray & operator >>(PIByteArray & s, 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: public:
//! Contructs ascii symbol //! Contructs ascii symbol
PIChar(const char c) {ch = c; ch &= 0xFF;} PIChar(const char c) {ch = c; ch &= 0xFF;}
@@ -135,7 +135,7 @@ private:
}; };
//! Output operator to \a PICout //! Output operator to \a PICout
PICout operator <<(PICout s, const PIChar & v); PICout PIP_EXPORT operator <<(PICout s, const PIChar & v);
//! Compare operator //! Compare operator
inline bool operator ==(const char v, const PIChar & c) {return (PIChar(v) == c);} inline bool operator ==(const char v, const PIChar & c) {return (PIChar(v) == c);}

View File

@@ -105,7 +105,7 @@ PIMap<PIString, PIVariant> PIObject::properties() const {
bool PIObject::execute(const PIString & method, const PIVector<PIVariant> & vl) { bool PIObject::execute(const PIString & method, const PIVector<PIVariantSimple> & vl) {
if (method.isEmpty()) return false; if (method.isEmpty()) return false;
if (!isPIObject()) { if (!isPIObject()) {
piCout << "Error: \"execute(" << method << ")\":" << (void*)this << "is not PIObject!"; piCout << "Error: \"execute(" << method << ")\":" << (void*)this << "is not PIObject!";
@@ -121,7 +121,7 @@ bool PIObject::execute(const PIString & method, const PIVector<PIVariant> & vl)
} }
bool PIObject::executeQueued(PIObject * performer, const PIString & method, const PIVector<PIVariant> & vl) { bool PIObject::executeQueued(PIObject * performer, const PIString & method, const PIVector<PIVariantSimple> & vl) {
if (!isPIObject()) { if (!isPIObject()) {
piCout << "Error: \"executeQueued(" << method << ")\": this(" << (void*)this << ") is not PIObject!"; piCout << "Error: \"executeQueued(" << method << ")\": this(" << (void*)this << ") is not PIObject!";
return false; return false;
@@ -535,14 +535,14 @@ PIMutex & PIObject::mutexObjects() {
} }
void PIObject::callAddrV(void * slot, void * obj, int args, const PIVector<PIVariant> & vl) { void PIObject::callAddrV(void * slot, void * obj, int args, const PIVector<PIVariantSimple> & vl) {
args = piMini(args, vl.size_s()); args = piMini(args, vl.size_s());
switch (args) { switch (args) {
case 0: ((void(*)(void *))slot)(obj); break; case 0: ((void(*)(void *))slot)(obj); break;
case 1: ((void(*)(void * , const PIVariant & ))slot)(obj, vl[0]); break; case 1: ((void(*)(void * , const PIVariantSimple & ))slot)(obj, vl[0]); break;
case 2: ((void(*)(void * , const PIVariant & , const PIVariant & ))slot)(obj, vl[0], vl[1]); break; case 2: ((void(*)(void * , const PIVariantSimple & , const PIVariantSimple & ))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 3: ((void(*)(void * , const PIVariantSimple & , const PIVariantSimple & , const PIVariantSimple & ))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 4: ((void(*)(void * , const PIVariantSimple & , const PIVariantSimple & , const PIVariantSimple & , const PIVariantSimple & ))slot)(obj, vl[0], vl[1], vl[2], vl[3]); break;
default: break; default: break;
} }
} }

View File

@@ -27,6 +27,7 @@
#include "piinit.h" #include "piinit.h"
#include "pivariant.h" #include "pivariant.h"
#include "pivariantsimple.h"
#include "pimutex.h" #include "pimutex.h"
#include "piset.h" #include "piset.h"
#include "piqueue.h" #include "piqueue.h"
@@ -101,33 +102,33 @@ public:
void setThreadSafe(bool yes) {thread_safe_ = yes;} void setThreadSafe(bool yes) {thread_safe_ = yes;}
bool isThreadSafe() const {return thread_safe_;} bool isThreadSafe() const {return thread_safe_;}
bool execute(const PIString & method, const PIVector<PIVariant> & vl); bool execute(const PIString & method, const PIVector<PIVariantSimple> & vl);
bool execute(const PIString & method) {return execute(method, PIVector<PIVariant>());} bool execute(const PIString & method) {return execute(method, PIVector<PIVariantSimple>());}
bool execute(const PIString & method, const PIVariant & v0) {return execute(method, PIVector<PIVariant>() << v0);} bool execute(const PIString & method, const PIVariantSimple & v0) {return execute(method, PIVector<PIVariantSimple>() << v0);}
bool execute(const PIString & method, const PIVariant & v0, const PIVariant & v1) {return execute(method, PIVector<PIVariant>() << v0 << v1);} bool execute(const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1) {return execute(method, PIVector<PIVariantSimple>() << v0 << v1);}
bool execute(const PIString & method, const PIVariant & v0, const PIVariant & v1, const PIVariant & v2) {return execute(method, PIVector<PIVariant>() << v0 << v1 << v2);} bool execute(const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2) {return execute(method, PIVector<PIVariantSimple>() << v0 << v1 << v2);}
bool execute(const PIString & method, const PIVariant & v0, const PIVariant & v1, const PIVariant & v2, const PIVariant & v3) {return execute(method, PIVector<PIVariant>() << v0 << v1 << v2 << v3);} bool execute(const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2, const PIVariantSimple & v3) {return execute(method, PIVector<PIVariantSimple>() << v0 << v1 << v2 << v3);}
bool executeQueued(PIObject * performer, const PIString & method, const PIVector<PIVariant> & vl); bool executeQueued(PIObject * performer, const PIString & method, const PIVector<PIVariantSimple> & vl);
bool executeQueued(PIObject * performer, const PIString & method) {return executeQueued(performer, method, PIVector<PIVariant>());} bool executeQueued(PIObject * performer, const PIString & method) {return executeQueued(performer, method, PIVector<PIVariantSimple>());}
bool executeQueued(PIObject * performer, const PIString & method, const PIVariant & v0) {return executeQueued(performer, method, PIVector<PIVariant>() << v0);} bool executeQueued(PIObject * performer, const PIString & method, const PIVariantSimple & v0) {return executeQueued(performer, method, PIVector<PIVariantSimple>() << v0);}
bool executeQueued(PIObject * performer, const PIString & method, const PIVariant & v0, const PIVariant & v1) {return executeQueued(performer, method, PIVector<PIVariant>() << v0 << v1);} bool executeQueued(PIObject * performer, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1) {return executeQueued(performer, method, PIVector<PIVariantSimple>() << v0 << v1);}
bool executeQueued(PIObject * performer, const PIString & method, const PIVariant & v0, const PIVariant & v1, const PIVariant & v2) {return executeQueued(performer, method, PIVector<PIVariant>() << v0 << v1 << v2);} bool executeQueued(PIObject * performer, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2) {return executeQueued(performer, method, PIVector<PIVariantSimple>() << 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<PIVariant>() << v0 << v1 << v2 << v3);} bool executeQueued(PIObject * performer, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2, const PIVariantSimple & v3) {return executeQueued(performer, method, PIVector<PIVariantSimple>() << v0 << v1 << v2 << v3);}
static bool execute(PIObject * o, const PIString & method, const PIVector<PIVariant> & vl) {return o->execute(method, vl);} static bool execute(PIObject * o, const PIString & method, const PIVector<PIVariantSimple> & vl) {return o->execute(method, vl);}
static bool execute(PIObject * o, const PIString & method) {return execute(o, method, PIVector<PIVariant>());} static bool execute(PIObject * o, const PIString & method) {return execute(o, method, PIVector<PIVariantSimple>());}
static bool execute(PIObject * o, const PIString & method, const PIVariant & v0) {return execute(o, method, PIVector<PIVariant>() << v0);} static bool execute(PIObject * o, const PIString & method, const PIVariantSimple & v0) {return execute(o, method, PIVector<PIVariantSimple>() << v0);}
static bool execute(PIObject * o, const PIString & method, const PIVariant & v0, const PIVariant & v1) {return execute(o, method, PIVector<PIVariant>() << v0 << v1);} static bool execute(PIObject * o, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1) {return execute(o, method, PIVector<PIVariantSimple>() << v0 << v1);}
static bool execute(PIObject * o, const PIString & method, const PIVariant & v0, const PIVariant & v1, const PIVariant & v2) {return execute(o, method, PIVector<PIVariant>() << v0 << v1 << v2);} static bool execute(PIObject * o, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2) {return execute(o, method, PIVector<PIVariantSimple>() << 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<PIVariant>() << v0 << v1 << v2 << v3);} 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<PIVariantSimple>() << v0 << v1 << v2 << v3);}
static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVector<PIVariant> & vl) {return o->executeQueued(performer, method, vl);} static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVector<PIVariantSimple> & vl) {return o->executeQueued(performer, method, vl);}
static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method) {return executeQueued(o, performer, method, PIVector<PIVariant>());} static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method) {return executeQueued(o, performer, method, PIVector<PIVariantSimple>());}
static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVariant & v0) {return executeQueued(o, performer, method, PIVector<PIVariant>() << v0);} static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVariantSimple & v0) {return executeQueued(o, performer, method, PIVector<PIVariantSimple>() << v0);}
static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVariant & v0, const PIVariant & v1) {return executeQueued(o, performer, method, PIVector<PIVariant>() << v0 << v1);} static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1) {return executeQueued(o, performer, method, PIVector<PIVariantSimple>() << 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<PIVariant>() << v0 << v1 << v2);} 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<PIVariantSimple>() << 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<PIVariant>() << v0 << v1 << v2 << v3);} 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<PIVariantSimple>() << v0 << v1 << v2 << v3);}
void dump(const PIString & line_prefix = PIString()) const; void dump(const PIString & line_prefix = PIString()) const;
@@ -201,8 +202,8 @@ public:
(*((std::function<void(T0)>*)i.functor))(v0); (*((std::function<void(T0)>*)i.functor))(v0);
} else { } else {
if (i.performer) { if (i.performer) {
PIVector<PIVariant> vl; PIVector<PIVariantSimple> vl;
if (i.args_count > 0) vl << PIVariant::fromValue(v0); if (i.args_count > 0) vl << PIVariantSimple::fromValue(v0);
i.performer->postQueuedEvent(__QueuedEvent(i.slot, i.dest, i.dest_o, sender, vl)); i.performer->postQueuedEvent(__QueuedEvent(i.slot, i.dest, i.dest_o, sender, vl));
} else { } else {
bool ts = sender->thread_safe_; bool ts = sender->thread_safe_;
@@ -232,9 +233,9 @@ public:
(*((std::function<void(T0, T1)>*)i.functor))(v0, v1); (*((std::function<void(T0, T1)>*)i.functor))(v0, v1);
} else { } else {
if (i.performer) { if (i.performer) {
PIVector<PIVariant> vl; PIVector<PIVariantSimple> vl;
if (i.args_count > 0) vl << PIVariant::fromValue(v0); if (i.args_count > 0) vl << PIVariantSimple::fromValue(v0);
if (i.args_count > 1) vl << PIVariant::fromValue(v1); if (i.args_count > 1) vl << PIVariantSimple::fromValue(v1);
i.performer->postQueuedEvent(__QueuedEvent(i.slot, i.dest, i.dest_o, sender, vl)); i.performer->postQueuedEvent(__QueuedEvent(i.slot, i.dest, i.dest_o, sender, vl));
} else { } else {
bool ts = sender->thread_safe_; bool ts = sender->thread_safe_;
@@ -267,10 +268,10 @@ public:
(*((std::function<void(T0, T1, T2)>*)i.functor))(v0, v1, v2); (*((std::function<void(T0, T1, T2)>*)i.functor))(v0, v1, v2);
} else { } else {
if (i.performer) { if (i.performer) {
PIVector<PIVariant> vl; PIVector<PIVariantSimple> vl;
if (i.args_count > 0) vl << PIVariant::fromValue(v0); if (i.args_count > 0) vl << PIVariantSimple::fromValue(v0);
if (i.args_count > 1) vl << PIVariant::fromValue(v1); if (i.args_count > 1) vl << PIVariantSimple::fromValue(v1);
if (i.args_count > 2) vl << PIVariant::fromValue(v2); if (i.args_count > 2) vl << PIVariantSimple::fromValue(v2);
i.performer->postQueuedEvent(__QueuedEvent(i.slot, i.dest, i.dest_o, sender, vl)); i.performer->postQueuedEvent(__QueuedEvent(i.slot, i.dest, i.dest_o, sender, vl));
} else { } else {
bool ts = sender->thread_safe_; bool ts = sender->thread_safe_;
@@ -304,11 +305,11 @@ public:
(*((std::function<void(T0, T1, T2, T3)>*)i.functor))(v0, v1, v2, v3); (*((std::function<void(T0, T1, T2, T3)>*)i.functor))(v0, v1, v2, v3);
} else { } else {
if (i.performer) { if (i.performer) {
PIVector<PIVariant> vl; PIVector<PIVariantSimple> vl;
if (i.args_count > 0) vl << PIVariant::fromValue(v0); if (i.args_count > 0) vl << PIVariantSimple::fromValue(v0);
if (i.args_count > 1) vl << PIVariant::fromValue(v1); if (i.args_count > 1) vl << PIVariantSimple::fromValue(v1);
if (i.args_count > 2) vl << PIVariant::fromValue(v2); if (i.args_count > 2) vl << PIVariantSimple::fromValue(v2);
if (i.args_count > 3) vl << PIVariant::fromValue(v3); if (i.args_count > 3) vl << PIVariantSimple::fromValue(v3);
i.performer->postQueuedEvent(__QueuedEvent(i.slot, i.dest, i.dest_o, sender, vl)); i.performer->postQueuedEvent(__QueuedEvent(i.slot, i.dest, i.dest_o, sender, vl));
} else { } else {
bool ts = sender->thread_safe_; bool ts = sender->thread_safe_;
@@ -452,7 +453,7 @@ private:
}; };
struct __QueuedEvent { struct __QueuedEvent {
__QueuedEvent(void * sl = 0, void * d = 0, PIObject * d_o = 0, PIObject * s = 0, const PIVector<PIVariant> & v = PIVector<PIVariant>()) { __QueuedEvent(void * sl = 0, void * d = 0, PIObject * d_o = 0, PIObject * s = 0, const PIVector<PIVariantSimple> & v = PIVector<PIVariantSimple>()) {
slot = sl; slot = sl;
dest = d; dest = d;
dest_o = d_o; dest_o = d_o;
@@ -463,7 +464,7 @@ private:
void * dest; void * dest;
PIObject * dest_o; PIObject * dest_o;
PIObject * src; PIObject * src;
PIVector<PIVariant> values; PIVector<PIVariantSimple> values;
}; };
class Deleter { class Deleter {
@@ -496,7 +497,7 @@ private:
static PIVector<PIObject * > & objects(); static PIVector<PIObject * > & objects();
static PIMutex & mutexObjects(); static PIMutex & mutexObjects();
static void callAddrV(void * slot, void * obj, int args, const PIVector<PIVariant> & vl); static void callAddrV(void * slot, void * obj, int args, const PIVector<PIVariantSimple> & vl);
PIVector<__Connection> connections; PIVector<__Connection> connections;

View File

@@ -269,7 +269,7 @@
PIMutexLocker ml(__meta_mutex()); \ PIMutexLocker ml(__meta_mutex()); \
__MetaData & eh(__meta_data()[__classNameIDS()]); \ __MetaData & eh(__meta_data()[__classNameIDS()]); \
void * fp = (void*)(ret(*)(void*, a0))__stat_eh_##name##__; \ 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; \ if (eh.eh_set[fp]) return; \
eh.eh_set << fp; \ eh.eh_set << fp; \
__MetaFunc & f(eh.eh_func[fp]); \ __MetaFunc & f(eh.eh_func[fp]); \
@@ -287,7 +287,7 @@
PIMutexLocker ml(__meta_mutex()); \ PIMutexLocker ml(__meta_mutex()); \
__MetaData & eh(__meta_data()[__classNameIDS()]); \ __MetaData & eh(__meta_data()[__classNameIDS()]); \
void * fp = (void*)(ret(*)(void*, a0, a1))__stat_eh_##name##__; \ 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; \ if (eh.eh_set[fp]) return; \
eh.eh_set << fp; \ eh.eh_set << fp; \
__MetaFunc & f(eh.eh_func[fp]); \ __MetaFunc & f(eh.eh_func[fp]); \
@@ -305,7 +305,7 @@
PIMutexLocker ml(__meta_mutex()); \ PIMutexLocker ml(__meta_mutex()); \
__MetaData & eh(__meta_data()[__classNameIDS()]); \ __MetaData & eh(__meta_data()[__classNameIDS()]); \
void * fp = (void*)(ret(*)(void*, a0, a1, a2))__stat_eh_##name##__; \ 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; \ if (eh.eh_set[fp]) return; \
eh.eh_set << fp; \ eh.eh_set << fp; \
__MetaFunc & f(eh.eh_func[fp]); \ __MetaFunc & f(eh.eh_func[fp]); \
@@ -323,7 +323,7 @@
PIMutexLocker ml(__meta_mutex()); \ PIMutexLocker ml(__meta_mutex()); \
__MetaData & eh(__meta_data()[__classNameIDS()]); \ __MetaData & eh(__meta_data()[__classNameIDS()]); \
void * fp = (void*)(ret(*)(void*, a0, a1, a2, a3))__stat_eh_##name##__; \ 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; \ if (eh.eh_set[fp]) return; \
eh.eh_set << fp; \ eh.eh_set << fp; \
__MetaFunc & f(eh.eh_func[fp]); \ __MetaFunc & f(eh.eh_func[fp]); \
@@ -345,7 +345,7 @@
#define EVENT_HANDLER1(ret, name, a0, n0) \ #define EVENT_HANDLER1(ret, name, a0, n0) \
EH_INIT1(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_##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); \ __PTYPE(a0) tv0 = __VVALUE(a0, v0); \
return ((__PIObject__*)__o__)->name(tv0);} \ return ((__PIObject__*)__o__)->name(tv0);} \
ret name(a0 n0) ret name(a0 n0)
@@ -353,7 +353,7 @@
#define EVENT_HANDLER2(ret, name, a0, n0, a1, n1) \ #define EVENT_HANDLER2(ret, name, a0, n0, a1, n1) \
EH_INIT2(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_##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(a0) tv0 = __VVALUE(a0, v0); \
__PTYPE(a1) tv1 = __VVALUE(a1, v1); \ __PTYPE(a1) tv1 = __VVALUE(a1, v1); \
return ((__PIObject__*)__o__)->name(tv0, tv1);} \ return ((__PIObject__*)__o__)->name(tv0, tv1);} \
@@ -362,7 +362,7 @@
#define EVENT_HANDLER3(ret, name, a0, n0, a1, n1, a2, n2) \ #define EVENT_HANDLER3(ret, name, a0, n0, a1, n1, a2, n2) \
EH_INIT3(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_##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(a0) tv0 = __VVALUE(a0, v0); \
__PTYPE(a1) tv1 = __VVALUE(a1, v1); \ __PTYPE(a1) tv1 = __VVALUE(a1, v1); \
__PTYPE(a2) tv2 = __VVALUE(a2, v2); \ __PTYPE(a2) tv2 = __VVALUE(a2, v2); \
@@ -372,7 +372,7 @@
#define EVENT_HANDLER4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) \ #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) \ 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_##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(a0) tv0 = __VVALUE(a0, v0); \
__PTYPE(a1) tv1 = __VVALUE(a1, v1); \ __PTYPE(a1) tv1 = __VVALUE(a1, v1); \
__PTYPE(a2) tv2 = __VVALUE(a2, v2); \ __PTYPE(a2) tv2 = __VVALUE(a2, v2); \
@@ -391,25 +391,25 @@
#define EVENT_VHANDLER1(ret, name, a0, n0) \ #define EVENT_VHANDLER1(ret, name, a0, n0) \
EH_INIT1(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_##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) virtual ret name(a0 n0)
#define EVENT_VHANDLER2(ret, name, a0, n0, a1, n1) \ #define EVENT_VHANDLER2(ret, name, a0, n0, a1, n1) \
EH_INIT2(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_##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) virtual ret name(a0 n0, a1 n1)
#define EVENT_VHANDLER3(ret, name, a0, n0, a1, n1, a2, n2) \ #define EVENT_VHANDLER3(ret, name, a0, n0, a1, n1, a2, n2) \
EH_INIT3(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_##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) virtual ret name(a0 n0, a1 n1, a2 n2)
#define EVENT_VHANDLER4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) \ #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) \ 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_##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) virtual ret name(a0 n0, a1 n1, a2 n2, a3 n3)
#define EVENT_VHANDLER EVENT_VHANDLER0 #define EVENT_VHANDLER EVENT_VHANDLER0

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef PIVARIANTSIMPLE_H
#define PIVARIANTSIMPLE_H
#include "pistring.h"
#include <typeinfo>
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<uint, __VariantFunctionsBase__*> & registered() {static PIMap<uint, __VariantFunctionsBase__*> ret; return ret;}
};
template<typename T>
class __VariantFunctions__: public __VariantFunctionsBase__ {
public:
__VariantFunctionsBase__ * instance() final {static __VariantFunctions__<T> ret; return &ret;}

тут правильнее во всех функциях использовать final вместо override

тут правильнее во всех функциях использовать final вместо override
Outdated
Review

ok

ok
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")*/;}

правильнее назвать функцию assign

правильнее назвать функцию assign
Outdated
Review

ok

ok
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 <typename T>
void setValue(const T & v) {
if (f) {
if (isMyType<T>()) {
f->assignT(ptr, (const void *)&v);
return;
}
}
destroy();
f = __VariantFunctions__<T>().instance();
f->newT(ptr, (const void *)&v);
}
template <typename T>
T value() const {
if (!f) return T();
if (!isMyType<T>())
return T();
return *(T*)(ptr);
}
template <typename T>
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 <typename T>
bool isMyType() const {
uint mh = f->hash(), th = __VariantFunctions__<T>().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__<Type>().instance(); \
__VariantFunctionsBase__::registered()[f->hash()] = f; \
STATIC_INITIALIZER_END()
#endif // PIVARIANTSIMPLE_H

View File

@@ -124,10 +124,12 @@ PIString PIFile::FileInfo::extension() const {
PIString PIFile::FileInfo::dir() const { PIString PIFile::FileInfo::dir() const {
if (path.isEmpty()) return PIString(); if (path.isEmpty()) return PIString();
PIString ret = path.mid(0, path.findLast(PIDir::separator)); int ind = path.findLast(PIDir::separator);
if (ret.isEmpty()) ret = PIDir::separator; PIString ret;
if (!PIDir(ret).isExists()) return (PIStringAscii(".") + PIDir::separator); if (ind >= 0)
return ret; ret = path.mid(0, ind);
if (ret.isEmpty()) ret = ".";
return ret + PIDir::separator;
} }

View File

@@ -36,7 +36,7 @@ public:
explicit PIFile(); explicit PIFile();
struct PIP_EXPORT FileInfo { 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 { enum Flag {
File = 0x01, File = 0x01,

View File

@@ -47,22 +47,6 @@ const complexld complexld_i(0., 1.);
const complexld complexld_0(0.); const complexld complexld_0(0.);
const complexld complexld_1(1.); 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 sign(const complexd & x) {return complexd(sign(x.real()), sign(x.imag()));}
inline complexd round(const complexd & c) {return complexd(piRound<double>(c.real()), piRound<double>(c.imag()));} inline complexd round(const complexd & c) {return complexd(piRound<double>(c.real()), piRound<double>(c.imag()));}

160
main.cpp
View File

@@ -1,79 +1,99 @@
#include "pip.h" #include "pip.h"
#include "pivariantsimple.h"
#define REGISTER_CNT (__COUNTER__) template<typename T>
#define REGISTER_V_STREAM_INTERNAL(T, C) \ struct __VariantTypeInfo__ {
class _VariantRegistrator_##C##__ { \ typedef T PureType;
public: \ typedef const T ConstPureType;
_VariantRegistrator_##C##__() { \ typedef T * PointerType;
__VariantFunctionsBase__ * f = __VariantFunctions__<int>().instance(); \ typedef const T * ConstPointerType;
__VariantFunctionsBase__::registered()[f->hash()] = f; \ typedef T & ReferenceType;
} \ typedef const T & ConstReferenceType;
}; \
_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);
}; };
#define __TYPEINFO_SINGLE(PT, T) \
template<> struct __PIVariantTypeInfo__<T> { \
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 { #define REGISTER_VARIANT_TYPEINFO(T) \
PIOBJECT(Recv) __TYPEINFO_SINGLE(T, T &) \
public: __TYPEINFO_SINGLE(T, const T) \
Recv() {piCout << "Recv";} __TYPEINFO_SINGLE(T, const T &)
~Recv() {piCout << "~Recv";}
EVENT_HANDLER1(void, eh, PIObject * , o) {
piCout << "eh ..." << o;
o->deleteLater(); struct SwitchChannel {
piMSleep(1000); SwitchChannel(bool on_ = true, float dur_ = 10.f, int m_count = 0, short unrely = -1) {
piCout << "eh ok"; 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];
}; };
/*
inline PIByteArray & operator <<(PIByteArray & ba, const SwitchChannel & v) {
Send * s = new Send(); PIChunkStream cs;
Recv * r = new Recv(); cs << cs.chunk(1, v.on)
<< cs.chunk(2, v.duration)
#include "piconditionvar.h" << cs.chunk(3, v.max_count)
int main() { << cs.chunk(4, v.unreliability);
ba << cs.data();
CONNECTU(s, ev, r, eh); return ba;
s->ev(r); }
r->deleteLater(); inline PIByteArray & operator >>(PIByteArray & ba, SwitchChannel & v) {
s->deleteLater(); PIByteArray src; ba >> src; PIChunkStream cs(src);
piMSleep(1500); while (!cs.atEnd()) {
//s->deleteLater(); switch (cs.read()) {
//delete o; case 1: cs.get(v.on); break;
//eth.dump(); case 2: cs.get(v.duration); break;
//versionCompare("",""); case 3: cs.get(v.max_count); break;
//PICloudServer s("127.0.0.1:10101"); case 4: cs.get(v.unreliability); break;
//s.startThreadedRead(); }
piMSleep(10); }
return ba;
/*PIMutex m; }*/
PIConditionVariable var; inline PICout operator <<(PICout c, const SwitchChannel & v) {
c << v.on << v.duration << v.max_count << v.unreliability;
PIThread::runOnce([&](){ return c;
piCout << "wait ..."; }
m.lock();
var.wait(m);
m.unlock();
piCout << "wait done"; int Acnt = 0;
});
class A {
piMSleep(100); public:
var.notifyAll();*/ A() {moved = false; i = "constructor"; piCout << "A()"; ++Acnt;}
A(const PIString & s): i(s) {moved = false; piCout << "A(String)"; ++Acnt;}
return 0; 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;
} }