Автооптимизация контейнеров и (де)сериализаций в PIByteArray
Reviewed-on: https://git.shs.tools/SHS/pip/pulls/44
This commit was merged in pull request #44.
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
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
|
#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
|
||||||
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;}
|
||||||
|
|
||||||
|
//! \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);
|
||||||
|
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;
|
||||||
|
}
|
||||||
__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);}
|
||||||
|
|||||||
@@ -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);}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
158
libs/main/core/pivariantsimple.h
Normal file
158
libs/main/core/pivariantsimple.h
Normal 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;}
|
||||||
|
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 <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
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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
160
main.cpp
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user