From 55f42f73f5af360c7a9596988c28e5bf07c7342f Mon Sep 17 00:00:00 2001 From: Stepan Fomenko Date: Thu, 24 Sep 2020 16:44:53 +0300 Subject: [PATCH 01/98] Restore piconditionvar.cpp after wrong fix --- libs/main/thread/piconditionvar.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/main/thread/piconditionvar.cpp b/libs/main/thread/piconditionvar.cpp index 9ad6538b..6cbfce6b 100644 --- a/libs/main/thread/piconditionvar.cpp +++ b/libs/main/thread/piconditionvar.cpp @@ -90,7 +90,7 @@ bool PIConditionVariable::waitFor(PIMutex &lk, int timeoutMs) { #ifdef WINDOWS isNotTimeout = SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), timeoutMs) != 0; #else - timespec abstime = {.tv_sec = timeoutMs / 1000, .tv_nsec = timeoutMs % 1000 * 1000000}; + timespec abstime = {.tv_sec = timeoutMs / 1000, .tv_nsec = timeoutMs % 1000000 * 1000000}; isNotTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &abstime) == 0; #endif if (PRIVATE->isDestroying) return false; @@ -111,7 +111,7 @@ bool PIConditionVariable::waitFor(PIMutex& lk, int timeoutMs, const std::functio timeoutMs - (int)measurer.elapsed_m()) == 0; #else int timeoutCurr = timeoutMs - (int)measurer.elapsed_m(); - timespec abstime = {.tv_sec = timeoutCurr / 1000, .tv_nsec = timeoutCurr % 1000 * 1000000}; + timespec abstime = {.tv_sec = timeoutCurr / 1000, .tv_nsec = timeoutCurr % 1000000 * 1000000}; bool isTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &abstime) != 0; #endif if (isTimeout) return false; From 0e1a3d3a23d43084dc6bcffdc3abb296f8ec90ca Mon Sep 17 00:00:00 2001 From: Stepan Fomenko Date: Thu, 24 Sep 2020 17:04:55 +0300 Subject: [PATCH 02/98] Fix nanosecond calc bug in piconditionvar.cpp --- libs/main/thread/piconditionvar.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/main/thread/piconditionvar.cpp b/libs/main/thread/piconditionvar.cpp index 6cbfce6b..e3f9b4a1 100644 --- a/libs/main/thread/piconditionvar.cpp +++ b/libs/main/thread/piconditionvar.cpp @@ -90,7 +90,7 @@ bool PIConditionVariable::waitFor(PIMutex &lk, int timeoutMs) { #ifdef WINDOWS isNotTimeout = SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), timeoutMs) != 0; #else - timespec abstime = {.tv_sec = timeoutMs / 1000, .tv_nsec = timeoutMs % 1000000 * 1000000}; + timespec abstime = {.tv_sec = timeoutMs / 1000, .tv_nsec = timeoutMs % 1000000}; isNotTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &abstime) == 0; #endif if (PRIVATE->isDestroying) return false; @@ -111,7 +111,7 @@ bool PIConditionVariable::waitFor(PIMutex& lk, int timeoutMs, const std::functio timeoutMs - (int)measurer.elapsed_m()) == 0; #else int timeoutCurr = timeoutMs - (int)measurer.elapsed_m(); - timespec abstime = {.tv_sec = timeoutCurr / 1000, .tv_nsec = timeoutCurr % 1000000 * 1000000}; + timespec abstime = {.tv_sec = timeoutCurr / 1000, .tv_nsec = timeoutCurr % 1000000}; bool isTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &abstime) != 0; #endif if (isTimeout) return false; From bf17a003e7edaad6bca3731aa5b56edb4c9b8068 Mon Sep 17 00:00:00 2001 From: Stepan Fomenko Date: Thu, 24 Sep 2020 17:20:25 +0300 Subject: [PATCH 03/98] =?UTF-8?q?o(=E2=95=A5=EF=B9=8F=E2=95=A5)o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libs/main/thread/piconditionvar.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/main/thread/piconditionvar.cpp b/libs/main/thread/piconditionvar.cpp index e3f9b4a1..9ad6538b 100644 --- a/libs/main/thread/piconditionvar.cpp +++ b/libs/main/thread/piconditionvar.cpp @@ -90,7 +90,7 @@ bool PIConditionVariable::waitFor(PIMutex &lk, int timeoutMs) { #ifdef WINDOWS isNotTimeout = SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), timeoutMs) != 0; #else - timespec abstime = {.tv_sec = timeoutMs / 1000, .tv_nsec = timeoutMs % 1000000}; + timespec abstime = {.tv_sec = timeoutMs / 1000, .tv_nsec = timeoutMs % 1000 * 1000000}; isNotTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &abstime) == 0; #endif if (PRIVATE->isDestroying) return false; @@ -111,7 +111,7 @@ bool PIConditionVariable::waitFor(PIMutex& lk, int timeoutMs, const std::functio timeoutMs - (int)measurer.elapsed_m()) == 0; #else int timeoutCurr = timeoutMs - (int)measurer.elapsed_m(); - timespec abstime = {.tv_sec = timeoutCurr / 1000, .tv_nsec = timeoutCurr % 1000000}; + timespec abstime = {.tv_sec = timeoutCurr / 1000, .tv_nsec = timeoutCurr % 1000 * 1000000}; bool isTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &abstime) != 0; #endif if (isTimeout) return false; From 2d02cea40c5bedb7be3426547a809dc3210d23bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A4=D0=BE=D0=BC=D0=B5=D0=BD=D0=BA=D0=BE=20=D0=A1=D1=82?= =?UTF-8?q?=D0=B5=D0=BF=D0=B0=D0=BD=20=D0=92=D0=BB=D0=B0=D0=B4=D0=B8=D0=BC?= =?UTF-8?q?=D0=B8=D1=80=D0=BE=D0=B2=D0=B8=D1=87?= Date: Fri, 25 Sep 2020 12:01:53 +0300 Subject: [PATCH 04/98] Fix waitFor timeout behaviour --- libs/main/thread/piconditionvar.cpp | 35 ++++++++++++++------ tests/concurrent/BlockingDequeueUnitTest.cpp | 4 --- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/libs/main/thread/piconditionvar.cpp b/libs/main/thread/piconditionvar.cpp index 9ad6538b..f7743d0a 100644 --- a/libs/main/thread/piconditionvar.cpp +++ b/libs/main/thread/piconditionvar.cpp @@ -35,7 +35,6 @@ PRIVATE_DEFINITION_START(PIConditionVariable) CONDITION_VARIABLE nativeHandle; #else pthread_cond_t nativeHandle; - PIMutex * currentLock; #endif bool isDestroying; PRIVATE_DEFINITION_END(PIConditionVariable) @@ -46,9 +45,12 @@ PIConditionVariable::PIConditionVariable() { InitializeConditionVariable(&PRIVATE->nativeHandle); #else PRIVATE->isDestroying = false; - PRIVATE->currentLock = nullptr; - memset(&(PRIVATE->nativeHandle), 0, sizeof(PRIVATE->nativeHandle)); - pthread_cond_init(&PRIVATE->nativeHandle, NULL); + + pthread_condattr_t condattr; + pthread_condattr_init(&condattr); + pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC); + memset(&(PRIVATE->nativeHandle), 0, sizeof(PRIVATE->nativeHandle)); + pthread_cond_init(&PRIVATE->nativeHandle, &condattr); #endif } @@ -84,23 +86,38 @@ void PIConditionVariable::wait(PIMutex& lk, const std::function& conditi } } +void timespec_add_ms(timespec* ts, int ms) { + ts->tv_sec += ms / 1000; + ts->tv_nsec += ms % 1000 * 1000000; + if (ts->tv_nsec > 1000 * 1000 * 1000) { + ts->tv_sec++; + ts->tv_nsec /= 1000 * 1000 * 1000; + } +} bool PIConditionVariable::waitFor(PIMutex &lk, int timeoutMs) { bool isNotTimeout; #ifdef WINDOWS isNotTimeout = SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), timeoutMs) != 0; #else - timespec abstime = {.tv_sec = timeoutMs / 1000, .tv_nsec = timeoutMs % 1000 * 1000000}; - isNotTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &abstime) == 0; + timespec expire_ts; + clock_gettime(CLOCK_MONOTONIC, &expire_ts); + timespec_add_ms(&expire_ts, timeoutMs); + isNotTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &expire_ts) == 0; #endif if (PRIVATE->isDestroying) return false; return isNotTimeout; } - bool PIConditionVariable::waitFor(PIMutex& lk, int timeoutMs, const std::function &condition) { bool isCondition; +#ifdef WINDOWS PITimeMeasurer measurer; +#else + timespec expire_ts; + clock_gettime(CLOCK_MONOTONIC, &expire_ts); + timespec_add_ms(&expire_ts, timeoutMs); +#endif while (true) { isCondition = condition(); if (isCondition) break; @@ -110,9 +127,7 @@ bool PIConditionVariable::waitFor(PIMutex& lk, int timeoutMs, const std::functio (PCRITICAL_SECTION)lk.handle(), timeoutMs - (int)measurer.elapsed_m()) == 0; #else - int timeoutCurr = timeoutMs - (int)measurer.elapsed_m(); - timespec abstime = {.tv_sec = timeoutCurr / 1000, .tv_nsec = timeoutCurr % 1000 * 1000000}; - bool isTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &abstime) != 0; + bool isTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &expire_ts) != 0; #endif if (isTimeout) return false; if (PRIVATE->isDestroying) return false; diff --git a/tests/concurrent/BlockingDequeueUnitTest.cpp b/tests/concurrent/BlockingDequeueUnitTest.cpp index 993326dd..8c9c8818 100644 --- a/tests/concurrent/BlockingDequeueUnitTest.cpp +++ b/tests/concurrent/BlockingDequeueUnitTest.cpp @@ -14,9 +14,7 @@ public: void wait(PIMutex& lk, const std::function& condition) override { isWaitCalled = true; - lk.lock(); isTrueCondition = condition(); - lk.unlock(); } bool waitFor(PIMutex& lk, int timeoutMs) override { @@ -27,10 +25,8 @@ public: bool waitFor(PIMutex& lk, int timeoutMs, const std::function& condition) override { isWaitForCalled = true; - lk.lock(); isTrueCondition = condition(); timeout = timeoutMs; - lk.unlock(); return isTrueCondition; } }; From 829f0af9d2de079c9e2858a60f07bfe06fe9febe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A4=D0=BE=D0=BC=D0=B5=D0=BD=D0=BA=D0=BE=20=D0=A1=D1=82?= =?UTF-8?q?=D0=B5=D0=BF=D0=B0=D0=BD=20=D0=92=D0=BB=D0=B0=D0=B4=D0=B8=D0=BC?= =?UTF-8?q?=D0=B8=D1=80=D0=BE=D0=B2=D0=B8=D1=87?= Date: Fri, 25 Sep 2020 12:03:15 +0300 Subject: [PATCH 05/98] Fix waitFor timeout behaviour --- libs/main/thread/piconditionvar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/main/thread/piconditionvar.cpp b/libs/main/thread/piconditionvar.cpp index f7743d0a..9480bb79 100644 --- a/libs/main/thread/piconditionvar.cpp +++ b/libs/main/thread/piconditionvar.cpp @@ -91,7 +91,7 @@ void timespec_add_ms(timespec* ts, int ms) { ts->tv_nsec += ms % 1000 * 1000000; if (ts->tv_nsec > 1000 * 1000 * 1000) { ts->tv_sec++; - ts->tv_nsec /= 1000 * 1000 * 1000; + ts->tv_nsec -= 1000 * 1000 * 1000; } } From 2ba05c81b130202f3a43bfc0154f1d51e78052ab Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 25 Sep 2020 13:03:56 +0300 Subject: [PATCH 06/98] disable pistring tests --- tests/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 68c51388..07693426 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -17,4 +17,4 @@ endmacro() # Concurrent tests pip_test(concurrent "") pip_test(math "") -pip_test(core "") +#pip_test(core "") From c3f0cc0b03ddbeb863dd4ca568c4164fbd2c8d25 Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 25 Sep 2020 14:08:40 +0300 Subject: [PATCH 07/98] PISystemTime toTimespec and PIConditionVariable fix --- libs/main/core/pitime.cpp | 11 +++++++++-- libs/main/core/pitime.h | 2 ++ libs/main/thread/piconditionvar.cpp | 21 ++++++++------------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/libs/main/core/pitime.cpp b/libs/main/core/pitime.cpp index 5e3fdb8c..3d041053 100644 --- a/libs/main/core/pitime.cpp +++ b/libs/main/core/pitime.cpp @@ -212,6 +212,13 @@ PIDateTime PIDateTime::current() { } +void PISystemTime::toTimespec(void * ts) { +#ifndef WINDOWS + t_cur->tv_sec = seconds; + t_cur->tv_nsec = nanoseconds; +#endif +} + PISystemTime PISystemTime::abs() const { if (seconds < 0) return PISystemTime(piAbsl(seconds) - 1, 1000000000l - piAbsl(nanoseconds)); @@ -255,12 +262,12 @@ PISystemTime PISystemTime::current(bool precise_but_not_system) { timeval tv; tv.tv_sec = 0; tv.tv_usec = 0; - gettimeofday(&tv, NULL); + gettimeofday(&tv, NULL); t_cur.tv_sec = tv.tv_sec; t_cur.tv_nsec = tv.tv_usec * 1000; # else timespec t_cur; - clock_gettime(0, &t_cur); + clock_gettime(precise_but_not_system ? CLOCK_MONOTONIC : 0, &t_cur); # endif # endif return PISystemTime(t_cur.tv_sec, t_cur.tv_nsec); diff --git a/libs/main/core/pitime.h b/libs/main/core/pitime.h index e0a00c0b..90df73c7 100644 --- a/libs/main/core/pitime.h +++ b/libs/main/core/pitime.h @@ -93,6 +93,8 @@ public: //! If you call this function on system time returned with \a PISystemTime::current() thread will be sleep almost forever. void sleep() {piUSleep(piFloord(toMicroseconds()));} // wait self value, useful to wait some dT = (t1 - t0) + //! On Unix system assign current value to timespec struct + void toTimespec(void *ts); //! Returns copy of this system time with absolutely values of s and ns PISystemTime abs() const; diff --git a/libs/main/thread/piconditionvar.cpp b/libs/main/thread/piconditionvar.cpp index 9480bb79..a1092e13 100644 --- a/libs/main/thread/piconditionvar.cpp +++ b/libs/main/thread/piconditionvar.cpp @@ -86,37 +86,32 @@ void PIConditionVariable::wait(PIMutex& lk, const std::function& conditi } } -void timespec_add_ms(timespec* ts, int ms) { - ts->tv_sec += ms / 1000; - ts->tv_nsec += ms % 1000 * 1000000; - if (ts->tv_nsec > 1000 * 1000 * 1000) { - ts->tv_sec++; - ts->tv_nsec -= 1000 * 1000 * 1000; - } -} bool PIConditionVariable::waitFor(PIMutex &lk, int timeoutMs) { bool isNotTimeout; #ifdef WINDOWS isNotTimeout = SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), timeoutMs) != 0; #else - timespec expire_ts; - clock_gettime(CLOCK_MONOTONIC, &expire_ts); - timespec_add_ms(&expire_ts, timeoutMs); + timespec expire_ts; + PISystemTime st = PISystemTime::current(true); + st.addMilliseconds(timeoutMs); + st.toTimespec(&expire_ts); isNotTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &expire_ts) == 0; #endif if (PRIVATE->isDestroying) return false; return isNotTimeout; } + bool PIConditionVariable::waitFor(PIMutex& lk, int timeoutMs, const std::function &condition) { bool isCondition; #ifdef WINDOWS PITimeMeasurer measurer; #else timespec expire_ts; - clock_gettime(CLOCK_MONOTONIC, &expire_ts); - timespec_add_ms(&expire_ts, timeoutMs); + PISystemTime st = PISystemTime::current(true); + st.addMilliseconds(timeoutMs); + st.toTimespec(&expire_ts); #endif while (true) { isCondition = condition(); From b6583c3d02c5dcc5c878ea5fbdedbeb9b0c58ed7 Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 25 Sep 2020 14:13:36 +0300 Subject: [PATCH 08/98] fix toTimespec --- libs/main/core/pitime.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/main/core/pitime.cpp b/libs/main/core/pitime.cpp index 3d041053..fad48c04 100644 --- a/libs/main/core/pitime.cpp +++ b/libs/main/core/pitime.cpp @@ -214,8 +214,8 @@ PIDateTime PIDateTime::current() { void PISystemTime::toTimespec(void * ts) { #ifndef WINDOWS - t_cur->tv_sec = seconds; - t_cur->tv_nsec = nanoseconds; + ts->tv_sec = seconds; + ts->tv_nsec = nanoseconds; #endif } From b771eebfbb50f48293404de05230f64a0dbc14aa Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 25 Sep 2020 14:15:46 +0300 Subject: [PATCH 09/98] fix toTimespec 2 --- libs/main/core/pitime.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/main/core/pitime.cpp b/libs/main/core/pitime.cpp index fad48c04..a78f6b1a 100644 --- a/libs/main/core/pitime.cpp +++ b/libs/main/core/pitime.cpp @@ -214,8 +214,8 @@ PIDateTime PIDateTime::current() { void PISystemTime::toTimespec(void * ts) { #ifndef WINDOWS - ts->tv_sec = seconds; - ts->tv_nsec = nanoseconds; + (timespec*)ts->tv_sec = seconds; + (timespec*)ts->tv_nsec = nanoseconds; #endif } From 1ec69cca818d5af74f304438c6b0c924419c13d7 Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 25 Sep 2020 14:17:58 +0300 Subject: [PATCH 10/98] fix toTimespec --- libs/main/core/pitime.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/main/core/pitime.cpp b/libs/main/core/pitime.cpp index a78f6b1a..220289e9 100644 --- a/libs/main/core/pitime.cpp +++ b/libs/main/core/pitime.cpp @@ -214,8 +214,8 @@ PIDateTime PIDateTime::current() { void PISystemTime::toTimespec(void * ts) { #ifndef WINDOWS - (timespec*)ts->tv_sec = seconds; - (timespec*)ts->tv_nsec = nanoseconds; + ((timespec*)ts)->tv_sec = seconds; + ((timespec*)ts)->tv_nsec = nanoseconds; #endif } From 53cd72a4b0eeb8e8d23c1c83744aeb899fe8bb7f Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 25 Sep 2020 14:25:25 +0300 Subject: [PATCH 11/98] PIConditionVariable fix --- libs/main/thread/piconditionvar.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/libs/main/thread/piconditionvar.cpp b/libs/main/thread/piconditionvar.cpp index a1092e13..7eb476d9 100644 --- a/libs/main/thread/piconditionvar.cpp +++ b/libs/main/thread/piconditionvar.cpp @@ -46,10 +46,12 @@ PIConditionVariable::PIConditionVariable() { #else PRIVATE->isDestroying = false; - pthread_condattr_t condattr; - pthread_condattr_init(&condattr); - pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC); - memset(&(PRIVATE->nativeHandle), 0, sizeof(PRIVATE->nativeHandle)); + pthread_condattr_t condattr; + pthread_condattr_init(&condattr); +# ifndef MAC_OS + pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC); +# endif + memset(&(PRIVATE->nativeHandle), 0, sizeof(PRIVATE->nativeHandle)); pthread_cond_init(&PRIVATE->nativeHandle, &condattr); #endif } From a42e5a7756a7f5b690f8d3a20ce3b3edf92ddf68 Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 25 Sep 2020 14:34:07 +0300 Subject: [PATCH 12/98] template experiment, PIMutex recursive in all systems --- libs/main/math/pimathmatrix.h | 22 ++++++++-------------- libs/main/thread/pimutex.cpp | 2 +- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/libs/main/math/pimathmatrix.h b/libs/main/math/pimathmatrix.h index 897fe6ae..3f89c4b5 100644 --- a/libs/main/math/pimathmatrix.h +++ b/libs/main/math/pimathmatrix.h @@ -34,7 +34,7 @@ * @param v is input parameter of type T * @return true if zero, false if not zero */ -template +template::value, int>::type = 0> inline bool _PIMathMatrixNullCompare(const T v) { static_assert(std::is_floating_point::value, "Type must be floating point"); return (piAbs(v) < T(1E-200)); @@ -46,22 +46,16 @@ inline bool _PIMathMatrixNullCompare(const T v) { * @param v is input parameter of type colmplexf * @return true if zero, false if not zero */ -template<> -inline bool _PIMathMatrixNullCompare(const complexf v) { +template::value || + std::is_floating_point::value + , int>::type = 0> +inline bool _PIMathMatrixNullCompare(const T v) { + static_assert(std::is_floating_point::value, "Type must be floating point"); + static_assert(std::is_floating_point::value, "Type must be floating point"); return (abs(v) < float(1E-200)); } -/** -* @brief Inline funtion of compare with zero complexd type -* -* @param v is input parameter of type colmplexd -* @return true if zero, false if not zero -*/ -template<> -inline bool _PIMathMatrixNullCompare(const complexd v) { - return (abs(v) < double(1E-200)); -} - /// Matrix templated diff --git a/libs/main/thread/pimutex.cpp b/libs/main/thread/pimutex.cpp index 2c0a97b2..e605f3b4 100644 --- a/libs/main/thread/pimutex.cpp +++ b/libs/main/thread/pimutex.cpp @@ -105,7 +105,7 @@ void PIMutex::init() { pthread_mutexattr_t attr; memset(&attr, 0, sizeof(attr)); pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); memset(&(PRIVATE->mutex), 0, sizeof(PRIVATE->mutex)); pthread_mutex_init(&(PRIVATE->mutex), &attr); pthread_mutexattr_destroy(&attr); From c971550535df752726f8aebb1864c9ab8abc95d4 Mon Sep 17 00:00:00 2001 From: Andrey Date: Sat, 26 Sep 2020 19:46:34 +0300 Subject: [PATCH 13/98] pimathfloatnullcompare --- libs/main/math/pimathcomplex.h | 29 +++++++++++++++++++++++++++++ libs/main/math/pimathmatrix.h | 32 ++------------------------------ 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/libs/main/math/pimathcomplex.h b/libs/main/math/pimathcomplex.h index 2bcc7fea..46d75e6b 100644 --- a/libs/main/math/pimathcomplex.h +++ b/libs/main/math/pimathcomplex.h @@ -117,4 +117,33 @@ inline PIVector2D abs(const PIVector2D & v) { return result; } + +/** +* @brief Inline funtion of compare with zero different types +* +* @param v is input parameter of type T +* @return true if zero, false if not zero +*/ +template::value, int>::type = 0> +inline bool PIMathFloatNullCompare(const T v) { + static_assert(std::is_floating_point::value, "Type must be floating point"); + return (piAbs(v) < T(1E-200)); +} + +/** +* @brief Inline funtion of compare with zero colmplexf type +* +* @param v is input parameter of type colmplexf +* @return true if zero, false if not zero +*/ +template::value || + std::is_floating_point::value + , int>::type = 0> +inline bool PIMathFloatNullCompare(const T v) { + static_assert(std::is_floating_point::value, "Type must be floating point"); + static_assert(std::is_floating_point::value, "Type must be floating point"); + return (abs(v) < float(1E-200)); +} + #endif // PIMATHCOMPLEX_H diff --git a/libs/main/math/pimathmatrix.h b/libs/main/math/pimathmatrix.h index 3f89c4b5..1d5b71ee 100644 --- a/libs/main/math/pimathmatrix.h +++ b/libs/main/math/pimathmatrix.h @@ -28,34 +28,6 @@ #include "pimathvector.h" #include "pimathcomplex.h" -/** -* @brief Inline funtion of compare with zero different types -* -* @param v is input parameter of type T -* @return true if zero, false if not zero -*/ -template::value, int>::type = 0> -inline bool _PIMathMatrixNullCompare(const T v) { - static_assert(std::is_floating_point::value, "Type must be floating point"); - return (piAbs(v) < T(1E-200)); -} - -/** -* @brief Inline funtion of compare with zero colmplexf type -* -* @param v is input parameter of type colmplexf -* @return true if zero, false if not zero -*/ -template::value || - std::is_floating_point::value - , int>::type = 0> -inline bool _PIMathMatrixNullCompare(const T v) { - static_assert(std::is_floating_point::value, "Type must be floating point"); - static_assert(std::is_floating_point::value, "Type must be floating point"); - return (abs(v) < float(1E-200)); -} - /// Matrix templated @@ -1219,7 +1191,7 @@ public: for (uint k = i; k < _V2D::cols_; ++k) smat.element(k, j) -= mul * smat.element(k, i); } if (i < _V2D::cols_ - 1) { - if (_PIMathMatrixNullCompare(smat.element(i + 1, i + 1))) { + if (PIMathFloatNullCompare(smat.element(i + 1, i + 1))) { if (ok != 0) *ok = false; return *this; } @@ -1269,7 +1241,7 @@ public: if (sv != 0) (*sv)[j] -= mul * (*sv)[i]; } if (i < _V2D::cols_ - 1) { - if (_PIMathMatrixNullCompare(smat.element(i + 1, i + 1))) { + if (PIMathFloatNullCompare(smat.element(i + 1, i + 1))) { if (ok != 0) *ok = false; return *this; } From ff3dfab2707b20ff74d6bcdfe269a8466a884e36 Mon Sep 17 00:00:00 2001 From: Andrey Date: Sat, 26 Sep 2020 19:47:33 +0300 Subject: [PATCH 14/98] version --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c14eb2f..357ffe0c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0) cmake_policy(SET CMP0017 NEW) # need include() with .cmake project(pip) set(pip_MAJOR 2) -set(pip_MINOR 8) +set(pip_MINOR 9) set(pip_REVISION 0) set(pip_SUFFIX ) set(pip_COMPANY SHS) From 7530ae5d30441abd0dc782e1588bb76d5932c781 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Sun, 27 Sep 2020 20:07:47 +0300 Subject: [PATCH 15/98] Add PISpinlock and PISpinlockLocker --- CMakeLists.txt | 2 +- libs/main/thread/pimutex.cpp | 2 +- libs/main/thread/pimutex.h | 4 +- libs/main/thread/pispinlock.cpp | 30 +++++++++++++ libs/main/thread/pispinlock.h | 75 +++++++++++++++++++++++++++++++ libs/main/thread/pithreadmodule.h | 1 + 6 files changed, 110 insertions(+), 4 deletions(-) create mode 100644 libs/main/thread/pispinlock.cpp create mode 100644 libs/main/thread/pispinlock.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 357ffe0c..7936ad08 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_policy(SET CMP0017 NEW) # need include() with .cmake project(pip) set(pip_MAJOR 2) set(pip_MINOR 9) -set(pip_REVISION 0) +set(pip_REVISION 1) set(pip_SUFFIX ) set(pip_COMPANY SHS) set(pip_DOMAIN org.SHS) diff --git a/libs/main/thread/pimutex.cpp b/libs/main/thread/pimutex.cpp index e605f3b4..be259ed3 100644 --- a/libs/main/thread/pimutex.cpp +++ b/libs/main/thread/pimutex.cpp @@ -1,6 +1,6 @@ /* PIP - Platform Independent Primitives - Mutex + PIMutex, PIMutexLocker Ivan Pelipenko peri4ko@yandex.ru, Stephan Fomenko, Andrey Bychkov work.a.b@yandex.ru This program is free software: you can redistribute it and/or modify diff --git a/libs/main/thread/pimutex.h b/libs/main/thread/pimutex.h index a551625d..9165c725 100644 --- a/libs/main/thread/pimutex.h +++ b/libs/main/thread/pimutex.h @@ -1,9 +1,9 @@ /*! \file pimutex.h - * \brief PIMutexLocker + * \brief PIMutex, PIMutexLocker */ /* PIP - Platform Independent Primitives - PIMutexLocker + PIMutex, PIMutexLocker Ivan Pelipenko peri4ko@yandex.ru, Stephan Fomenko, Andrey Bychkov work.a.b@yandex.ru This program is free software: you can redistribute it and/or modify diff --git a/libs/main/thread/pispinlock.cpp b/libs/main/thread/pispinlock.cpp new file mode 100644 index 00000000..3262f39b --- /dev/null +++ b/libs/main/thread/pispinlock.cpp @@ -0,0 +1,30 @@ +/* + PIP - Platform Independent Primitives + PISpinlock + 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 . +*/ + +/** \class PISpinlock + * \brief Spinlock + * \details + * \section PISpinlock_sec0 Synopsis + * %PISpinlock provides synchronization blocks between several threads. + * PISpinlock functionality similar to PIMutex, but working on atomic + * type and \a lock() method wait with 100% CPU load. + * \note + * Use this type instead of PIMutex when less waiting time is more + * important than CPU load! + * */ diff --git a/libs/main/thread/pispinlock.h b/libs/main/thread/pispinlock.h new file mode 100644 index 00000000..6de315c4 --- /dev/null +++ b/libs/main/thread/pispinlock.h @@ -0,0 +1,75 @@ +/*! \file pispinlock.h + * \brief PISpinlock +*/ +/* + PIP - Platform Independent Primitives + PISpinlock + Ivan Pelipenko peri4ko@yandex.ru + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + +#ifndef PISPINLOCK_H +#define PISPINLOCK_H + +#include "piinit.h" +#include + + +class PIP_EXPORT PISpinlock +{ +public: + NO_COPY_CLASS(PISpinlock) + + //! Constructs unlocked spinlock + explicit PISpinlock() {flag.clear();} + + //! Destroy spinlock + ~PISpinlock() {} + + + //! \brief Lock spinlock + //! \details If spinlock is unlocked it set to locked state and returns immediate. + //! If spinlock is already locked function blocks until spinlock will be unlocked + void lock() {while (flag.test_and_set(std::memory_order_acquire));} + + //! \brief Unlock spinlock + //! \details In any case this function returns immediate + void unlock() {flag.clear(std::memory_order_release);} + +private: + std::atomic_flag flag; + +}; + + +//! \brief PISpinlockLocker +//! \details +//! When a PISpinlockLocker object is created, it attempts to lock the spinlock it is given, if "condition" true. +//! When control leaves the scope in which the PISpinlockLocker object was created, +//! the PISpinlockLocker is destructed and the spinlock is released, if "condition" true. +//! If "condition" false this class do nothing. +//! The PISpinlockLocker class is non-copyable. +class PIP_EXPORT PISpinlockLocker +{ +public: + NO_COPY_CLASS(PISpinlockLocker) + PISpinlockLocker(PISpinlock & s, bool condition = true): spinlock(s), cond(condition) {if (cond) spinlock.lock();} + ~PISpinlockLocker() {if (cond) spinlock.unlock();} +private: + PISpinlock & spinlock; + bool cond; +}; + +#endif // PISPINLOCK_H diff --git a/libs/main/thread/pithreadmodule.h b/libs/main/thread/pithreadmodule.h index 5973dfe4..cb1128e1 100644 --- a/libs/main/thread/pithreadmodule.h +++ b/libs/main/thread/pithreadmodule.h @@ -21,6 +21,7 @@ #define PITHREADMODULE_H #include "pimutex.h" +#include "pispinlock.h" #include "pithread.h" #include "pitimer.h" #include "pipipelinethread.h" From 0e31de4f759cc8093dbe8ca92cc67e88c5bc3053 Mon Sep 17 00:00:00 2001 From: Stepan Fomenko Date: Mon, 28 Sep 2020 11:34:30 +0300 Subject: [PATCH 16/98] Improve template & doc for PIMathFloatNullCompare --- libs/main/math/pimathcomplex.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/libs/main/math/pimathcomplex.h b/libs/main/math/pimathcomplex.h index 46d75e6b..268e7daf 100644 --- a/libs/main/math/pimathcomplex.h +++ b/libs/main/math/pimathcomplex.h @@ -119,10 +119,10 @@ inline PIVector2D abs(const PIVector2D & v) { /** -* @brief Inline funtion of compare with zero different types +* @brief floating point number specific comparison between value passed as parameter and zero * -* @param v is input parameter of type T -* @return true if zero, false if not zero +* @param v floating point parameter for comparison +* @return true if v in locality of zero, otherwise false */ template::value, int>::type = 0> inline bool PIMathFloatNullCompare(const T v) { @@ -131,15 +131,15 @@ inline bool PIMathFloatNullCompare(const T v) { } /** -* @brief Inline funtion of compare with zero colmplexf type +* @brief floating point number specific comparison between parameter value and zero. * -* @param v is input parameter of type colmplexf -* @return true if zero, false if not zero +* @param v complex with floating point real and imag parts +* @return true if absolute of v in locality of zero, otherwise false */ template::value || - std::is_floating_point::value - , int>::type = 0> + std::is_floating_point::value && + std::is_floating_point::value + , int>::type = 0> inline bool PIMathFloatNullCompare(const T v) { static_assert(std::is_floating_point::value, "Type must be floating point"); static_assert(std::is_floating_point::value, "Type must be floating point"); From e474c5a8de1b27fb5057a6344dcb4312aa65405a Mon Sep 17 00:00:00 2001 From: andrey Date: Mon, 28 Sep 2020 15:38:45 +0300 Subject: [PATCH 17/98] remove __PICONTAINERS_SIMPLE_TYPE__ --- libs/main/containers/pideque.h | 115 +++++++++++++++++--------- libs/main/containers/pimap.h | 3 - libs/main/containers/pivector.h | 114 +++++++++++++++++--------- libs/main/containers/pivector2d.h | 25 ++---- libs/main/core/pibytearray.h | 1 - libs/main/math/pimathcomplex.h | 10 --- main.cpp | 131 ++++++++++++++++-------------- 7 files changed, 227 insertions(+), 172 deletions(-) diff --git a/libs/main/containers/pideque.h b/libs/main/containers/pideque.h index dd62b501..82d00b45 100644 --- a/libs/main/containers/pideque.h +++ b/libs/main/containers/pideque.h @@ -209,7 +209,22 @@ public: inline T * data(size_t index = 0) {return &(pid_data[pid_start + index]);} inline const T * data(size_t index = 0) const {return &(pid_data[pid_start + index]);} - inline PIDeque & clear() {resize(0); return *this;} + template::value + , int>::type = 0> + inline PIDeque & clear() { + resize(0); + return *this; + } + template::value + , int>::type = 0> + inline PIDeque & clear() { + PIINTROSPECTION_CONTAINER_UNUSED(T, pid_size) + pid_size = 0; + return *this; + } + inline PIDeque & fill(const T & f = T()) { deleteT(pid_data + pid_start, pid_size); PIINTROSPECTION_CONTAINER_USED(T, pid_size) @@ -218,10 +233,20 @@ public: return *this; } inline PIDeque & assign(const T & f = T()) {return fill(f);} + template::value + , int>::type = 0> inline PIDeque & assign(size_t new_size, const T & f) { resize(new_size); return fill(f); } + template::value + , int>::type = 0> + inline PIDeque & assign(size_t new_size, const T & f) { + _resizeRaw(new_size); + return fill(f); + } inline PIDeque & resize(size_t new_size, const T & f = T()) { if (new_size < pid_size) { @@ -236,9 +261,18 @@ public: } return *this; } + + template::value + , int>::type = 0> inline PIDeque & _resizeRaw(size_t new_size) { - piCout << "Error, \"resizeRaw()\" only allowed for simple type declared with __PIDEQUE_SIMPLE_TYPE__ macro!"; - assert(0); + if (new_size > pid_size) { + PIINTROSPECTION_CONTAINER_USED(T, (new_size-pid_size)); + } + if (new_size < pid_size) { + PIINTROSPECTION_CONTAINER_UNUSED(T, (pid_size-new_size)); + } + alloc(new_size, true); return *this; } @@ -437,11 +471,24 @@ private: ++t; return (1 << t); } + template::value + , int>::type = 0> inline void newT(T * dst, const T * src, size_t s) { PIINTROSPECTION_CONTAINER_USED(T, s) for (size_t i = 0; i < s; ++i) elementNew(dst + i, src[i]); } + template::value + , int>::type = 0> + inline void newT(T * dst, const T * src, size_t s) { + PIINTROSPECTION_CONTAINER_USED(T, s) + memcpy((void*)(dst), (const void*)(src), s * sizeof(T)); + } + template::value + , int>::type = 0> inline void deleteT(T * d, size_t sz) { PIINTROSPECTION_CONTAINER_UNUSED(T, sz) if ((uchar*)d != 0) { @@ -449,9 +496,36 @@ private: elementDelete(d[i]); } } + template::value + , int>::type = 0> + inline void deleteT(T * d, size_t sz) { + PIINTROSPECTION_CONTAINER_UNUSED(T, sz) + } + template::value + , int>::type = 0> inline void elementNew(T * to, const T & from) {new(to)T(from);} + template::value + , int>::type = 0> inline void elementNew(T * to, T && from) {new(to)T(std::move(from));} + template::value + , int>::type = 0> + inline void elementNew(T1 * to, const T & from) {(*to) = from;} + template::value + , int>::type = 0> + inline void elementNew(T * to, T && from) {(*to) = std::move(from);} + template::value + , int>::type = 0> inline void elementDelete(T & from) {from.~T();} + template::value + , int>::type = 0> + inline void elementDelete(T & from) {} inline void dealloc() { if ((uchar*)pid_data != 0) free((uchar*)pid_data); pid_data = 0; @@ -520,41 +594,6 @@ private: ssize_t pid_start; }; -#define __PIDEQUE_SIMPLE_TYPE__(T) \ - template<> inline void PIDeque::newT(T * dst, const T * src, size_t s) {PIINTROSPECTION_CONTAINER_USED(T, s); memcpy((void*)(dst), (const void*)(src), s * sizeof(T));} \ - template<> inline void PIDeque::deleteT(T *, size_t sz) {PIINTROSPECTION_CONTAINER_UNUSED(T, sz);} \ - template<> inline void PIDeque::elementNew(T * to, const T & from) {(*to) = from;} \ - template<> inline void PIDeque::elementNew(T * to, T && from) {(*to) = std::move(from);} \ - template<> inline void PIDeque::elementDelete(T &) {;} \ - template<> inline PIDeque & PIDeque::_resizeRaw(size_t new_size) { \ - if (new_size > pid_size) { \ - PIINTROSPECTION_CONTAINER_USED(T, (new_size-pid_size)); \ - } \ - if (new_size < pid_size) { \ - PIINTROSPECTION_CONTAINER_UNUSED(T, (pid_size-new_size)); \ - } \ - alloc(new_size, true); \ - return *this; \ - } \ - template<> inline PIDeque & PIDeque::clear() {PIINTROSPECTION_CONTAINER_UNUSED(T, pid_size); pid_size = 0; return *this;} \ - template<> inline PIDeque & PIDeque::assign(size_t new_size, const T & f) {_resizeRaw(new_size); return fill(f);} - - -__PIDEQUE_SIMPLE_TYPE__(bool) -__PIDEQUE_SIMPLE_TYPE__(char) -__PIDEQUE_SIMPLE_TYPE__(uchar) -__PIDEQUE_SIMPLE_TYPE__(short) -__PIDEQUE_SIMPLE_TYPE__(ushort) -__PIDEQUE_SIMPLE_TYPE__(int) -__PIDEQUE_SIMPLE_TYPE__(uint) -__PIDEQUE_SIMPLE_TYPE__(long) -__PIDEQUE_SIMPLE_TYPE__(ulong) -__PIDEQUE_SIMPLE_TYPE__(llong) -__PIDEQUE_SIMPLE_TYPE__(ullong) -__PIDEQUE_SIMPLE_TYPE__(float) -__PIDEQUE_SIMPLE_TYPE__(double) -__PIDEQUE_SIMPLE_TYPE__(ldouble) - #ifdef PIP_STD_IOSTREAM template diff --git a/libs/main/containers/pimap.h b/libs/main/containers/pimap.h index 38339dd7..ab4c6007 100644 --- a/libs/main/containers/pimap.h +++ b/libs/main/containers/pimap.h @@ -28,9 +28,6 @@ #include "pivector.h" #include "pideque.h" #include "pipair.h" -# define __PICONTAINERS_SIMPLE_TYPE__(T) \ -__PIDEQUE_SIMPLE_TYPE__(T)\ -__PIVECTOR_SIMPLE_TYPE__(T) template diff --git a/libs/main/containers/pivector.h b/libs/main/containers/pivector.h index 73f4d572..e7a3bd48 100644 --- a/libs/main/containers/pivector.h +++ b/libs/main/containers/pivector.h @@ -210,7 +210,22 @@ public: inline T * data(size_t index = 0) {return &(piv_data[index]);} inline const T * data(size_t index = 0) const {return &(piv_data[index]);} - inline PIVector & clear() {resize(0); return *this;} + template::value + , int>::type = 0> + inline PIVector & clear() { + resize(0); + return *this; + } + template::value + , int>::type = 0> + inline PIVector & clear() { + PIINTROSPECTION_CONTAINER_UNUSED(T, piv_size) + piv_size = 0; + return *this; + } + inline PIVector & fill(const T & f = T()) { deleteT(piv_data, piv_size); PIINTROSPECTION_CONTAINER_USED(T, piv_size) @@ -219,10 +234,20 @@ public: return *this; } inline PIVector & assign(const T & f = T()) {return fill(f);} + template::value + , int>::type = 0> inline PIVector & assign(size_t new_size, const T & f) { resize(new_size); return fill(f); } + template::value + , int>::type = 0> + inline PIVector & assign(size_t new_size, const T & f) { + _resizeRaw(new_size); + return fill(f); + } inline PIVector & resize(size_t new_size, const T & f = T()) { if (new_size < piv_size) { @@ -239,9 +264,17 @@ public: } return *this; } + template::value + , int>::type = 0> inline PIVector & _resizeRaw(size_t new_size) { - piCout << "Error, \"resizeRaw()\" only allowed for simple type declared with __PIVECTOR_SIMPLE_TYPE__ macro!"; - assert(0); + if (new_size > piv_size) { + PIINTROSPECTION_CONTAINER_USED(T, (new_size-piv_size)); + } + if (new_size < piv_size) { + PIINTROSPECTION_CONTAINER_UNUSED(T, (piv_size-new_size)); + } + alloc(new_size); return *this; } inline void _copyRaw(T * dst, const T * src, size_t size) { @@ -425,11 +458,24 @@ private: while (s_ >> t) ++t; return (1 << t); } + template::value + , int>::type = 0> inline void newT(T * dst, const T * src, size_t s) { PIINTROSPECTION_CONTAINER_USED(T, s) for (size_t i = 0; i < s; ++i) elementNew(dst + i, src[i]); } + template::value + , int>::type = 0> + inline void newT(T * dst, const T * src, size_t s) { + PIINTROSPECTION_CONTAINER_USED(T, s) + memcpy((void*)(dst), (const void*)(src), s * sizeof(T)); + } + template::value + , int>::type = 0> inline void deleteT(T * d, size_t sz) { PIINTROSPECTION_CONTAINER_UNUSED(T, sz) if ((uchar*)d != 0) { @@ -437,9 +483,36 @@ private: elementDelete(d[i]); } } + template::value + , int>::type = 0> + inline void deleteT(T * d, size_t sz) { + PIINTROSPECTION_CONTAINER_UNUSED(T, sz) + } + template::value + , int>::type = 0> inline void elementNew(T * to, const T & from) {new(to)T(from);} + template::value + , int>::type = 0> inline void elementNew(T * to, T && from) {new(to)T(std::move(from));} + template::value + , int>::type = 0> + inline void elementNew(T1 * to, const T & from) {(*to) = from;} + template::value + , int>::type = 0> + inline void elementNew(T * to, T && from) {(*to) = std::move(from);} + template::value + , int>::type = 0> inline void elementDelete(T & from) {from.~T();} + template::value + , int>::type = 0> + inline void elementDelete(T & from) {} inline void dealloc() { if ((uchar*)piv_data != 0) free((uchar*)piv_data); piv_data = 0; @@ -464,41 +537,6 @@ private: }; -#define __PIVECTOR_SIMPLE_TYPE__(T) \ - template<> inline void PIVector::newT(T * dst, const T * src, size_t s) {PIINTROSPECTION_CONTAINER_USED(T, s); memcpy((void*)(dst), (const void*)(src), s * sizeof(T));} \ - template<> inline void PIVector::deleteT(T *, size_t sz) {PIINTROSPECTION_CONTAINER_UNUSED(T, sz);} \ - template<> inline void PIVector::elementNew(T * to, const T & from) {(*to) = from;} \ - template<> inline void PIVector::elementNew(T * to, T && from) {(*to) = std::move(from);} \ - template<> inline void PIVector::elementDelete(T &) {;} \ - template<> inline PIVector & PIVector::_resizeRaw(size_t new_size) { \ - if (new_size > piv_size) { \ - PIINTROSPECTION_CONTAINER_USED(T, (new_size-piv_size)); \ - } \ - if (new_size < piv_size) { \ - PIINTROSPECTION_CONTAINER_UNUSED(T, (piv_size-new_size)); \ - } \ - alloc(new_size); \ - return *this; \ - } \ - template<> inline PIVector & PIVector::clear() {PIINTROSPECTION_CONTAINER_UNUSED(T, piv_size); piv_size = 0; return *this;} \ - template<> inline PIVector & PIVector::assign(size_t new_size, const T & f) {_resizeRaw(new_size); return fill(f);} - - -__PIVECTOR_SIMPLE_TYPE__(bool) -__PIVECTOR_SIMPLE_TYPE__(char) -__PIVECTOR_SIMPLE_TYPE__(uchar) -__PIVECTOR_SIMPLE_TYPE__(short) -__PIVECTOR_SIMPLE_TYPE__(ushort) -__PIVECTOR_SIMPLE_TYPE__(int) -__PIVECTOR_SIMPLE_TYPE__(uint) -__PIVECTOR_SIMPLE_TYPE__(long) -__PIVECTOR_SIMPLE_TYPE__(ulong) -__PIVECTOR_SIMPLE_TYPE__(llong) -__PIVECTOR_SIMPLE_TYPE__(ullong) -__PIVECTOR_SIMPLE_TYPE__(float) -__PIVECTOR_SIMPLE_TYPE__(double) -__PIVECTOR_SIMPLE_TYPE__(ldouble) - #ifdef PIP_STD_IOSTREAM template diff --git a/libs/main/containers/pivector2d.h b/libs/main/containers/pivector2d.h index f573439f..ad9b1ea3 100644 --- a/libs/main/containers/pivector2d.h +++ b/libs/main/containers/pivector2d.h @@ -251,9 +251,13 @@ public: piSwap(cols_, other.cols_); } + template::value + , int>::type = 0> inline PIVector2D & _resizeRaw(size_t r, size_t c) { - piCout << "Error, \"resizeRaw()\" only allowed for simple type declared with __PIVECTOR_SIMPLE_TYPE__ macro!"; - assert(0); + rows_ = r; + cols_ = c; + mat._resizeRaw(r*c); return *this; } @@ -287,22 +291,5 @@ inline PICout operator <<(PICout s, const PIVector2D & v) { return s; } -#define __PIVECTOR2D_SIMPLE_TYPE__(T) \ - template<> inline PIVector2D & PIVector2D::_resizeRaw(size_t r, size_t c) {rows_ = r; cols_ = c; mat._resizeRaw(r*c); return *this;} - -__PIVECTOR2D_SIMPLE_TYPE__(bool) -__PIVECTOR2D_SIMPLE_TYPE__(char) -__PIVECTOR2D_SIMPLE_TYPE__(uchar) -__PIVECTOR2D_SIMPLE_TYPE__(short) -__PIVECTOR2D_SIMPLE_TYPE__(ushort) -__PIVECTOR2D_SIMPLE_TYPE__(int) -__PIVECTOR2D_SIMPLE_TYPE__(uint) -__PIVECTOR2D_SIMPLE_TYPE__(long) -__PIVECTOR2D_SIMPLE_TYPE__(ulong) -__PIVECTOR2D_SIMPLE_TYPE__(llong) -__PIVECTOR2D_SIMPLE_TYPE__(ullong) -__PIVECTOR2D_SIMPLE_TYPE__(float) -__PIVECTOR2D_SIMPLE_TYPE__(double) -__PIVECTOR2D_SIMPLE_TYPE__(ldouble) #endif // PIVECTOR2D_H diff --git a/libs/main/core/pibytearray.h b/libs/main/core/pibytearray.h index d3d532b4..9c6bb60e 100644 --- a/libs/main/core/pibytearray.h +++ b/libs/main/core/pibytearray.h @@ -28,7 +28,6 @@ #include "pimap.h" #include "pivector2d.h" -__PICONTAINERS_SIMPLE_TYPE__(PIChar) #define __PIBYTEARRAY_SIMPLE_TYPE__(T) \ template<> \ diff --git a/libs/main/math/pimathcomplex.h b/libs/main/math/pimathcomplex.h index 268e7daf..e633b5c4 100644 --- a/libs/main/math/pimathcomplex.h +++ b/libs/main/math/pimathcomplex.h @@ -47,16 +47,6 @@ const complexld complexld_i(0., 1.); const complexld complexld_0(0.); const complexld complexld_1(1.); -__PICONTAINERS_SIMPLE_TYPE__(complexi) -__PICONTAINERS_SIMPLE_TYPE__(complexs) -__PICONTAINERS_SIMPLE_TYPE__(complexf) -__PICONTAINERS_SIMPLE_TYPE__(complexd) -__PICONTAINERS_SIMPLE_TYPE__(complexld) -__PIVECTOR2D_SIMPLE_TYPE__(complexi) -__PIVECTOR2D_SIMPLE_TYPE__(complexs) -__PIVECTOR2D_SIMPLE_TYPE__(complexf) -__PIVECTOR2D_SIMPLE_TYPE__(complexd) -__PIVECTOR2D_SIMPLE_TYPE__(complexld) __PIBYTEARRAY_SIMPLE_TYPE__(complexi) __PIBYTEARRAY_SIMPLE_TYPE__(complexs) __PIBYTEARRAY_SIMPLE_TYPE__(complexf) diff --git a/main.cpp b/main.cpp index 1165af51..070f9cdc 100644 --- a/main.cpp +++ b/main.cpp @@ -1,79 +1,84 @@ #include "pip.h" - -#define REGISTER_CNT (__COUNTER__) -#define REGISTER_V_STREAM_INTERNAL(T, C) \ - class _VariantRegistrator_##C##__ { \ - public: \ - _VariantRegistrator_##C##__() { \ - __VariantFunctionsBase__ * f = __VariantFunctions__().instance(); \ - __VariantFunctionsBase__::registered()[f->hash()] = f; \ - } \ - }; \ - _VariantRegistrator_##C##__ __registrator_##C##__; - - -#define REGISTER_V_STREAM_INTERNAL_W(T, C) REGISTER_V_STREAM_INTERNAL(T, C) -#define REGISTER_V_STREAM(T) REGISTER_V_STREAM_INTERNAL_W(T, __COUNTER__) - - - - -class Send: public PIObject { - PIOBJECT(Send) -public: - Send() {piCout << "Send";} - ~Send() {piCout << "~Send";} - EVENT1(ev, PIObject * , o); +struct A { + double x1; + //double x2; }; +inline PIByteArray & operator <<(PIByteArray & s, const A & a) {s << a.x1/* << a.x2*/; return s;} +inline PIByteArray & operator >>(PIByteArray & s, A & a) {s >> a.x1/* >> a.x2*/; return s;} - -class Recv: public PIObject { - PIOBJECT(Recv) -public: - Recv() {piCout << "Recv";} - ~Recv() {piCout << "~Recv";} - EVENT_HANDLER1(void, eh, PIObject * , o) { - piCout << "eh ..." << o; - o->deleteLater(); - piMSleep(1000); - piCout << "eh ok"; +struct B { + B() { + x1=0; + //x2=0; } + B(const B & b) = default; + B & operator =(const B & b) {x1=b.x1; return *this;} + double x1; + //double x2; }; +inline PIByteArray & operator <<(PIByteArray & s, const B & a) {s << a.x1/* << a.x2*/; return s;} +inline PIByteArray & operator >>(PIByteArray & s, B & a) {s >> a.x1/* >> a.x2*/; return s;} - -Send * s = new Send(); -Recv * r = new Recv(); +//__PIVECTOR_SIMPLE_TYPE__(B) #include "piconditionvar.h" int main() { + PITimeMeasurer tm; + PIByteArray ba; ba.reserve(100*100*16); - CONNECTU(s, ev, r, eh); - s->ev(r); - r->deleteLater(); - s->deleteLater(); - piMSleep(1500); - //s->deleteLater(); - //delete o; - //eth.dump(); - //versionCompare("",""); - //PICloudServer s("127.0.0.1:10101"); - //s.startThreadedRead(); - piMSleep(10); + PIVector2D vx; + PIVector2D vd; + ba << vx; + ba >> vx; + vd.resize(100, 100); + vx = vd; + tm.reset(); + for(int i=0; i<1000; ++i) { + vx.clear(); + vx = vd; + ba << vx; + ba >> vd; + } + piCout << tm.elapsed_m(); - /*PIMutex m; - PIConditionVariable var; + PIVector2D ax; + PIVector2D ad; + ad.resize(100, 100); + ax = ad; + tm.reset(); + for(int i=0; i<1000; ++i) { + ax.clear(); + ax = ad; + ba << ax; + ba >> ad; + } + piCout << tm.elapsed_m(); - PIThread::runOnce([&](){ - piCout << "wait ..."; - m.lock(); - var.wait(m); - m.unlock(); - piCout << "wait done"; - }); - - piMSleep(100); - var.notifyAll();*/ + PIVector2D bx; + PIVector2D bd; + bd.resize(100, 100); + bx = bd; + tm.reset(); + for(int i=0; i<1000; ++i) { + bx.clear(); + bx = bd; + ba << bx; + ba >> bd; + } + piCout << tm.elapsed_m(); + PIVector2D cx; + PIVector2D cd; + cd.resize(100, 100); + cx = cd; + tm.reset(); + for(int i=0; i<1000; ++i) { + cx.clear(); + cx = cd; + ba << cx; + ba >> cd; + } + piCout << tm.elapsed_m(); return 0; } From 2ca8db70f3a5dbe1ae8c641e99f49860cdaaf56a Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Thu, 1 Oct 2020 19:04:10 +0300 Subject: [PATCH 18/98] pibytearray patch, now automatic supports all simple types --- libs/main/core/pibytearray.h | 373 +++++++++++++++++++++++---------- libs/main/core/pichar.h | 4 +- libs/main/math/pimathcomplex.h | 4 +- main.cpp | 16 +- 4 files changed, 268 insertions(+), 129 deletions(-) diff --git a/libs/main/core/pibytearray.h b/libs/main/core/pibytearray.h index 9c6bb60e..76e3e6b0 100644 --- a/libs/main/core/pibytearray.h +++ b/libs/main/core/pibytearray.h @@ -28,22 +28,6 @@ #include "pimap.h" #include "pivector2d.h" - -#define __PIBYTEARRAY_SIMPLE_TYPE__(T) \ -template<> \ -inline PIByteArray & operator <<(PIByteArray & s, const PIVector & v) {s << int(v.size_s()); int os = s.size_s(); s.enlarge(v.size_s()*sizeof(T)); memcpy(s.data(os), v.data(), v.size_s()*sizeof(T)); return s;} \ -template<> \ -inline PIByteArray & operator >>(PIByteArray & s, PIVector & v) {assert(s.size_s() >= 4); int sz; s >> sz; v._resizeRaw(sz); if (sz > 0) memcpy(v.data(), s.data(), sz*sizeof(T)); s.remove(0, sz*sizeof(T)); return s;} \ -template<> \ -inline PIByteArray & operator <<(PIByteArray & s, const PIDeque & v) {s << int(v.size_s()); int os = s.size_s(); s.enlarge(v.size_s()*sizeof(T)); memcpy(s.data(os), v.data(), v.size_s()*sizeof(T)); return s;} \ -template<> \ -inline PIByteArray & operator >>(PIByteArray & s, PIDeque & v) {assert(s.size_s() >= 4); int sz; s >> sz; v._resizeRaw(sz); if (sz > 0) memcpy(v.data(), s.data(), sz*sizeof(T)); s.remove(0, sz*sizeof(T)); return s;} \ -template<> \ -inline PIByteArray & operator <<(PIByteArray & s, const PIVector2D & v) {s << int(v.rows()) << int(v.cols()); int os = s.size_s(); s.enlarge(v.size_s()*sizeof(T)); memcpy(s.data(os), v.data(), v.size_s()*sizeof(T)); return s;} \ -template<> \ -inline PIByteArray & operator >>(PIByteArray & s, PIVector2D & v) {assert(s.size_s() >= 8); int r, c; s >> r >> c; v._resizeRaw(r, c); int sz = r*c; if (sz > 0) memcpy(v.data(), s.data(), sz*sizeof(T)); s.remove(0, sz*sizeof(T)); return s;} - - class PIString; class PIByteArray; @@ -137,7 +121,36 @@ public: static PIByteArray fromBase64(const PIString & base64); }; -inline bool operator <(const PIByteArray & v0, const PIByteArray & v1) {if (v0.size() == v1.size()) {for (uint i = 0; i < v0.size(); ++i) if (v0[i] != v1[i]) return v0[i] < v1[i]; return false;} return v0.size() < v1.size();} +//! \relatesalso PIByteArray \brief Byte arrays compare operator +inline bool operator <(const PIByteArray & v0, const PIByteArray & v1) { + if (v0.size() == v1.size()) { + for (uint i = 0; i < v0.size(); ++i) + if (v0[i] != v1[i]) + return v0[i] < v1[i]; + return false; + } + return v0.size() < v1.size(); +} + +//! \relatesalso PIByteArray \brief Byte arrays compare operator +inline bool operator ==(PIByteArray & f, PIByteArray & s) { + if (f.size_s() != s.size_s()) + return false; + for (int i = 0; i < f.size_s(); ++i) + if (f[i] != s[i]) + return false; + return true; +} + +//! \relatesalso PIByteArray \brief Byte arrays compare operator +inline bool operator !=(PIByteArray & f, PIByteArray & s) { + if (f.size_s() != s.size_s()) + return true; + for (int i = 0; i < f.size_s(); ++i) + if (f[i] != s[i]) + return true; + return false; +} #ifdef PIP_STD_IOSTREAM //! \relatesalso PIByteArray \brief Output to std::ostream operator @@ -147,114 +160,260 @@ inline std::ostream & operator <<(std::ostream & s, const PIByteArray & ba); //! \relatesalso PIByteArray \brief Output to PICout operator PIP_EXPORT PICout operator <<(PICout s, const PIByteArray & ba); + + + +// store operators for basic types + + #define PBA_OPERATOR_TO int os = s.size_s(); s.enlarge(sizeof(v)); memcpy(s.data(os), &v, sizeof(v)); +//! \relatesalso PIByteArray \brief Store operator +inline PIByteArray & operator <<(PIByteArray & s, const bool v) {s.push_back(v); return s;} //! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, bool v) {s.push_back(v); return s;} +inline PIByteArray & operator <<(PIByteArray & s, const char v) {s.push_back(v); return s;} + //! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, char v) {s.push_back(v); return s;} +inline PIByteArray & operator <<(PIByteArray & s, const uchar v) {s.push_back(v); return s;} + //! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, uchar v) {s.push_back(v); return s;} -//! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, const short v) {PBA_OPERATOR_TO return s;} -//! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, const int v) {PBA_OPERATOR_TO return s;} -//! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, const long & v) {PBA_OPERATOR_TO return s;} -//! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, const llong & v) {PBA_OPERATOR_TO return s;} -//! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, const ushort v) {PBA_OPERATOR_TO return s;} -//! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, const uint v) {PBA_OPERATOR_TO return s;} -//! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, const ulong & v) {PBA_OPERATOR_TO return s;} -//! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, const ullong & v) {PBA_OPERATOR_TO return s;} -//! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, const float v) {PBA_OPERATOR_TO return s;} -//! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, const double & v) {PBA_OPERATOR_TO return s;} -//! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, const ldouble & v) {PBA_OPERATOR_TO return s;} +inline PIByteArray & operator <<(PIByteArray & s, const PIChar & v) {PBA_OPERATOR_TO return s;} + //! \relatesalso PIByteArray \brief Store operator template inline PIByteArray & operator <<(PIByteArray & s, const PIFlags & v) {PBA_OPERATOR_TO return s;} + +//! \relatesalso PIByteArray \brief Store operator for any trivial copyable type +template::value, int>::type = 0> +inline PIByteArray & operator <<(PIByteArray & s, const T & v) {PBA_OPERATOR_TO return s;} + //! \relatesalso PIByteArray \brief Store operator, see \ref PIByteArray_sec1 for details -inline PIByteArray & operator <<(PIByteArray & s, const PIByteArray & v) {s << int(v.size_s()); int os = s.size_s(); s.enlarge(v.size_s()); if (v.size_s() > 0) memcpy(s.data(os), v.data(), v.size()); return s;} +inline PIByteArray & operator <<(PIByteArray & s, const PIByteArray & v) { + s << int(v.size_s()); + int os = s.size_s(); + if (v.size_s() > 0) { + s.enlarge(v.size_s()); + memcpy(s.data(os), v.data(), v.size()); + } + return s; +} + //! \relatesalso PIByteArray \brief Store operator, see \ref PIByteArray_sec1 for details -inline PIByteArray & operator <<(PIByteArray & s, const PIByteArray::RawData & v) {int os = s.size_s(); s.enlarge(v.s); if (v.s > 0) memcpy(s.data(os), v.d, v.s); return s;} +inline PIByteArray & operator <<(PIByteArray & s, const PIByteArray::RawData & v) { + int os = s.size_s(); + if (v.s > 0) { + s.enlarge(v.s); + memcpy(s.data(os), v.d, v.s); + } + return s; +} + +//! \relatesalso PIByteArray \brief Store operator for PIVector of any trivial copyable type +template::value, int>::type = 0> +inline PIByteArray & operator <<(PIByteArray & s, const PIVector & v) { + s << int(v.size_s()); + int os = s.size_s(); + if (v.size_s() > 0) { + s.enlarge(v.size_s()*sizeof(T)); + memcpy(s.data(os), v.data(), v.size_s()*sizeof(T)); + } + return s; +} + +//! \relatesalso PIByteArray \brief Store operator for PIDeque of any trivial copyable type +template::value, int>::type = 0> +inline PIByteArray & operator <<(PIByteArray & s, const PIDeque & v) { + s << int(v.size_s()); + int os = s.size_s(); + if (v.size_s() > 0) { + s.enlarge(v.size_s()*sizeof(T)); + memcpy(s.data(os), v.data(), v.size_s()*sizeof(T)); + } + return s; +} + +//! \relatesalso PIByteArray \brief Store operator for PIVector2D of any trivial copyable type +template::value, int>::type = 0> +inline PIByteArray & operator <<(PIByteArray & s, const PIVector2D & v) { + s << int(v.rows()) << int(v.cols()); + int os = s.size_s(); + if (v.size_s() > 0) { + s.enlarge(v.size_s()*sizeof(T)); + memcpy(s.data(os), v.data(), v.size_s()*sizeof(T)); + } + return s; +} + +//! \relatesalso PIByteArray \brief Store operator +inline PIByteArray & operator <<(PIByteArray & s, const PIBitArray & v) {s << v.size_ << v.data_; return s;} + +//! \relatesalso PIPair \brief Store operator +template +inline PIByteArray & operator <<(PIByteArray & s, const PIPair & v) {s << v.first << v.second; return s;} #undef PBA_OPERATOR_TO + + + + +// restore operators for basic types + + #define PBA_OPERATOR_FROM memcpy((void*)(&v), s.data(), sizeof(v)); s.remove(0, sizeof(v)); //! \relatesalso PIByteArray \brief Restore operator inline PIByteArray & operator >>(PIByteArray & s, bool & v) {assert(s.size() >= 1u); v = s.take_front(); return s;} + //! \relatesalso PIByteArray \brief Restore operator inline PIByteArray & operator >>(PIByteArray & s, char & v) {assert(s.size() >= 1u); v = s.take_front(); return s;} + //! \relatesalso PIByteArray \brief Restore operator inline PIByteArray & operator >>(PIByteArray & s, uchar & v) {assert(s.size() >= 1u); v = s.take_front(); return s;} + //! \relatesalso PIByteArray \brief Restore operator -inline PIByteArray & operator >>(PIByteArray & s, short & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;} -//! \relatesalso PIByteArray \brief Restore operator -inline PIByteArray & operator >>(PIByteArray & s, int & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;} -//! \relatesalso PIByteArray \brief Restore operator -inline PIByteArray & operator >>(PIByteArray & s, long & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;} -//! \relatesalso PIByteArray \brief Restore operator -inline PIByteArray & operator >>(PIByteArray & s, llong & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;} -//! \relatesalso PIByteArray \brief Restore operator -inline PIByteArray & operator >>(PIByteArray & s, ushort & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;} -//! \relatesalso PIByteArray \brief Restore operator -inline PIByteArray & operator >>(PIByteArray & s, uint & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;} -//! \relatesalso PIByteArray \brief Restore operator -inline PIByteArray & operator >>(PIByteArray & s, ulong & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;} -//! \relatesalso PIByteArray \brief Restore operator -inline PIByteArray & operator >>(PIByteArray & s, ullong & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;} -//! \relatesalso PIByteArray \brief Restore operator -inline PIByteArray & operator >>(PIByteArray & s, float & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;} -//! \relatesalso PIByteArray \brief Restore operator -inline PIByteArray & operator >>(PIByteArray & s, double & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;} -//! \relatesalso PIByteArray \brief Restore operator -inline PIByteArray & operator >>(PIByteArray & s, ldouble & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;} +inline PIByteArray & operator >>(PIByteArray & s, PIChar & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;} + +//! \relatesalso PIByteArray \brief Restore operator for any trivial copyable type +template::value, int>::type = 0> +inline PIByteArray & operator >>(PIByteArray & s, T & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;} + //! \relatesalso PIByteArray \brief Restore operator template inline PIByteArray & operator >>(PIByteArray & s, PIFlags & v) {PBA_OPERATOR_FROM return s;} + //! \relatesalso PIByteArray \brief Restore operator, see \ref PIByteArray_sec1 for details PIP_EXPORT PIByteArray & operator >>(PIByteArray & s, PIByteArray & v); + //! \relatesalso PIByteArray \brief Restore operator, see \ref PIByteArray_sec1 for details -inline PIByteArray & operator >>(PIByteArray & s, PIByteArray::RawData v) {assert(s.size_s() >= v.s); if (v.s > 0) memcpy((void*)(v.d), s.data(), v.s); s.remove(0, v.s); return s;} +inline PIByteArray & operator >>(PIByteArray & s, PIByteArray::RawData v) { + assert(s.size_s() >= v.s); + if (v.s > 0) { + memcpy((void*)(v.d), s.data(), v.s); + s.remove(0, v.s); + } + return s; +} + +//! \relatesalso PIByteArray \brief Restore operator for PIVector of any trivial copyable type +template::value, int>::type = 0> +inline PIByteArray & operator >>(PIByteArray & s, PIVector & v) { + assert(s.size_s() >= 4); + int sz; s >> sz; + v._resizeRaw(sz); + if (sz > 0) { + memcpy(v.data(), s.data(), sz*sizeof(T)); + s.remove(0, sz*sizeof(T)); + } + return s; +} + +//! \relatesalso PIByteArray \brief Restore operator for PIDeque of any trivial copyable type +template::value, int>::type = 0> +inline PIByteArray & operator >>(PIByteArray & s, PIDeque & v) { + assert(s.size_s() >= 4); + int sz; s >> sz; + v._resizeRaw(sz); + if (sz > 0) { + memcpy(v.data(), s.data(), sz*sizeof(T)); + s.remove(0, sz*sizeof(T)); + } + return s; +} + +//! \relatesalso PIByteArray \brief Restore operator for PIVector2D of any trivial copyable type +template::value, int>::type = 0> +inline PIByteArray & operator >>(PIByteArray & s, PIVector2D & v) { + assert(s.size_s() >= 8); + int r, c; s >> r >> c; + v._resizeRaw(r, c); + int sz = r*c; + if (sz > 0) { + memcpy(v.data(), s.data(), sz*sizeof(T)); + s.remove(0, sz*sizeof(T)); + } + return s; +} + +//! \relatesalso PIByteArray \brief Restore operator +inline PIByteArray & operator >>(PIByteArray & s, PIBitArray & v) {assert(s.size_s() >= 8); s >> v.size_ >> v.data_; return s;} + +//! \relatesalso PIPair \brief Restore operator +template +inline PIByteArray & operator >>(PIByteArray & s, PIPair & v) {s >> v.first >> v.second; return s;} #undef PBA_OPERATOR_FROM -template inline PIByteArray & operator <<(PIByteArray & s, const PIPair & v); -//! \relatesalso PIByteArray \brief Store operator -template inline PIByteArray & operator <<(PIByteArray & s, const PIVector & v); -//! \relatesalso PIByteArray \brief Store operator -template inline PIByteArray & operator <<(PIByteArray & s, const PIDeque & v); - //! \relatesalso PIByteArray \brief Store operator -template inline PIByteArray & operator <<(PIByteArray & s, const PIMap & v); -//! Write operator to \c PIByteArray -inline PIByteArray & operator <<(PIByteArray & s, const PIChar & v) {s << v.ch; return s;} - -//! \relatesalso PIByteArray \brief Restore operator -template inline PIByteArray & operator >>(PIByteArray & s, PIPair & v); -//! \relatesalso PIByteArray \brief Restore operator -template inline PIByteArray & operator >>(PIByteArray & s, PIVector & v); -//! \relatesalso PIByteArray \brief Restore operator -template inline PIByteArray & operator >>(PIByteArray & s, PIDeque & v); - //! \relatesalso PIByteArray \brief Restore operator -template inline PIByteArray & operator >>(PIByteArray & s, PIMap & v); -//! Read operator from \c PIByteArray -inline PIByteArray & operator >>(PIByteArray & s, PIChar & v) {s >> v.ch; return s;} -//! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, const PIBitArray & v) {s << v.size_ << v.data_; return s;} -template -inline PIByteArray & operator <<(PIByteArray & s, const PIPair & v) {s << v.first << v.second; return s;} -template -inline PIByteArray & operator <<(PIByteArray & s, const PIVector & v) {s << int(v.size_s()); for (uint i = 0; i < v.size(); ++i) s << v[i]; return s;} -template -inline PIByteArray & operator <<(PIByteArray & s, const PIDeque & v) {s << int(v.size_s()); for (uint i = 0; i < v.size(); ++i) s << v[i]; return s;} + +// store operators for complex types + + +//! \relatesalso PIByteArray \brief Store operator for PIVector of any non-trivial copyable type +template::value, int>::type = 0> +inline PIByteArray & operator <<(PIByteArray & s, const PIVector & v) { + s << int(v.size_s()); + for (uint i = 0; i < v.size(); ++i) s << v[i]; + return s; +} + +//! \relatesalso PIByteArray \brief Store operator for PIDeque of any non-trivial copyable type +template::value, int>::type = 0> +inline PIByteArray & operator <<(PIByteArray & s, const PIDeque & v) { + s << int(v.size_s()); + for (uint i = 0; i < v.size(); ++i) s << v[i]; + return s; +} + +//! \relatesalso PIByteArray \brief Store operator for PIVector2D of any non-trivial copyable type +template::value, int>::type = 0> +inline PIByteArray & operator <<(PIByteArray & s, const PIVector2D & v) { + s << int(v.rows()) << int(v.cols()) << v.toPlainVector(); + return s; +} + + + + +// restore operators for complex types + + +//! \relatesalso PIByteArray \brief Restore operator for PIVector of any non-trivial copyable type +template::value, int>::type = 0> +inline PIByteArray & operator >>(PIByteArray & s, PIVector & v) { + assert(s.size_s() >= 4); + int sz; s >> sz; + v.resize(sz); + for (int i = 0; i < sz; ++i) s >> v[i]; + return s; +} + +//! \relatesalso PIByteArray \brief Restore operator for PIDeque of any non-trivial copyable type +template::value, int>::type = 0> +inline PIByteArray & operator >>(PIByteArray & s, PIDeque & v) { + assert(s.size_s() >= 4); + int sz; s >> sz; + v.resize(sz); + for (int i = 0; i < sz; ++i) s >> v[i]; + return s; +} + +//! \relatesalso PIByteArray \brief Restore operator for PIVector2D of any non-trivial copyable type +template::value, int>::type = 0> +inline PIByteArray & operator >>(PIByteArray & s, PIVector2D & v) { + assert(s.size_s() >= 8); + int r,c; + PIVector tmp; + s >> r >> c >> tmp; + v = PIVector2D(r, c, tmp); + return s; +} + + + + +// other types + + template inline PIByteArray & operator <<(PIByteArray & s, const PIMap & v) { s << int(v.pim_index.size_s()); @@ -263,18 +422,8 @@ inline PIByteArray & operator <<(PIByteArray & s, const PIMap & v) { s << v.pim_content; return s; } -template -inline PIByteArray & operator <<(PIByteArray & s, const PIVector2D & v) {s << int(v.rows()) << int(v.cols()) << v.toPlainVector(); return s;} -//! \relatesalso PIByteArray \brief Restore operator -inline PIByteArray & operator >>(PIByteArray & s, PIBitArray & v) {assert(s.size_s() >= 8); s >> v.size_ >> v.data_; return s;} -template -inline PIByteArray & operator >>(PIByteArray & s, PIPair & v) {s >> v.first >> v.second; return s;} -template -inline PIByteArray & operator >>(PIByteArray & s, PIVector & v) {assert(s.size_s() >= 4); int sz; s >> sz; v.resize(sz); for (int i = 0; i < sz; ++i) s >> v[i]; return s;} -template -inline PIByteArray & operator >>(PIByteArray & s, PIDeque & v) {assert(s.size_s() >= 4); int sz; s >> sz; v.resize(sz); for (int i = 0; i < sz; ++i) s >> v[i]; return s;} template inline PIByteArray & operator >>(PIByteArray & s, PIMap & v) { assert(s.size_s() >= 4); @@ -291,21 +440,15 @@ inline PIByteArray & operator >>(PIByteArray & s, PIMap & v) { } return s; } -template -inline PIByteArray & operator >>(PIByteArray & s, PIVector2D & v) {assert(s.size_s() >= 8); int r,c; PIVector tmp; s >> r >> c >> tmp; v = PIVector2D(r, c, tmp); return s;} -template + +template::value, int>::type = 0> inline PIByteArray & operator <<(PIByteArray & s, const T & ) {piCout << "[PIByteArray] Warning: using undeclared operator < +template::value, int>::type = 0> inline PIByteArray & operator >>(PIByteArray & s, T & ) {piCout << "[PIByteArray] Warning: using undeclared operator >>!"; return s;} - -//! \relatesalso PIByteArray \brief Byte arrays compare operator -inline bool operator ==(PIByteArray & f, PIByteArray & s) {if (f.size_s() != s.size_s()) return false; for (int i = 0; i < f.size_s(); ++i) if (f[i] != s[i]) return false; return true;} -//! \relatesalso PIByteArray \brief Byte arrays compare operator -inline bool operator !=(PIByteArray & f, PIByteArray & s) {if (f.size_s() != s.size_s()) return true; for (int i = 0; i < f.size_s(); ++i) if (f[i] != s[i]) return true; return false;} - +/* __PIBYTEARRAY_SIMPLE_TYPE__(bool) __PIBYTEARRAY_SIMPLE_TYPE__(char) __PIBYTEARRAY_SIMPLE_TYPE__(short) @@ -320,7 +463,7 @@ __PIBYTEARRAY_SIMPLE_TYPE__(float) __PIBYTEARRAY_SIMPLE_TYPE__(double) __PIBYTEARRAY_SIMPLE_TYPE__(ldouble) __PIBYTEARRAY_SIMPLE_TYPE__(PIChar) - +*/ template<> inline uint piHash(const PIByteArray & ba) {return ba.hash();} template<> inline void piSwap(PIByteArray & f, PIByteArray & s) {f.swap(s);} diff --git a/libs/main/core/pichar.h b/libs/main/core/pichar.h index 5b18db41..a01b07ce 100644 --- a/libs/main/core/pichar.h +++ b/libs/main/core/pichar.h @@ -34,7 +34,7 @@ class PIP_EXPORT PIChar friend class PIString; friend PIByteArray & operator <<(PIByteArray & s, const PIChar & v); friend PIByteArray & operator >>(PIByteArray & s, PIChar & v); - friend PICout operator <<(PICout s, const PIChar & v); + friend PICout PIP_EXPORT operator <<(PICout s, const PIChar & v); public: //! Contructs ascii symbol PIChar(const char c) {ch = c; ch &= 0xFF;} @@ -135,7 +135,7 @@ private: }; //! Output operator to \a PICout -PICout operator <<(PICout s, const PIChar & v); +PICout PIP_EXPORT operator <<(PICout s, const PIChar & v); //! Compare operator inline bool operator ==(const char v, const PIChar & c) {return (PIChar(v) == c);} diff --git a/libs/main/math/pimathcomplex.h b/libs/main/math/pimathcomplex.h index e633b5c4..9d428d56 100644 --- a/libs/main/math/pimathcomplex.h +++ b/libs/main/math/pimathcomplex.h @@ -46,13 +46,13 @@ const complexd complexd_1(1.); const complexld complexld_i(0., 1.); const complexld complexld_0(0.); const complexld complexld_1(1.); - +/* __PIBYTEARRAY_SIMPLE_TYPE__(complexi) __PIBYTEARRAY_SIMPLE_TYPE__(complexs) __PIBYTEARRAY_SIMPLE_TYPE__(complexf) __PIBYTEARRAY_SIMPLE_TYPE__(complexd) __PIBYTEARRAY_SIMPLE_TYPE__(complexld) - +*/ inline complexd sign(const complexd & x) {return complexd(sign(x.real()), sign(x.imag()));} inline complexd round(const complexd & c) {return complexd(piRound(c.real()), piRound(c.imag()));} diff --git a/main.cpp b/main.cpp index 070f9cdc..d27a590f 100644 --- a/main.cpp +++ b/main.cpp @@ -2,31 +2,27 @@ struct A { double x1; - //double x2; + //PIString str; }; -inline PIByteArray & operator <<(PIByteArray & s, const A & a) {s << a.x1/* << a.x2*/; return s;} -inline PIByteArray & operator >>(PIByteArray & s, A & a) {s >> a.x1/* >> a.x2*/; return s;} +//inline PIByteArray & operator <<(PIByteArray & s, const A & a) {s << a.x1/* << a.x2*/; return s;} +//inline PIByteArray & operator >>(PIByteArray & s, A & a) {s >> a.x1/* >> a.x2*/; return s;} struct B { B() { x1=0; - //x2=0; } B(const B & b) = default; - B & operator =(const B & b) {x1=b.x1; return *this;} + //B & operator =(const B & b) {x1=b.x1; return *this;} + //A aa; double x1; - //double x2; }; -inline PIByteArray & operator <<(PIByteArray & s, const B & a) {s << a.x1/* << a.x2*/; return s;} -inline PIByteArray & operator >>(PIByteArray & s, B & a) {s >> a.x1/* >> a.x2*/; return s;} - //__PIVECTOR_SIMPLE_TYPE__(B) #include "piconditionvar.h" int main() { - PITimeMeasurer tm; PIByteArray ba; ba.reserve(100*100*16); + PITimeMeasurer tm; PIVector2D vx; PIVector2D vd; ba << vx; From 298765b7d8788624ca551da973db453384a6cf73 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Thu, 1 Oct 2020 21:50:41 +0300 Subject: [PATCH 19/98] new class PIVariantSimple PIObject::CONNECTU_QUEUED moved to PIVariantSimple static_assert on undeclared operators PIByteArray << and >> with complex types --- libs/main/core/pibytearray.h | 28 ++---- libs/main/core/piobject.cpp | 14 +-- libs/main/core/piobject.h | 83 ++++++++-------- libs/main/core/piobject_macros.h | 24 ++--- libs/main/core/pivariantsimple.h | 158 +++++++++++++++++++++++++++++ libs/main/math/pimathcomplex.h | 8 +- main.cpp | 165 +++++++++++++++++-------------- 7 files changed, 321 insertions(+), 159 deletions(-) create mode 100644 libs/main/core/pivariantsimple.h diff --git a/libs/main/core/pibytearray.h b/libs/main/core/pibytearray.h index 76e3e6b0..7db8b7b5 100644 --- a/libs/main/core/pibytearray.h +++ b/libs/main/core/pibytearray.h @@ -444,26 +444,16 @@ inline PIByteArray & operator >>(PIByteArray & s, PIMap & v) { template::value, int>::type = 0> -inline PIByteArray & operator <<(PIByteArray & s, const T & ) {piCout << "[PIByteArray] Warning: using undeclared operator <::value, int>::type = 0> -inline PIByteArray & operator >>(PIByteArray & s, T & ) {piCout << "[PIByteArray] Warning: using undeclared operator >>!"; return s;} +inline PIByteArray & operator <<(PIByteArray & s, const T & ) { + static_assert(std::is_trivially_copyable::value, "[PIByteArray] Error: using undeclared operator << for complex type!"); + return s; +} -/* -__PIBYTEARRAY_SIMPLE_TYPE__(bool) -__PIBYTEARRAY_SIMPLE_TYPE__(char) -__PIBYTEARRAY_SIMPLE_TYPE__(short) -__PIBYTEARRAY_SIMPLE_TYPE__(ushort) -__PIBYTEARRAY_SIMPLE_TYPE__(int) -__PIBYTEARRAY_SIMPLE_TYPE__(uint) -__PIBYTEARRAY_SIMPLE_TYPE__(long) -__PIBYTEARRAY_SIMPLE_TYPE__(ulong) -__PIBYTEARRAY_SIMPLE_TYPE__(llong) -__PIBYTEARRAY_SIMPLE_TYPE__(ullong) -__PIBYTEARRAY_SIMPLE_TYPE__(float) -__PIBYTEARRAY_SIMPLE_TYPE__(double) -__PIBYTEARRAY_SIMPLE_TYPE__(ldouble) -__PIBYTEARRAY_SIMPLE_TYPE__(PIChar) -*/ +template::value, int>::type = 0> +inline PIByteArray & operator >>(PIByteArray & s, T & ) { + static_assert(std::is_trivially_copyable::value, "[PIByteArray] Error: using undeclared operator >> for complex type!"); + return s; +} template<> inline uint piHash(const PIByteArray & ba) {return ba.hash();} template<> inline void piSwap(PIByteArray & f, PIByteArray & s) {f.swap(s);} diff --git a/libs/main/core/piobject.cpp b/libs/main/core/piobject.cpp index fa04cd78..06fe88d9 100644 --- a/libs/main/core/piobject.cpp +++ b/libs/main/core/piobject.cpp @@ -105,7 +105,7 @@ PIMap PIObject::properties() const { -bool PIObject::execute(const PIString & method, const PIVector & vl) { +bool PIObject::execute(const PIString & method, const PIVector & vl) { if (method.isEmpty()) return false; if (!isPIObject()) { piCout << "Error: \"execute(" << method << ")\":" << (void*)this << "is not PIObject!"; @@ -121,7 +121,7 @@ bool PIObject::execute(const PIString & method, const PIVector & vl) } -bool PIObject::executeQueued(PIObject * performer, const PIString & method, const PIVector & vl) { +bool PIObject::executeQueued(PIObject * performer, const PIString & method, const PIVector & vl) { if (!isPIObject()) { piCout << "Error: \"executeQueued(" << method << ")\": this(" << (void*)this << ") is not PIObject!"; return false; @@ -535,14 +535,14 @@ PIMutex & PIObject::mutexObjects() { } -void PIObject::callAddrV(void * slot, void * obj, int args, const PIVector & vl) { +void PIObject::callAddrV(void * slot, void * obj, int args, const PIVector & vl) { args = piMini(args, vl.size_s()); switch (args) { case 0: ((void(*)(void *))slot)(obj); break; - case 1: ((void(*)(void * , const PIVariant & ))slot)(obj, vl[0]); break; - case 2: ((void(*)(void * , const PIVariant & , const PIVariant & ))slot)(obj, vl[0], vl[1]); break; - case 3: ((void(*)(void * , const PIVariant & , const PIVariant & , const PIVariant & ))slot)(obj, vl[0], vl[1], vl[2]); break; - case 4: ((void(*)(void * , const PIVariant & , const PIVariant & , const PIVariant & , const PIVariant & ))slot)(obj, vl[0], vl[1], vl[2], vl[3]); break; + case 1: ((void(*)(void * , const PIVariantSimple & ))slot)(obj, vl[0]); break; + case 2: ((void(*)(void * , const PIVariantSimple & , const PIVariantSimple & ))slot)(obj, vl[0], vl[1]); break; + case 3: ((void(*)(void * , const PIVariantSimple & , const PIVariantSimple & , const PIVariantSimple & ))slot)(obj, vl[0], vl[1], vl[2]); break; + case 4: ((void(*)(void * , const PIVariantSimple & , const PIVariantSimple & , const PIVariantSimple & , const PIVariantSimple & ))slot)(obj, vl[0], vl[1], vl[2], vl[3]); break; default: break; } } diff --git a/libs/main/core/piobject.h b/libs/main/core/piobject.h index abfb5436..e85b30c0 100644 --- a/libs/main/core/piobject.h +++ b/libs/main/core/piobject.h @@ -27,6 +27,7 @@ #include "piinit.h" #include "pivariant.h" +#include "pivariantsimple.h" #include "pimutex.h" #include "piset.h" #include "piqueue.h" @@ -101,33 +102,33 @@ public: void setThreadSafe(bool yes) {thread_safe_ = yes;} bool isThreadSafe() const {return thread_safe_;} - bool execute(const PIString & method, const PIVector & vl); - bool execute(const PIString & method) {return execute(method, PIVector());} - bool execute(const PIString & method, const PIVariant & v0) {return execute(method, PIVector() << v0);} - bool execute(const PIString & method, const PIVariant & v0, const PIVariant & v1) {return execute(method, PIVector() << v0 << v1);} - bool execute(const PIString & method, const PIVariant & v0, const PIVariant & v1, const PIVariant & v2) {return execute(method, PIVector() << v0 << v1 << v2);} - bool execute(const PIString & method, const PIVariant & v0, const PIVariant & v1, const PIVariant & v2, const PIVariant & v3) {return execute(method, PIVector() << v0 << v1 << v2 << v3);} + bool execute(const PIString & method, const PIVector & vl); + bool execute(const PIString & method) {return execute(method, PIVector());} + bool execute(const PIString & method, const PIVariantSimple & v0) {return execute(method, PIVector() << v0);} + bool execute(const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1) {return execute(method, PIVector() << v0 << v1);} + bool execute(const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2) {return execute(method, PIVector() << v0 << v1 << v2);} + bool execute(const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2, const PIVariantSimple & v3) {return execute(method, PIVector() << v0 << v1 << v2 << v3);} - bool executeQueued(PIObject * performer, const PIString & method, const PIVector & vl); - bool executeQueued(PIObject * performer, const PIString & method) {return executeQueued(performer, method, PIVector());} - bool executeQueued(PIObject * performer, const PIString & method, const PIVariant & v0) {return executeQueued(performer, method, PIVector() << v0);} - bool executeQueued(PIObject * performer, const PIString & method, const PIVariant & v0, const PIVariant & v1) {return executeQueued(performer, method, PIVector() << v0 << v1);} - bool executeQueued(PIObject * performer, const PIString & method, const PIVariant & v0, const PIVariant & v1, const PIVariant & v2) {return executeQueued(performer, method, PIVector() << v0 << v1 << v2);} - bool executeQueued(PIObject * performer, const PIString & method, const PIVariant & v0, const PIVariant & v1, const PIVariant & v2, const PIVariant & v3) {return executeQueued(performer, method, PIVector() << v0 << v1 << v2 << v3);} + bool executeQueued(PIObject * performer, const PIString & method, const PIVector & vl); + bool executeQueued(PIObject * performer, const PIString & method) {return executeQueued(performer, method, PIVector());} + bool executeQueued(PIObject * performer, const PIString & method, const PIVariantSimple & v0) {return executeQueued(performer, method, PIVector() << v0);} + bool executeQueued(PIObject * performer, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1) {return executeQueued(performer, method, PIVector() << v0 << v1);} + bool executeQueued(PIObject * performer, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2) {return executeQueued(performer, method, PIVector() << v0 << v1 << v2);} + bool executeQueued(PIObject * performer, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2, const PIVariantSimple & v3) {return executeQueued(performer, method, PIVector() << v0 << v1 << v2 << v3);} - static bool execute(PIObject * o, const PIString & method, const PIVector & vl) {return o->execute(method, vl);} - static bool execute(PIObject * o, const PIString & method) {return execute(o, method, PIVector());} - static bool execute(PIObject * o, const PIString & method, const PIVariant & v0) {return execute(o, method, PIVector() << v0);} - static bool execute(PIObject * o, const PIString & method, const PIVariant & v0, const PIVariant & v1) {return execute(o, method, PIVector() << v0 << v1);} - static bool execute(PIObject * o, const PIString & method, const PIVariant & v0, const PIVariant & v1, const PIVariant & v2) {return execute(o, method, PIVector() << v0 << v1 << v2);} - static bool execute(PIObject * o, const PIString & method, const PIVariant & v0, const PIVariant & v1, const PIVariant & v2, const PIVariant & v3) {return execute(o, method, PIVector() << v0 << v1 << v2 << v3);} + static bool execute(PIObject * o, const PIString & method, const PIVector & vl) {return o->execute(method, vl);} + static bool execute(PIObject * o, const PIString & method) {return execute(o, method, PIVector());} + static bool execute(PIObject * o, const PIString & method, const PIVariantSimple & v0) {return execute(o, method, PIVector() << v0);} + static bool execute(PIObject * o, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1) {return execute(o, method, PIVector() << v0 << v1);} + static bool execute(PIObject * o, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2) {return execute(o, method, PIVector() << v0 << v1 << v2);} + static bool execute(PIObject * o, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2, const PIVariantSimple & v3) {return execute(o, method, PIVector() << v0 << v1 << v2 << v3);} - static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVector & vl) {return o->executeQueued(performer, method, vl);} - static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method) {return executeQueued(o, performer, method, PIVector());} - static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVariant & v0) {return executeQueued(o, performer, method, PIVector() << v0);} - static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVariant & v0, const PIVariant & v1) {return executeQueued(o, performer, method, PIVector() << v0 << v1);} - static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVariant & v0, const PIVariant & v1, const PIVariant & v2) {return executeQueued(o, performer, method, PIVector() << v0 << v1 << v2);} - static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVariant & v0, const PIVariant & v1, const PIVariant & v2, const PIVariant & v3) {return executeQueued(o, performer, method, PIVector() << v0 << v1 << v2 << v3);} + static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVector & vl) {return o->executeQueued(performer, method, vl);} + static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method) {return executeQueued(o, performer, method, PIVector());} + static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVariantSimple & v0) {return executeQueued(o, performer, method, PIVector() << v0);} + static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1) {return executeQueued(o, performer, method, PIVector() << v0 << v1);} + static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2) {return executeQueued(o, performer, method, PIVector() << v0 << v1 << v2);} + static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2, const PIVariantSimple & v3) {return executeQueued(o, performer, method, PIVector() << v0 << v1 << v2 << v3);} void dump(const PIString & line_prefix = PIString()) const; @@ -201,8 +202,8 @@ public: (*((std::function*)i.functor))(v0); } else { if (i.performer) { - PIVector vl; - if (i.args_count > 0) vl << PIVariant::fromValue(v0); + PIVector vl; + if (i.args_count > 0) vl << PIVariantSimple::fromValue(v0); i.performer->postQueuedEvent(__QueuedEvent(i.slot, i.dest, i.dest_o, sender, vl)); } else { bool ts = sender->thread_safe_; @@ -232,9 +233,9 @@ public: (*((std::function*)i.functor))(v0, v1); } else { if (i.performer) { - PIVector vl; - if (i.args_count > 0) vl << PIVariant::fromValue(v0); - if (i.args_count > 1) vl << PIVariant::fromValue(v1); + PIVector vl; + if (i.args_count > 0) vl << PIVariantSimple::fromValue(v0); + if (i.args_count > 1) vl << PIVariantSimple::fromValue(v1); i.performer->postQueuedEvent(__QueuedEvent(i.slot, i.dest, i.dest_o, sender, vl)); } else { bool ts = sender->thread_safe_; @@ -267,10 +268,10 @@ public: (*((std::function*)i.functor))(v0, v1, v2); } else { if (i.performer) { - PIVector vl; - if (i.args_count > 0) vl << PIVariant::fromValue(v0); - if (i.args_count > 1) vl << PIVariant::fromValue(v1); - if (i.args_count > 2) vl << PIVariant::fromValue(v2); + PIVector vl; + if (i.args_count > 0) vl << PIVariantSimple::fromValue(v0); + if (i.args_count > 1) vl << PIVariantSimple::fromValue(v1); + if (i.args_count > 2) vl << PIVariantSimple::fromValue(v2); i.performer->postQueuedEvent(__QueuedEvent(i.slot, i.dest, i.dest_o, sender, vl)); } else { bool ts = sender->thread_safe_; @@ -304,11 +305,11 @@ public: (*((std::function*)i.functor))(v0, v1, v2, v3); } else { if (i.performer) { - PIVector vl; - if (i.args_count > 0) vl << PIVariant::fromValue(v0); - if (i.args_count > 1) vl << PIVariant::fromValue(v1); - if (i.args_count > 2) vl << PIVariant::fromValue(v2); - if (i.args_count > 3) vl << PIVariant::fromValue(v3); + PIVector vl; + if (i.args_count > 0) vl << PIVariantSimple::fromValue(v0); + if (i.args_count > 1) vl << PIVariantSimple::fromValue(v1); + if (i.args_count > 2) vl << PIVariantSimple::fromValue(v2); + if (i.args_count > 3) vl << PIVariantSimple::fromValue(v3); i.performer->postQueuedEvent(__QueuedEvent(i.slot, i.dest, i.dest_o, sender, vl)); } else { bool ts = sender->thread_safe_; @@ -452,7 +453,7 @@ private: }; struct __QueuedEvent { - __QueuedEvent(void * sl = 0, void * d = 0, PIObject * d_o = 0, PIObject * s = 0, const PIVector & v = PIVector()) { + __QueuedEvent(void * sl = 0, void * d = 0, PIObject * d_o = 0, PIObject * s = 0, const PIVector & v = PIVector()) { slot = sl; dest = d; dest_o = d_o; @@ -463,7 +464,7 @@ private: void * dest; PIObject * dest_o; PIObject * src; - PIVector values; + PIVector values; }; class Deleter { @@ -496,7 +497,7 @@ private: static PIVector & objects(); static PIMutex & mutexObjects(); - static void callAddrV(void * slot, void * obj, int args, const PIVector & vl); + static void callAddrV(void * slot, void * obj, int args, const PIVector & vl); PIVector<__Connection> connections; diff --git a/libs/main/core/piobject_macros.h b/libs/main/core/piobject_macros.h index c4c5da43..261c4531 100644 --- a/libs/main/core/piobject_macros.h +++ b/libs/main/core/piobject_macros.h @@ -269,7 +269,7 @@ PIMutexLocker ml(__meta_mutex()); \ __MetaData & eh(__meta_data()[__classNameIDS()]); \ void * fp = (void*)(ret(*)(void*, a0))__stat_eh_##name##__; \ - void * fpV = (void*)(ret(*)(void*, const PIVariant &))__stat_eh_v_##name##__; \ + void * fpV = (void*)(ret(*)(void*, const PIVariantSimple &))__stat_eh_v_##name##__; \ if (eh.eh_set[fp]) return; \ eh.eh_set << fp; \ __MetaFunc & f(eh.eh_func[fp]); \ @@ -287,7 +287,7 @@ PIMutexLocker ml(__meta_mutex()); \ __MetaData & eh(__meta_data()[__classNameIDS()]); \ void * fp = (void*)(ret(*)(void*, a0, a1))__stat_eh_##name##__; \ - void * fpV = (void*)(ret(*)(void*, const PIVariant &, const PIVariant &))__stat_eh_v_##name##__; \ + void * fpV = (void*)(ret(*)(void*, const PIVariantSimple &, const PIVariantSimple &))__stat_eh_v_##name##__; \ if (eh.eh_set[fp]) return; \ eh.eh_set << fp; \ __MetaFunc & f(eh.eh_func[fp]); \ @@ -305,7 +305,7 @@ PIMutexLocker ml(__meta_mutex()); \ __MetaData & eh(__meta_data()[__classNameIDS()]); \ void * fp = (void*)(ret(*)(void*, a0, a1, a2))__stat_eh_##name##__; \ - void * fpV = (void*)(ret(*)(void*, const PIVariant &, const PIVariant &, const PIVariant &))__stat_eh_v_##name##__; \ + void * fpV = (void*)(ret(*)(void*, const PIVariantSimple &, const PIVariantSimple &, const PIVariantSimple &))__stat_eh_v_##name##__; \ if (eh.eh_set[fp]) return; \ eh.eh_set << fp; \ __MetaFunc & f(eh.eh_func[fp]); \ @@ -323,7 +323,7 @@ PIMutexLocker ml(__meta_mutex()); \ __MetaData & eh(__meta_data()[__classNameIDS()]); \ void * fp = (void*)(ret(*)(void*, a0, a1, a2, a3))__stat_eh_##name##__; \ - void * fpV = (void*)(ret(*)(void*, const PIVariant &, const PIVariant &, const PIVariant &, const PIVariant &))__stat_eh_v_##name##__; \ + void * fpV = (void*)(ret(*)(void*, const PIVariantSimple &, const PIVariantSimple &, const PIVariantSimple &, const PIVariantSimple &))__stat_eh_v_##name##__; \ if (eh.eh_set[fp]) return; \ eh.eh_set << fp; \ __MetaFunc & f(eh.eh_func[fp]); \ @@ -345,7 +345,7 @@ #define EVENT_HANDLER1(ret, name, a0, n0) \ EH_INIT1(ret, name, a0, n0) \ static ret __stat_eh_##name##__(void * __o__, a0 n0) {return ((__PIObject__*)__o__)->name(n0);} \ - static ret __stat_eh_v_##name##__(void * __o__, const PIVariant & v0) { \ + static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0) { \ __PTYPE(a0) tv0 = __VVALUE(a0, v0); \ return ((__PIObject__*)__o__)->name(tv0);} \ ret name(a0 n0) @@ -353,7 +353,7 @@ #define EVENT_HANDLER2(ret, name, a0, n0, a1, n1) \ EH_INIT2(ret, name, a0, n0, a1, n1) \ static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1) {return ((__PIObject__*)__o__)->name(n0, n1);} \ - static ret __stat_eh_v_##name##__(void * __o__, const PIVariant & v0, const PIVariant & v1) { \ + static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0, const PIVariantSimple & v1) { \ __PTYPE(a0) tv0 = __VVALUE(a0, v0); \ __PTYPE(a1) tv1 = __VVALUE(a1, v1); \ return ((__PIObject__*)__o__)->name(tv0, tv1);} \ @@ -362,7 +362,7 @@ #define EVENT_HANDLER3(ret, name, a0, n0, a1, n1, a2, n2) \ EH_INIT3(ret, name, a0, n0, a1, n1, a2, n2) \ static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1, a2 n2) {return ((__PIObject__*)__o__)->name(n0, n1, n2);} \ - static ret __stat_eh_v_##name##__(void * __o__, const PIVariant & v0, const PIVariant & v1, const PIVariant & v2) { \ + static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2) { \ __PTYPE(a0) tv0 = __VVALUE(a0, v0); \ __PTYPE(a1) tv1 = __VVALUE(a1, v1); \ __PTYPE(a2) tv2 = __VVALUE(a2, v2); \ @@ -372,7 +372,7 @@ #define EVENT_HANDLER4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) \ EH_INIT4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) \ static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1, a2 n2, a3 n3) {return ((__PIObject__*)__o__)->name(n0, n1, n2, n3);} \ - static ret __stat_eh_v_##name##__(void * __o__, const PIVariant & v0, const PIVariant & v1, const PIVariant & v2, const PIVariant & v3) { \ + static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2, const PIVariantSimple & v3) { \ __PTYPE(a0) tv0 = __VVALUE(a0, v0); \ __PTYPE(a1) tv1 = __VVALUE(a1, v1); \ __PTYPE(a2) tv2 = __VVALUE(a2, v2); \ @@ -391,25 +391,25 @@ #define EVENT_VHANDLER1(ret, name, a0, n0) \ EH_INIT1(ret, name, a0, n0) \ static ret __stat_eh_##name##__(void * __o__, a0 n0) {return ((__PIObject__*)__o__)->name(n0);} \ - static ret __stat_eh_v_##name##__(void * __o__, const PIVariant & v0) {return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0));} \ + static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0) {return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0));} \ virtual ret name(a0 n0) #define EVENT_VHANDLER2(ret, name, a0, n0, a1, n1) \ EH_INIT2(ret, name, a0, n0, a1, n1) \ static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1) {return ((__PIObject__*)__o__)->name(n0, n1);} \ - static ret __stat_eh_v_##name##__(void * __o__, const PIVariant & v0, const PIVariant & v1) {return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1));} \ + static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0, const PIVariantSimple & v1) {return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1));} \ virtual ret name(a0 n0, a1 n1) #define EVENT_VHANDLER3(ret, name, a0, n0, a1, n1, a2, n2) \ EH_INIT3(ret, name, a0, n0, a1, n1, a2, n2) \ static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1, a2 n2) {return ((__PIObject__*)__o__)->name(n0, n1, n2);} \ - static ret __stat_eh_v_##name##__(void * __o__, const PIVariant & v0, const PIVariant & v1, const PIVariant & v2) {return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1), __VVALUE(a2, v2));} \ + static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2) {return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1), __VVALUE(a2, v2));} \ virtual ret name(a0 n0, a1 n1, a2 n2) #define EVENT_VHANDLER4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) \ EH_INIT4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) \ static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1, a2 n2, a3 n3) {return ((__PIObject__*)__o__)->name(n0, n1, n2, n3);} \ - static ret __stat_eh_v_##name##__(void * __o__, const PIVariant & v0, const PIVariant & v1, const PIVariant & v2, const PIVariant & v3) {return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1), __VVALUE(a2, v2), __VVALUE(a3, v3));} \ + static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2, const PIVariantSimple & v3) {return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1), __VVALUE(a2, v2), __VVALUE(a3, v3));} \ virtual ret name(a0 n0, a1 n1, a2 n2, a3 n3) #define EVENT_VHANDLER EVENT_VHANDLER0 diff --git a/libs/main/core/pivariantsimple.h b/libs/main/core/pivariantsimple.h new file mode 100644 index 00000000..ba2d2e9e --- /dev/null +++ b/libs/main/core/pivariantsimple.h @@ -0,0 +1,158 @@ +/*! \file pivariantsimple.h + * \brief Variant simple type + * + * This file declares PIVariantSimple +*/ +/* + PIP - Platform Independent Primitives + Variant simple type + Ivan Pelipenko peri4ko@yandex.ru + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + +#ifndef PIVARIANTSIMPLE_H +#define PIVARIANTSIMPLE_H + +#include "pistring.h" +#include + + +class __VariantFunctionsBase__ { +public: + virtual __VariantFunctionsBase__ * instance() {return 0;} + virtual PIString typeName() const {return PIString();} + virtual uint hash() const {return 0;} + virtual void newT(void *& ptr, const void * value) {;} + virtual void newNullT(void *& ptr) {;} + virtual void equalT(void *& ptr, const void * value) {;} + virtual void deleteT(void *& ptr) {;} + //virtual PIByteArray toData(const void * ptr) const {return PIByteArray();} + //virtual void fromData(void *& ptr, PIByteArray ba) {;} + static PIMap & registered() {static PIMap ret; return ret;} +}; + + +template +class __VariantFunctions__: public __VariantFunctionsBase__ { +public: + __VariantFunctionsBase__ * instance() override {static __VariantFunctions__ ret; return &ret;} + PIString typeName() const override {static PIString ret(typeid(T).name()); return ret;} + uint hash() const override {static uint ret = typeName().hash(); return ret;} + void newT(void *& ptr, const void * value) override {ptr = (void*)(new T(*(const T*)value)); /*printf(" * new\n")*/;} + void newNullT(void *& ptr) override {ptr = (void*)(new T());/* printf(" * new null\n")*/;} + void equalT(void *& ptr, const void * value) override {*(T*)ptr = *(const T*)value; /*printf(" * =\n")*/;} + void deleteT(void *& ptr) override {delete (T*)(ptr); /*printf(" * del\n")*/;} + //PIByteArray toData(const void * ptr) const override {PIByteArray ret; ret << (*(const T* &)ptr); return ret;} + //void fromData(void *& ptr, PIByteArray ba) override {ba >> *(T*)ptr;} +}; + +class PIVariantSimple { +public: + PIVariantSimple() {ptr = 0; f = 0;} + PIVariantSimple(const PIVariantSimple & v) { + ptr = 0; + f = v.f; + if (f && v.ptr) + f->newT(ptr, v.ptr); + } + ~PIVariantSimple() {destroy();} + + PIVariantSimple & operator=(const PIVariantSimple & v) { + destroy(); + f = v.f; + if (f && v.ptr) + f->newT(ptr, v.ptr); + return *this; + } + + template + void setValue(const T & v) { + if (f) { + if (isMyType()) { + f->equalT(ptr, (const void *)&v); + return; + } + } + destroy(); + f = __VariantFunctions__().instance(); + f->newT(ptr, (const void *)&v); + } + + template + T value() const { + if (!f) return T(); + if (!isMyType()) + return T(); + return *(T*)(ptr); + } + + template + static PIVariantSimple fromValue(const T & v) { + PIVariantSimple ret; + ret.setValue(v); + return ret; + } + + /* + PIByteArray save() const { + if (!ptr || !f) return PIByteArray(); + PIByteArray ret; + ret << f->hash(); + ret.append(f->toData(ptr)); + return ret; + } + + bool load(PIByteArray ba) { + if (ba.size_s() < 4) return false; + uint h(0); ba >> h; + destroy(); + f = __VariantFunctionsBase__::registered().value(h, 0); + if (!f) return false; + f->newNullT(ptr); + f->fromData(ptr, ba); + return true; + } + */ + +private: + template + bool isMyType() const { + uint mh = f->hash(), th = __VariantFunctions__().instance()->hash(); + if (mh == 0 || th == 0) return false; + return mh == th; + } + + void destroy() { + if (ptr && f) + f->deleteT(ptr); + ptr = 0; + f = 0; + } + + void * ptr; + __VariantFunctionsBase__ * f; + +}; + + +#define REGISTER_PIVARIANTSIMPLE_STREAM(Type) \ + STATIC_INITIALIZER_BEGIN() \ + __VariantFunctionsBase__ * f = __VariantFunctions__().instance(); \ + __VariantFunctionsBase__::registered()[f->hash()] = f; \ + STATIC_INITIALIZER_END() + + + +#endif // PIVARIANTSIMPLE_H diff --git a/libs/main/math/pimathcomplex.h b/libs/main/math/pimathcomplex.h index 9d428d56..79e651d5 100644 --- a/libs/main/math/pimathcomplex.h +++ b/libs/main/math/pimathcomplex.h @@ -46,13 +46,7 @@ const complexd complexd_1(1.); const complexld complexld_i(0., 1.); const complexld complexld_0(0.); const complexld complexld_1(1.); -/* -__PIBYTEARRAY_SIMPLE_TYPE__(complexi) -__PIBYTEARRAY_SIMPLE_TYPE__(complexs) -__PIBYTEARRAY_SIMPLE_TYPE__(complexf) -__PIBYTEARRAY_SIMPLE_TYPE__(complexd) -__PIBYTEARRAY_SIMPLE_TYPE__(complexld) -*/ + inline complexd sign(const complexd & x) {return complexd(sign(x.real()), sign(x.imag()));} inline complexd round(const complexd & c) {return complexd(piRound(c.real()), piRound(c.imag()));} diff --git a/main.cpp b/main.cpp index d27a590f..28bd520d 100644 --- a/main.cpp +++ b/main.cpp @@ -1,80 +1,99 @@ #include "pip.h" +#include "pivariantsimple.h" -struct A { - double x1; - //PIString str; + +template +struct __VariantTypeInfo__ { + typedef T PureType; + typedef const T ConstPureType; + typedef T * PointerType; + typedef const T * ConstPointerType; + typedef T & ReferenceType; + typedef const T & ConstReferenceType; }; -//inline PIByteArray & operator <<(PIByteArray & s, const A & a) {s << a.x1/* << a.x2*/; return s;} -//inline PIByteArray & operator >>(PIByteArray & s, A & a) {s >> a.x1/* >> a.x2*/; return s;} -struct B { - B() { - x1=0; +#define __TYPEINFO_SINGLE(PT, T) \ + template<> struct __PIVariantTypeInfo__ { \ + typedef PT PureType; \ + typedef const PT ConstPureType; \ + typedef PT * PointerType; \ + typedef const PT * ConstPointerType; \ + typedef PT & ReferenceType; \ + typedef const PT & ConstReferenceType; \ + }; + +#define REGISTER_VARIANT_TYPEINFO(T) \ + __TYPEINFO_SINGLE(T, T &) \ + __TYPEINFO_SINGLE(T, const T) \ + __TYPEINFO_SINGLE(T, const T &) + + + +struct SwitchChannel { + SwitchChannel(bool on_ = true, float dur_ = 10.f, int m_count = 0, short unrely = -1) { + on = on_ ? 1 : 0; + duration = dur_; + max_count = m_count; + overload[0] = overload[1] = false; + unreliability = unrely; } - B(const B & b) = default; - //B & operator =(const B & b) {x1=b.x1; return *this;} - //A aa; - double x1; + uchar on; + short unreliability; + float duration; + int max_count; + bool overload[2]; }; -//__PIVECTOR_SIMPLE_TYPE__(B) - -#include "piconditionvar.h" -int main() { - PIByteArray ba; ba.reserve(100*100*16); - - PITimeMeasurer tm; - PIVector2D vx; - PIVector2D vd; - ba << vx; - ba >> vx; - vd.resize(100, 100); - vx = vd; - tm.reset(); - for(int i=0; i<1000; ++i) { - vx.clear(); - vx = vd; - ba << vx; - ba >> vd; - } - piCout << tm.elapsed_m(); - - PIVector2D ax; - PIVector2D ad; - ad.resize(100, 100); - ax = ad; - tm.reset(); - for(int i=0; i<1000; ++i) { - ax.clear(); - ax = ad; - ba << ax; - ba >> ad; - } - piCout << tm.elapsed_m(); - - PIVector2D bx; - PIVector2D bd; - bd.resize(100, 100); - bx = bd; - tm.reset(); - for(int i=0; i<1000; ++i) { - bx.clear(); - bx = bd; - ba << bx; - ba >> bd; - } - piCout << tm.elapsed_m(); - - PIVector2D cx; - PIVector2D cd; - cd.resize(100, 100); - cx = cd; - tm.reset(); - for(int i=0; i<1000; ++i) { - cx.clear(); - cx = cd; - ba << cx; - ba >> cd; - } - piCout << tm.elapsed_m(); - return 0; +/* +inline PIByteArray & operator <<(PIByteArray & ba, const SwitchChannel & v) { + PIChunkStream cs; + cs << cs.chunk(1, v.on) + << cs.chunk(2, v.duration) + << cs.chunk(3, v.max_count) + << cs.chunk(4, v.unreliability); + ba << cs.data(); + return ba; +} +inline PIByteArray & operator >>(PIByteArray & ba, SwitchChannel & v) { + PIByteArray src; ba >> src; PIChunkStream cs(src); + while (!cs.atEnd()) { + switch (cs.read()) { + case 1: cs.get(v.on); break; + case 2: cs.get(v.duration); break; + case 3: cs.get(v.max_count); break; + case 4: cs.get(v.unreliability); break; + } + } + return ba; +}*/ +inline PICout operator <<(PICout c, const SwitchChannel & v) { + c << v.on << v.duration << v.max_count << v.unreliability; + return c; +} + + + +int Acnt = 0; + +class A { +public: + A() {moved = false; i = "constructor"; piCout << "A()"; ++Acnt;} + A(const PIString & s): i(s) {moved = false; piCout << "A(String)"; ++Acnt;} + A(const A & a): i(a.i) {moved = false; piCout << "copy A(&)"; ++Acnt;} + A(A && a): i(std::move(a.i)) {moved = false; a.moved = true; piCout << "copy A(&&)"; ++Acnt;} + ~A() {piCout << "~A()" << moved; --Acnt;} + void swap(A & a) {piCout << "swap A()"; piSwap(i, a.i);} + A & operator =(const A & a) {i = a.i; piCout << "= A&"; return *this;} + A & operator =(A && a) {piSwap(i, a.i); a.moved = true; piCout << "= A&&)"; return *this;} + PIString i; + bool moved; + static void F(int) {} +}; +PIByteArray & operator <<(PIByteArray & ba, const A & v) {ba << v.i; return ba;} +PIByteArray & operator >>(PIByteArray & ba, A & v) {ba >> v.i; return ba;} + + +int main() { + A a; + PIByteArray ba; + ba >> a; } From f3d673986919b9801ac72a16e6f02474956cba8e Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Fri, 2 Oct 2020 11:11:55 +0300 Subject: [PATCH 20/98] code brush --- libs/main/core/pibytearray.h | 20 ++++++-------------- libs/main/core/pivariantsimple.h | 22 +++++++++++----------- libs/main/io_devices/pifile.cpp | 10 ++++++---- libs/main/io_devices/pifile.h | 2 +- 4 files changed, 24 insertions(+), 30 deletions(-) diff --git a/libs/main/core/pibytearray.h b/libs/main/core/pibytearray.h index 7db8b7b5..a5e9488d 100644 --- a/libs/main/core/pibytearray.h +++ b/libs/main/core/pibytearray.h @@ -166,8 +166,6 @@ PIP_EXPORT PICout operator <<(PICout s, const PIByteArray & ba); // store operators for basic types -#define PBA_OPERATOR_TO int os = s.size_s(); s.enlarge(sizeof(v)); memcpy(s.data(os), &v, sizeof(v)); - //! \relatesalso PIByteArray \brief Store operator inline PIByteArray & operator <<(PIByteArray & s, const bool v) {s.push_back(v); return s;} @@ -178,14 +176,14 @@ inline PIByteArray & operator <<(PIByteArray & s, const char v) {s.push_back(v); inline PIByteArray & operator <<(PIByteArray & s, const uchar v) {s.push_back(v); return s;} //! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, const PIChar & v) {PBA_OPERATOR_TO return s;} +inline PIByteArray & operator <<(PIByteArray & s, const PIChar & v) {int os = s.size_s(); s.enlarge(sizeof(v)); memcpy(s.data(os), &v, sizeof(v)); return s;} //! \relatesalso PIByteArray \brief Store operator -template inline PIByteArray & operator <<(PIByteArray & s, const PIFlags & v) {PBA_OPERATOR_TO return s;} +template inline PIByteArray & operator <<(PIByteArray & s, const PIFlags & v) {int os = s.size_s(); s.enlarge(sizeof(v)); memcpy(s.data(os), &v, sizeof(v)); return s;} //! \relatesalso PIByteArray \brief Store operator for any trivial copyable type template::value, int>::type = 0> -inline PIByteArray & operator <<(PIByteArray & s, const T & v) {PBA_OPERATOR_TO return s;} +inline PIByteArray & operator <<(PIByteArray & s, const T & v) {int os = s.size_s(); s.enlarge(sizeof(v)); memcpy(s.data(os), &v, sizeof(v)); return s;} //! \relatesalso PIByteArray \brief Store operator, see \ref PIByteArray_sec1 for details inline PIByteArray & operator <<(PIByteArray & s, const PIByteArray & v) { @@ -251,16 +249,12 @@ inline PIByteArray & operator <<(PIByteArray & s, const PIBitArray & v) {s << v. template inline PIByteArray & operator <<(PIByteArray & s, const PIPair & v) {s << v.first << v.second; return s;} -#undef PBA_OPERATOR_TO - // restore operators for basic types -#define PBA_OPERATOR_FROM memcpy((void*)(&v), s.data(), sizeof(v)); s.remove(0, sizeof(v)); - //! \relatesalso PIByteArray \brief Restore operator inline PIByteArray & operator >>(PIByteArray & s, bool & v) {assert(s.size() >= 1u); v = s.take_front(); return s;} @@ -271,14 +265,14 @@ inline PIByteArray & operator >>(PIByteArray & s, char & v) {assert(s.size() >= inline PIByteArray & operator >>(PIByteArray & s, uchar & v) {assert(s.size() >= 1u); v = s.take_front(); return s;} //! \relatesalso PIByteArray \brief Restore operator -inline PIByteArray & operator >>(PIByteArray & s, PIChar & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;} +inline PIByteArray & operator >>(PIByteArray & s, PIChar & v) {assert(s.size() >= sizeof(v)); memcpy((void*)(&v), s.data(), sizeof(v)); s.remove(0, sizeof(v)); return s;} //! \relatesalso PIByteArray \brief Restore operator for any trivial copyable type template::value, int>::type = 0> -inline PIByteArray & operator >>(PIByteArray & s, T & v) {assert(s.size() >= sizeof(v)); PBA_OPERATOR_FROM return s;} +inline PIByteArray & operator >>(PIByteArray & s, T & v) {assert(s.size() >= sizeof(v)); memcpy((void*)(&v), s.data(), sizeof(v)); s.remove(0, sizeof(v)); return s;} //! \relatesalso PIByteArray \brief Restore operator -template inline PIByteArray & operator >>(PIByteArray & s, PIFlags & v) {PBA_OPERATOR_FROM return s;} +template inline PIByteArray & operator >>(PIByteArray & s, PIFlags & v) {memcpy((void*)(&v), s.data(), sizeof(v)); s.remove(0, sizeof(v)); return s;} //! \relatesalso PIByteArray \brief Restore operator, see \ref PIByteArray_sec1 for details PIP_EXPORT PIByteArray & operator >>(PIByteArray & s, PIByteArray & v); @@ -340,8 +334,6 @@ inline PIByteArray & operator >>(PIByteArray & s, PIBitArray & v) {assert(s.size template inline PIByteArray & operator >>(PIByteArray & s, PIPair & v) {s >> v.first >> v.second; return s;} -#undef PBA_OPERATOR_FROM - diff --git a/libs/main/core/pivariantsimple.h b/libs/main/core/pivariantsimple.h index ba2d2e9e..64114a4e 100644 --- a/libs/main/core/pivariantsimple.h +++ b/libs/main/core/pivariantsimple.h @@ -36,7 +36,7 @@ public: virtual uint hash() const {return 0;} virtual void newT(void *& ptr, const void * value) {;} virtual void newNullT(void *& ptr) {;} - virtual void equalT(void *& ptr, const void * value) {;} + virtual void assignT(void *& ptr, const void * value) {;} virtual void deleteT(void *& ptr) {;} //virtual PIByteArray toData(const void * ptr) const {return PIByteArray();} //virtual void fromData(void *& ptr, PIByteArray ba) {;} @@ -47,15 +47,15 @@ public: template class __VariantFunctions__: public __VariantFunctionsBase__ { public: - __VariantFunctionsBase__ * instance() override {static __VariantFunctions__ ret; return &ret;} - PIString typeName() const override {static PIString ret(typeid(T).name()); return ret;} - uint hash() const override {static uint ret = typeName().hash(); return ret;} - void newT(void *& ptr, const void * value) override {ptr = (void*)(new T(*(const T*)value)); /*printf(" * new\n")*/;} - void newNullT(void *& ptr) override {ptr = (void*)(new T());/* printf(" * new null\n")*/;} - void equalT(void *& ptr, const void * value) override {*(T*)ptr = *(const T*)value; /*printf(" * =\n")*/;} - void deleteT(void *& ptr) override {delete (T*)(ptr); /*printf(" * del\n")*/;} - //PIByteArray toData(const void * ptr) const override {PIByteArray ret; ret << (*(const T* &)ptr); return ret;} - //void fromData(void *& ptr, PIByteArray ba) override {ba >> *(T*)ptr;} + __VariantFunctionsBase__ * instance() final {static __VariantFunctions__ ret; return &ret;} + PIString typeName() const final {static PIString ret(typeid(T).name()); return ret;} + uint hash() const final {static uint ret = typeName().hash(); return ret;} + void newT(void *& ptr, const void * value) final {ptr = (void*)(new T(*(const T*)value)); /*printf(" * new\n")*/;} + void newNullT(void *& ptr) final {ptr = (void*)(new T());/* printf(" * new null\n")*/;} + void assignT(void *& ptr, const void * value) final {*(T*)ptr = *(const T*)value; /*printf(" * =\n")*/;} + void deleteT(void *& ptr) final {delete (T*)(ptr); /*printf(" * del\n")*/;} + //PIByteArray toData(const void * ptr) const final {PIByteArray ret; ret << (*(const T* &)ptr); return ret;} + //void fromData(void *& ptr, PIByteArray ba) final {ba >> *(T*)ptr;} }; class PIVariantSimple { @@ -81,7 +81,7 @@ public: void setValue(const T & v) { if (f) { if (isMyType()) { - f->equalT(ptr, (const void *)&v); + f->assignT(ptr, (const void *)&v); return; } } diff --git a/libs/main/io_devices/pifile.cpp b/libs/main/io_devices/pifile.cpp index 8f598b05..c8754a08 100644 --- a/libs/main/io_devices/pifile.cpp +++ b/libs/main/io_devices/pifile.cpp @@ -124,10 +124,12 @@ PIString PIFile::FileInfo::extension() const { PIString PIFile::FileInfo::dir() const { if (path.isEmpty()) return PIString(); - PIString ret = path.mid(0, path.findLast(PIDir::separator)); - if (ret.isEmpty()) ret = PIDir::separator; - if (!PIDir(ret).isExists()) return (PIStringAscii(".") + PIDir::separator); - return ret; + int ind = path.findLast(PIDir::separator); + PIString ret; + if (ind >= 0) + ret = path.mid(0, ind); + if (ret.isEmpty()) ret = "."; + return ret + PIDir::separator; } diff --git a/libs/main/io_devices/pifile.h b/libs/main/io_devices/pifile.h index 56b1df6f..a84cd63d 100644 --- a/libs/main/io_devices/pifile.h +++ b/libs/main/io_devices/pifile.h @@ -36,7 +36,7 @@ public: explicit PIFile(); struct PIP_EXPORT FileInfo { - FileInfo() {size = 0; id_group = id_user = 0;} + FileInfo(const PIString & path_ = PIString()) {path = path_; size = 0; id_group = id_user = 0;} enum Flag { File = 0x01, From f57f2c47f4361344cc28511802588027c7117aec Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Fri, 2 Oct 2020 11:30:17 +0300 Subject: [PATCH 21/98] version 2.10.0 --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7936ad08..9165454c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,8 +2,8 @@ cmake_minimum_required(VERSION 3.0) cmake_policy(SET CMP0017 NEW) # need include() with .cmake project(pip) set(pip_MAJOR 2) -set(pip_MINOR 9) -set(pip_REVISION 1) +set(pip_MINOR 10) +set(pip_REVISION 0) set(pip_SUFFIX ) set(pip_COMPANY SHS) set(pip_DOMAIN org.SHS) From 7421f8c9a03a1166728a1f49e4bd357c7f72248a Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Fri, 2 Oct 2020 14:23:05 +0300 Subject: [PATCH 22/98] first try --- libs/main/system/pilibrary.h | 3 + libs/main/system/piplugin.cpp | 162 ++++++++++++++++++++++++++++++++++ libs/main/system/piplugin.h | 158 +++++++++++++++++++++++++++++++++ 3 files changed, 323 insertions(+) create mode 100644 libs/main/system/piplugin.cpp create mode 100644 libs/main/system/piplugin.h diff --git a/libs/main/system/pilibrary.h b/libs/main/system/pilibrary.h index 581fa5d1..17b61dc3 100644 --- a/libs/main/system/pilibrary.h +++ b/libs/main/system/pilibrary.h @@ -1,3 +1,6 @@ +/*! \file pilibrary.h +* \brief Dynamic library +*/ /* PIP - Platform Independent Primitives Dynamic library diff --git a/libs/main/system/piplugin.cpp b/libs/main/system/piplugin.cpp new file mode 100644 index 00000000..b651d6b9 --- /dev/null +++ b/libs/main/system/piplugin.cpp @@ -0,0 +1,162 @@ +/* + PIP - Platform Independent Primitives + Plugin helpers + Ivan Pelipenko peri4ko@yandex.ru + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + +#ifndef PIP_FREERTOS + +#include "piplugin.h" +#include "pifile.h" +#include "piincludes_p.h" + +#define STR_WF(s) #s +#define STR(s) STR_WF(s) + + +PIPluginInfo * PIPluginInfo::instance() { + static PIPluginInfo ret; + return &ret; +} + + + + +PIPluginLoader::PIPluginLoader(const PIString & name) { + func_loader_version = nullptr; + func_plugin_info = nullptr; + func_static_merge = nullptr; + plugin_info = nullptr; + loaded = false; + if (!name.isEmpty()) + load(name); +} + + +PIPluginLoader::~PIPluginLoader() { + lib.unload(); +} + + +bool PIPluginLoader::load(const PIString & name) { + unload(); + if (!lib.load(findLibrary(name))) return false; + piCout << "loading" << lib.path() << "..."; + func_loader_version = (FunctionLoaderVersion)lib.resolve(STR(__PIP_PLUGIN_LOADER_VERSION_FUNC__)); + if (!func_loader_version) { + piCout << "Load plugin \"" << name << "\" error: can`t find" << STR(__PIP_PLUGIN_LOADER_VERSION_FUNC__); + unload(); + return false; + } + if (__PIP_PLUGIN_LOADER_VERSION__ != func_loader_version()) { + piCout << "Load plugin \"" << name << "\" error: invalid loader version: plugin" << __PIP_PLUGIN_LOADER_VERSION__ << "!=" << func_loader_version(); + unload(); + return false; + } + func_plugin_info = (FunctionPluginInfo)lib.resolve(STR(__PIP_PLUGIN_PLUGIN_INFO_FUNC__)); + if (!func_plugin_info) { + piCout << "Load plugin \"" << name << "\" error: can`t find" << STR(__PIP_PLUGIN_PLUGIN_INFO_FUNC__); + unload(); + return false; + } + plugin_info = func_plugin_info(); + if (!plugin_info) { + piCout << "Load plugin \"" << name << "\" error: null PIPluginInfo"; + unload(); + return false; + } + if (PIPluginInfo::instance()->user_version.size_s() > 1) { + PIString pversion = plugin_info->user_version, lversion = PIPluginInfo::instance()->user_version; + if (pversion != lversion) { + piCout << "Load plugin \"" << name << "\" error: invalid user version: plugin" << pversion << "!=" << lversion; + unload(); + return false; + } + } + func_static_merge = (FunctionStaticMerge)lib.resolve(STR(__PIP_PLUGIN_STATIC_MERGE_FUNC__)); + if (func_static_merge) { + piCout << PIPluginInfo::instance()->static_sections.keys() << plugin_info->static_sections.keys(); + auto it = PIPluginInfo::instance()->static_sections.makeIterator(); + while (it.next()) { + if (!plugin_info->static_sections.contains(it.key())) + continue; + func_static_merge(it.key(), plugin_info->static_sections.value(it.key()), it.value()); + } + } + loaded = true; + return true; +} + + +void PIPluginLoader::unload() { + lib.unload(); + plugin_info = nullptr; + loaded = false; +} + + +PIString PIPluginLoader::libPath() { + return lib.path(); +} + + +void * PIPluginLoader::resolve(const char * name) { + if (!loaded) return nullptr; + return lib.resolve(name); +} + + +void PIPluginLoader::mergeStatic() { + if (!loaded || !func_static_merge || !plugin_info) return; + auto it = PIPluginInfo::instance()->static_sections.makeIterator(); + while (it.next()) { + if (!plugin_info->static_sections.contains(it.key())) + continue; + func_static_merge(it.key(), it.value(), plugin_info->static_sections.value(it.key())); + } +} + + +PIString PIPluginLoader::findLibrary(const PIString & path) { + static const PIStringList prefixes({"", "lib"}); + static const PIStringList suffixes({"", libExtension()}); + PIFile::FileInfo fi(path); + PIString dir = fi.dir(), name = fi.name(); + piForeachC (PIString & p, prefixes) { + piForeachC (PIString & s, suffixes) { + PIString fn = dir + p + name + s; + if (PIFile::isExists(fn)) + return fn; + } + } + return PIString(); +} + + +PIString PIPluginLoader::libExtension() { + return +#ifdef WINDOWS + ".dll" +#elif defined(MAC_OS) + ".dylib" +#else + ".so" +#endif + ; +} + + +#endif // PIP_FREERTOS diff --git a/libs/main/system/piplugin.h b/libs/main/system/piplugin.h new file mode 100644 index 00000000..7ed670d2 --- /dev/null +++ b/libs/main/system/piplugin.h @@ -0,0 +1,158 @@ +/*! \file piplugin.h +* \brief Plugin helpers +*/ +/* + PIP - Platform Independent Primitives + Plugin helpers + Ivan Pelipenko peri4ko@yandex.ru + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ +# +#ifndef PIPLUGIN_H +#define PIPLUGIN_H + +#ifndef PIP_FREERTOS + +#include "pilibrary.h" +#include "pistringlist.h" + +#ifdef DOXYGEN + + +//! Set user version to check it while loading +#define PIP_PLUGIN_SET_USER_VERSION(v) + +//! Add pointer to future merge with plugin. Type is integer +#define PIP_PLUGIN_ADD_STATIC_SECTION(type, ptr) + +//! Declare plugin export functions +#define PIP_PLUGIN + +//! Declare function to merge static sections. This is functions +//! with 3 arguments: (int type, void * from, void * to). +//! This function invoked first while loading plugin with +//! "from" - plugin scope, "to" - application scope, and second +//! (optionally) on \a PIPluginLoader::mergeStatic() method with +//! "from" - application scope, "to" - plugin scope. So with macro +//! you can merge application and plugin static data. +#define PIP_PLUGIN_STATIC_SECTION_MERGE + + +#else + + +#ifdef WINDOWS +# define PIP_PLUGIN_EXPORT __declspec(dllexport) +#else +# define PIP_PLUGIN_EXPORT +#endif + +#define __PIP_PLUGIN_LOADER_VERSION_FUNC__ pip_loader_version +#define __PIP_PLUGIN_PLUGIN_INFO_FUNC__ pip_plugin_info +#define __PIP_PLUGIN_STATIC_MERGE_FUNC__ pip_merge_static +#define __PIP_PLUGIN_LOADER_VERSION__ 1 + +#define PIP_PLUGIN_SET_USER_VERSION(v) \ + STATIC_INITIALIZER_BEGIN \ + PIPluginInfo::instance()->setUserVersion(v); \ + STATIC_INITIALIZER_END + +#define PIP_PLUGIN_ADD_STATIC_SECTION(type, ptr) \ + STATIC_INITIALIZER_BEGIN \ + PIPluginInfo::instance()->setStaticSection(type, ptr); \ + STATIC_INITIALIZER_END + +#define PIP_PLUGIN \ + extern "C" { \ + PIP_PLUGIN_EXPORT int __PIP_PLUGIN_LOADER_VERSION_FUNC__() {return __PIP_PLUGIN_LOADER_VERSION__;} \ + PIP_PLUGIN_EXPORT PIPluginInfo * __PIP_PLUGIN_PLUGIN_INFO_FUNC__() {return PIPluginInfo::instance();} \ + } + +#define PIP_PLUGIN_STATIC_SECTION_MERGE \ + extern "C" { \ + PIP_PLUGIN_EXPORT void __PIP_PLUGIN_STATIC_MERGE_FUNC__(int type, void * from, void * to); \ + } \ + void __PIP_PLUGIN_STATIC_MERGE_FUNC__(int type, void * from, void * to) + + +#endif + + + +class PIP_EXPORT PIPluginInfo { +public: + PIPluginInfo() {} + + void setUserVersion(const PIString & v) {user_version = v;} + void setStaticSection(int type, void * ptr) {static_sections[type] = ptr;} + + static PIPluginInfo * instance(); + + PIString user_version; + PIMap static_sections; +}; + + + + +class PIP_EXPORT PIPluginLoader { +public: + typedef int(*FunctionLoaderVersion)(); + typedef PIPluginInfo*(*FunctionPluginInfo)(); + typedef void(*FunctionStaticMerge)(int, void *, void *); + + //! Contruscts loader with filename "name" + PIPluginLoader(const PIString & name = PIString()); + + //! Destructor + ~PIPluginLoader(); + + + //! Load plugin with base filename "name". Loader try prefix "lib" + //! and suffix ".dll", ".so" or ".dylib", depends on platform + bool load(const PIString & name); + + //! Unload plugin and free library + void unload(); + + //! Returns loaded plugin library path + PIString libPath(); + + //! Resolve symbol "name" from plugin library + void * resolve(const char * name); + + //! Invoke plugin PIP_PLUGIN_STATIC_SECTION_MERGE function + //! on every common type, with "from" - application scope, + //! "to" - plugin scope + void mergeStatic(); + +private: + NO_COPY_CLASS(PIPluginLoader) + + PIString findLibrary(const PIString & path); + static PIString libExtension(); + + PILibrary lib; + FunctionLoaderVersion func_loader_version; + FunctionPluginInfo func_plugin_info; + FunctionStaticMerge func_static_merge; + PIPluginInfo * plugin_info; + bool loaded; + +}; + + +#endif // PIP_FREERTOS +#endif // PIPLUGIN_H From 334efaefbe4bb110ef4c6fa78f12a4335acb3a1b Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 2 Oct 2020 15:04:15 +0300 Subject: [PATCH 23/98] code clean --- libs/main/core/pibytearray.cpp | 11 ++++++++++ libs/main/core/pibytearray.h | 34 +++++++++++------------------- libs/main/core/pichar.h | 2 -- libs/main/core/piflags.h | 4 ---- libs/main/core/pipropertystorage.h | 12 +++++------ libs/main/core/pitime.h | 13 ------------ libs/main/core/pivariantsimple.h | 6 +++--- libs/main/io_devices/piethernet.h | 4 ---- libs/main/math/pigeometry.h | 12 ----------- libs/main/math/pimathcomplex.h | 14 ------------ libs/main/math/pimathvector.h | 4 ---- main.cpp | 14 ++++++++++-- tests/CMakeLists.txt | 1 - 13 files changed, 44 insertions(+), 87 deletions(-) diff --git a/libs/main/core/pibytearray.cpp b/libs/main/core/pibytearray.cpp index f939ef0a..3c4a01a9 100644 --- a/libs/main/core/pibytearray.cpp +++ b/libs/main/core/pibytearray.cpp @@ -401,3 +401,14 @@ PIByteArray & operator >>(PIByteArray & s, PIByteArray & v) { } return s; } + + +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; +} diff --git a/libs/main/core/pibytearray.h b/libs/main/core/pibytearray.h index a5e9488d..ad00a8a1 100644 --- a/libs/main/core/pibytearray.h +++ b/libs/main/core/pibytearray.h @@ -175,27 +175,18 @@ inline PIByteArray & operator <<(PIByteArray & s, const char v) {s.push_back(v); //! \relatesalso PIByteArray \brief Store operator inline PIByteArray & operator <<(PIByteArray & s, const uchar v) {s.push_back(v); return s;} -//! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, const PIChar & v) {int os = s.size_s(); s.enlarge(sizeof(v)); memcpy(s.data(os), &v, sizeof(v)); return s;} - -//! \relatesalso PIByteArray \brief Store operator -template inline PIByteArray & operator <<(PIByteArray & s, const PIFlags & v) {int os = s.size_s(); s.enlarge(sizeof(v)); memcpy(s.data(os), &v, sizeof(v)); return s;} - //! \relatesalso PIByteArray \brief Store operator for any trivial copyable type template::value, int>::type = 0> -inline PIByteArray & operator <<(PIByteArray & s, const T & v) {int os = s.size_s(); s.enlarge(sizeof(v)); memcpy(s.data(os), &v, sizeof(v)); return s;} - -//! \relatesalso PIByteArray \brief Store operator, see \ref PIByteArray_sec1 for details -inline PIByteArray & operator <<(PIByteArray & s, const PIByteArray & v) { - s << int(v.size_s()); +inline PIByteArray & operator <<(PIByteArray & s, const T & v) { int os = s.size_s(); - if (v.size_s() > 0) { - s.enlarge(v.size_s()); - memcpy(s.data(os), v.data(), v.size()); - } + s.enlarge(sizeof(v)); + memcpy(s.data(os), &v, sizeof(v)); return s; } +//! \relatesalso PIByteArray \brief Store operator, see \ref PIByteArray_sec1 for details +PIP_EXPORT PIByteArray & operator <<(PIByteArray & s, const PIByteArray & v); + //! \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(); @@ -264,15 +255,14 @@ inline PIByteArray & operator >>(PIByteArray & s, char & v) {assert(s.size() >= //! \relatesalso PIByteArray \brief Restore operator inline PIByteArray & operator >>(PIByteArray & s, uchar & v) {assert(s.size() >= 1u); v = s.take_front(); return s;} -//! \relatesalso PIByteArray \brief Restore operator -inline PIByteArray & operator >>(PIByteArray & s, PIChar & v) {assert(s.size() >= sizeof(v)); memcpy((void*)(&v), s.data(), sizeof(v)); s.remove(0, sizeof(v)); return s;} - //! \relatesalso PIByteArray \brief Restore operator for any trivial copyable type template::value, int>::type = 0> -inline PIByteArray & operator >>(PIByteArray & s, T & v) {assert(s.size() >= sizeof(v)); memcpy((void*)(&v), s.data(), sizeof(v)); s.remove(0, sizeof(v)); return s;} - -//! \relatesalso PIByteArray \brief Restore operator -template inline PIByteArray & operator >>(PIByteArray & s, PIFlags & v) {memcpy((void*)(&v), s.data(), sizeof(v)); s.remove(0, sizeof(v)); return s;} +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, see \ref PIByteArray_sec1 for details PIP_EXPORT PIByteArray & operator >>(PIByteArray & s, PIByteArray & v); diff --git a/libs/main/core/pichar.h b/libs/main/core/pichar.h index a01b07ce..a2b5dad2 100644 --- a/libs/main/core/pichar.h +++ b/libs/main/core/pichar.h @@ -32,8 +32,6 @@ extern PIP_EXPORT char * __utf8name__; class PIP_EXPORT PIChar { friend class PIString; - friend PIByteArray & operator <<(PIByteArray & s, const PIChar & v); - friend PIByteArray & operator >>(PIByteArray & s, PIChar & v); friend PICout PIP_EXPORT operator <<(PICout s, const PIChar & v); public: //! Contructs ascii symbol diff --git a/libs/main/core/piflags.h b/libs/main/core/piflags.h index d7584dd5..6d824826 100644 --- a/libs/main/core/piflags.h +++ b/libs/main/core/piflags.h @@ -38,8 +38,6 @@ public: PIFlags(): flags(0) {;} //! Constructor with flags = Enum "e" PIFlags(Enum e): flags(e) {;} - //! Constructor with flags = PIFlags "f" - PIFlags(const PIFlags & f): flags(f.flags) {;} //! Constructor with flags = int "i" PIFlags(const int i): flags(i) {;} //! Set flags "f" to value "on" @@ -49,8 +47,6 @@ public: //! Set flag "i" to value "on" PIFlags & setFlag(const int & i, bool on = true) {if (on) flags |= i; else flags &= ~i; return *this;} //! copy operator - void operator =(const PIFlags & f) {flags = f.flags;} - //! copy operator void operator =(const Enum & e) {flags = e;} //! copy operator void operator =(const int & i) {flags = i;} diff --git a/libs/main/core/pipropertystorage.h b/libs/main/core/pipropertystorage.h index c338b968..9dc4098c 100644 --- a/libs/main/core/pipropertystorage.h +++ b/libs/main/core/pipropertystorage.h @@ -162,12 +162,12 @@ public: */ void setPropertyComment(const PIString & name, const PIString & comment); - /** - * @brief Set flags of property with specific name if name is present in storage. - * - * @param name of property to set flags - * @param flags to set - */ + /** + * @brief Set flags of property with specific name if name is present in storage. + * + * @param name of property to set flags + * @param flags to set + */ void setPropertyFlags(const PIString & name, int flags); PIPropertyStorage & operator <<(const PIPropertyStorage::Property & p) {props << p; return *this;} diff --git a/libs/main/core/pitime.h b/libs/main/core/pitime.h index 90df73c7..9c9a959d 100644 --- a/libs/main/core/pitime.h +++ b/libs/main/core/pitime.h @@ -60,8 +60,6 @@ public: //! Contructs system time with s = "s" and ns = "ns" PISystemTime(int s, int ns) {seconds = s; nanoseconds = ns; checkOverflows();} - //! Contructs system time from another - PISystemTime(const PISystemTime & t) {seconds = t.seconds; nanoseconds = t.nanoseconds;} //! Returns stored system time value in seconds double toSeconds() const {return double(seconds) + nanoseconds / 1.e+9;} @@ -172,13 +170,6 @@ private: //! \relatesalso PICout \relatesalso PICout \brief Output operator to PICout inline PICout operator <<(PICout s, const PISystemTime & v) {s.space(); s.setControl(0, true); s << "(" << v.seconds << " s, " << v.nanoseconds << " ns)"; s.restoreControl(); return s;} -//! \relatesalso PISystemTime \relatesalso PIByteArray \brief Output operator to PIByteArray -inline PIByteArray & operator <<(PIByteArray & s, const PISystemTime & v) {s << v.seconds << v.nanoseconds; return s;} - -//! \relatesalso PISystemTime \relatesalso PIByteArray \brief Input operator from PIByteArray -inline PIByteArray & operator >>(PIByteArray & s, PISystemTime & v) {s >> v.seconds >> v.nanoseconds; return s;} - - struct PIP_EXPORT PITime { @@ -199,8 +190,6 @@ PIP_EXPORT bool operator >(const PITime & t0, const PITime & t1); inline bool operator !=(const PITime & t0, const PITime & t1) {return !(t0 == t1);} inline bool operator <=(const PITime & t0, const PITime & t1) {return !(t0 > t1);} inline bool operator >=(const PITime & t0, const PITime & t1) {return !(t0 < t1);} -inline PIByteArray & operator <<(PIByteArray & s, const PITime & v) {s << v.hours << v.minutes << v.seconds << v.milliseconds; return s;} -inline PIByteArray & operator >>(PIByteArray & s, PITime & v) {s >> v.hours >> v.minutes >> v.seconds >> v.milliseconds; return s;} //! \relatesalso PICout \relatesalso PICout \brief Output operator to PICout PIP_EXPORT PICout operator <<(PICout s, const PITime & v); @@ -223,8 +212,6 @@ PIP_EXPORT bool operator >(const PIDate & t0, const PIDate & t1); inline bool operator !=(const PIDate & t0, const PIDate & t1) {return !(t0 == t1);} inline bool operator <=(const PIDate & t0, const PIDate & t1) {return !(t0 > t1);} inline bool operator >=(const PIDate & t0, const PIDate & t1) {return !(t0 < t1);} -inline PIByteArray & operator <<(PIByteArray & s, const PIDate & v) {s << v.year << v.month << v.day; return s;} -inline PIByteArray & operator >>(PIByteArray & s, PIDate & v) {s >> v.year >> v.month >> v.day; return s;} //! \relatesalso PICout \relatesalso PICout \brief Output operator to PICout PIP_EXPORT PICout operator <<(PICout s, const PIDate & v); diff --git a/libs/main/core/pivariantsimple.h b/libs/main/core/pivariantsimple.h index 64114a4e..17412749 100644 --- a/libs/main/core/pivariantsimple.h +++ b/libs/main/core/pivariantsimple.h @@ -40,7 +40,7 @@ public: virtual void deleteT(void *& ptr) {;} //virtual PIByteArray toData(const void * ptr) const {return PIByteArray();} //virtual void fromData(void *& ptr, PIByteArray ba) {;} - static PIMap & registered() {static PIMap ret; return ret;} + //static PIMap & registered() {static PIMap ret; return ret;} }; @@ -146,13 +146,13 @@ private: }; - +/* #define REGISTER_PIVARIANTSIMPLE_STREAM(Type) \ STATIC_INITIALIZER_BEGIN() \ __VariantFunctionsBase__ * f = __VariantFunctions__().instance(); \ __VariantFunctionsBase__::registered()[f->hash()] = f; \ STATIC_INITIALIZER_END() - +*/ #endif // PIVARIANTSIMPLE_H diff --git a/libs/main/io_devices/piethernet.h b/libs/main/io_devices/piethernet.h index bb9f988e..266134a0 100644 --- a/libs/main/io_devices/piethernet.h +++ b/libs/main/io_devices/piethernet.h @@ -65,8 +65,6 @@ public: //! \brief IPv4 network address, IP and port class PIP_EXPORT Address { friend class PIEthernet; - friend inline PIByteArray & operator <<(PIByteArray & s, const PIEthernet::Address & v); - friend inline PIByteArray & operator >>(PIByteArray & s, PIEthernet::Address & v); public: //! Contructs %Address with binary representation of IP and port @@ -519,7 +517,5 @@ inline PICout operator <<(PICout s, const PIEthernet::Address & v) {s.space(); s inline bool operator ==(const PIEthernet::Address & v0, const PIEthernet::Address & v1) {return (v0.ip() == v1.ip() && v0.port() == v1.port());} inline bool operator !=(const PIEthernet::Address & v0, const PIEthernet::Address & v1) {return (v0.ip() != v1.ip() || v0.port() != v1.port());} -inline PIByteArray & operator <<(PIByteArray & s, const PIEthernet::Address & v) {s << v.ip_ << v.port_; return s;} -inline PIByteArray & operator >>(PIByteArray & s, PIEthernet::Address & v) {s >> v.ip_ >> v.port_; return s;} #endif // PIETHERNET_H diff --git a/libs/main/math/pigeometry.h b/libs/main/math/pigeometry.h index ad2df750..65bf39d1 100644 --- a/libs/main/math/pigeometry.h +++ b/libs/main/math/pigeometry.h @@ -59,12 +59,6 @@ public: template PICout operator <<(PICout & s, const PIPoint & v) {s.setControl(0, true); s << "Point{" << v.x << ", " << v.y << "}"; s.restoreControl(); return s;} -template -inline PIByteArray & operator <<(PIByteArray & s, const PIPoint & v) {s << v.x << v.y; return s;} - -template -inline PIByteArray & operator >>(PIByteArray & s, PIPoint & v) {s >> v.x >> v.y; return s;} - typedef PIPoint PIPointi; typedef PIPoint PIPointu; @@ -145,12 +139,6 @@ public: template PICout operator <<(PICout & s, const PIRect & v) {s.setControl(0, true); s << "Rect{" << v.x0 << ", " << v.y0 << "; " << v.x1 - v.x0 << ", " << v.y1 - v.y0 << "}"; s.restoreControl(); return s;} -template -inline PIByteArray & operator <<(PIByteArray & s, const PIRect & v) {s << v.x0 << v.x1 << v.y0 << v.y1; return s;} - -template -inline PIByteArray & operator >>(PIByteArray & s, PIRect & v) {s >> v.x0 >> v.x1 >> v.y0 >> v.y1; return s;} - typedef PIRect PIRecti; typedef PIRect PIRectu; diff --git a/libs/main/math/pimathcomplex.h b/libs/main/math/pimathcomplex.h index 79e651d5..369513a4 100644 --- a/libs/main/math/pimathcomplex.h +++ b/libs/main/math/pimathcomplex.h @@ -69,20 +69,6 @@ inline complexd log10(const complexd & c) {return log(c) / M_LN10;} template inline PICout operator <<(PICout s, const complex & v) {s.space(); s.setControl(0, true); s << "(" << v.real() << "; " << v.imag() << ")"; s.restoreControl(); return s;} -//! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, complexf v) {float t; t = v.real(); s << t; t = v.imag(); s << t; return s;} -//! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, complexd v) {double t; t = v.real(); s << t; t = v.imag(); s << t; return s;} -//! \relatesalso PIByteArray \brief Store operator -inline PIByteArray & operator <<(PIByteArray & s, complexld v) {ldouble t; t = v.real(); s << t; t = v.imag(); s << t; return s;} - -//! \relatesalso PIByteArray \brief Restore operator -inline PIByteArray & operator >>(PIByteArray & s, complexf & v) {float t0, t1; s >> t0; s >> t1; v = complexf(t0, t1); return s;} -//! \relatesalso PIByteArray \brief Restore operator -inline PIByteArray & operator >>(PIByteArray & s, complexd & v) {double t0, t1; s >> t0; s >> t1; v = complexd(t0, t1); return s;} -//! \relatesalso PIByteArray \brief Restore operator -inline PIByteArray & operator >>(PIByteArray & s, complexld & v) {ldouble t0, t1; s >> t0; s >> t1; v = complexld(t0, t1); return s;} - inline PIVector abs(const PIVector & v) { PIVector result; diff --git a/libs/main/math/pimathvector.h b/libs/main/math/pimathvector.h index 7c4a9b41..75bc284e 100644 --- a/libs/main/math/pimathvector.h +++ b/libs/main/math/pimathvector.h @@ -125,10 +125,6 @@ inline PIMathVectorT sqrt(const PIMathVectorT & v) {PIMa template inline PIMathVectorT sqr(const PIMathVectorT & v) {PIMathVectorT ret; PIMV_FOR(i, 0) {ret[i] = sqr(v[i]);} return ret;} -template -inline PIByteArray & operator <<(PIByteArray & s, const PIMathVectorT & v) {for (uint i = 0; i < Size; ++i) s << v[i]; return s;} -template -inline PIByteArray & operator >>(PIByteArray & s, PIMathVectorT & v) {for (uint i = 0; i < Size; ++i) s >> v[i]; return s;} template inline PIMathVectorT<2u, T> createVectorT2(T x, T y) {return PIMathVectorT<2u, T>(PIVector() << x << y);} diff --git a/main.cpp b/main.cpp index 28bd520d..732d268d 100644 --- a/main.cpp +++ b/main.cpp @@ -74,6 +74,14 @@ inline PICout operator <<(PICout c, const SwitchChannel & v) { int Acnt = 0; +struct MM { + int x; + double y; + char c; + PIPointd h; +}; + + class A { public: A() {moved = false; i = "constructor"; piCout << "A()"; ++Acnt;} @@ -86,10 +94,12 @@ public: A & operator =(A && a) {piSwap(i, a.i); a.moved = true; piCout << "= A&&)"; return *this;} PIString i; bool moved; + MM m; 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;} + +inline PIByteArray & operator <<(PIByteArray & ba, const A & v) {ba << v.i << v.m; return ba;} +inline PIByteArray & operator >>(PIByteArray & ba, A & v) {ba >> v.i >> v.m; return ba;} int main() { diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 07693426..bebb15da 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -17,4 +17,3 @@ endmacro() # Concurrent tests pip_test(concurrent "") pip_test(math "") -#pip_test(core "") From f9b497b5c01f29153bd8ebd434d36d85303c67e3 Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 2 Oct 2020 15:07:36 +0300 Subject: [PATCH 24/98] revert operator for PIMathVectorT --- libs/main/math/pimathvector.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libs/main/math/pimathvector.h b/libs/main/math/pimathvector.h index 75bc284e..09b8d07b 100644 --- a/libs/main/math/pimathvector.h +++ b/libs/main/math/pimathvector.h @@ -125,6 +125,11 @@ inline PIMathVectorT sqrt(const PIMathVectorT & v) {PIMa template inline PIMathVectorT sqr(const PIMathVectorT & v) {PIMathVectorT ret; PIMV_FOR(i, 0) {ret[i] = sqr(v[i]);} return ret;} +template +inline PIByteArray & operator <<(PIByteArray & s, const PIMathVectorT & v) {for (uint i = 0; i < Size; ++i) s << v[i]; return s;} +template +inline PIByteArray & operator >>(PIByteArray & s, PIMathVectorT & v) {for (uint i = 0; i < Size; ++i) s >> v[i]; return s;} + template inline PIMathVectorT<2u, T> createVectorT2(T x, T y) {return PIMathVectorT<2u, T>(PIVector() << x << y);} From b7aef483b70491c663d8c9a881bbd6aa6aa7522e Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Sat, 3 Oct 2020 13:32:43 +0300 Subject: [PATCH 25/98] PIVariantSimple now has no error when assign to non-copyable typeName patch pip_cmg according to last PIByteArray changes plugin system fix --- libs/main/code/picodeinfo.h | 7 ++++ libs/main/core/pivariantsimple.h | 19 +++++++--- libs/main/system/piplugin.cpp | 55 ++++++++++++++++++++++++----- libs/main/system/piplugin.h | 25 ++++++++----- utils/code_model_generator/main.cpp | 2 +- 5 files changed, 86 insertions(+), 22 deletions(-) diff --git a/libs/main/code/picodeinfo.h b/libs/main/code/picodeinfo.h index 97506149..c95d58b0 100644 --- a/libs/main/code/picodeinfo.h +++ b/libs/main/code/picodeinfo.h @@ -174,6 +174,13 @@ inline const char * getMemberType(const char * class_name, const char * member_n PIP_EXPORT PIVariant getMemberAsVariant(const void * p, const char * class_name, const char * member_name); + +template::value, int>::type = 0> +void serialize(PIByteArray & ret, const T & v) {ret << v;} + +template::value, int>::type = 0> +void serialize(PIByteArray & ret, const T & v) {} + } class PIP_EXPORT __PICodeInfoInitializer__ { diff --git a/libs/main/core/pivariantsimple.h b/libs/main/core/pivariantsimple.h index 64114a4e..c9b354be 100644 --- a/libs/main/core/pivariantsimple.h +++ b/libs/main/core/pivariantsimple.h @@ -40,12 +40,21 @@ public: virtual void deleteT(void *& ptr) {;} //virtual PIByteArray toData(const void * ptr) const {return PIByteArray();} //virtual void fromData(void *& ptr, PIByteArray ba) {;} - static PIMap & registered() {static PIMap ret; return ret;} + //static PIMap & registered() {static PIMap ret; return ret;} +}; + + +template +class __VariantFunctions__: public __VariantFunctionsBase__ { +public: + __VariantFunctionsBase__ * instance() final {static __VariantFunctions__ ret; return &ret;} + PIString typeName() const final {static PIString ret(typeid(T).name()); return ret;} + uint hash() const final {static uint ret = typeName().hash(); return ret;} }; template -class __VariantFunctions__: public __VariantFunctionsBase__ { +class __VariantFunctions__::value>::type>: public __VariantFunctionsBase__ { public: __VariantFunctionsBase__ * instance() final {static __VariantFunctions__ ret; return &ret;} PIString typeName() const final {static PIString ret(typeid(T).name()); return ret;} @@ -58,6 +67,7 @@ public: //void fromData(void *& ptr, PIByteArray ba) final {ba >> *(T*)ptr;} }; + class PIVariantSimple { public: PIVariantSimple() {ptr = 0; f = 0;} @@ -129,6 +139,7 @@ public: private: template bool isMyType() const { + if (!f) return false; uint mh = f->hash(), th = __VariantFunctions__().instance()->hash(); if (mh == 0 || th == 0) return false; return mh == th; @@ -146,13 +157,13 @@ private: }; - +/* #define REGISTER_PIVARIANTSIMPLE_STREAM(Type) \ STATIC_INITIALIZER_BEGIN() \ __VariantFunctionsBase__ * f = __VariantFunctions__().instance(); \ __VariantFunctionsBase__::registered()[f->hash()] = f; \ STATIC_INITIALIZER_END() - +*/ #endif // PIVARIANTSIMPLE_H diff --git a/libs/main/system/piplugin.cpp b/libs/main/system/piplugin.cpp index b651d6b9..a711e7d7 100644 --- a/libs/main/system/piplugin.cpp +++ b/libs/main/system/piplugin.cpp @@ -27,6 +27,36 @@ #define STR(s) STR_WF(s) +PIPluginInfo::PIPluginInfo() { + in_plugin = false; +} + + +void PIPluginInfo::setUserVersion(const PIString & v) { + user_version[in_plugin ? 1 : 0] = v; +} + + +void PIPluginInfo::setStaticSection(int type, void * ptr) { + static_sections[in_plugin ? 1 : 0][type] = ptr; +} + + +PIString PIPluginInfo::userVersion(bool plugin) const { + return user_version[plugin ? 1 : 0]; +} + + +PIMap PIPluginInfo::staticSections(bool plugin) const { + return static_sections[plugin ? 1 : 0]; +} + + +void PIPluginInfo::enterPlugin() { + in_plugin = true; +} + + PIPluginInfo * PIPluginInfo::instance() { static PIPluginInfo ret; return &ret; @@ -78,8 +108,8 @@ bool PIPluginLoader::load(const PIString & name) { unload(); return false; } - if (PIPluginInfo::instance()->user_version.size_s() > 1) { - PIString pversion = plugin_info->user_version, lversion = PIPluginInfo::instance()->user_version; + if (PIPluginInfo::instance()->userVersion(false).size_s() > 1) { + PIString pversion = plugin_info->userVersion(true), lversion = PIPluginInfo::instance()->userVersion(false); if (pversion != lversion) { piCout << "Load plugin \"" << name << "\" error: invalid user version: plugin" << pversion << "!=" << lversion; unload(); @@ -88,12 +118,16 @@ bool PIPluginLoader::load(const PIString & name) { } func_static_merge = (FunctionStaticMerge)lib.resolve(STR(__PIP_PLUGIN_STATIC_MERGE_FUNC__)); if (func_static_merge) { - piCout << PIPluginInfo::instance()->static_sections.keys() << plugin_info->static_sections.keys(); - auto it = PIPluginInfo::instance()->static_sections.makeIterator(); + auto pss = plugin_info->staticSections(true), lss = PIPluginInfo::instance()->staticSections(false); + piCout << lss.keys() << pss.keys(); + + auto it = lss.makeIterator(); while (it.next()) { - if (!plugin_info->static_sections.contains(it.key())) + if (!pss.contains(it.key())) continue; - func_static_merge(it.key(), plugin_info->static_sections.value(it.key()), it.value()); + void * from = pss.value(it.key()), * to = it.value(); + if (from != to) + func_static_merge(it.key(), from, to); } } loaded = true; @@ -121,11 +155,14 @@ void * PIPluginLoader::resolve(const char * name) { void PIPluginLoader::mergeStatic() { if (!loaded || !func_static_merge || !plugin_info) return; - auto it = PIPluginInfo::instance()->static_sections.makeIterator(); + auto pss = plugin_info->staticSections(true), lss = PIPluginInfo::instance()->staticSections(false); + auto it = lss.makeIterator(); while (it.next()) { - if (!plugin_info->static_sections.contains(it.key())) + if (!pss.contains(it.key())) continue; - func_static_merge(it.key(), it.value(), plugin_info->static_sections.value(it.key())); + void * from = it.value(), * to = pss.value(it.key()); + if (from != to) + func_static_merge(it.key(), from, to); } } diff --git a/libs/main/system/piplugin.h b/libs/main/system/piplugin.h index 7ed670d2..99a1576c 100644 --- a/libs/main/system/piplugin.h +++ b/libs/main/system/piplugin.h @@ -31,15 +31,15 @@ #ifdef DOXYGEN +//! Declare plugin export functions, should be used before other PIP_PLUGIN_* macros +#define PIP_PLUGIN + //! Set user version to check it while loading #define PIP_PLUGIN_SET_USER_VERSION(v) //! Add pointer to future merge with plugin. Type is integer #define PIP_PLUGIN_ADD_STATIC_SECTION(type, ptr) -//! Declare plugin export functions -#define PIP_PLUGIN - //! Declare function to merge static sections. This is functions //! with 3 arguments: (int type, void * from, void * to). //! This function invoked first while loading plugin with @@ -75,6 +75,9 @@ STATIC_INITIALIZER_END #define PIP_PLUGIN \ + STATIC_INITIALIZER_BEGIN \ + PIPluginInfo::instance()->enterPlugin(); \ + STATIC_INITIALIZER_END \ extern "C" { \ PIP_PLUGIN_EXPORT int __PIP_PLUGIN_LOADER_VERSION_FUNC__() {return __PIP_PLUGIN_LOADER_VERSION__;} \ PIP_PLUGIN_EXPORT PIPluginInfo * __PIP_PLUGIN_PLUGIN_INFO_FUNC__() {return PIPluginInfo::instance();} \ @@ -93,15 +96,21 @@ class PIP_EXPORT PIPluginInfo { public: - PIPluginInfo() {} + PIPluginInfo(); - void setUserVersion(const PIString & v) {user_version = v;} - void setStaticSection(int type, void * ptr) {static_sections[type] = ptr;} + void setUserVersion(const PIString & v); + void setStaticSection(int type, void * ptr); + PIString userVersion(bool plugin) const; + PIMap staticSections(bool plugin) const; + void enterPlugin(); static PIPluginInfo * instance(); - PIString user_version; - PIMap static_sections; +private: + PIString user_version[2]; + PIMap static_sections[2]; + bool in_plugin; + }; diff --git a/utils/code_model_generator/main.cpp b/utils/code_model_generator/main.cpp index b207d679..8742ef26 100755 --- a/utils/code_model_generator/main.cpp +++ b/utils/code_model_generator/main.cpp @@ -325,7 +325,7 @@ void makeGetterValue(PIFile & f, const PICodeParser::Entity * e) { piForeachC (PICodeParser::Member & m, e->members) { if (m.is_type_ptr || m.isBitfield() || !m.dims.isEmpty() || (m.visibility != PICodeParser::Public)) continue; - f << "\tif (strcmp(name, \"" << m.name << "\") == 0) {ret << o->" << m.name << "; return ret;}\n"; + f << "\tif (strcmp(name, \"" << m.name << "\") == 0) {serialize(ret, o->" << m.name << "); return ret;}\n"; } f << "\treturn ret;\n}\n"; } From bf1808f1c47b6b8f9aa03903d73ed7fd8fd6afed Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Tue, 6 Oct 2020 00:53:37 +0300 Subject: [PATCH 26/98] version 2.10.1 Documentation of PIPluginLoader Remove PIVariantSimple ability to assign any type, leave only assignable --- CMakeLists.txt | 5 +- libs/main/core/piincludes.cpp | 35 ++++---- libs/main/core/pivariantsimple.h | 6 +- libs/main/system/piplugin.cpp | 141 ++++++++++++++++++++++++++++++- libs/main/system/piplugin.h | 15 +++- 5 files changed, 179 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9165454c..e448f8b8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_policy(SET CMP0017 NEW) # need include() with .cmake project(pip) set(pip_MAJOR 2) set(pip_MINOR 10) -set(pip_REVISION 0) +set(pip_REVISION 1) set(pip_SUFFIX ) set(pip_COMPANY SHS) set(pip_DOMAIN org.SHS) @@ -433,6 +433,9 @@ if (NOT CROSSTOOLS) # Test program if(PIP_UTILS) + #add_library(pip_plugin SHARED "test_plugin.h" "test_plugin.cpp") + #target_link_libraries(pip_plugin pip) + add_executable(pip_test "main.cpp") target_link_libraries(pip_test pip pip_cloud) if (LUA_FOUND) diff --git a/libs/main/core/piincludes.cpp b/libs/main/core/piincludes.cpp index 6b480a21..aa583426 100644 --- a/libs/main/core/piincludes.cpp +++ b/libs/main/core/piincludes.cpp @@ -79,6 +79,22 @@ PIString PIPVersion() { return ret; } + +void piqsort(void * base, size_t num, size_t size, int (*compar)(const void *, const void *)) { + qsort(base, num, size, compar); +} + + +void randomize() { + srand(PISystemTime::current(true).nanoseconds); +} + + +int randomi() { + return rand(); +} + + /*! \class PICout * \brief Class for formatted output similar std::cout * @@ -131,6 +147,9 @@ PIString PIPVersion() { * * packets extractor (\a PIPacketExtractor) * * binary log (\a PIBinaryLog) * * complex I/O point (\a PIConnection) + * * Run-time libraries + * * abstract (\a PILibrary) + * * plugin (\a PIPluginLoader) * * connection quality diagnotic (\a PIDiagnostics) * * command-line arguments parser (\a PICLI) * * math evaluator (\a PIEvaluator) @@ -247,19 +266,3 @@ int main(int argc, char * argv[]) { /*! \page using_advanced Advanced using * Sorry, creativity crysis xD */ - - -void piqsort(void * base, size_t num, size_t size, int (*compar)(const void *, const void *)) { - qsort(base, num, size, compar); -} - - -void randomize() { - srand(PISystemTime::current(true).nanoseconds); -} - - -int randomi() { - return rand(); -} - diff --git a/libs/main/core/pivariantsimple.h b/libs/main/core/pivariantsimple.h index c9b354be..017872c2 100644 --- a/libs/main/core/pivariantsimple.h +++ b/libs/main/core/pivariantsimple.h @@ -43,7 +43,7 @@ public: //static PIMap & registered() {static PIMap ret; return ret;} }; - +/* template class __VariantFunctions__: public __VariantFunctionsBase__ { public: @@ -51,10 +51,10 @@ public: PIString typeName() const final {static PIString ret(typeid(T).name()); return ret;} uint hash() const final {static uint ret = typeName().hash(); return ret;} }; - +*/ template -class __VariantFunctions__::value>::type>: public __VariantFunctionsBase__ { +class __VariantFunctions__/*::value>::type>*/: public __VariantFunctionsBase__ { public: __VariantFunctionsBase__ * instance() final {static __VariantFunctions__ ret; return &ret;} PIString typeName() const final {static PIString ret(typeid(T).name()); return ret;} diff --git a/libs/main/system/piplugin.cpp b/libs/main/system/piplugin.cpp index a711e7d7..e93f6b37 100644 --- a/libs/main/system/piplugin.cpp +++ b/libs/main/system/piplugin.cpp @@ -23,6 +23,140 @@ #include "pifile.h" #include "piincludes_p.h" +/*! \class PIPluginLoader + * \brief Plugin loader + * + * \section PIPluginLoader_sec0 Synopsis + * This class provides several macro to define plugin and %PIPluginLoader - class + * to load and check plugin. + * + * \section PIPluginLoader_sec1 Plugin side + * Plugin is a shared library that can be loaded in run-time. + * This is only PIP_PLUGIN macro necessary to define plugin. + * If you want to set and check some version, use macro + * \a PIP_PLUGIN_SET_USER_VERSION(version). Also you can + * define a function to merge static sections between application + * and plugin with macro \a PIP_PLUGIN_STATIC_SECTION_MERGE. Before + * merge, you should set pointers to that sections with macro + * \a PIP_PLUGIN_ADD_STATIC_SECTION(type, ptr). + * + * \section PIPluginLoader_sec2 Application side + * Application should use class \a PIPluginLoader to load + * plugin. Main function is \a load(PIString name). + * "name" is base name of library, %PIPluginLoader + * try to use sevaral names, , lib and + * "dll", "so" and "dylib" extensions, depends on system. + * For example: + * \code + * PIPluginLoader l; + * l.load("foo"); + * \endcode + * On Windows, try to open "foo", "libfoo", "foo.dll" and + * "libfoo.dll". + * If you using user version check, you should set it + * with macro \a PIP_PLUGIN_SET_USER_VERSION(version). + * When plugin is successfully loaded and checked, + * you can load your custom cymbols with function + * \a resolve(name), similar to PILibrary. + * \note You should use PIP_PLUGIN_EXPORT and "export "C"" + * with functions you want to use with \a resolve(name)! + * + * \section PIPluginLoader_sec3 Static sections + * Macro \a PIP_PLUGIN_STATIC_SECTION_MERGE defines function + * with arguments (int type, void * from, void * to), so you + * can leave this macro as declaration or define its body next: + * \code + * PIP_PLUGIN_STATIC_SECTION_MERGE() { + * switch (type) { + * ... + * } + * } + * \endcode + * \note If you using singletones, remember that cpp-defined + * singletones in shared libraries are single for whole application, + * including plugins! But if you use h-defined singletones or + * static linking, there are many objects in application and you + * should merge their content with this macro. + * + * Anyway, if this is macro \a PIP_PLUGIN_STATIC_SECTION_MERGE, it + * called once while loading plugin with "from" - plugin side + * and "to" - application side, and second (optionally) on method + * \a mergeStatic() with "from" - application side and "to" - plugin side. + * First direction allow you to copy all defined static content from plugin + * to application, and second - after loading all plugins (for example) + * to copy static content from application (and all plugins) to plugin. + * + * \section PIPluginLoader_sec4 Examples + * Simple plugin: + * \code + * #include + * + * PIP_PLUGIN + * + * extern "C" { + * PIP_PLUGIN_EXPORT void myFunc() { + * piCout << "Hello plugin!"; + * } + * } + * \endcode + * + * Application: + * \code + * #include + * int main() { + * PIPluginLoader pl; + * pl.load("your_lib"); + * if (pl.isLoaded()) { + * typedef void(*MyFunc)(); + * MyFunc f = (MyFunc)pl.resolve("myFunc"); + * if (f) f(); + * } + * return 0; + * } + * \endcode + * + * Complex plugin: + * \code + * #include + * + * PIStringList global_list; + * + * PIP_PLUGIN + * PIP_PLUGIN_SET_USER_VERSION("1.0.0") + * PIP_PLUGIN_ADD_STATIC_SECTION(1, &global_list) + * + * STATIC_INITIALIZER_BEGIN + * global_list << "plugin_init"; + * STATIC_INITIALIZER_END + * + * PIP_PLUGIN_STATIC_SECTION_MERGE { + * PIStringList * sfrom = (PIStringList*)from, * sto = (PIStringList*)to; + * *sto << *sfrom; + * sto->removeDuplicates(); + * } + * \endcode + * + * Application: + * \code + * #include + * + * PIStringList global_list; + * + * PIP_PLUGIN_SET_USER_VERSION("1.0.0"); + * PIP_PLUGIN_ADD_STATIC_SECTION(1, &global_list); + * + * int main() { + * global_list << "app"; + * PIPluginLoader pl; + * pl.load("your_lib"); + * pl.mergeStatic(); + * piCout << "list =" << global_list; + * return 0; + * } + * \endcode + * + */ + #define STR_WF(s) #s #define STR(s) STR_WF(s) @@ -84,7 +218,7 @@ PIPluginLoader::~PIPluginLoader() { bool PIPluginLoader::load(const PIString & name) { unload(); if (!lib.load(findLibrary(name))) return false; - piCout << "loading" << lib.path() << "..."; + //piCout << "loading" << lib.path() << "..."; func_loader_version = (FunctionLoaderVersion)lib.resolve(STR(__PIP_PLUGIN_LOADER_VERSION_FUNC__)); if (!func_loader_version) { piCout << "Load plugin \"" << name << "\" error: can`t find" << STR(__PIP_PLUGIN_LOADER_VERSION_FUNC__); @@ -142,6 +276,11 @@ void PIPluginLoader::unload() { } +bool PIPluginLoader::isLoaded() const { + return loaded; +} + + PIString PIPluginLoader::libPath() { return lib.path(); } diff --git a/libs/main/system/piplugin.h b/libs/main/system/piplugin.h index 99a1576c..df313b2c 100644 --- a/libs/main/system/piplugin.h +++ b/libs/main/system/piplugin.h @@ -19,7 +19,7 @@ You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ -# + #ifndef PIPLUGIN_H #define PIPLUGIN_H @@ -32,12 +32,15 @@ //! Declare plugin export functions, should be used before other PIP_PLUGIN_* macros +//! \relatedalso PIPluginLoader #define PIP_PLUGIN //! Set user version to check it while loading -#define PIP_PLUGIN_SET_USER_VERSION(v) +//! \relatedalso PIPluginLoader +#define PIP_PLUGIN_SET_USER_VERSION(version) //! Add pointer to future merge with plugin. Type is integer +//! \relatedalso PIPluginLoader #define PIP_PLUGIN_ADD_STATIC_SECTION(type, ptr) //! Declare function to merge static sections. This is functions @@ -47,8 +50,13 @@ //! (optionally) on \a PIPluginLoader::mergeStatic() method with //! "from" - application scope, "to" - plugin scope. So with macro //! you can merge application and plugin static data. +//! \relatedalso PIPluginLoader #define PIP_PLUGIN_STATIC_SECTION_MERGE +//! Mark method to export +//! \relatedalso PIPluginLoader +#define PIP_PLUGIN_EXPORT + #else @@ -136,6 +144,9 @@ public: //! Unload plugin and free library void unload(); + //! Returns if plugin is successfully loaded + bool isLoaded() const; + //! Returns loaded plugin library path PIString libPath(); From 0004d2696f1b8723008c34a13848232fb802e24b Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Wed, 7 Oct 2020 23:29:18 +0300 Subject: [PATCH 27/98] PIString::fromAscii() new overload --- libs/main/core/pistring.cpp | 11 +++++++---- libs/main/core/pistring.h | 3 +++ libs/main/system/piplugin.cpp | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/libs/main/core/pistring.cpp b/libs/main/core/pistring.cpp index c5e5c3e5..578d949a 100644 --- a/libs/main/core/pistring.cpp +++ b/libs/main/core/pistring.cpp @@ -333,11 +333,14 @@ PIString PIString::fromAscii(const char * s) { ret.push_back(PIChar(s[l])); ++l; } - /*while (s[l] != '\0') ++l; + return ret; +} + + +PIString PIString::fromAscii(const char * s, int len) { PIString ret; - ret.resize(l); - for (int i = 0; i < l; ++i) - ret[i] = s[i];*/ + for (int l = 0; l < len; ++l) + ret.push_back(PIChar(s[l])); return ret; } diff --git a/libs/main/core/pistring.h b/libs/main/core/pistring.h index 75e06b46..455ad87d 100644 --- a/libs/main/core/pistring.h +++ b/libs/main/core/pistring.h @@ -722,6 +722,9 @@ public: //! \brief Return string constructed from ASCII static PIString fromAscii(const char * s); + //! \brief Return string constructed from "len" chars ASCII + static PIString fromAscii(const char * s, int len); + //! \brief Return string constructed from "c" codepage static PIString fromCodepage(const char * s, const char * c); diff --git a/libs/main/system/piplugin.cpp b/libs/main/system/piplugin.cpp index e93f6b37..3d6686c3 100644 --- a/libs/main/system/piplugin.cpp +++ b/libs/main/system/piplugin.cpp @@ -56,7 +56,7 @@ * If you using user version check, you should set it * with macro \a PIP_PLUGIN_SET_USER_VERSION(version). * When plugin is successfully loaded and checked, - * you can load your custom cymbols with function + * you can load your custom symbols with function * \a resolve(name), similar to PILibrary. * \note You should use PIP_PLUGIN_EXPORT and "export "C"" * with functions you want to use with \a resolve(name)! From 4c0fe72d71a2f785e1a044e2285c4598bc1888d4 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Wed, 7 Oct 2020 23:43:20 +0300 Subject: [PATCH 28/98] PICrypt first init fail patch --- libs/crypt/picrypt.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libs/crypt/picrypt.cpp b/libs/crypt/picrypt.cpp index 742e6147..a129db7b 100644 --- a/libs/crypt/picrypt.cpp +++ b/libs/crypt/picrypt.cpp @@ -409,6 +409,8 @@ bool PICrypt::init() { if (inited) return true; //piCout << "[PICrypt]" << "init ..."; inited = sodium_init(); + if (!inited) + inited = sodium_init(); //piCout << "[PICrypt]" << "init" << inited; return inited; #else From 16cfdc709b12eb9e1d1476db3bef852a81a680d4 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Thu, 8 Oct 2020 22:29:47 +0300 Subject: [PATCH 29/98] new PIChunkStream::extract() method --- libs/main/core/pichunkstream.cpp | 9 +++++++++ libs/main/core/pichunkstream.h | 3 +++ 2 files changed, 12 insertions(+) diff --git a/libs/main/core/pichunkstream.cpp b/libs/main/core/pichunkstream.cpp index c80455d3..7920f1b4 100644 --- a/libs/main/core/pichunkstream.cpp +++ b/libs/main/core/pichunkstream.cpp @@ -115,7 +115,16 @@ void PIChunkStream::readAll() { PIChunkStream::~PIChunkStream() { +} + +bool PIChunkStream::extract(PIByteArray & data) { + if (data.size_s() < 4) return false; + data >> tmp_data; + if (tmp_data.size_s() < 4) return false; + data_ = &tmp_data; + _init(); + return true; } diff --git a/libs/main/core/pichunkstream.h b/libs/main/core/pichunkstream.h index 89dad97d..d771143b 100644 --- a/libs/main/core/pichunkstream.h +++ b/libs/main/core/pichunkstream.h @@ -67,6 +67,9 @@ public: //! Add data to this chunk strean with ID "id" and value "data" template PIChunkStream & add(int id, const T & data) {*this << ChunkConst(id, data); return *this;} + //! Extract %PIByteArray from "data" and set it current stream. Returns if has data to read. + bool extract(PIByteArray & data); + void setSource(const PIByteArray & data); void setSource(PIByteArray * data); From 2e3204806f1ebe6d04f684f3c465d76c6b303c80 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Thu, 8 Oct 2020 22:42:42 +0300 Subject: [PATCH 30/98] pichunkstream.cpp documentation --- libs/main/core/pichunkstream.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/libs/main/core/pichunkstream.cpp b/libs/main/core/pichunkstream.cpp index 7920f1b4..ba6f9e4d 100644 --- a/libs/main/core/pichunkstream.cpp +++ b/libs/main/core/pichunkstream.cpp @@ -41,13 +41,22 @@ * but you should definitely know type of this value. You can read from byte array * while \a atEnd() if false. * - * \section PIChunkStream_ex0 Example - * Prepare your structs to work with %PIChunkStream + * \section PIChunkStream_sec2 Examples + * + * Using simple operator and cascade serialization: + * + * Prepare your structs to work with %PIChunkStream: * \snippet pichunkstream.cpp struct - * Writing to %PIChunkStream + * Old-style writing to %PIChunkStream: * \snippet pichunkstream.cpp write - * Reading from %PIChunkStream + * Fastest reading from %PIChunkStream: * \snippet pichunkstream.cpp read + * + * And next code show how to serialize your struct with %PIChunkStream: + * \snippet pichunkstream.cpp write_new + * + * ... and deserialize: + * \snippet pichunkstream.cpp read_new */ From 51775a5ee6e06e9aa8c25c7477ea7d938250cc62 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Thu, 8 Oct 2020 22:47:32 +0300 Subject: [PATCH 31/98] next easing of PIChunkStream::extract() --- doc/examples/pichunkstream.cpp | 18 ++++++++++++++++++ libs/main/core/pichunkstream.cpp | 4 +++- libs/main/core/pichunkstream.h | 6 ++++-- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/doc/examples/pichunkstream.cpp b/doc/examples/pichunkstream.cpp index ec2048eb..dc6003ce 100644 --- a/doc/examples/pichunkstream.cpp +++ b/doc/examples/pichunkstream.cpp @@ -47,3 +47,21 @@ while (!cs2.atEnd()) { } piCout << i << str << f << s.i << s.f << s.s; //! [read] + +//! [write_new] +PIByteArray & operator <<(PIByteArray & s, const S & value) { + PIChunkStream cs; + cs.add(1, value.i).add(2, value.f).add(3, value.s); + s << cs.data(); + return s; +} +//! [write_new] +//! [read_new] +PIByteArray & operator >>(PIByteArray & s, S & value) { + PIChunkStream cs; + if (!cs.extract(s)) return s; + cs.readAll(); + cs.get(1, value.i).get(2, value.f).get(3, value.s); + return b; +} +//! [read_new] diff --git a/libs/main/core/pichunkstream.cpp b/libs/main/core/pichunkstream.cpp index ba6f9e4d..b5525aa3 100644 --- a/libs/main/core/pichunkstream.cpp +++ b/libs/main/core/pichunkstream.cpp @@ -127,12 +127,14 @@ PIChunkStream::~PIChunkStream() { } -bool PIChunkStream::extract(PIByteArray & data) { +bool PIChunkStream::extract(PIByteArray & data, bool read_all) { if (data.size_s() < 4) return false; data >> tmp_data; if (tmp_data.size_s() < 4) return false; data_ = &tmp_data; _init(); + if (read_all) + readAll(); return true; } diff --git a/libs/main/core/pichunkstream.h b/libs/main/core/pichunkstream.h index d771143b..256c620d 100644 --- a/libs/main/core/pichunkstream.h +++ b/libs/main/core/pichunkstream.h @@ -67,8 +67,10 @@ public: //! Add data to this chunk strean with ID "id" and value "data" template PIChunkStream & add(int id, const T & data) {*this << ChunkConst(id, data); return *this;} - //! Extract %PIByteArray from "data" and set it current stream. Returns if has data to read. - bool extract(PIByteArray & data); + //! Extract %PIByteArray from "data" and set it current stream. + //! If "read_all" then call \a readAll() after extract. + //! Returns if has data to read. + bool extract(PIByteArray & data, bool read_all = false); void setSource(const PIByteArray & data); void setSource(PIByteArray * data); From 8ef4c9ca2347653cac2ea0e8bc718127c66bb4e1 Mon Sep 17 00:00:00 2001 From: Andrey Date: Fri, 16 Oct 2020 12:28:57 +0300 Subject: [PATCH 32/98] fix PIByteArray load/store operators for containers --- libs/main/console/piscreentypes.h | 4 +- libs/main/core/pibytearray.h | 48 +++++----- libs/main/core/pivariantsimple.h | 4 +- main.cpp | 144 ++++++++++++++---------------- tests/concurrent/testutil.h | 2 +- 5 files changed, 96 insertions(+), 106 deletions(-) diff --git a/libs/main/console/piscreentypes.h b/libs/main/console/piscreentypes.h index 05335ed1..cce0e6fd 100644 --- a/libs/main/console/piscreentypes.h +++ b/libs/main/console/piscreentypes.h @@ -140,8 +140,10 @@ namespace PIScreenTypes { inline PIByteArray & operator <<(PIByteArray & s, const PIScreenTypes::Cell & v) {s << v.format.raw_format << v.symbol; return s;} - inline PIByteArray & operator >>(PIByteArray & s, PIScreenTypes::Cell & v) {s >> v.format.raw_format >> v.symbol; return s;} +inline PIByteArray & operator <<(PIByteArray & s, const PIScreenTypes::TileEvent & v) {s << v.type << v.data; return s;} +inline PIByteArray & operator >>(PIByteArray & s, PIScreenTypes::TileEvent & v) {s >> v.type >> v.data; return s;} + #endif // PISCREENTYPES_H diff --git a/libs/main/core/pibytearray.h b/libs/main/core/pibytearray.h index ad00a8a1..dfeeab5d 100644 --- a/libs/main/core/pibytearray.h +++ b/libs/main/core/pibytearray.h @@ -197,8 +197,8 @@ inline PIByteArray & operator <<(PIByteArray & s, const PIByteArray::RawData & v return s; } -//! \relatesalso PIByteArray \brief Store operator for PIVector of any trivial copyable type -template::value, int>::type = 0> +//! \relatesalso PIByteArray \brief Store operator for PIVector of any fundamental type +template::value, int>::type = 0> inline PIByteArray & operator <<(PIByteArray & s, const PIVector & v) { s << int(v.size_s()); int os = s.size_s(); @@ -209,8 +209,8 @@ inline PIByteArray & operator <<(PIByteArray & s, const PIVector & v) { return s; } -//! \relatesalso PIByteArray \brief Store operator for PIDeque of any trivial copyable type -template::value, int>::type = 0> +//! \relatesalso PIByteArray \brief Store operator for PIDeque of any fundamental type +template::value, int>::type = 0> inline PIByteArray & operator <<(PIByteArray & s, const PIDeque & v) { s << int(v.size_s()); int os = s.size_s(); @@ -221,8 +221,8 @@ inline PIByteArray & operator <<(PIByteArray & s, const PIDeque & v) { return s; } -//! \relatesalso PIByteArray \brief Store operator for PIVector2D of any trivial copyable type -template::value, int>::type = 0> +//! \relatesalso PIByteArray \brief Store operator for PIVector2D of any fundamental type +template::value, int>::type = 0> inline PIByteArray & operator <<(PIByteArray & s, const PIVector2D & v) { s << int(v.rows()) << int(v.cols()); int os = s.size_s(); @@ -277,8 +277,8 @@ inline PIByteArray & operator >>(PIByteArray & s, PIByteArray::RawData v) { return s; } -//! \relatesalso PIByteArray \brief Restore operator for PIVector of any trivial copyable type -template::value, int>::type = 0> +//! \relatesalso PIByteArray \brief Restore operator for PIVector of any fundamental type +template::value, int>::type = 0> inline PIByteArray & operator >>(PIByteArray & s, PIVector & v) { assert(s.size_s() >= 4); int sz; s >> sz; @@ -290,8 +290,8 @@ inline PIByteArray & operator >>(PIByteArray & s, PIVector & v) { return s; } -//! \relatesalso PIByteArray \brief Restore operator for PIDeque of any trivial copyable type -template::value, int>::type = 0> +//! \relatesalso PIByteArray \brief Restore operator for PIDeque of any fundamental type +template::value, int>::type = 0> inline PIByteArray & operator >>(PIByteArray & s, PIDeque & v) { assert(s.size_s() >= 4); int sz; s >> sz; @@ -303,8 +303,8 @@ inline PIByteArray & operator >>(PIByteArray & s, PIDeque & v) { return s; } -//! \relatesalso PIByteArray \brief Restore operator for PIVector2D of any trivial copyable type -template::value, int>::type = 0> +//! \relatesalso PIByteArray \brief Restore operator for PIVector2D of any fundamental type +template::value, int>::type = 0> inline PIByteArray & operator >>(PIByteArray & s, PIVector2D & v) { assert(s.size_s() >= 8); int r, c; s >> r >> c; @@ -330,24 +330,24 @@ inline PIByteArray & operator >>(PIByteArray & s, PIPair & v) {s > // store operators for complex types -//! \relatesalso PIByteArray \brief Store operator for PIVector of any non-trivial copyable type -template::value, int>::type = 0> +//! \relatesalso PIByteArray \brief Store operator for PIVector of any compound type +template::value, int>::type = 0> inline PIByteArray & operator <<(PIByteArray & s, const PIVector & v) { s << int(v.size_s()); for (uint i = 0; i < v.size(); ++i) s << v[i]; return s; } -//! \relatesalso PIByteArray \brief Store operator for PIDeque of any non-trivial copyable type -template::value, int>::type = 0> +//! \relatesalso PIByteArray \brief Store operator for PIDeque of any compound type +template::value, int>::type = 0> inline PIByteArray & operator <<(PIByteArray & s, const PIDeque & v) { s << int(v.size_s()); for (uint i = 0; i < v.size(); ++i) s << v[i]; return s; } -//! \relatesalso PIByteArray \brief Store operator for PIVector2D of any non-trivial copyable type -template::value, int>::type = 0> +//! \relatesalso PIByteArray \brief Store operator for PIVector2D of any compound type +template::value, int>::type = 0> inline PIByteArray & operator <<(PIByteArray & s, const PIVector2D & v) { s << int(v.rows()) << int(v.cols()) << v.toPlainVector(); return s; @@ -359,8 +359,8 @@ inline PIByteArray & operator <<(PIByteArray & s, const PIVector2D & v) { // restore operators for complex types -//! \relatesalso PIByteArray \brief Restore operator for PIVector of any non-trivial copyable type -template::value, int>::type = 0> +//! \relatesalso PIByteArray \brief Restore operator for PIVector of any compound type +template::value, int>::type = 0> inline PIByteArray & operator >>(PIByteArray & s, PIVector & v) { assert(s.size_s() >= 4); int sz; s >> sz; @@ -369,8 +369,8 @@ inline PIByteArray & operator >>(PIByteArray & s, PIVector & v) { return s; } -//! \relatesalso PIByteArray \brief Restore operator for PIDeque of any non-trivial copyable type -template::value, int>::type = 0> +//! \relatesalso PIByteArray \brief Restore operator for PIDeque of any compound type +template::value, int>::type = 0> inline PIByteArray & operator >>(PIByteArray & s, PIDeque & v) { assert(s.size_s() >= 4); int sz; s >> sz; @@ -379,8 +379,8 @@ inline PIByteArray & operator >>(PIByteArray & s, PIDeque & v) { return s; } -//! \relatesalso PIByteArray \brief Restore operator for PIVector2D of any non-trivial copyable type -template::value, int>::type = 0> +//! \relatesalso PIByteArray \brief Restore operator for PIVector2D of any compound type +template::value, int>::type = 0> inline PIByteArray & operator >>(PIByteArray & s, PIVector2D & v) { assert(s.size_s() >= 8); int r,c; diff --git a/libs/main/core/pivariantsimple.h b/libs/main/core/pivariantsimple.h index 017872c2..63130902 100644 --- a/libs/main/core/pivariantsimple.h +++ b/libs/main/core/pivariantsimple.h @@ -159,10 +159,10 @@ private: /* #define REGISTER_PIVARIANTSIMPLE_STREAM(Type) \ - STATIC_INITIALIZER_BEGIN() \ + STATIC_INITIALIZER_BEGIN \ __VariantFunctionsBase__ * f = __VariantFunctions__().instance(); \ __VariantFunctionsBase__::registered()[f->hash()] = f; \ - STATIC_INITIALIZER_END() + STATIC_INITIALIZER_END */ diff --git a/main.cpp b/main.cpp index 732d268d..96806c39 100644 --- a/main.cpp +++ b/main.cpp @@ -2,85 +2,22 @@ #include "pivariantsimple.h" -template -struct __VariantTypeInfo__ { - typedef T PureType; - typedef const T ConstPureType; - typedef T * PointerType; - typedef const T * ConstPointerType; - typedef T & ReferenceType; - typedef const T & ConstReferenceType; -}; - -#define __TYPEINFO_SINGLE(PT, T) \ - template<> struct __PIVariantTypeInfo__ { \ - typedef PT PureType; \ - typedef const PT ConstPureType; \ - typedef PT * PointerType; \ - typedef const PT * ConstPointerType; \ - typedef PT & ReferenceType; \ - typedef const PT & ConstReferenceType; \ - }; - -#define REGISTER_VARIANT_TYPEINFO(T) \ - __TYPEINFO_SINGLE(T, T &) \ - __TYPEINFO_SINGLE(T, const T) \ - __TYPEINFO_SINGLE(T, const T &) - - - -struct SwitchChannel { - SwitchChannel(bool on_ = true, float dur_ = 10.f, int m_count = 0, short unrely = -1) { - on = on_ ? 1 : 0; - duration = dur_; - max_count = m_count; - overload[0] = overload[1] = false; - unreliability = unrely; - } - uchar on; - short unreliability; - float duration; - int max_count; - bool overload[2]; -}; -/* -inline PIByteArray & operator <<(PIByteArray & ba, const SwitchChannel & v) { - PIChunkStream cs; - cs << cs.chunk(1, v.on) - << cs.chunk(2, v.duration) - << cs.chunk(3, v.max_count) - << cs.chunk(4, v.unreliability); - ba << cs.data(); - return ba; -} -inline PIByteArray & operator >>(PIByteArray & ba, SwitchChannel & v) { - PIByteArray src; ba >> src; PIChunkStream cs(src); - while (!cs.atEnd()) { - switch (cs.read()) { - case 1: cs.get(v.on); break; - case 2: cs.get(v.duration); break; - case 3: cs.get(v.max_count); break; - case 4: cs.get(v.unreliability); break; - } - } - return ba; -}*/ -inline PICout operator <<(PICout c, const SwitchChannel & v) { - c << v.on << v.duration << v.max_count << v.unreliability; - return c; -} - - - -int Acnt = 0; - +#pragma pack(push, 1) struct MM { int x; + int x2; double y; - char c; - PIPointd h; + char c[16]; + int e2; + int e; + //PIPointd h; }; +#pragma pack(pop) +inline PIByteArray & operator <<(PIByteArray & ba, const MM & v) {piCout << "xep1"; ba << v.x << v.y << v.c; return ba;} +inline PIByteArray & operator >>(PIByteArray & ba, MM & v) {piCout << "xep2"; ba >> v.x >> v.y >> v.c; return ba;} + +int Acnt = 0; class A { public: @@ -102,8 +39,59 @@ inline PIByteArray & operator <<(PIByteArray & ba, const A & v) {ba << v.i << v. inline PIByteArray & operator >>(PIByteArray & ba, A & v) {ba >> v.i >> v.m; return ba;} -int main() { - A a; - PIByteArray ba; - ba >> a; +/* +class HelperBase { +public: + virtual void bsl(PIByteArray & ba, void * o) = 0; +}; + + +template +class Helper : public HelperBase { +public: +void bsl(PIByteArray & ba, void * o) override { + ba << (*(X*)o); + piCout << ba.size(); + ba >> (*(X*)o); + piCout << ba.size(); } +}; + + +class TypeHelper { +public: + HelperBase * h; + template inline void regtype() { + h = new Helper(); + } +}; +*/ + + +int main() { + PIByteArray ba; +// TypeHelper th; +// th.regtype(); + MM m; + PIVector vm; + vm << m;; + ba << m; + piCout << ba.toHex(); + ba.clear(); + piCout << "==="; + ba << vm; + piCout << ba.toHex(); +// th.h->bsl(ba, &m); +// th.regtype(); +// CAN_Raw c; +// th.h->bsl(ba, &c); +// PIVariantSimple v; +// v.setValue(m); +// ba = v.save(); +// piCout << ba.toHex(); +// PIVariantSimple v2; +// v2.load(ba); +// piCout << v2.save().toHex(); + return 0; +} + diff --git a/tests/concurrent/testutil.h b/tests/concurrent/testutil.h index 7c3c15c7..2966862f 100644 --- a/tests/concurrent/testutil.h +++ b/tests/concurrent/testutil.h @@ -8,7 +8,7 @@ * Minimum wait thread start, switch context or another interthread communication action time. Increase it if tests * write "Start thread timeout reach!" message. You can reduce it if you want increase test performance. */ -const int WAIT_THREAD_TIME_MS = 40; +const int WAIT_THREAD_TIME_MS = 400; const int THREAD_COUNT = 5; From 43fb497b32ec39754ada668ac3724433168dccab Mon Sep 17 00:00:00 2001 From: Andrey Date: Fri, 16 Oct 2020 12:30:06 +0300 Subject: [PATCH 33/98] pip version --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e448f8b8..1e0391a5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,9 +2,9 @@ cmake_minimum_required(VERSION 3.0) cmake_policy(SET CMP0017 NEW) # need include() with .cmake project(pip) set(pip_MAJOR 2) -set(pip_MINOR 10) -set(pip_REVISION 1) -set(pip_SUFFIX ) +set(pip_MINOR 11) +set(pip_REVISION 0) +set(pip_SUFFIX beta) set(pip_COMPANY SHS) set(pip_DOMAIN org.SHS) From 80c6809e428f8c97611821e69afa085e9bd6f535 Mon Sep 17 00:00:00 2001 From: Andrey Date: Fri, 16 Oct 2020 12:43:46 +0300 Subject: [PATCH 34/98] test fix --- main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main.cpp b/main.cpp index 96806c39..0496406a 100644 --- a/main.cpp +++ b/main.cpp @@ -73,8 +73,9 @@ int main() { // TypeHelper th; // th.regtype(); MM m; + memset(&m, 0xAC, sizeof(MM)); PIVector vm; - vm << m;; + vm << m; ba << m; piCout << ba.toHex(); ba.clear(); From d0ef71c9330e64642fdda535f0d3dfb1396aed0b Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Sat, 17 Oct 2020 21:16:26 +0300 Subject: [PATCH 35/98] version 1.12.0_beta. Very important fix in PIByteArray! Now containers stream operators for trivial types works correct --- CMakeLists.txt | 2 +- libs/main/core/pibytearray.h | 116 +++++++++++++++++++++++++++++------ main.cpp | 72 ++++++---------------- 3 files changed, 116 insertions(+), 74 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e0391a5..6c4173c9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0) cmake_policy(SET CMP0017 NEW) # need include() with .cmake project(pip) set(pip_MAJOR 2) -set(pip_MINOR 11) +set(pip_MINOR 12) set(pip_REVISION 0) set(pip_SUFFIX beta) set(pip_COMPANY SHS) diff --git a/libs/main/core/pibytearray.h b/libs/main/core/pibytearray.h index dfeeab5d..687a4d76 100644 --- a/libs/main/core/pibytearray.h +++ b/libs/main/core/pibytearray.h @@ -119,6 +119,16 @@ public: static PIByteArray fromHex(PIString str); static PIByteArray fromBase64(const PIByteArray & base64); static PIByteArray fromBase64(const PIString & base64); + + + class StreamRef { + public: + StreamRef(PIByteArray & s): ba(s) {} + operator PIByteArray&() {return ba;} + private: + PIByteArray & ba; + }; + }; //! \relatesalso PIByteArray \brief Byte arrays compare operator @@ -177,7 +187,7 @@ inline PIByteArray & operator <<(PIByteArray & s, const uchar v) {s.push_back(v) //! \relatesalso PIByteArray \brief Store operator for any trivial copyable type template::value, int>::type = 0> -inline PIByteArray & operator <<(PIByteArray & s, const T & v) { +inline PIByteArray::StreamRef operator <<(PIByteArray & s, const T & v) { int os = s.size_s(); s.enlarge(sizeof(v)); memcpy(s.data(os), &v, sizeof(v)); @@ -197,8 +207,10 @@ inline PIByteArray & operator <<(PIByteArray & s, const PIByteArray::RawData & v return s; } -//! \relatesalso PIByteArray \brief Store operator for PIVector of any fundamental type -template::value, int>::type = 0> +//! \relatesalso PIByteArray \brief Store operator for PIVector of any trivial copyable type +template::value, int>::type = 0, + typename std::enable_if< std::is_same() << std::declval()), PIByteArray::StreamRef>::value, int>::type = 0> inline PIByteArray & operator <<(PIByteArray & s, const PIVector & v) { s << int(v.size_s()); int os = s.size_s(); @@ -208,9 +220,19 @@ inline PIByteArray & operator <<(PIByteArray & s, const PIVector & v) { } return s; } +template::value, int>::type = 0, + typename std::enable_if() << std::declval()), PIByteArray::StreamRef>::value, int>::type = 0> +inline PIByteArray & operator <<(PIByteArray & s, const PIVector & v) { + s << int(v.size_s()); + for (uint i = 0; i < v.size(); ++i) s << v[i]; + return s; +} -//! \relatesalso PIByteArray \brief Store operator for PIDeque of any fundamental type -template::value, int>::type = 0> +//! \relatesalso PIByteArray \brief Store operator for PIDeque of any trivial copyable type +template::value, int>::type = 0, + typename std::enable_if< std::is_same() << std::declval()), PIByteArray::StreamRef>::value, int>::type = 0> inline PIByteArray & operator <<(PIByteArray & s, const PIDeque & v) { s << int(v.size_s()); int os = s.size_s(); @@ -220,9 +242,19 @@ inline PIByteArray & operator <<(PIByteArray & s, const PIDeque & v) { } return s; } +template::value, int>::type = 0, + typename std::enable_if() << std::declval()), PIByteArray::StreamRef>::value, int>::type = 0> +inline PIByteArray & operator <<(PIByteArray & s, const PIDeque & v) { + s << int(v.size_s()); + for (uint i = 0; i < v.size(); ++i) s << v[i]; + return s; +} -//! \relatesalso PIByteArray \brief Store operator for PIVector2D of any fundamental type -template::value, int>::type = 0> +//! \relatesalso PIByteArray \brief Store operator for PIVector2D of any trivial copyable type +template::value, int>::type = 0, + typename std::enable_if< std::is_same() << std::declval()), PIByteArray::StreamRef>::value, int>::type = 0> inline PIByteArray & operator <<(PIByteArray & s, const PIVector2D & v) { s << int(v.rows()) << int(v.cols()); int os = s.size_s(); @@ -232,6 +264,13 @@ inline PIByteArray & operator <<(PIByteArray & s, const PIVector2D & v) { } return s; } +template::value, int>::type = 0, + typename std::enable_if() << std::declval()), PIByteArray::StreamRef>::value, int>::type = 0> +inline PIByteArray & operator <<(PIByteArray & s, const PIVector2D & v) { + s << int(v.rows()) << int(v.cols()) << v.toPlainVector(); + return s; +} //! \relatesalso PIByteArray \brief Store operator inline PIByteArray & operator <<(PIByteArray & s, const PIBitArray & v) {s << v.size_ << v.data_; return s;} @@ -257,7 +296,7 @@ inline PIByteArray & operator >>(PIByteArray & s, uchar & v) {assert(s.size() >= //! \relatesalso PIByteArray \brief Restore operator for any trivial copyable type template::value, int>::type = 0> -inline PIByteArray & operator >>(PIByteArray & s, T & v) { +inline PIByteArray::StreamRef operator >>(PIByteArray & s, T & v) { assert(s.size() >= sizeof(v)); memcpy((void*)(&v), s.data(), sizeof(v)); s.remove(0, sizeof(v)); @@ -277,8 +316,10 @@ inline PIByteArray & operator >>(PIByteArray & s, PIByteArray::RawData v) { return s; } -//! \relatesalso PIByteArray \brief Restore operator for PIVector of any fundamental type -template::value, int>::type = 0> +//! \relatesalso PIByteArray \brief Restore operator for PIVector of any trivial copyable type +template::value, int>::type = 0, + typename std::enable_if< std::is_same() << std::declval()), PIByteArray::StreamRef>::value, int>::type = 0> inline PIByteArray & operator >>(PIByteArray & s, PIVector & v) { assert(s.size_s() >= 4); int sz; s >> sz; @@ -289,9 +330,21 @@ inline PIByteArray & operator >>(PIByteArray & s, PIVector & v) { } return s; } +template::value, int>::type = 0, + typename std::enable_if() << std::declval()), PIByteArray::StreamRef>::value, int>::type = 0> +inline PIByteArray & operator >>(PIByteArray & s, PIVector & v) { + assert(s.size_s() >= 4); + int sz; s >> sz; + v.resize(sz); + for (int i = 0; i < sz; ++i) s >> v[i]; + return s; +} -//! \relatesalso PIByteArray \brief Restore operator for PIDeque of any fundamental type -template::value, int>::type = 0> +//! \relatesalso PIByteArray \brief Restore operator for PIDeque of any trivial copyable type +template::value, int>::type = 0, + typename std::enable_if< std::is_same() << std::declval()), PIByteArray::StreamRef>::value, int>::type = 0> inline PIByteArray & operator >>(PIByteArray & s, PIDeque & v) { assert(s.size_s() >= 4); int sz; s >> sz; @@ -302,9 +355,21 @@ inline PIByteArray & operator >>(PIByteArray & s, PIDeque & v) { } return s; } +template::value, int>::type = 0, + typename std::enable_if() << std::declval()), PIByteArray::StreamRef>::value, int>::type = 0> +inline PIByteArray & operator >>(PIByteArray & s, PIDeque & v) { + assert(s.size_s() >= 4); + int sz; s >> sz; + v.resize(sz); + for (int i = 0; i < sz; ++i) s >> v[i]; + return s; +} -//! \relatesalso PIByteArray \brief Restore operator for PIVector2D of any fundamental type -template::value, int>::type = 0> +//! \relatesalso PIByteArray \brief Restore operator for PIVector2D of any trivial copyable type +template::value, int>::type = 0, + typename std::enable_if< std::is_same() << std::declval()), PIByteArray::StreamRef>::value, int>::type = 0> inline PIByteArray & operator >>(PIByteArray & s, PIVector2D & v) { assert(s.size_s() >= 8); int r, c; s >> r >> c; @@ -316,6 +381,17 @@ inline PIByteArray & operator >>(PIByteArray & s, PIVector2D & v) { } return s; } +template::value, int>::type = 0, + typename std::enable_if() << std::declval()), PIByteArray::StreamRef>::value, int>::type = 0> +inline PIByteArray & operator >>(PIByteArray & s, PIVector2D & v) { + assert(s.size_s() >= 8); + int r,c; + PIVector tmp; + s >> r >> c >> tmp; + v = PIVector2D(r, c, tmp); + return s; +} //! \relatesalso PIByteArray \brief Restore operator inline PIByteArray & operator >>(PIByteArray & s, PIBitArray & v) {assert(s.size_s() >= 8); s >> v.size_ >> v.data_; return s;} @@ -331,7 +407,7 @@ inline PIByteArray & operator >>(PIByteArray & s, PIPair & v) {s > //! \relatesalso PIByteArray \brief Store operator for PIVector of any compound type -template::value, int>::type = 0> +template::value, int>::type = 0> inline PIByteArray & operator <<(PIByteArray & s, const PIVector & v) { s << int(v.size_s()); for (uint i = 0; i < v.size(); ++i) s << v[i]; @@ -339,7 +415,7 @@ inline PIByteArray & operator <<(PIByteArray & s, const PIVector & v) { } //! \relatesalso PIByteArray \brief Store operator for PIDeque of any compound type -template::value, int>::type = 0> +template::value, int>::type = 0> inline PIByteArray & operator <<(PIByteArray & s, const PIDeque & v) { s << int(v.size_s()); for (uint i = 0; i < v.size(); ++i) s << v[i]; @@ -347,7 +423,7 @@ inline PIByteArray & operator <<(PIByteArray & s, const PIDeque & v) { } //! \relatesalso PIByteArray \brief Store operator for PIVector2D of any compound type -template::value, int>::type = 0> +template::value, int>::type = 0> inline PIByteArray & operator <<(PIByteArray & s, const PIVector2D & v) { s << int(v.rows()) << int(v.cols()) << v.toPlainVector(); return s; @@ -360,7 +436,7 @@ inline PIByteArray & operator <<(PIByteArray & s, const PIVector2D & v) { //! \relatesalso PIByteArray \brief Restore operator for PIVector of any compound type -template::value, int>::type = 0> +template::value, int>::type = 0> inline PIByteArray & operator >>(PIByteArray & s, PIVector & v) { assert(s.size_s() >= 4); int sz; s >> sz; @@ -370,7 +446,7 @@ inline PIByteArray & operator >>(PIByteArray & s, PIVector & v) { } //! \relatesalso PIByteArray \brief Restore operator for PIDeque of any compound type -template::value, int>::type = 0> +template::value, int>::type = 0> inline PIByteArray & operator >>(PIByteArray & s, PIDeque & v) { assert(s.size_s() >= 4); int sz; s >> sz; @@ -380,7 +456,7 @@ inline PIByteArray & operator >>(PIByteArray & s, PIDeque & v) { } //! \relatesalso PIByteArray \brief Restore operator for PIVector2D of any compound type -template::value, int>::type = 0> +template::value, int>::type = 0> inline PIByteArray & operator >>(PIByteArray & s, PIVector2D & v) { assert(s.size_s() >= 8); int r,c; diff --git a/main.cpp b/main.cpp index 0496406a..cc9da2ef 100644 --- a/main.cpp +++ b/main.cpp @@ -1,7 +1,6 @@ #include "pip.h" #include "pivariantsimple.h" - #pragma pack(push, 1) struct MM { int x; @@ -14,9 +13,6 @@ struct MM { }; #pragma pack(pop) -inline PIByteArray & operator <<(PIByteArray & ba, const MM & v) {piCout << "xep1"; ba << v.x << v.y << v.c; return ba;} -inline PIByteArray & operator >>(PIByteArray & ba, MM & v) {piCout << "xep2"; ba >> v.x >> v.y >> v.c; return ba;} - int Acnt = 0; class A { @@ -29,6 +25,7 @@ public: 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;} + bool operator ==(const A & a) {return true;} PIString i; bool moved; MM m; @@ -38,61 +35,30 @@ public: inline PIByteArray & operator <<(PIByteArray & ba, const A & v) {ba << v.i << v.m; return ba;} inline PIByteArray & operator >>(PIByteArray & ba, A & v) {ba >> v.i >> v.m; return ba;} - -/* -class HelperBase { -public: - virtual void bsl(PIByteArray & ba, void * o) = 0; -}; - - -template -class Helper : public HelperBase { -public: -void bsl(PIByteArray & ba, void * o) override { - ba << (*(X*)o); - piCout << ba.size(); - ba >> (*(X*)o); - piCout << ba.size(); -} -}; - - -class TypeHelper { -public: - HelperBase * h; - template inline void regtype() { - h = new Helper(); - } -}; -*/ +inline PIByteArray & operator <<(PIByteArray & ba, const MM & v) {piCout << "<<"; ba << v.x << v.y << v.c; return ba;} +inline PIByteArray & operator >>(PIByteArray & ba, MM & v) {piCout << ">>"; ba >> v.x >> v.y >> v.c; return ba;} int main() { PIByteArray ba; -// TypeHelper th; -// th.regtype(); MM m; - memset(&m, 0xAC, sizeof(MM)); - PIVector vm; - vm << m; + m.e = 2; + m.y = 0.1; + PIVector v; + //v.resize(1,2,m); + v << m << m; + + piCout << "m:"; ba << m; - piCout << ba.toHex(); + piCout << ba; + ba >> m; + piCout << ba; + ba.clear(); - piCout << "==="; - ba << vm; - piCout << ba.toHex(); -// th.h->bsl(ba, &m); -// th.regtype(); -// CAN_Raw c; -// th.h->bsl(ba, &c); -// PIVariantSimple v; -// v.setValue(m); -// ba = v.save(); -// piCout << ba.toHex(); -// PIVariantSimple v2; -// v2.load(ba); -// piCout << v2.save().toHex(); + piCout << "v:"; + ba << v; + piCout << ba; + ba >> v; + piCout << ba; return 0; } - From 6d7da02de6872ae57c718bb3782884566265845b Mon Sep 17 00:00:00 2001 From: Andrey Date: Sun, 18 Oct 2020 12:00:52 +0300 Subject: [PATCH 36/98] PIPluginLoader lib lastError --- libs/main/system/piplugin.cpp | 13 ++++++++++--- libs/main/system/piplugin.h | 3 +++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/libs/main/system/piplugin.cpp b/libs/main/system/piplugin.cpp index 3d6686c3..5db97ffb 100644 --- a/libs/main/system/piplugin.cpp +++ b/libs/main/system/piplugin.cpp @@ -217,7 +217,10 @@ PIPluginLoader::~PIPluginLoader() { bool PIPluginLoader::load(const PIString & name) { unload(); - if (!lib.load(findLibrary(name))) return false; + if (!lib.load(findLibrary(name))) { + piCout << "Load plugin \"" << name << "\"load failed with error: " << lib.lastError().trimmed(); + return false; + } //piCout << "loading" << lib.path() << "..."; func_loader_version = (FunctionLoaderVersion)lib.resolve(STR(__PIP_PLUGIN_LOADER_VERSION_FUNC__)); if (!func_loader_version) { @@ -253,8 +256,7 @@ bool PIPluginLoader::load(const PIString & name) { func_static_merge = (FunctionStaticMerge)lib.resolve(STR(__PIP_PLUGIN_STATIC_MERGE_FUNC__)); if (func_static_merge) { auto pss = plugin_info->staticSections(true), lss = PIPluginInfo::instance()->staticSections(false); - piCout << lss.keys() << pss.keys(); - + //piCout << lss.keys() << pss.keys(); auto it = lss.makeIterator(); while (it.next()) { if (!pss.contains(it.key())) @@ -286,6 +288,11 @@ PIString PIPluginLoader::libPath() { } +PIString PIPluginLoader::lastError() { + return lib.lastError(); +} + + void * PIPluginLoader::resolve(const char * name) { if (!loaded) return nullptr; return lib.resolve(name); diff --git a/libs/main/system/piplugin.h b/libs/main/system/piplugin.h index df313b2c..1238235f 100644 --- a/libs/main/system/piplugin.h +++ b/libs/main/system/piplugin.h @@ -150,6 +150,9 @@ public: //! Returns loaded plugin library path PIString libPath(); + //! Returns library lastError + PIString lastError(); + //! Resolve symbol "name" from plugin library void * resolve(const char * name); From 5078269d0f893f15fdbdeb62601e84be2a1a4136 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Sun, 18 Oct 2020 19:50:07 +0300 Subject: [PATCH 37/98] PIPluginLoader patch for several plugins --- libs/main/system/piplugin.cpp | 133 ++++++++++++++++++++++++---------- libs/main/system/piplugin.h | 79 ++++++++++++++------ 2 files changed, 149 insertions(+), 63 deletions(-) diff --git a/libs/main/system/piplugin.cpp b/libs/main/system/piplugin.cpp index 5db97ffb..45701453 100644 --- a/libs/main/system/piplugin.cpp +++ b/libs/main/system/piplugin.cpp @@ -162,37 +162,70 @@ PIPluginInfo::PIPluginInfo() { - in_plugin = false; } void PIPluginInfo::setUserVersion(const PIString & v) { - user_version[in_plugin ? 1 : 0] = v; + user_version = v; } void PIPluginInfo::setStaticSection(int type, void * ptr) { - static_sections[in_plugin ? 1 : 0][type] = ptr; + static_sections[type] = ptr; } -PIString PIPluginInfo::userVersion(bool plugin) const { - return user_version[plugin ? 1 : 0]; +PIString PIPluginInfo::userVersion() const { + return user_version; } -PIMap PIPluginInfo::staticSections(bool plugin) const { - return static_sections[plugin ? 1 : 0]; +PIMap PIPluginInfo::staticSections() const { + return static_sections; } -void PIPluginInfo::enterPlugin() { - in_plugin = true; + + + +PIPluginInfoStorage::PIPluginInfoStorage() { + enterPlugin(0); } -PIPluginInfo * PIPluginInfo::instance() { - static PIPluginInfo ret; +PIPluginInfo * PIPluginInfoStorage::currentInfo() { + return info[current]; +} + + +PIPluginInfo * PIPluginInfoStorage::pluginInfo(void * p) { + return info.value(p, nullptr); +} + + +PIPluginInfo * PIPluginInfoStorage::applicationInfo() { + return info[0]; +} + + +PIPluginInfo * PIPluginInfoStorage::enterPlugin(void * p) { + current = p; + PIPluginInfo *& i(info[p]); + if (!i) i = new PIPluginInfo(); + return i; +} + + +void PIPluginInfoStorage::unloadPlugin(void * p) { + if (current == p) current = 0; + PIPluginInfo *& i(info[p]); + if (!i) delete i; + info.remove(p); +} + + +PIPluginInfoStorage * PIPluginInfoStorage::instance() { + static PIPluginInfoStorage ret; return &ret; } @@ -201,61 +234,61 @@ PIPluginInfo * PIPluginInfo::instance() { PIPluginLoader::PIPluginLoader(const PIString & name) { func_loader_version = nullptr; - func_plugin_info = nullptr; func_static_merge = nullptr; - plugin_info = nullptr; + error = Unknown; loaded = false; + messages = true; if (!name.isEmpty()) load(name); } PIPluginLoader::~PIPluginLoader() { - lib.unload(); + unload(); } bool PIPluginLoader::load(const PIString & name) { unload(); + PIPluginInfo * ai = PIPluginInfoStorage::instance()->applicationInfo(); + PIPluginInfo * pi = PIPluginInfoStorage::instance()->enterPlugin(this); if (!lib.load(findLibrary(name))) { - piCout << "Load plugin \"" << name << "\"load failed with error: " << lib.lastError().trimmed(); + unload(); + error = LibraryLoadError; + error_str = "Load plugin \"" + name + "\" error: can`t load lib: " + lib.lastError(); + if (messages) piCout << error_str; return false; } //piCout << "loading" << lib.path() << "..."; func_loader_version = (FunctionLoaderVersion)lib.resolve(STR(__PIP_PLUGIN_LOADER_VERSION_FUNC__)); if (!func_loader_version) { - piCout << "Load plugin \"" << name << "\" error: can`t find" << STR(__PIP_PLUGIN_LOADER_VERSION_FUNC__); unload(); + error = MissingSymbols; + error_str = "Load plugin \"" + name + "\" error: can`t find " + STR(__PIP_PLUGIN_LOADER_VERSION_FUNC__); + if (messages) piCout << error_str; return false; } if (__PIP_PLUGIN_LOADER_VERSION__ != func_loader_version()) { - piCout << "Load plugin \"" << name << "\" error: invalid loader version: plugin" << __PIP_PLUGIN_LOADER_VERSION__ << "!=" << func_loader_version(); unload(); + error = InvalidLoaderVersion; + error_str = "Load plugin \"" + name + "\" error: invalid loader version: application = " + PIString::fromNumber(func_loader_version()) + + ", plugin = " + PIString::fromNumber(__PIP_PLUGIN_LOADER_VERSION__); + if (messages) piCout << error_str; return false; } - func_plugin_info = (FunctionPluginInfo)lib.resolve(STR(__PIP_PLUGIN_PLUGIN_INFO_FUNC__)); - if (!func_plugin_info) { - piCout << "Load plugin \"" << name << "\" error: can`t find" << STR(__PIP_PLUGIN_PLUGIN_INFO_FUNC__); - unload(); - return false; - } - plugin_info = func_plugin_info(); - if (!plugin_info) { - piCout << "Load plugin \"" << name << "\" error: null PIPluginInfo"; - unload(); - return false; - } - if (PIPluginInfo::instance()->userVersion(false).size_s() > 1) { - PIString pversion = plugin_info->userVersion(true), lversion = PIPluginInfo::instance()->userVersion(false); + if (ai->userVersion().size_s() > 1) { + PIString pversion = pi->userVersion(), lversion = ai->userVersion(); if (pversion != lversion) { - piCout << "Load plugin \"" << name << "\" error: invalid user version: plugin" << pversion << "!=" << lversion; unload(); + error = InvalidUserVersion; + error_str = "Load plugin \"" + name + "\" error: invalid user version: application = " + lversion + ", plugin = " + pversion; + if (messages) piCout << error_str; return false; } } func_static_merge = (FunctionStaticMerge)lib.resolve(STR(__PIP_PLUGIN_STATIC_MERGE_FUNC__)); if (func_static_merge) { - auto pss = plugin_info->staticSections(true), lss = PIPluginInfo::instance()->staticSections(false); + auto pss = pi->staticSections(), lss = ai->staticSections(); //piCout << lss.keys() << pss.keys(); auto it = lss.makeIterator(); while (it.next()) { @@ -267,14 +300,17 @@ bool PIPluginLoader::load(const PIString & name) { } } loaded = true; + error = NoError; return true; } void PIPluginLoader::unload() { lib.unload(); - plugin_info = nullptr; loaded = false; + error_str.clear(); + error = Unknown; + PIPluginInfoStorage::instance()->unloadPlugin(this); } @@ -283,13 +319,28 @@ bool PIPluginLoader::isLoaded() const { } -PIString PIPluginLoader::libPath() { - return lib.path(); +PIPluginLoader::Error PIPluginLoader::lastError() const { + return error; } -PIString PIPluginLoader::lastError() { - return lib.lastError(); +PIString PIPluginLoader::lastErrorText() const { + return error_str; +} + + +void PIPluginLoader::setMessages(bool yes) { + messages = yes; +} + + +bool PIPluginLoader::isMessages() const { + return messages; +} + + +PIString PIPluginLoader::libPath() { + return lib.path(); } @@ -300,8 +351,10 @@ void * PIPluginLoader::resolve(const char * name) { void PIPluginLoader::mergeStatic() { - if (!loaded || !func_static_merge || !plugin_info) return; - auto pss = plugin_info->staticSections(true), lss = PIPluginInfo::instance()->staticSections(false); + if (!loaded || !func_static_merge) return; + PIPluginInfo * ai = PIPluginInfoStorage::instance()->applicationInfo(); + PIPluginInfo * pi = PIPluginInfoStorage::instance()->pluginInfo(this); + auto pss = pi->staticSections(), lss = ai->staticSections(); auto it = lss.makeIterator(); while (it.next()) { if (!pss.contains(it.key())) diff --git a/libs/main/system/piplugin.h b/libs/main/system/piplugin.h index 1238235f..9e75c534 100644 --- a/libs/main/system/piplugin.h +++ b/libs/main/system/piplugin.h @@ -68,27 +68,24 @@ #endif #define __PIP_PLUGIN_LOADER_VERSION_FUNC__ pip_loader_version -#define __PIP_PLUGIN_PLUGIN_INFO_FUNC__ pip_plugin_info #define __PIP_PLUGIN_STATIC_MERGE_FUNC__ pip_merge_static -#define __PIP_PLUGIN_LOADER_VERSION__ 1 +#define __PIP_PLUGIN_LOADER_VERSION__ 2 #define PIP_PLUGIN_SET_USER_VERSION(v) \ STATIC_INITIALIZER_BEGIN \ - PIPluginInfo::instance()->setUserVersion(v); \ + PIPluginInfo * pi = PIPluginInfoStorage::instance()->currentInfo(); \ + if (pi) pi->setUserVersion(v); \ STATIC_INITIALIZER_END #define PIP_PLUGIN_ADD_STATIC_SECTION(type, ptr) \ STATIC_INITIALIZER_BEGIN \ - PIPluginInfo::instance()->setStaticSection(type, ptr); \ + PIPluginInfo * pi = PIPluginInfoStorage::instance()->currentInfo(); \ + if (pi) pi->setStaticSection(type, ptr); \ STATIC_INITIALIZER_END #define PIP_PLUGIN \ - STATIC_INITIALIZER_BEGIN \ - PIPluginInfo::instance()->enterPlugin(); \ - STATIC_INITIALIZER_END \ extern "C" { \ PIP_PLUGIN_EXPORT int __PIP_PLUGIN_LOADER_VERSION_FUNC__() {return __PIP_PLUGIN_LOADER_VERSION__;} \ - PIP_PLUGIN_EXPORT PIPluginInfo * __PIP_PLUGIN_PLUGIN_INFO_FUNC__() {return PIPluginInfo::instance();} \ } #define PIP_PLUGIN_STATIC_SECTION_MERGE \ @@ -108,16 +105,34 @@ public: void setUserVersion(const PIString & v); void setStaticSection(int type, void * ptr); - PIString userVersion(bool plugin) const; - PIMap staticSections(bool plugin) const; - void enterPlugin(); - - static PIPluginInfo * instance(); + PIString userVersion() const; + PIMap staticSections() const; private: - PIString user_version[2]; - PIMap static_sections[2]; - bool in_plugin; + PIString user_version; + PIMap static_sections; + +}; + + + +class PIP_EXPORT PIPluginInfoStorage { +public: + PIPluginInfoStorage(); + + PIPluginInfo * currentInfo(); + PIPluginInfo * pluginInfo(void * p); + PIPluginInfo * applicationInfo(); + PIPluginInfo * enterPlugin(void * p); + void unloadPlugin(void * p); + + static PIPluginInfoStorage * instance(); + +private: + NO_COPY_CLASS(PIPluginInfoStorage) + + void * current; + PIMap info; }; @@ -127,9 +142,18 @@ private: class PIP_EXPORT PIPluginLoader { public: typedef int(*FunctionLoaderVersion)(); - typedef PIPluginInfo*(*FunctionPluginInfo)(); typedef void(*FunctionStaticMerge)(int, void *, void *); + //! Possible load plugin error + enum Error { + Unknown /** No \a load call yet */ , + NoError /** No error */ , + LibraryLoadError /** System can`t load library */ , + MissingSymbols /** Can`t find necessary symbols */ , + InvalidLoaderVersion /** Integer version mismatch */ , + InvalidUserVersion /** User version mismatch */ , + }; + //! Contruscts loader with filename "name" PIPluginLoader(const PIString & name = PIString()); @@ -147,12 +171,21 @@ public: //! Returns if plugin is successfully loaded bool isLoaded() const; + //! Returns error of last \a load() call + Error lastError() const; + + //! Returns error message of last \a load() call + PIString lastErrorText() const; + + //! Set if %PIPluginLoader should print load messages, \b true by default + void setMessages(bool yes); + + //! Returns if %PIPluginLoader should print load messages, \b true by default + bool isMessages() const; + //! Returns loaded plugin library path PIString libPath(); - //! Returns library lastError - PIString lastError(); - //! Resolve symbol "name" from plugin library void * resolve(const char * name); @@ -169,10 +202,10 @@ private: PILibrary lib; FunctionLoaderVersion func_loader_version; - FunctionPluginInfo func_plugin_info; FunctionStaticMerge func_static_merge; - PIPluginInfo * plugin_info; - bool loaded; + PIString error_str; + Error error; + bool loaded, messages; }; From 2794d866fd832a8b8426ad6fb1cd5f225ddd95a6 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Sun, 18 Oct 2020 19:51:59 +0300 Subject: [PATCH 38/98] PIPluginLoader fix --- libs/main/system/piplugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/main/system/piplugin.cpp b/libs/main/system/piplugin.cpp index 45701453..aaa01c55 100644 --- a/libs/main/system/piplugin.cpp +++ b/libs/main/system/piplugin.cpp @@ -219,7 +219,7 @@ PIPluginInfo * PIPluginInfoStorage::enterPlugin(void * p) { void PIPluginInfoStorage::unloadPlugin(void * p) { if (current == p) current = 0; PIPluginInfo *& i(info[p]); - if (!i) delete i; + if (i) delete i; info.remove(p); } From e0d46463aeb4ad96f71124896e6a62d94e635a04 Mon Sep 17 00:00:00 2001 From: Andrey Date: Mon, 19 Oct 2020 15:18:16 +0300 Subject: [PATCH 39/98] assert --- libs/main/containers/picontainers.h | 9 ----- libs/main/containers/pivector2d.h | 7 ++++ libs/main/core/pibase.h | 10 +++++ libs/main/core/piincludes.h | 1 + libs/main/geo/pigeoposition.cpp | 60 ++++++----------------------- libs/main/math/pifft.cpp | 16 ++------ libs/main/math/pimathmatrix.h | 51 +++++++++--------------- main.cpp | 27 ++++--------- 8 files changed, 60 insertions(+), 121 deletions(-) diff --git a/libs/main/containers/picontainers.h b/libs/main/containers/picontainers.h index 1d989b65..708d7e7b 100644 --- a/libs/main/containers/picontainers.h +++ b/libs/main/containers/picontainers.h @@ -28,15 +28,6 @@ #include "picout.h" #include "piintrospection_containers.h" -#ifdef PIP_DEBUG -# ifdef NDEBUG -# undef NDEBUG -# endif -# include -#endif -#ifndef assert -# define assert(x) -#endif #ifdef MAC_OS # include #else diff --git a/libs/main/containers/pivector2d.h b/libs/main/containers/pivector2d.h index ad9b1ea3..9223f9c3 100644 --- a/libs/main/containers/pivector2d.h +++ b/libs/main/containers/pivector2d.h @@ -234,6 +234,13 @@ public: return *this; } + inline bool operator ==(const PIVector2D & t) const { + if (cols_ != t.cols_ || rows_ != t.rows_) + return false; + return mat == t.mat; + } + inline bool operator !=(const PIVector2D & t) const {return !(*this == t);} + PIVector > toVectors() const { PIVector > ret; ret.reserve(rows_); diff --git a/libs/main/core/pibase.h b/libs/main/core/pibase.h index 73c79213..82b95935 100644 --- a/libs/main/core/pibase.h +++ b/libs/main/core/pibase.h @@ -155,6 +155,16 @@ extern char ** environ; #endif +#ifdef NDEBUG +# undef NDEBUG +#endif +#include +#ifndef assert +# define assert(x) +# define assertm(exp, msg) +#else +# define assertm(exp, msg) assert(((void)msg, exp)) +#endif #ifdef CC_GCC # undef DEPRECATED diff --git a/libs/main/core/piincludes.h b/libs/main/core/piincludes.h index ba158476..f09366e9 100644 --- a/libs/main/core/piincludes.h +++ b/libs/main/core/piincludes.h @@ -28,6 +28,7 @@ #endif #include + class PIMutex; class PIMutexLocker; class PIObject; diff --git a/libs/main/geo/pigeoposition.cpp b/libs/main/geo/pigeoposition.cpp index eac7e3a6..c7974546 100644 --- a/libs/main/geo/pigeoposition.cpp +++ b/libs/main/geo/pigeoposition.cpp @@ -203,10 +203,7 @@ double PIGeoPosition::height() const { PIGeoPosition &PIGeoPosition::setGeodetic(double lat, double lon, double ht, PIEllipsoidModel ell) { - if(lat > 90 || lat < -90) { - piCout << "[PIGeoPosition]" << "Achtung! Invalid latitude in setGeodetic:" << lat; - assert(lat <= 90 && lat >= -90); - } + assertm(lat <= 90 && lat >= -90, "Achtung! Invalid latitude in setGeodetic"); (*this)[0] = lat; (*this)[1] = lon; if((*this)[1] < 0) (*this)[1] += 360 * (1 + (unsigned long)((*this)[1]/360)); @@ -219,14 +216,8 @@ PIGeoPosition &PIGeoPosition::setGeodetic(double lat, double lon, double ht, PIE PIGeoPosition &PIGeoPosition::setGeocentric(double lat, double lon, double rad) { - if(lat > 90 || lat < -90) { - piCout << "[PIGeoPosition]" << "Achtung! Invalid latitude in setGeocentric:" << lat; - assert(lat <= 90 && lat >= -90); - } - if(rad < 0) { - piCout << "[PIGeoPosition]" << "Achtung! Invalid radius in setGeocentric:" << rad; - assert(rad >= 0); - } + assertm(lat <= 90 && lat >= -90, "Achtung! Invalid latitude in setGeocentric"); + assertm(rad >= 0, "Achtung! Invalid radius in setGeocentric"); (*this)[0] = lat; (*this)[1] = lon; (*this)[2] = rad; @@ -238,14 +229,8 @@ PIGeoPosition &PIGeoPosition::setGeocentric(double lat, double lon, double rad) PIGeoPosition &PIGeoPosition::setSpherical(double theta, double phi, double rad) { - if(theta < 0 || theta > 180) { - piCout << "[PIGeoPosition]" << "Achtung! Invalid theta in setSpherical:" << theta; - assert(theta <= 180 && theta >= 0); - } - if(rad < 0) { - piCout << "[PIGeoPosition]" << "Achtung! Invalid radius in setSpherical:" << rad; - assert(rad >= 0); - } + assertm(theta <= 180 && theta >= 0, "Achtung! Invalid theta in setSpherical"); + assertm(rad >= 0, "Achtung! Invalid radius in setSpherical"); (*this)[0] = theta; (*this)[1] = phi; (*this)[2] = rad; @@ -439,24 +424,15 @@ bool PIGeoPosition::operator==(const PIGeoPosition &right) const { void PIGeoPosition::initialize(PIMathVectorT3d v, PIGeoPosition::CoordinateSystem sys, PIEllipsoidModel ell) { double a(v[0]), b(v[1]), c(v[2]); if(sys == Geodetic || sys==Geocentric) { - if(a > 90 || a < -90) { - piCout << "[PIGeoPosition]" << "Achtung! Invalid latitude in constructor:" << a; - assert(a <= 90 && a >= -90); - } + assertm(a <= 90 && a >= -90, "Achtung! Invalid latitude in constructor"); if(b < 0) b += 360*(1+(unsigned long)(b/360)); else if(b >= 360) b -= 360*(unsigned long)(b/360); } if(sys==Geocentric || sys==Spherical) { - if(c < 0) { - piCout << "[PIGeoPosition]" << "Achtung! Invalid radius in constructor:" << c; - assert(c >= 0); - } + assertm(c >= 0, "Achtung! Invalid radius in constructor"); } if(sys==Spherical) { - if(a < 0 || a > 180) { - piCout << "[PIGeoPosition]" << "Achtung! Invalid theta in constructor:" << a; - assert(a >= 0 && a <= 180); - } + assertm(a >= 0 && a <= 180, "Achtung! Invalid theta in constructor"); if(b < 0) b += 360*(1+(unsigned long)(b/360)); else if(b >= 360) b -= 360*(unsigned long)(b/360); } @@ -493,10 +469,7 @@ double PIGeoPosition::elevationGeodetic(const PIGeoPosition &p) const { r.transformTo(Cartesian); s.transformTo(Cartesian); PIMathVectorT3d z = s - r; - if (z.length() <= 1e-4) { // if the positions are within .1 millimeter - piCout << "[PIGeoPosition]" << "Positions are within .1 millimeter" << z; - assert(z.length() > 1e-4); - } + assertm(z.length() > 1e-4, "Positions are within .1 millimeter"); PIMathVectorT3d kv; // Compute k vector in local North-East-Up (NEU) system kv[0] = cos(lat) * cos(lng); kv[1] = cos(lat) * sin(lng); @@ -517,10 +490,7 @@ double PIGeoPosition::azimuth(const PIGeoPosition &p) const { xyz = xy + r[2] * r[2]; xy = sqrt(xy); xyz = sqrt(xyz); - if (xy <= 1e-14 || xyz <=1e-14) { - piCout << "[PIGeoPosition]" << "Divide by Zero Error"; - assert(xy > 1e-14 && xyz > 1e-14); - } + assertm(xy > 1e-14 && xyz > 1e-14, "Divide by Zero Error"); cosl = r[0] / xy; sinl = r[1] / xy; sint = r[2] / xyz; @@ -535,10 +505,7 @@ double PIGeoPosition::azimuth(const PIGeoPosition &p) const { p1 = (xn1 * z1) + (xn2 * z2) + (xn3 * z3) ; p2 = (xe1 * z1) + (xe2 * z2) ; test = piAbsd(p1) + piAbsd(p2); - if (test < 1.0e-16) { - piCout << "[PIGeoPosition]" << "azAngle(), failed p1+p2 test" << test; - assert(test >= 1.0e-16); - } + assertm(test >= 1.0e-16, "azAngle(), failed p1+p2 test"); alpha = 90 - atan2(p1, p2) * rad2deg; if (alpha < 0) return alpha + 360; else return alpha; @@ -553,10 +520,7 @@ double PIGeoPosition::azimuthGeodetic(const PIGeoPosition &p) const { s.transformTo(Cartesian); PIMathVectorT3d z; z = s - r; - if (z.length() <= 1e-4) { // if the positions are within .1 millimeter - piCout << "[PIGeoPosition]" << "Positions are within 0.1 millimeter" << z.length(); - assert(z.length() > 1e-4); - } + assertm(z.length() > 1e-4, "Positions are within 0.1 millimeter"); PIMathVectorT3d iv; // Compute i vector in local North-East-Up (NEU) system iv[0] = -sin(lat) * cos(lng); iv[1] = -sin(lat) * sin(lng); diff --git a/libs/main/math/pifft.cpp b/libs/main/math/pifft.cpp index 7fbb6ca7..6a0ea413 100644 --- a/libs/main/math/pifft.cpp +++ b/libs/main/math/pifft.cpp @@ -177,17 +177,13 @@ void PIFFT_double::ftbasegeneratecomplexfftplan(uint n, ftplan * plan) { curplan.plan.resize(planarraysize); int ftbase_ftbasecffttask = 0; ftbase_ftbasegenerateplanrec(n, ftbase_ftbasecffttask, plan, &plansize, &precomputedsize, &planarraysize, &tmpmemsize, &stackmemsize, stackptr); - if (stackptr != 0) { - return;//ae_assert(stackptr==0, "Internal error in FTBaseGenerateComplexFFTPlan: stack ptr!"); - } + assert(stackptr==0); curplan.stackbuf.resize(piMax(stackmemsize, 1)); //ae_vector_set_length(&curplan.stackbuf, ae_maxint(stackmemsize, 1)); curplan.tmpbuf.resize(piMax(tmpmemsize, 1)); //ae_vector_set_length(&(curplan.tmpbuf), ae_maxint(tmpmemsize, 1)); curplan.precomputed.resize(piMax(precomputedsize, 1)); //ae_vector_set_length(&curplan.precomputed, ae_maxint(precomputedsize, 1)); stackptr = 0; ftbase_ftbaseprecomputeplanrec(plan, 0, stackptr); - if (stackptr != 0) { - return;//ae_assert(stackptr==0, "Internal error in FTBaseGenerateComplexFFTPlan: stack ptr!"); - } + assert(stackptr==0); } @@ -1117,17 +1113,13 @@ void PIFFT_float::ftbasegeneratecomplexfftplan(uint n, ftplan * plan) { curplan.plan.resize(planarraysize); int ftbase_ftbasecffttask = 0; ftbase_ftbasegenerateplanrec(n, ftbase_ftbasecffttask, plan, &plansize, &precomputedsize, &planarraysize, &tmpmemsize, &stackmemsize, stackptr); - if (stackptr != 0) { - return;//ae_assert(stackptr==0, "Internal error in FTBaseGenerateComplexFFTPlan: stack ptr!"); - } + assertm(stackptr==0, "Internal error in FTBaseGenerateComplexFFTPlan"); curplan.stackbuf.resize(piMax(stackmemsize, 1)); //ae_vector_set_length(&curplan.stackbuf, ae_maxint(stackmemsize, 1)); curplan.tmpbuf.resize(piMax(tmpmemsize, 1)); //ae_vector_set_length(&(curplan.tmpbuf), ae_maxint(tmpmemsize, 1)); curplan.precomputed.resize(piMax(precomputedsize, 1)); //ae_vector_set_length(&curplan.precomputed, ae_maxint(precomputedsize, 1)); stackptr = 0; ftbase_ftbaseprecomputeplanrec(plan, 0, stackptr); - if (stackptr != 0) { - return;//ae_assert(stackptr==0, "Internal error in FTBaseGenerateComplexFFTPlan: stack ptr!"); - } + assertm(stackptr==0, "Internal error in FTBaseGenerateComplexFFTPlan"); } diff --git a/libs/main/math/pimathmatrix.h b/libs/main/math/pimathmatrix.h index 1d5b71ee..73993dec 100644 --- a/libs/main/math/pimathmatrix.h +++ b/libs/main/math/pimathmatrix.h @@ -890,6 +890,11 @@ public: return tm; } + static _CMatrix zero(const uint cols, const uint rows) { + _V2D::resize(rows, cols); + fill(Type(0)); + } + /** * @brief Creates a row matrix of every element that is equal to every element of the vector * @@ -1002,49 +1007,27 @@ public: */ bool isValid() const { return !PIVector2D::isEmpty(); } - /** - * @brief Matrix assignment to matrix "v" - * - * @param v matrix for the assigment - * @return matrix equal with v - */ - _CMatrix &operator=(const PIVector > &v) { - *this = _CMatrix(v); - return *this; - } - - /** - * @brief Compare with matrix "sm" - * - * @param sm matrix for the compare - * @return if matrices are equal true, else false - */ - bool operator==(const _CMatrix &sm) const { - PIMM_FOR_A(i) if (_V2D::mat[i] != sm.mat[i]) return false; - return true; - } - - /** - * @brief Compare with matrix "sm" - * - * @param sm matrix for the compare - * @return if matrices are not equal true, else false - */ - bool operator!=(const _CMatrix &sm) const { return !(*this == sm); } - /** * @brief Addition assignment with matrix "sm" * * @param sm matrix for the addition assigment */ - void operator+=(const _CMatrix &sm) { PIMM_FOR_A(i) _V2D::mat[i] += sm.mat[i]; } + void operator+=(const _CMatrix &sm) { + assert(_V2D::rows() == sm.rows()); + assert(_V2D::cols() == sm.cols()); + PIMM_FOR_A(i) _V2D::mat[i] += sm.mat[i]; + } /** * @brief Subtraction assignment with matrix "sm" * * @param sm matrix for the subtraction assigment */ - void operator-=(const _CMatrix &sm) { PIMM_FOR_A(i) _V2D::mat[i] -= sm.mat[i]; } + void operator-=(const _CMatrix &sm) { + assert(_V2D::rows() == sm.rows()); + assert(_V2D::cols() == sm.cols()); + PIMM_FOR_A(i) _V2D::mat[i] -= sm.mat[i]; + } /** * @brief Multiplication assignment with value "v" @@ -1079,6 +1062,8 @@ public: */ _CMatrix operator+(const _CMatrix &sm) const { _CMatrix tm(*this); + assert(tm.rows() == sm.rows()); + assert(tm.cols() == sm.cols()); PIMM_FOR_A(i) tm.mat[i] += sm.mat[i]; return tm; } @@ -1091,6 +1076,8 @@ public: */ _CMatrix operator-(const _CMatrix &sm) const { _CMatrix tm(*this); + assert(tm.rows() == sm.rows()); + assert(tm.cols() == sm.cols()); PIMM_FOR_A(i) tm.mat[i] -= sm.mat[i]; return tm; } diff --git a/main.cpp b/main.cpp index cc9da2ef..78d2da5d 100644 --- a/main.cpp +++ b/main.cpp @@ -40,25 +40,12 @@ inline PIByteArray & operator >>(PIByteArray & ba, MM & v) {piCout << ">>" int main() { - PIByteArray ba; - MM m; - m.e = 2; - m.y = 0.1; - PIVector v; - //v.resize(1,2,m); - v << m << m; - - piCout << "m:"; - ba << m; - piCout << ba; - ba >> m; - piCout << ba; - - ba.clear(); - piCout << "v:"; - ba << v; - piCout << ba; - ba >> v; - piCout << ba; + PIMathMatrixd m = PIMathMatrixd::identity(3,3); + m.fill(0); + PIMathMatrixd m2 = PIMathMatrixd::identity(3,4); + piCout << m; + piCout << m2; + piCout << m * m2; + piCout << m2 * m; return 0; } From 94fc54159b48d8868bc3f0b19e505e5ec31f3ab5 Mon Sep 17 00:00:00 2001 From: Andrey Date: Mon, 19 Oct 2020 15:20:48 +0300 Subject: [PATCH 40/98] version --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6c4173c9..a9237f2a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0) cmake_policy(SET CMP0017 NEW) # need include() with .cmake project(pip) set(pip_MAJOR 2) -set(pip_MINOR 12) +set(pip_MINOR 13) set(pip_REVISION 0) set(pip_SUFFIX beta) set(pip_COMPANY SHS) From 16f22f38c7db10cd6bc1fc4a3bed9fd5b549f14f Mon Sep 17 00:00:00 2001 From: Stepan Fomenko Date: Mon, 19 Oct 2020 16:27:42 +0300 Subject: [PATCH 41/98] Simple PIVector2D resize tests --- tests/math/testpivector2d.cpp | 54 +++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 tests/math/testpivector2d.cpp diff --git a/tests/math/testpivector2d.cpp b/tests/math/testpivector2d.cpp new file mode 100644 index 00000000..daf710b1 --- /dev/null +++ b/tests/math/testpivector2d.cpp @@ -0,0 +1,54 @@ +#include "gtest/gtest.h" +#include "pivector2d.h" + +void assert_fill_with(PIVector2D vec, int rows, int cols, int val) { + for(int r = 0; r < rows; r++) { + for(int c = 0; c < cols; c++) { + ASSERT_EQ(vec.element(r, c), val); + } + } +} + +int ROWS_COUNT_INIT = 200; +int ROWS_COUNT_INCREASE = 300; +int ROWS_COUNT_REDUCE = 100; + +int COLS_COUNT_INIT = 200; +int COLS_COUNT_INCREASE = 300; +int COLS_COUNT_REDUCE = 100; + +TEST(PIVector2D_Test, resize_is_increase_col_count) { + PIVector2D vec(ROWS_COUNT_INIT, COLS_COUNT_INIT, INT32_MAX); + vec.resize(ROWS_COUNT_INIT, COLS_COUNT_INCREASE, 0); + ASSERT_EQ(vec.cols(), COLS_COUNT_INCREASE); +} + +TEST(PIVector2D_Test, resize_is_reduce_col_count) { + PIVector2D vec(ROWS_COUNT_INIT, COLS_COUNT_INIT, INT32_MAX); + vec.resize(ROWS_COUNT_INIT, COLS_COUNT_REDUCE, 0); + ASSERT_EQ(vec.cols(), COLS_COUNT_REDUCE); +} + +TEST(PIVector2D_Test, resize_is_increase_rows_count) { + PIVector2D vec(ROWS_COUNT_INIT, COLS_COUNT_INIT, INT32_MAX); + vec.resize(ROWS_COUNT_INCREASE, COLS_COUNT_INIT, 0); + ASSERT_EQ(vec.rows(), ROWS_COUNT_INCREASE); +} + +TEST(PIVector2D_Test, resize_is_reduce_rows_count) { + PIVector2D vec(ROWS_COUNT_INIT, COLS_COUNT_INIT, INT32_MAX); + vec.resize(ROWS_COUNT_REDUCE, COLS_COUNT_INIT, 0); + ASSERT_EQ(vec.rows(), ROWS_COUNT_REDUCE); +} + +TEST(PIVector2D_Test, resize_increase_is_data_stay_consistent) { + PIVector2D vec(ROWS_COUNT_INIT, COLS_COUNT_INIT, INT32_MAX); + vec.resize(ROWS_COUNT_INCREASE, COLS_COUNT_INCREASE, 0); + assert_fill_with(vec, ROWS_COUNT_INIT, COLS_COUNT_INIT, INT32_MAX); +} + +TEST(PIVector2D_Test, resize_reduce_is_data_stay_consistent) { + PIVector2D vec(ROWS_COUNT_INIT, COLS_COUNT_INIT, INT32_MAX); + vec.resize(ROWS_COUNT_REDUCE, COLS_COUNT_REDUCE, 0); + assert_fill_with(vec, ROWS_COUNT_REDUCE, COLS_COUNT_REDUCE, INT32_MAX); +} \ No newline at end of file From b6430c0863f20c9ca5f2d55eff0574ed2c0687fd Mon Sep 17 00:00:00 2001 From: Stepan Fomenko Date: Mon, 19 Oct 2020 16:47:54 +0300 Subject: [PATCH 42/98] Complicate tests for PIVector2D::resize --- tests/math/testpivector2d.cpp | 56 +++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 22 deletions(-) diff --git a/tests/math/testpivector2d.cpp b/tests/math/testpivector2d.cpp index daf710b1..0657f8df 100644 --- a/tests/math/testpivector2d.cpp +++ b/tests/math/testpivector2d.cpp @@ -1,54 +1,66 @@ #include "gtest/gtest.h" #include "pivector2d.h" -void assert_fill_with(PIVector2D vec, int rows, int cols, int val) { +int ROWS_COUNT_INIT = 4; +int ROWS_COUNT_INCREASE = 6; +int ROWS_COUNT_REDUCE = 2; + +int COLS_COUNT_INIT = 4; +int COLS_COUNT_INCREASE = 6; +int COLS_COUNT_REDUCE = 2; + +void assert_fill_with(PIVector2D vec, int rows, int cols) { for(int r = 0; r < rows; r++) { for(int c = 0; c < cols; c++) { - ASSERT_EQ(vec.element(r, c), val); + ASSERT_EQ(vec.element(r, c), r * COLS_COUNT_INIT + c); } } } -int ROWS_COUNT_INIT = 200; -int ROWS_COUNT_INCREASE = 300; -int ROWS_COUNT_REDUCE = 100; +class Vector2D : public ::testing::Test { +protected: + void SetUp() override { + for (int r = 0; r < ROWS_COUNT_INIT; ++r) { + for (int c = 0; c < COLS_COUNT_INIT; ++c) { + vec.element(r, c) = r * COLS_COUNT_INIT + c; + } + } + } -int COLS_COUNT_INIT = 200; -int COLS_COUNT_INCREASE = 300; -int COLS_COUNT_REDUCE = 100; + PIVector2D vec = PIVector2D(ROWS_COUNT_INIT, COLS_COUNT_INIT); +}; -TEST(PIVector2D_Test, resize_is_increase_col_count) { - PIVector2D vec(ROWS_COUNT_INIT, COLS_COUNT_INIT, INT32_MAX); +TEST_F(Vector2D, resize_is_increase_col_count) { vec.resize(ROWS_COUNT_INIT, COLS_COUNT_INCREASE, 0); ASSERT_EQ(vec.cols(), COLS_COUNT_INCREASE); } -TEST(PIVector2D_Test, resize_is_reduce_col_count) { - PIVector2D vec(ROWS_COUNT_INIT, COLS_COUNT_INIT, INT32_MAX); +TEST_F(Vector2D, resize_is_reduce_col_count) { vec.resize(ROWS_COUNT_INIT, COLS_COUNT_REDUCE, 0); ASSERT_EQ(vec.cols(), COLS_COUNT_REDUCE); } -TEST(PIVector2D_Test, resize_is_increase_rows_count) { - PIVector2D vec(ROWS_COUNT_INIT, COLS_COUNT_INIT, INT32_MAX); +TEST_F(Vector2D, resize_is_increase_rows_count) { vec.resize(ROWS_COUNT_INCREASE, COLS_COUNT_INIT, 0); ASSERT_EQ(vec.rows(), ROWS_COUNT_INCREASE); } -TEST(PIVector2D_Test, resize_is_reduce_rows_count) { - PIVector2D vec(ROWS_COUNT_INIT, COLS_COUNT_INIT, INT32_MAX); +TEST_F(Vector2D, resize_is_reduce_rows_count) { vec.resize(ROWS_COUNT_REDUCE, COLS_COUNT_INIT, 0); ASSERT_EQ(vec.rows(), ROWS_COUNT_REDUCE); } -TEST(PIVector2D_Test, resize_increase_is_data_stay_consistent) { - PIVector2D vec(ROWS_COUNT_INIT, COLS_COUNT_INIT, INT32_MAX); +TEST_F(Vector2D, resize_increase_is_data_stay_consistent) { vec.resize(ROWS_COUNT_INCREASE, COLS_COUNT_INCREASE, 0); - assert_fill_with(vec, ROWS_COUNT_INIT, COLS_COUNT_INIT, INT32_MAX); + assert_fill_with(vec, ROWS_COUNT_INIT, COLS_COUNT_INIT); } -TEST(PIVector2D_Test, resize_reduce_is_data_stay_consistent) { - PIVector2D vec(ROWS_COUNT_INIT, COLS_COUNT_INIT, INT32_MAX); +TEST_F(Vector2D, resize_reduce_is_data_stay_consistent) { + piCout << "Before:"; + piCout << vec; + piCout << ""; vec.resize(ROWS_COUNT_REDUCE, COLS_COUNT_REDUCE, 0); - assert_fill_with(vec, ROWS_COUNT_REDUCE, COLS_COUNT_REDUCE, INT32_MAX); + piCout << "After:"; + piCout << vec; + assert_fill_with(vec, ROWS_COUNT_REDUCE, COLS_COUNT_REDUCE); } \ No newline at end of file From ac911d9b3e47b362081ecc59f151548d29eb4330 Mon Sep 17 00:00:00 2001 From: Stepan Fomenko Date: Mon, 19 Oct 2020 17:34:51 +0300 Subject: [PATCH 43/98] Increase reduce cols tests granularity --- tests/math/testpivector2d.cpp | 54 ++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/tests/math/testpivector2d.cpp b/tests/math/testpivector2d.cpp index 0657f8df..9a42f8ed 100644 --- a/tests/math/testpivector2d.cpp +++ b/tests/math/testpivector2d.cpp @@ -1,12 +1,12 @@ #include "gtest/gtest.h" #include "pivector2d.h" -int ROWS_COUNT_INIT = 4; -int ROWS_COUNT_INCREASE = 6; +int ROWS_COUNT_INIT = 3; +int ROWS_COUNT_INCREASE = 4; int ROWS_COUNT_REDUCE = 2; -int COLS_COUNT_INIT = 4; -int COLS_COUNT_INCREASE = 6; +int COLS_COUNT_INIT = 3; +int COLS_COUNT_INCREASE = 4; int COLS_COUNT_REDUCE = 2; void assert_fill_with(PIVector2D vec, int rows, int cols) { @@ -19,6 +19,8 @@ void assert_fill_with(PIVector2D vec, int rows, int cols) { class Vector2D : public ::testing::Test { protected: + PIVector2D vec = PIVector2D(ROWS_COUNT_INIT, COLS_COUNT_INIT); + void SetUp() override { for (int r = 0; r < ROWS_COUNT_INIT; ++r) { for (int c = 0; c < COLS_COUNT_INIT; ++c) { @@ -27,7 +29,26 @@ protected: } } - PIVector2D vec = PIVector2D(ROWS_COUNT_INIT, COLS_COUNT_INIT); + void resize_reduce_is_data_stay_consistent(int newRowsCount, int newColsCount) { + piCout << "Before:"; + piCout << vec; + piCout << ""; + vec.resize(newRowsCount, newColsCount, 0); + piCout << "After:"; + piCout << vec; + assert_fill_with(vec, newRowsCount, newColsCount); + } + + void resize_increase_is_data_stay_consistent(int newRowsCount, int newColsCount) { + vec.resize(newRowsCount, newColsCount, 0); + assert_fill_with(vec, ROWS_COUNT_INIT, COLS_COUNT_INIT); + + for (int r = ROWS_COUNT_INIT; r < newRowsCount; ++r) { + for (int c = COLS_COUNT_INIT; c < newColsCount; ++c) { + ASSERT_EQ(vec.element(r, c), 0); + } + } + } }; TEST_F(Vector2D, resize_is_increase_col_count) { @@ -50,17 +71,18 @@ TEST_F(Vector2D, resize_is_reduce_rows_count) { ASSERT_EQ(vec.rows(), ROWS_COUNT_REDUCE); } -TEST_F(Vector2D, resize_increase_is_data_stay_consistent) { - vec.resize(ROWS_COUNT_INCREASE, COLS_COUNT_INCREASE, 0); - assert_fill_with(vec, ROWS_COUNT_INIT, COLS_COUNT_INIT); +TEST_F(Vector2D, resize_increase_both_is_data_stay_consistent) { + resize_increase_is_data_stay_consistent(ROWS_COUNT_INCREASE, COLS_COUNT_INCREASE); } -TEST_F(Vector2D, resize_reduce_is_data_stay_consistent) { - piCout << "Before:"; - piCout << vec; - piCout << ""; - vec.resize(ROWS_COUNT_REDUCE, COLS_COUNT_REDUCE, 0); - piCout << "After:"; - piCout << vec; - assert_fill_with(vec, ROWS_COUNT_REDUCE, COLS_COUNT_REDUCE); +TEST_F(Vector2D, resize_reduce_cols_is_data_stay_consistent) { + resize_reduce_is_data_stay_consistent(ROWS_COUNT_INIT, COLS_COUNT_REDUCE); +} + +TEST_F(Vector2D, resize_reduce_rows_is_data_stay_consistent) { + resize_reduce_is_data_stay_consistent(ROWS_COUNT_REDUCE, COLS_COUNT_INIT); +} + +TEST_F(Vector2D, resize_reduce_both_is_data_stay_consistent) { + resize_reduce_is_data_stay_consistent(ROWS_COUNT_REDUCE, COLS_COUNT_REDUCE); } \ No newline at end of file From d84adf2bc7efe6063f215fb7c288f488d7fa6a3c Mon Sep 17 00:00:00 2001 From: Andrey Date: Mon, 19 Oct 2020 17:37:24 +0300 Subject: [PATCH 44/98] PIVector2D resize --- libs/main/containers/pivector2d.h | 2 +- main.cpp | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/libs/main/containers/pivector2d.h b/libs/main/containers/pivector2d.h index 9223f9c3..8946a6cc 100644 --- a/libs/main/containers/pivector2d.h +++ b/libs/main/containers/pivector2d.h @@ -218,7 +218,7 @@ public: int cs = (cols - cols_); if (cs < 0) { for (size_t r=0; r>(PIByteArray & ba, MM & v) {piCout << ">>" int main() { - PIMathMatrixd m = PIMathMatrixd::identity(3,3); - m.fill(0); - PIMathMatrixd m2 = PIMathMatrixd::identity(3,4); + PIMathMatrixd m = PIMathMatrixd::identity(5,5); +// m.fill(9); + //PIMathMatrixd m2 = PIMathMatrixd::identity(3,4); + piCout << m; + m.resize(3,3); piCout << m; - piCout << m2; - piCout << m * m2; - piCout << m2 * m; return 0; } From ff6d5cedaa2f696d2b41ebd96fe68cf36c436716 Mon Sep 17 00:00:00 2001 From: Andrey Date: Mon, 19 Oct 2020 17:52:51 +0300 Subject: [PATCH 45/98] PIVector2D tests --- tests/math/testpivector2d.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/math/testpivector2d.cpp b/tests/math/testpivector2d.cpp index 9a42f8ed..37f77e8f 100644 --- a/tests/math/testpivector2d.cpp +++ b/tests/math/testpivector2d.cpp @@ -1,13 +1,13 @@ #include "gtest/gtest.h" #include "pivector2d.h" -int ROWS_COUNT_INIT = 3; -int ROWS_COUNT_INCREASE = 4; -int ROWS_COUNT_REDUCE = 2; +int ROWS_COUNT_INIT = 31; +int ROWS_COUNT_INCREASE = 41; +int ROWS_COUNT_REDUCE = 22; -int COLS_COUNT_INIT = 3; -int COLS_COUNT_INCREASE = 4; -int COLS_COUNT_REDUCE = 2; +int COLS_COUNT_INIT = 34; +int COLS_COUNT_INCREASE = 44; +int COLS_COUNT_REDUCE = 13; void assert_fill_with(PIVector2D vec, int rows, int cols) { for(int r = 0; r < rows; r++) { @@ -85,4 +85,4 @@ TEST_F(Vector2D, resize_reduce_rows_is_data_stay_consistent) { TEST_F(Vector2D, resize_reduce_both_is_data_stay_consistent) { resize_reduce_is_data_stay_consistent(ROWS_COUNT_REDUCE, COLS_COUNT_REDUCE); -} \ No newline at end of file +} From 6789d068e355e36554e7c396f415536bf3a7d192 Mon Sep 17 00:00:00 2001 From: Andrey Date: Mon, 19 Oct 2020 17:59:52 +0300 Subject: [PATCH 46/98] fix pimathmatrix --- libs/main/math/pimathmatrix.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/libs/main/math/pimathmatrix.h b/libs/main/math/pimathmatrix.h index 73993dec..9dd8ee7c 100644 --- a/libs/main/math/pimathmatrix.h +++ b/libs/main/math/pimathmatrix.h @@ -882,7 +882,7 @@ public: * * @param cols is number of matrix column uint type * @param rows is number of matrix row uint type - * @return identity matrix of type PIMathMatrix + * @return identity matrix(cols,rows) */ static _CMatrix identity(const uint cols, const uint rows) { _CMatrix tm(cols, rows); @@ -890,9 +890,17 @@ public: return tm; } + /** + * @brief Creates a matrix filled by zeros + * + * @param cols is number of matrix column uint type + * @param rows is number of matrix row uint type + * @return zero matrix(cols,rows) + */ static _CMatrix zero(const uint cols, const uint rows) { - _V2D::resize(rows, cols); - fill(Type(0)); + _CMatrix tm(cols, rows); + tm.fill(Type(0)); + return tm; } /** From 7b5555f63d2f6e23ce540ae3108d653873c3fce2 Mon Sep 17 00:00:00 2001 From: andrey Date: Wed, 21 Oct 2020 17:58:42 +0300 Subject: [PATCH 47/98] refactor pimathvector.h --- libs/main/math/pimathmatrix.h | 2 +- libs/main/math/pimathvector.h | 373 +++++++++++++++++++++++--------- libs/main/math/piquaternion.cpp | 4 +- 3 files changed, 272 insertions(+), 107 deletions(-) diff --git a/libs/main/math/pimathmatrix.h b/libs/main/math/pimathmatrix.h index 9dd8ee7c..645c9e22 100644 --- a/libs/main/math/pimathmatrix.h +++ b/libs/main/math/pimathmatrix.h @@ -1227,7 +1227,7 @@ public: ++crow; smat.swapRows(i, crow); mtmp.swapRows(i, crow); - if (sv != 0) sv->swap(i, crow); + if (sv != 0) sv->swapElements(i, crow); } for (uint j = i + 1; j < _V2D::rows_; ++j) { mul = smat.element(i, j) / smat.element(i, i); diff --git a/libs/main/math/pimathvector.h b/libs/main/math/pimathvector.h index 09b8d07b..010b74e3 100644 --- a/libs/main/math/pimathvector.h +++ b/libs/main/math/pimathvector.h @@ -28,85 +28,151 @@ template class PIMathMatrixT; +#define PIMATHVECTOR_ZERO_CMP Type(1E-100) + /// Vector templated -#define PIMV_FOR(v, s) for (uint v = s; v < Size; ++v) +#define PIMV_FOR for (uint i = 0; i < Size; ++i) template class PIP_EXPORT PIMathVectorT { typedef PIMathVectorT _CVector; static_assert(std::is_arithmetic::value, "Type must be arithmetic"); - static_assert(Size > 0, "Size count must be > 0"); + static_assert(Size > 0, "Size must be > 0"); public: - PIMathVectorT() {resize();} - PIMathVectorT(const PIVector & val) {resize(); PIMV_FOR(i, 0) c[i] = val[i];} - PIMathVectorT(const _CVector & st, const _CVector & fn) {resize(); set(st, fn);} + PIMathVectorT(const Type & v = Type()) {PIMV_FOR c[i] = v;} + PIMathVectorT(const PIVector & val) { + assert(Size == val.size()); + PIMV_FOR c[i] = val[i]; + } + static _CVector fromTwoPoints(const _CVector & st, const _CVector & fn) { + _CVector tv; + PIMV_FOR tv[i] = fn[i] - st[i]; + return tv; + } uint size() const {return Size;} - _CVector & fill(const Type & v) {PIMV_FOR(i, 0) c[i] = v; return *this;} - _CVector & set(const _CVector & st, const _CVector & fn) {PIMV_FOR(i, 0) c[i] = fn[i] - st[i]; return *this;} - _CVector & move(const Type & v) {PIMV_FOR(i, 0) c[i] += v; return *this;} - _CVector & move(const _CVector & v) {PIMV_FOR(i, 0) c[i] += v[i]; return *this;} - Type lengthSqr() const {Type tv(0); PIMV_FOR(i, 0) tv += (c[i] * c[i]); return tv;} + _CVector & fill(const Type & v) {PIMV_FOR c[i] = v; return *this;} + _CVector & move(const Type & v) {PIMV_FOR c[i] += v; return *this;} + _CVector & move(const _CVector & v) {PIMV_FOR c[i] += v[i]; return *this;} + Type lengthSqr() const { + Type tv(0); + PIMV_FOR tv += c[i] * c[i]; + return tv; + } Type length() const {return sqrt(lengthSqr());} - Type manhattanLength() const {Type tv(0); PIMV_FOR(i, 0) tv += fabs(c[i]); return tv;} - Type angleCos(const _CVector & v) const {Type tv = v.length() * length(); return (tv == Type(0) ? Type(0) : ((*this) ^ v) / tv);} - Type angleSin(const _CVector & v) const {Type tv = angleCos(v); return sqrt(Type(1) - tv * tv);} + Type manhattanLength() const { + Type tv(0); + PIMV_FOR tv += piAbs(c[i]); + return tv; + } + Type angleCos(const _CVector & v) const { + Type tv = v.length() * length(); + assert(piAbs(tv) > PIMATHVECTOR_ZERO_CMP); + return dot(v) / tv; + } + Type angleSin(const _CVector & v) const { + Type tv = angleCos(v); + return sqrt(Type(1) - tv * tv); + } Type angleRad(const _CVector & v) const {return acos(angleCos(v));} - Type angleDeg(const _CVector & v) const {return toDeg(acos(angleCos(v)));} - Type angleElevation(const _CVector & v) const {_CVector z = v - *this; double c = z.angleCos(*this); return 90.0 - acos(c) * rad2deg;} - _CVector projection(const _CVector & v) {Type tv = v.length(); return (tv == Type(0) ? _CVector() : v * (((*this) ^ v) / tv));} - _CVector & normalize() {Type tv = length(); if (tv == Type(1)) return *this; if (piAbs(tv) <= Type(1E-100)) {fill(Type(0)); return *this;} PIMV_FOR(i, 0) c[i] /= tv; return *this;} + Type angleDeg(const _CVector & v) const {return toDeg(angleRad(v));} + Type angleElevation(const _CVector & v) const {return 90.0 - angleDeg(v - *this);} + _CVector projection(const _CVector & v) { + Type tv = v.length(); + assert(piAbs(tv) > PIMATHVECTOR_ZERO_CMP); + return v * (dot(v) / tv); + } + _CVector & normalize() { + Type tv = length(); + assert(piAbs(tv) > PIMATHVECTOR_ZERO_CMP); + if (tv == Type(1)) return *this; + PIMV_FOR c[i] /= tv; + return *this; + } _CVector normalized() {_CVector tv(*this); tv.normalize(); return tv;} - _CVector cross(const _CVector & v) {return (*this) * v;} - Type dot(const _CVector & v) const {return (*this) ^ v;} - bool isNull() const {PIMV_FOR(i, 0) if (c[i] != Type(0)) return false; return true;} + bool isNull() const {PIMV_FOR if (c[i] != Type(0)) return false; return true;} bool isOrtho(const _CVector & v) const {return ((*this) ^ v) == Type(0);} Type & at(uint index) {return c[index];} Type at(uint index) const {return c[index];} Type & operator [](uint index) {return c[index];} Type operator [](uint index) const {return c[index];} - _CVector & operator =(const _CVector & v) {memcpy(c, v.c, sizeof(Type) * Size); return *this;} - _CVector & operator =(const Type & v) {PIMV_FOR(i, 0) c[i] = v; return *this;} - bool operator ==(const _CVector & v) const {PIMV_FOR(i, 0) if (c[i] != v[i]) return false; return true;} + _CVector & operator =(const Type & v) {PIMV_FOR c[i] = v; return *this;} + bool operator ==(const _CVector & v) const {PIMV_FOR if (c[i] != v[i]) return false; return true;} bool operator !=(const _CVector & v) const {return !(*this == c);} - void operator +=(const _CVector & v) {PIMV_FOR(i, 0) c[i] += v[i];} - void operator -=(const _CVector & v) {PIMV_FOR(i, 0) c[i] -= v[i];} - void operator *=(const Type & v) {PIMV_FOR(i, 0) c[i] *= v;} - void operator *=(const _CVector & v) {PIMV_FOR(i, 0) c[i] *= v[i];} - void operator /=(const Type & v) {PIMV_FOR(i, 0) c[i] /= v;} - void operator /=(const _CVector & v) {PIMV_FOR(i, 0) c[i] /= v[i];} - _CVector operator -() const {_CVector tv; PIMV_FOR(i, 0) tv[i] = -c[i]; return tv;} - _CVector operator +(const _CVector & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] += v[i]; return tv;} - _CVector operator -(const _CVector & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] -= v[i]; return tv;} - _CVector operator *(const Type & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] *= v; return tv;} - _CVector operator /(const Type & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] /= v; return tv;} - _CVector operator /(const _CVector & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] /= v[i]; return tv;} - _CVector operator *(const _CVector & v) const {if (Size != 3) return _CVector(); _CVector tv; tv.fill(Type(1)); tv[0] = c[1]*v[2] - v[1]*c[2]; tv[1] = v[0]*c[2] - c[0]*v[2]; tv[2] = c[0]*v[1] - v[0]*c[1]; return tv;} - _CVector operator &(const _CVector & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] *= v[i]; return tv;} - Type operator ^(const _CVector & v) const {Type tv(0); PIMV_FOR(i, 0) tv += c[i] * v[i]; return tv;} + void operator +=(const _CVector & v) {PIMV_FOR c[i] += v[i];} + void operator -=(const _CVector & v) {PIMV_FOR c[i] -= v[i];} + void operator *=(const Type & v) {PIMV_FOR c[i] *= v;} + void operator /=(const Type & v) { + assert(piAbs(v) > PIMATHVECTOR_ZERO_CMP); + PIMV_FOR c[i] /= v; + } + _CVector operator -() const { + _CVector tv; + PIMV_FOR tv[i] = -c[i]; + return tv; + } + _CVector operator +(const _CVector & v) const { + _CVector tv(*this); + PIMV_FOR tv[i] += v[i]; + return tv; + } + _CVector operator -(const _CVector & v) const { + _CVector tv(*this); + PIMV_FOR tv[i] -= v[i]; + return tv; + } + _CVector operator *(const Type & v) const { + _CVector tv(*this); + PIMV_FOR tv[i] *= v; + return tv; + } + _CVector operator /(const Type & v) const { + assert(piAbs(v) > PIMATHVECTOR_ZERO_CMP); + _CVector tv = _CVector(*this); + PIMV_FOR tv[i] /= v; + return tv; + } + + _CVector cross(const _CVector & v) const { + static_assert(Size == 3, "cross product avalible only for 3D vectors"); + _CVector tv; + tv[0] = c[1]*v[2] - v[1]*c[2]; + tv[1] = v[0]*c[2] - c[0]*v[2]; + tv[2] = c[0]*v[1] - v[0]*c[1]; + return tv; + } + Type dot(const _CVector & v) const { + Type tv(0); + PIMV_FOR tv += c[i] * v[i]; + return tv; + } PIMathMatrixT<1, Size, Type> transposed() const { PIMathMatrixT<1, Size, Type> ret; - PIMV_FOR(i, 0) ret[0][i] = c[i]; + PIMV_FOR ret[0][i] = c[i]; return ret; } Type distToLine(const _CVector & lp0, const _CVector & lp1) { - _CVector a(lp0, lp1), b(lp0, *this), c(lp1, *this); - Type f = fabs(a[0]*b[1] - a[1]*b[0]) / a.length(); - return f;} + _CVector a(lp0, lp1); + Type tv = a.length(); + assert(piAbs(tv) > PIMATHVECTOR_ZERO_CMP); + _CVector b(lp0, *this); + return piAbs(a[0]*b[1] - a[1]*b[0]) / tv; + } template /// vector {Size, Type} to vector {Size1, Type1} - PIMathVectorT turnTo() const {PIMathVectorT tv; uint sz = piMin(Size, Size1); for (uint i = 0; i < sz; ++i) tv[i] = c[i]; return tv;} - - static _CVector filled(const Type & v) {_CVector vv; PIMV_FOR(i, 0) vv[i] = v; return vv;} + PIMathVectorT turnTo() const { + PIMathVectorT tv; + uint sz = piMin(Size, Size1); + for (uint i = 0; i < sz; ++i) tv[i] = c[i]; + return tv; + } private: - void resize(const Type & new_value = Type()) {for (uint i = 0; i < Size; ++i) c[i] = new_value;} - Type c[Size]; }; @@ -117,18 +183,8 @@ inline PIMathVectorT operator *(const Type & x, const PIMathVectorT< } template -inline PICout operator <<(PICout s, const PIMathVectorT & v) {s << "{"; PIMV_FOR(i, 0) {s << v[i]; if (i < Size - 1) s << ", ";} s << "}"; return s;} -template -inline bool operator ||(const PIMathVectorT & f, const PIMathVectorT & s) {return (f * s).isNull();} -template -inline PIMathVectorT sqrt(const PIMathVectorT & v) {PIMathVectorT ret; PIMV_FOR(i, 0) {ret[i] = sqrt(v[i]);} return ret;} -template -inline PIMathVectorT sqr(const PIMathVectorT & v) {PIMathVectorT ret; PIMV_FOR(i, 0) {ret[i] = sqr(v[i]);} return ret;} +inline PICout operator <<(PICout s, const PIMathVectorT & v) {s << "{"; PIMV_FOR {s << v[i]; if (i < Size - 1) s << ", ";} s << "}"; return s;} -template -inline PIByteArray & operator <<(PIByteArray & s, const PIMathVectorT & v) {for (uint i = 0; i < Size; ++i) s << v[i]; return s;} -template -inline PIByteArray & operator >>(PIByteArray & s, PIMathVectorT & v) {for (uint i = 0; i < Size; ++i) s >> v[i]; return s;} template @@ -158,7 +214,7 @@ typedef PIMathVectorT<4u, double> PIMathVectorT4d; /// Vector -#define PIMV_FOR(v, s) for (uint v = s; v < c.size(); ++v) +#define PIMV_FOR for (uint i = 0; i < c.size(); ++i) template class PIP_EXPORT PIMathVector { @@ -166,63 +222,167 @@ class PIP_EXPORT PIMathVector { template friend PIByteArray & operator <<(PIByteArray & s, const PIMathVector & v); template friend PIByteArray & operator >>(PIByteArray & s, PIMathVector & v); public: - PIMathVector(const uint size = 0) {c.resize(size);} - PIMathVector(const PIVector & val) {c.resize(val.size()); PIMV_FOR(i, 0) c[i] = val[i];} - PIMathVector(const _CVector & st, const _CVector & fn) {c.resize(st.size()); PIMV_FOR(i, 0) c[i] = fn[i] - st[i];} + PIMathVector(const uint size = 0, const Type & new_value = Type()) {c.resize(size, new_value);} + PIMathVector(const PIVector & val) {c = val;} + + template + PIMathVector(const PIMathVectorT & val) {c.resize(Size); PIMV_FOR c[i] = val[i];} + + static PIMathVector fromTwoPoints(const _CVector & st, const _CVector & fn) { + assert(st.size() == fn.size()); + _CVector v(st.size()); + for (uint i = 0; i < v.size(); ++i) v.c[i] = fn[i] - st[i]; + } uint size() const {return c.size();} - _CVector & resize(uint size, const Type & new_value = Type()) {c.resize(size, new_value); return *this;} - _CVector resized(uint size, const Type & new_value = Type()) {_CVector tv = _CVector(*this); tv.resize(size, new_value); return tv;} - _CVector & fill(const Type & v) {PIMV_FOR(i, 0) c[i] = v; return *this;} - _CVector & move(const Type & v) {PIMV_FOR(i, 0) c[i] += v; return *this;} - _CVector & move(const _CVector & v) {PIMV_FOR(i, 0) c[i] += v[i]; return *this;} - _CVector & swap(uint fe, uint se) {piSwap(c[fe], c[se]); return *this;} - Type lengthSqr() const {Type tv(0); PIMV_FOR(i, 0) tv += (c[i] * c[i]); return tv;} + _CVector & resize(uint size, const Type & new_value = Type()) { + c.resize(size, new_value); + return *this; + } + _CVector resized(uint size, const Type & new_value = Type()) { + _CVector tv = _CVector(*this); + tv.resize(size, new_value); + return tv; + } + _CVector & fill(const Type & v) { + c.fill(v); + return *this; + } + _CVector & move(const Type & v) { + PIMV_FOR c[i] += v; + return *this; + } + _CVector & move(const _CVector & v) { + assert(c.size() == v.size()); + PIMV_FOR c[i] += v[i]; + return *this; + } + _CVector & swapElements(uint fe, uint se) { + piSwap(c[fe], c[se]); + return *this; + } + Type lengthSqr() const { + Type tv(0); + PIMV_FOR tv += c[i] * c[i]; + return tv; + } Type length() const {return sqrt(lengthSqr());} - Type manhattanLength() const {Type tv(0); PIMV_FOR(i, 0) tv += fabs(c[i]); return tv;} - Type angleCos(const _CVector & v) const {Type tv = v.length() * length(); return (tv == Type(0) ? Type(0) : ((*this) ^ v) / tv);} - Type angleSin(const _CVector & v) const {Type tv = angleCos(v); return sqrt(Type(1) - tv * tv);} + Type manhattanLength() const { + Type tv(0); + PIMV_FOR tv += piAbs(c[i]); + return tv; + } + Type angleCos(const _CVector & v) const { + assert(c.size() == v.size()); + Type tv = v.length() * length(); + assert(piAbs(tv) > PIMATHVECTOR_ZERO_CMP); + return dot(v) / tv; + } + Type angleSin(const _CVector & v) const { + assert(c.size() == v.size()); + Type tv = angleCos(v); + return sqrt(Type(1) - tv * tv); + } Type angleRad(const _CVector & v) const {return acos(angleCos(v));} - Type angleDeg(const _CVector & v) const {return toDeg(acos(angleCos(v)));} - _CVector projection(const _CVector & v) {Type tv = v.length(); return (tv == Type(0) ? _CVector() : v * (((*this) ^ v) / tv));} - _CVector & normalize() {Type tv = length(); if (tv == Type(1)) return *this; if (piAbs(tv) <= Type(1E-100)) {fill(Type(0)); return *this;} PIMV_FOR(i, 0) c[i] /= tv; return *this;} - _CVector normalized() {_CVector tv(*this); tv.normalize(); return tv;} - bool isNull() const {PIMV_FOR(i, 0) if (c[i] != Type(0)) return false; return true;} + Type angleDeg(const _CVector & v) const {return toDeg(angleRad(v));} + _CVector projection(const _CVector & v) { + assert(c.size() == v.size()); + Type tv = v.length(); + assert(piAbs(tv) > PIMATHVECTOR_ZERO_CMP); + return v * (dot(v) / tv); + } + _CVector & normalize() { + Type tv = length(); + assert(piAbs(tv) > PIMATHVECTOR_ZERO_CMP); + if (tv == Type(1)) return *this; + PIMV_FOR c[i] /= tv; + return *this; + } + _CVector normalized() { + _CVector tv(*this); + tv.normalize(); + return tv; + } + bool isNull() const { + PIMV_FOR if (c[i] != Type(0)) return false; + return true; + } bool isValid() const {return !c.isEmpty();} - - bool isOrtho(const _CVector & v) const {return ((*this) ^ v) == Type(0);} + bool isOrtho(const _CVector & v) const {return dot(v) == Type(0);} Type & at(uint index) {return c[index];} Type at(uint index) const {return c[index];} Type & operator [](uint index) {return c[index];} Type operator [](uint index) const {return c[index];} - _CVector & operator =(const _CVector & v) {c = v.c; return *this;} - _CVector & operator =(const Type & v) {PIMV_FOR(i, 0) c[i] = v; return *this;} - bool operator ==(const _CVector & v) const {PIMV_FOR(i, 0) if (c[i] != v[i]) return false; return true;} - bool operator !=(const _CVector & v) const {return !(*this == c);} - void operator +=(const _CVector & v) {PIMV_FOR(i, 0) c[i] += v[i];} - void operator -=(const _CVector & v) {PIMV_FOR(i, 0) c[i] -= v[i];} - void operator *=(const Type & v) {PIMV_FOR(i, 0) c[i] *= v;} - void operator *=(const _CVector & v) {PIMV_FOR(i, 0) c[i] *= v[i];} - void operator /=(const Type & v) {PIMV_FOR(i, 0) c[i] /= v;} - void operator /=(const _CVector & v) {PIMV_FOR(i, 0) c[i] /= v[i];} - _CVector operator -() const {_CVector tv; PIMV_FOR(i, 0) tv[i] = -c[i]; return tv;} - _CVector operator +(const _CVector & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] += v[i]; return tv;} - _CVector operator -(const _CVector & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] -= v[i]; return tv;} - _CVector operator *(const Type & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] *= v; return tv;} - _CVector operator /(const Type & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] /= v; return tv;} - _CVector operator *(const _CVector & v) const {if (c.size() < 3) return _CVector(); _CVector tv; tv.fill(Type(1)); tv[0] = c[1]*v[2] - v[1]*c[2]; tv[1] = v[0]*c[2] - c[0]*v[2]; tv[2] = c[0]*v[1] - v[0]*c[1]; return tv;} - _CVector operator &(const _CVector & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] *= v[i]; return tv;} - Type operator ^(const _CVector & v) const {Type tv(0); PIMV_FOR(i, 0) tv += c[i] * v[i]; return tv;} - - Type distToLine(const _CVector & lp0, const _CVector & lp1) { - _CVector a(lp0, lp1), b(lp0, *this), c(lp1, *this); - Type f = fabs(a[0]*b[1] - a[1]*b[0]) / a.length(); - return f; + bool operator ==(const _CVector & v) const {return c == v.c;} + bool operator !=(const _CVector & v) const {return c != v.c;} + void operator +=(const _CVector & v) { + assert(c.size() == v.size()); + PIMV_FOR c[i] += v[i]; + } + void operator -=(const _CVector & v) { + assert(c.size() == v.size()); + PIMV_FOR c[i] -= v[i]; + } + void operator *=(const Type & v) {PIMV_FOR c[i] *= v;} + void operator /=(const Type & v) { + assert(piAbs(v) > PIMATHVECTOR_ZERO_CMP); + PIMV_FOR c[i] /= v; + } + _CVector operator -() const { + _CVector tv(c.size()); + PIMV_FOR tv[i] = -c[i]; + return tv; + } + _CVector operator +(const _CVector & v) const { + assert(c.size() == v.size()); + _CVector tv(*this); + PIMV_FOR tv[i] += v[i]; + return tv; + } + _CVector operator -(const _CVector & v) const { + assert(c.size() == v.size()); + _CVector tv(*this); + PIMV_FOR tv[i] -= v[i]; + return tv; + } + _CVector operator *(const Type & v) const { + _CVector tv(*this); + PIMV_FOR tv[i] *= v; + return tv; + } + _CVector operator /(const Type & v) const { + assert(piAbs(v) > PIMATHVECTOR_ZERO_CMP); + _CVector tv(*this); + PIMV_FOR tv[i] /= v; + return tv; + } + _CVector cross(const _CVector & v) const { + assert(c.size() == 3); + assert(v.size() == 3); + _CVector tv(3); + tv[0] = c[1]*v[2] - v[1]*c[2]; + tv[1] = c[2]*v[0] - v[2]*c[0]; + tv[2] = c[0]*v[1] - v[0]*c[1]; + return tv; + } + Type dot(const _CVector & v) const { + assert(c.size() == v.size()); + Type tv(0); + PIMV_FOR tv += c[i] * v[i]; + return tv; + } + + Type distToLine(const _CVector & lp0, const _CVector & lp1) { + assert(c.size() == lp0.size()); + assert(c.size() == lp1.size()); + _CVector a = _CVector::fromTwoPoints(lp0, lp1); + Type tv = a.length(); + assert(piAbs(tv) > PIMATHVECTOR_ZERO_CMP); + _CVector b = _CVector::fromTwoPoints(lp0, *this); + return piAbs(a[0]*b[1] - a[1]*b[0]) / tv; } - template - PIMathVector turnTo(uint size) const {PIMathVector tv; uint sz = piMin(c.size(), size); for (uint i = 0; i < sz; ++i) tv[i] = c[i]; return tv;} PIVector toVector() const {return c;} inline Type * data() {return c.data();} @@ -233,6 +393,11 @@ private: }; +template +inline PIMathVector operator *(const Type & x, const PIMathVector & v) { + return v * x; +} + #undef PIMV_FOR #ifdef PIP_STD_IOSTREAM diff --git a/libs/main/math/piquaternion.cpp b/libs/main/math/piquaternion.cpp index 5ea23fe9..fa95ad7c 100644 --- a/libs/main/math/piquaternion.cpp +++ b/libs/main/math/piquaternion.cpp @@ -199,8 +199,8 @@ PIQuaternion PIQuaternion::fromRotationMatrix(const PIMathMatrixT33d & m) { PIQuaternion operator*(const PIQuaternion & q0, const PIQuaternion & q1) { PIMathVectorT3d v0(q0.vector()), v1(q1.vector()); - double r0 = q0.q[0] * q1.q[0] - (v0^v1); - PIMathVectorT3d qv = v1*q0.q[0] + v0*q1.q[0] + v0*v1; + double r0 = q0.q[0] * q1.q[0] - v0.dot(v1); + PIMathVectorT3d qv = v1*q0.q[0] + v0*q1.q[0] + v0.cross(v1); PIQuaternion ret; ret.q[0] = r0; ret.q[1] = qv[0]; From 6f3fdf4d4945bb24e807050147a3766c49611dff Mon Sep 17 00:00:00 2001 From: andrey Date: Wed, 21 Oct 2020 18:36:57 +0300 Subject: [PATCH 48/98] pimathvector.h mul --- libs/main/math/pimathvector.h | 50 ++++++++++++++++++++++++++++++++++- main.cpp | 9 +++---- 2 files changed, 52 insertions(+), 7 deletions(-) diff --git a/libs/main/math/pimathvector.h b/libs/main/math/pimathvector.h index 010b74e3..8983fd37 100644 --- a/libs/main/math/pimathvector.h +++ b/libs/main/math/pimathvector.h @@ -149,6 +149,14 @@ public: PIMV_FOR tv += c[i] * v[i]; return tv; } + _CVector mul(const _CVector & v) const { + _CVector tv(*this); + PIMV_FOR tv[i] *= v[i]; + return tv; + } + _CVector mul(const Type & v) const { + return (*this) * v; + } PIMathMatrixT<1, Size, Type> transposed() const { PIMathMatrixT<1, Size, Type> ret; @@ -172,6 +180,22 @@ public: return tv; } + static _CVector cross(const _CVector & v1, const _CVector & v2) { + return v1.cross(v2); + } + static _CVector dot(const _CVector & v1, const _CVector & v2) { + return v1.dot(v2); + } + static _CVector mul(const _CVector & v1, const _CVector & v2) { + return v1.mul(v2); + } + static _CVector mul(const Type & v1, const _CVector & v2) { + return v2 * v1; + } + static _CVector mul(const _CVector & v1, const Type & v2) { + return v1 * v2; + } + private: Type c[Size]; @@ -372,6 +396,15 @@ public: PIMV_FOR tv += c[i] * v[i]; return tv; } + _CVector mul(const _CVector & v) const { + assert(c.size() == v.size()); + _CVector tv(*this); + PIMV_FOR tv[i] *= v[i]; + return tv; + } + _CVector mul(const Type & v) const { + return (*this) * v; + } Type distToLine(const _CVector & lp0, const _CVector & lp1) { assert(c.size() == lp0.size()); @@ -388,9 +421,24 @@ public: inline Type * data() {return c.data();} inline const Type * data() const {return c.data();} + + static _CVector cross(const _CVector & v1, const _CVector & v2) { + return v1.cross(v2); + } + static _CVector dot(const _CVector & v1, const _CVector & v2) { + return v1.dot(v2); + } + static _CVector mul(const _CVector & v1, const _CVector & v2) { + return v1.mul(v2); + } + static _CVector mul(const Type & v1, const _CVector & v2) { + return v2 * v1; + } + static _CVector mul(const _CVector & v1, const Type & v2) { + return v1 * v2; + } private: PIVector c; - }; template diff --git a/main.cpp b/main.cpp index e4194112..072c42ab 100644 --- a/main.cpp +++ b/main.cpp @@ -40,11 +40,8 @@ inline PIByteArray & operator >>(PIByteArray & ba, MM & v) {piCout << ">>" int main() { - PIMathMatrixd m = PIMathMatrixd::identity(5,5); -// m.fill(9); - //PIMathMatrixd m2 = PIMathMatrixd::identity(3,4); - piCout << m; - m.resize(3,3); - piCout << m; + PIMathVectorT3d v3 = createVectorT3d(1,2,3); + PIMathVectord v(v3); + piCout << v; return 0; } From a7408922dfac67dc297c9d512434d69aeb665266 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Wed, 21 Oct 2020 18:49:04 +0300 Subject: [PATCH 49/98] add constexpr to pibase methods --- libs/main/core/pibase.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/libs/main/core/pibase.h b/libs/main/core/pibase.h index 82b95935..593a0dfa 100644 --- a/libs/main/core/pibase.h +++ b/libs/main/core/pibase.h @@ -358,7 +358,7 @@ inline bool piCompareBinary(const void * f, const void * s, size_t size) { * * Example: * \snippet piincludes.cpp round */ -template inline int piRound(const T & v) {return int(v >= T(0.) ? v + T(0.5) : v - T(0.5));} +template inline constexpr int piRound(const T & v) {return int(v >= T(0.) ? v + T(0.5) : v - T(0.5));} /*! \brief Templated function return floor of float falue * \details Floor is the largest integer that is not greater than value \n @@ -368,7 +368,7 @@ template inline int piRound(const T & v) {return int(v >= T(0.) ? v * * Example: * \snippet piincludes.cpp floor */ -template inline int piFloor(const T & v) {return v < T(0) ? int(v) - 1 : int(v);} +template inline constexpr int piFloor(const T & v) {return v < T(0) ? int(v) - 1 : int(v);} /*! \brief Templated function return ceil of float falue * \details Ceil is the smallest integer that is not less than value \n @@ -378,7 +378,7 @@ template inline int piFloor(const T & v) {return v < T(0) ? int(v) - * * Example: * \snippet piincludes.cpp ceil */ -template inline int piCeil(const T & v) {return v < T(0) ? int(v) : int(v) + 1;} +template inline constexpr int piCeil(const T & v) {return v < T(0) ? int(v) : int(v) + 1;} /*! \brief Templated function return absolute of numeric falue * \details Absolute is the positive or equal 0 value \n @@ -392,7 +392,7 @@ template inline int piCeil(const T & v) {return v < T(0) ? int(v) : * * Example: * \snippet piincludes.cpp abs */ -template inline T piAbs(const T & v) {return (v >= T(0) ? v : -v);} +template inline constexpr T piAbs(const T & v) {return (v >= T(0) ? v : -v);} /*! \brief Templated function return minimum of two values * \details There are some macros: @@ -405,7 +405,7 @@ template inline T piAbs(const T & v) {return (v >= T(0) ? v : -v);} * * Example: * \snippet piincludes.cpp min2 */ -template inline T piMin(const T & f, const T & s) {return ((f > s) ? s : f);} +template inline constexpr T piMin(const T & f, const T & s) {return ((f > s) ? s : f);} /*! \brief Templated function return minimum of tree values * \details There are some macros: @@ -418,7 +418,7 @@ template inline T piMin(const T & f, const T & s) {return ((f > s) ? * * Example: * \snippet piincludes.cpp min3 */ -template inline T piMin(const T & f, const T & s, const T & t) {return ((f < s && f < t) ? f : ((s < t) ? s : t));} +template inline constexpr T piMin(const T & f, const T & s, const T & t) {return ((f < s && f < t) ? f : ((s < t) ? s : t));} /*! \brief Templated function return maximum of two values * \details There are some macros: @@ -431,7 +431,7 @@ template inline T piMin(const T & f, const T & s, const T & t) {retu * * Example: * \snippet piincludes.cpp max2 */ -template inline T piMax(const T & f, const T & s) {return ((f < s) ? s : f);} +template inline constexpr T piMax(const T & f, const T & s) {return ((f < s) ? s : f);} /*! \brief Templated function return maximum of tree values * \details There are some macros: @@ -444,7 +444,7 @@ template inline T piMax(const T & f, const T & s) {return ((f < s) ? * * Example: * \snippet piincludes.cpp max3 */ -template inline T piMax(const T & f, const T & s, const T & t) {return ((f > s && f > t) ? f : ((s > t) ? s : t));} +template inline constexpr T piMax(const T & f, const T & s, const T & t) {return ((f > s && f > t) ? f : ((s > t) ? s : t));} /*! \brief Templated function return clamped value * \details Clamped is the not greater than "max" and not lesser than "min" value \n @@ -458,7 +458,7 @@ template inline T piMax(const T & f, const T & s, const T & t) {retu * * Example: * \snippet piincludes.cpp clamp */ -template inline T piClamp(const T & v, const T & min, const T & max) {return (v > max ? max : (v < min ? min : v));} +template inline constexpr T piClamp(const T & v, const T & min, const T & max) {return (v > max ? max : (v < min ? min : v));} /// Function inverse byte order in memory block inline void piLetobe(void * data, int size) { From 47be2d3d6297838a9eb22617e7a724824fb59d9d Mon Sep 17 00:00:00 2001 From: andrey Date: Wed, 21 Oct 2020 18:54:41 +0300 Subject: [PATCH 50/98] pimathvector.h div and std::initializer_list --- libs/main/math/pimathvector.h | 60 +++++++++++++++++++++++---------- libs/main/math/piquaternion.cpp | 4 +-- libs/main/math/piquaternion.h | 2 +- main.cpp | 4 ++- 4 files changed, 48 insertions(+), 22 deletions(-) diff --git a/libs/main/math/pimathvector.h b/libs/main/math/pimathvector.h index 8983fd37..4f89a7b9 100644 --- a/libs/main/math/pimathvector.h +++ b/libs/main/math/pimathvector.h @@ -46,6 +46,10 @@ public: assert(Size == val.size()); PIMV_FOR c[i] = val[i]; } + PIMathVectorT(std::initializer_list init_list) { + assert(Size == init_list.size()); + PIMV_FOR c[i] = init_list.begin()[i]; + } static _CVector fromTwoPoints(const _CVector & st, const _CVector & fn) { _CVector tv; PIMV_FOR tv[i] = fn[i] - st[i]; @@ -157,7 +161,18 @@ public: _CVector mul(const Type & v) const { return (*this) * v; } - + _CVector div(const _CVector & v) const { + _CVector tv(*this); + PIMV_FOR { + assert(piAbs(v[i]) > PIMATHVECTOR_ZERO_CMP); + tv[i] /= v[i]; + } + return tv; + } + _CVector div(const Type & v) const { + return (*this) / v; + } + PIMathMatrixT<1, Size, Type> transposed() const { PIMathMatrixT<1, Size, Type> ret; PIMV_FOR ret[0][i] = c[i]; @@ -195,6 +210,12 @@ public: static _CVector mul(const _CVector & v1, const Type & v2) { return v1 * v2; } + static _CVector div(const _CVector & v1, const _CVector & v2) { + return v1.div(v2); + } + static _CVector div(const _CVector & v1, const Type & v2) { + return v1 / v2; + } private: Type c[Size]; @@ -210,29 +231,13 @@ template inline PICout operator <<(PICout s, const PIMathVectorT & v) {s << "{"; PIMV_FOR {s << v[i]; if (i < Size - 1) s << ", ";} s << "}"; return s;} - -template -inline PIMathVectorT<2u, T> createVectorT2(T x, T y) {return PIMathVectorT<2u, T>(PIVector() << x << y);} -template -inline PIMathVectorT<3u, T> createVectorT3(T x, T y, T z) {return PIMathVectorT<3u, T>(PIVector() << x << y << z);} -template -inline PIMathVectorT<4u, T> createVectorT4(T x, T y, T z, T w) {return PIMathVectorT<4u, T>(PIVector() << x << y << z << w);} - typedef PIMathVectorT<2u, int> PIMathVectorT2i; typedef PIMathVectorT<3u, int> PIMathVectorT3i; typedef PIMathVectorT<4u, int> PIMathVectorT4i; typedef PIMathVectorT<2u, double> PIMathVectorT2d; typedef PIMathVectorT<3u, double> PIMathVectorT3d; typedef PIMathVectorT<4u, double> PIMathVectorT4d; -#define createVectorT2i createVectorT2 -#define createVectorT3i createVectorT3 -#define createVectorT4i createVectorT4 -#define createVectorT2f createVectorT2 -#define createVectorT3f createVectorT3 -#define createVectorT4f createVectorT4 -#define createVectorT2d createVectorT2 -#define createVectorT3d createVectorT3 -#define createVectorT4d createVectorT4 + #undef PIMV_FOR @@ -248,6 +253,7 @@ class PIP_EXPORT PIMathVector { public: PIMathVector(const uint size = 0, const Type & new_value = Type()) {c.resize(size, new_value);} PIMathVector(const PIVector & val) {c = val;} + PIMathVector(std::initializer_list init_list) {c = PIVector(init_list);} template PIMathVector(const PIMathVectorT & val) {c.resize(Size); PIMV_FOR c[i] = val[i];} @@ -405,6 +411,18 @@ public: _CVector mul(const Type & v) const { return (*this) * v; } + _CVector div(const _CVector & v) const { + assert(c.size() == v.size()); + _CVector tv(*this); + PIMV_FOR { + assert(piAbs(v[i]) > PIMATHVECTOR_ZERO_CMP); + tv[i] /= v[i]; + } + return tv; + } + _CVector div(const Type & v) const { + return (*this) / v; + } Type distToLine(const _CVector & lp0, const _CVector & lp1) { assert(c.size() == lp0.size()); @@ -437,6 +455,12 @@ public: static _CVector mul(const _CVector & v1, const Type & v2) { return v1 * v2; } + static _CVector div(const _CVector & v1, const _CVector & v2) { + return v1.div(v2); + } + static _CVector div(const _CVector & v1, const Type & v2) { + return v1 / v2; + } private: PIVector c; }; diff --git a/libs/main/math/piquaternion.cpp b/libs/main/math/piquaternion.cpp index fa95ad7c..9dc570a2 100644 --- a/libs/main/math/piquaternion.cpp +++ b/libs/main/math/piquaternion.cpp @@ -40,7 +40,7 @@ PIMathVectorT3d PIQuaternion::eyler() const { angle_z = atan2(-rmat[0][1] / c, rmat[0][0] / c); } if (angle_z < 0) angle_z = 2*M_PI + angle_z; - return createVectorT3d(angle_x,angle_y,angle_z); + return PIMathVectorT3d({angle_x,angle_y,angle_z}); } @@ -153,7 +153,7 @@ PIQuaternion PIQuaternion::fromAngles(double ax, double ay, double az) { } PIQuaternion PIQuaternion::fromAngles2(double ax, double ay, double az) { - double om = createVectorT3d(ax,ay,az).length(); + double om = PIMathVectorT3d({ax,ay,az}).length(); if (om == 0.) return PIQuaternion(PIMathVectorT3d(), 1.); PIQuaternion res; res.q[0] = cos(om/2); diff --git a/libs/main/math/piquaternion.h b/libs/main/math/piquaternion.h index e9b79e92..c54dbf89 100644 --- a/libs/main/math/piquaternion.h +++ b/libs/main/math/piquaternion.h @@ -39,7 +39,7 @@ public: double & scalar() {return q[0];} double scalar() const {return q[0];} - PIMathVectorT3d vector() const {return createVectorT3(q[1], q[2], q[3]);} + PIMathVectorT3d vector() const {return PIMathVectorT3d({q[1], q[2], q[3]});} PIMathVectorT3d eyler() const; PIMathMatrixT33d rotationMatrix() const; diff --git a/main.cpp b/main.cpp index 072c42ab..10dfb678 100644 --- a/main.cpp +++ b/main.cpp @@ -40,8 +40,10 @@ inline PIByteArray & operator >>(PIByteArray & ba, MM & v) {piCout << ">>" int main() { - PIMathVectorT3d v3 = createVectorT3d(1,2,3); + PIMathVectorT3d v3({1,2,3}); PIMathVectord v(v3); + PIMathVectord v2({3,2,1}); piCout << v; + piCout << v2; return 0; } From 13a0c1097afd19f0f2b41369c8ba4b9efff1edf0 Mon Sep 17 00:00:00 2001 From: andrey Date: Wed, 21 Oct 2020 18:55:31 +0300 Subject: [PATCH 51/98] version --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a9237f2a..8f00c155 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,9 +2,9 @@ cmake_minimum_required(VERSION 3.0) cmake_policy(SET CMP0017 NEW) # need include() with .cmake project(pip) set(pip_MAJOR 2) -set(pip_MINOR 13) +set(pip_MINOR 14) set(pip_REVISION 0) -set(pip_SUFFIX beta) +set(pip_SUFFIX alpha) set(pip_COMPANY SHS) set(pip_DOMAIN org.SHS) From b46825a5a07e688161432f091b815827c81bb248 Mon Sep 17 00:00:00 2001 From: andrey Date: Thu, 22 Oct 2020 12:44:30 +0300 Subject: [PATCH 52/98] PIMathMatrixT remove scale and rotate funcs --- libs/main/math/pimathmatrix.h | 241 ++++++++------------------------ libs/main/math/piquaternion.cpp | 10 -- libs/main/math/piquaternion.h | 3 - 3 files changed, 56 insertions(+), 198 deletions(-) diff --git a/libs/main/math/pimathmatrix.h b/libs/main/math/pimathmatrix.h index 645c9e22..1e263e15 100644 --- a/libs/main/math/pimathmatrix.h +++ b/libs/main/math/pimathmatrix.h @@ -31,12 +31,9 @@ /// Matrix templated -#define PIMM_FOR(r, c) for (uint c = 0; c < Cols; ++c) { for (uint r = 0; r < Rows; ++r) { -#define PIMM_FOR_WB(r, c) for (uint c = 0; c < Cols; ++c) for (uint r = 0; r < Rows; ++r) // without brakes -#define PIMM_FOR_I(r, c) for (uint r = 0; r < Rows; ++r) { for (uint c = 0; c < Cols; ++c) { -#define PIMM_FOR_I_WB(r, c) for (uint r = 0; r < Rows; ++r) for (uint c = 0; c < Cols; ++c) // without brakes -#define PIMM_FOR_C(v) for (uint v = 0; v < Cols; ++v) -#define PIMM_FOR_R(v) for (uint v = 0; v < Rows; ++v) +#define PIMM_FOR for (uint r = 0; r < Rows; ++r) for (uint c = 0; c < Cols; ++c) +#define PIMM_FOR_C for (uint i = 0; i < Cols; ++i) +#define PIMM_FOR_R for (uint i = 0; i < Rows; ++i) #pragma pack(push, 1) @@ -71,7 +68,16 @@ public: PIMathMatrixT(const PIVector &val) { resize(Rows, Cols); int i = 0; - PIMM_FOR_I_WB(r, c) m[r][c] = val[i++]; + PIMM_FOR m[r][c] = val[i++]; + } + + /** + * @brief Contructs PIMathMatrixT from C++11 initializer list + */ + PIMathMatrixT(std::initializer_list init_list) { + assert(Rows*Cols == init_list.size()); + int i = 0; + PIMM_FOR m[r][c] = init_list.begin()[i++]; } /** @@ -81,7 +87,7 @@ public: */ static _CMatrix identity() { _CMatrix tm = _CMatrix(); - PIMM_FOR_WB(r, c) tm.m[r][c] = (c == r ? Type(1) : Type(0)); + PIMM_FOR tm.m[r][c] = (c == r ? Type(1) : Type(0)); return tm; } @@ -93,73 +99,10 @@ public: */ static _CMatrix filled(const Type &v) { _CMatrix tm; - PIMM_FOR_WB(r, c) tm.m[r][c] = v; + PIMM_FOR tm.m[r][c] = v; return tm; } - /** - * @brief Rotation the matrix by an "angle". Works only with 2x2 matrix, - * else return default construction of PIMathMatrixT - * - * @param angle is the angle of rotation of the matrix - * @return rotated matrix - */ - static _CMatrix rotation(double angle) { return _CMatrix(); } - - /** - * @brief Rotation of the matrix by an "angle" along the X axis. Works only with 3x3 matrix, - * else return default construction of PIMathMatrixT - * - * @param angle is the angle of rotation of the matrix along the X axis - * @return rotated matrix - */ - static _CMatrix rotationX(double angle) { return _CMatrix(); } - - /** - * @brief Rotation of the matrix by an "angle" along the Y axis. Works only with 3x3 matrix, - * else return default construction of PIMathMatrixT - * - * @param angle is the angle of rotation of the matrix along the Y axis - * @return rotated matrix - */ - static _CMatrix rotationY(double angle) { return _CMatrix(); } - - /** - * @brief Rotation of the matrix by an "angle" along the Z axis. Works only with 3x3 matrix, - * else return default construction of PIMathMatrixT - * - * @param angle is the angle of rotation of the matrix along the Z axis - * @return rotated matrix - */ - static _CMatrix rotationZ(double angle) { return _CMatrix(); } - - /** - * @brief Scaling the matrix along the X axis by the value "factor". Works only with 3x3 and 2x2 matrix, - * else return default construction of PIMathMatrixT - * - * @param factor is the value of scaling by X axis - * @return rotated matrix - */ - static _CMatrix scaleX(double factor) { return _CMatrix(); } - - /** - * @brief Scaling the matrix along the Y axis by the value "factor". Works only with 3x3 and 2x2 matrix, - * else return default construction of PIMathMatrixT - * - * @param factor is the value of scaling by Y axis - * @return rotated matrix - */ - static _CMatrix scaleY(double factor) { return _CMatrix(); } - - /** - * @brief Scaling the matrix along the Z axis by the value "factor". Works only with 3x3 matrix, - * else return default construction of PIMathMatrixT - * - * @param factor is the value of scaling by Z axis - * @return rotated matrix - */ - static _CMatrix scaleZ(double factor) { return _CMatrix(); } - /** * @brief Method which returns number of columns in matrix * @@ -183,7 +126,7 @@ public: */ _CMCol col(uint index) { _CMCol tv; - PIMM_FOR_R(i) tv[i] = m[i][index]; + PIMM_FOR_R tv[i] = m[i][index]; return tv; } @@ -196,7 +139,7 @@ public: */ _CMRow row(uint index) { _CMRow tv; - PIMM_FOR_C(i) tv[i] = m[index][i]; + PIMM_FOR_C tv[i] = m[index][i]; return tv; } @@ -209,7 +152,7 @@ public: * @return matrix type _CMatrix */ _CMatrix &setCol(uint index, const _CMCol &v) { - PIMM_FOR_R(i) m[i][index] = v[i]; + PIMM_FOR_R m[i][index] = v[i]; return *this; } @@ -222,7 +165,7 @@ public: * @return matrix type _CMatrix */ _CMatrix &setRow(uint index, const _CMRow &v) { - PIMM_FOR_C(i) m[index][i] = v[i]; + PIMM_FOR_C m[index][i] = v[i]; return *this; } @@ -236,7 +179,7 @@ public: */ _CMatrix &swapRows(uint r0, uint r1) { Type t; - PIMM_FOR_C(i) { + PIMM_FOR_C { t = m[r0][i]; m[r0][i] = m[r1][i]; m[r1][i] = t; @@ -254,7 +197,7 @@ public: */ _CMatrix &swapCols(uint c0, uint c1) { Type t; - PIMM_FOR_R(i) { + PIMM_FOR_R { t = m[i][c0]; m[i][c0] = m[i][c1]; m[i][c1] = t; @@ -269,7 +212,7 @@ public: * @return filled matrix type _CMatrix */ _CMatrix &fill(const Type &v) { - PIMM_FOR_WB(r, c) m[r][c] = v; + PIMM_FOR m[r][c] = v; return *this; } @@ -286,7 +229,7 @@ public: * @return true if matrix is identitied, else false */ bool isIdentity() const { - PIMM_FOR_WB(r, c) if ((c == r) ? m[r][c] != Type(1) : m[r][c] != Type(0)) return false; + PIMM_FOR if ((c == r) ? m[r][c] != Type(1) : m[r][c] != Type(0)) return false; return true; } @@ -296,7 +239,7 @@ public: * @return true if matrix is null, else false */ bool isNull() const { - PIMM_FOR_WB(r, c) if (m[r][c] != Type(0)) return false; + PIMM_FOR if (m[r][c] != Type(0)) return false; return true; } @@ -354,7 +297,7 @@ public: * @return if matrices are equal true, else false */ bool operator==(const _CMatrix &sm) const { - PIMM_FOR_WB(r, c) if (m[r][c] != sm.m[r][c]) return false; + PIMM_FOR if (m[r][c] != sm.m[r][c]) return false; return true; } @@ -371,28 +314,28 @@ public: * * @param sm matrix for the addition assigment */ - void operator+=(const _CMatrix &sm) { PIMM_FOR_WB(r, c) m[r][c] += sm.m[r][c]; } + void operator+=(const _CMatrix &sm) { PIMM_FOR m[r][c] += sm.m[r][c]; } /** * @brief Subtraction assignment with matrix "sm" * * @param sm matrix for the subtraction assigment */ - void operator-=(const _CMatrix &sm) { PIMM_FOR_WB(r, c) m[r][c] -= sm.m[r][c]; } + void operator-=(const _CMatrix &sm) { PIMM_FOR m[r][c] -= sm.m[r][c]; } /** * @brief Multiplication assignment with value "v" * * @param v value for the multiplication assigment */ - void operator*=(const Type &v) { PIMM_FOR_WB(r, c) m[r][c] *= v; } + void operator*=(const Type &v) { PIMM_FOR m[r][c] *= v; } /** * @brief Division assignment with value "v" * * @param v value for the division assigment */ - void operator/=(const Type &v) { PIMM_FOR_WB(r, c) m[r][c] /= v; } + void operator/=(const Type &v) { PIMM_FOR m[r][c] /= v; } /** * @brief Matrix substraction @@ -401,7 +344,7 @@ public: */ _CMatrix operator-() const { _CMatrix tm; - PIMM_FOR_WB(r, c) tm.m[r][c] = -m[r][c]; + PIMM_FOR tm.m[r][c] = -m[r][c]; return tm; } @@ -413,7 +356,7 @@ public: */ _CMatrix operator+(const _CMatrix &sm) const { _CMatrix tm = _CMatrix(*this); - PIMM_FOR_WB(r, c) tm.m[r][c] += sm.m[r][c]; + PIMM_FOR tm.m[r][c] += sm.m[r][c]; return tm; } @@ -425,7 +368,7 @@ public: */ _CMatrix operator-(const _CMatrix &sm) const { _CMatrix tm = _CMatrix(*this); - PIMM_FOR_WB(r, c) tm.m[r][c] -= sm.m[r][c]; + PIMM_FOR tm.m[r][c] -= sm.m[r][c]; return tm; } @@ -437,7 +380,7 @@ public: */ _CMatrix operator*(const Type &v) const { _CMatrix tm = _CMatrix(*this); - PIMM_FOR_WB(r, c) tm.m[r][c] *= v; + PIMM_FOR tm.m[r][c] *= v; return tm; } @@ -449,7 +392,7 @@ public: */ _CMatrix operator/(const Type &v) const { _CMatrix tm = _CMatrix(*this); - PIMM_FOR_WB(r, c) tm.m[r][c] /= v; + PIMM_FOR tm.m[r][c] /= v; return tm; } @@ -467,10 +410,7 @@ public: if (ok) *ok = k; if (!k) return ret; ret = Type(1); - for (uint c = 0; c < Cols; ++c) - for (uint r = 0; r < Rows; ++r) - if (r == c) - ret *= m[r][c]; + PIMM_FOR if (r == c) ret *= m[r][c]; return ret; } @@ -590,7 +530,7 @@ public: */ _CMatrixI transposed() const { _CMatrixI tm; - PIMM_FOR_WB(r, c) tm[c][r] = m[r][c]; + PIMM_FOR tm[c][r] = m[r][c]; return tm; } @@ -598,7 +538,7 @@ private: void resize(uint rows_, uint cols_, const Type &new_value = Type()) { r_ = rows_; c_ = cols_; - PIMM_FOR_WB(r, c) m[r][c] = new_value; + PIMM_FOR m[r][c] = new_value; } int c_, r_; @@ -609,92 +549,22 @@ private: #pragma pack(pop) -template<> -inline PIMathMatrixT<2u, 2u> PIMathMatrixT<2u, 2u>::rotation(double angle) { - double c = cos(angle), s = sin(angle); - PIMathMatrixT<2u, 2u> tm; - tm[0][0] = tm[1][1] = c; - tm[0][1] = -s; - tm[1][0] = s; - return tm; -} -template<> -inline PIMathMatrixT<2u, 2u> PIMathMatrixT<2u, 2u>::scaleX(double factor) { - PIMathMatrixT<2u, 2u> tm; - tm[0][0] = factor; - tm[1][1] = 1.; - return tm; -} - -template<> -inline PIMathMatrixT<2u, 2u> PIMathMatrixT<2u, 2u>::scaleY(double factor) { - PIMathMatrixT<2u, 2u> tm; - tm[0][0] = 1.; - tm[1][1] = factor; - return tm; -} - -template<> -inline PIMathMatrixT<3u, 3u> PIMathMatrixT<3u, 3u>::rotationX(double angle) { - double c = cos(angle), s = sin(angle); - PIMathMatrixT<3u, 3u> tm; - tm[0][0] = 1.; - tm[1][1] = tm[2][2] = c; - tm[2][1] = s; - tm[1][2] = -s; - return tm; -} - -template<> -inline PIMathMatrixT<3u, 3u> PIMathMatrixT<3u, 3u>::rotationY(double angle) { - double c = cos(angle), s = sin(angle); - PIMathMatrixT<3u, 3u> tm; - tm[1][1] = 1.; - tm[0][0] = tm[2][2] = c; - tm[2][0] = -s; - tm[0][2] = s; - return tm; -} - -template<> -inline PIMathMatrixT<3u, 3u> PIMathMatrixT<3u, 3u>::rotationZ(double angle) { - double c = cos(angle), s = sin(angle); - PIMathMatrixT<3u, 3u> tm; - tm[2][2] = 1.; - tm[0][0] = tm[1][1] = c; - tm[1][0] = s; - tm[0][1] = -s; - return tm; -} - -template<> -inline PIMathMatrixT<3u, 3u> PIMathMatrixT<3u, 3u>::scaleX(double factor) { - PIMathMatrixT<3u, 3u> tm; - tm[1][1] = tm[2][2] = 1.; - tm[0][0] = factor; - return tm; -} - -template<> -inline PIMathMatrixT<3u, 3u> PIMathMatrixT<3u, 3u>::scaleY(double factor) { - PIMathMatrixT<3u, 3u> tm; - tm[0][0] = tm[2][2] = 1.; - tm[1][1] = factor; - return tm; -} - -template<> -inline PIMathMatrixT<3u, 3u> PIMathMatrixT<3u, 3u>::scaleZ(double factor) { - PIMathMatrixT<3u, 3u> tm; - tm[0][0] = tm[1][1] = 1.; - tm[2][2] = factor; - return tm; -} #ifdef PIP_STD_IOSTREAM template -inline std::ostream & operator <<(std::ostream & s, const PIMathMatrixT & m) {s << "{"; PIMM_FOR_I(r, c) s << m[r][c]; if (c < Cols - 1 || r < Rows - 1) s << ", ";} if (r < Rows - 1) s << std::endl << " ";} s << "}"; return s;} +inline std::ostream & operator <<(std::ostream & s, const PIMathMatrixT & m) { + s << "{"; + for (uint r = 0; r < Rows; ++r) { + for (uint c = 0; c < Cols; ++c) { + s << m[r][c]; + if (c < Cols - 1 || r < Rows - 1) s << ", "; + } + if (r < Rows - 1) s << std::endl << " "; + } + s << "}"; + return s; +} #endif /** @@ -707,9 +577,13 @@ inline std::ostream & operator <<(std::ostream & s, const PIMathMatrixT inline PICout operator<<(PICout s, const PIMathMatrixT &m) { s << "{"; - PIMM_FOR_I(r, c) s << m[r][c]; - if (c < Cols - 1 || r < Rows - 1) s << ", "; } - if (r < Rows - 1) s << PICoutManipulators::NewLine << " "; } + for (uint r = 0; r < Rows; ++r) { + for (uint c = 0; c < Cols; ++c) { + s << m[r][c]; + if (c < Cols - 1 || r < Rows - 1) s << ", "; + } + if (r < Rows - 1) s << PICoutManipulators::NewLine << " "; + } s << "}"; return s; } @@ -804,9 +678,6 @@ template class PIMathMatrix; #undef PIMM_FOR -#undef PIMM_FOR_WB -#undef PIMM_FOR_I -#undef PIMM_FOR_I_WB #undef PIMM_FOR_C #undef PIMM_FOR_R diff --git a/libs/main/math/piquaternion.cpp b/libs/main/math/piquaternion.cpp index 9dc570a2..d71c5389 100644 --- a/libs/main/math/piquaternion.cpp +++ b/libs/main/math/piquaternion.cpp @@ -96,16 +96,6 @@ void PIQuaternion::normalize() { } -PIMathMatrixT44d PIQuaternion::makeMatrix() const { - PIMathMatrixT44d ret; - ret[0][0] = q[0]; ret[0][1] = -q[1]; ret[0][2] = -q[2]; ret[0][3] = -q[3]; - ret[1][0] = q[1]; ret[1][1] = q[0]; ret[1][2] = -q[3]; ret[1][3] = q[2]; - ret[2][0] = q[2]; ret[2][1] = q[3]; ret[2][2] = q[0]; ret[2][3] = -q[1]; - ret[3][0] = q[3]; ret[3][1] = -q[2]; ret[3][2] = q[1]; ret[3][3] = q[0]; - return ret; -} - - PIQuaternion PIQuaternion::fromEyler(double ax, double ay, double az) { PIQuaternion q_heading; PIQuaternion q_pinch; diff --git a/libs/main/math/piquaternion.h b/libs/main/math/piquaternion.h index c54dbf89..4cfb6f1f 100644 --- a/libs/main/math/piquaternion.h +++ b/libs/main/math/piquaternion.h @@ -52,9 +52,6 @@ public: protected: double q[4]; - PIMathMatrixT44d makeMatrix() const; - - }; PIP_EXPORT PIQuaternion operator *(const double & a, const PIQuaternion & q); From 7413c7252b38018459139a3488757f0123b8ff51 Mon Sep 17 00:00:00 2001 From: andrey Date: Thu, 22 Oct 2020 16:13:39 +0300 Subject: [PATCH 53/98] refactor PIMathMatrixT and fix pimathvector.h --- libs/main/math/pimathmatrix.h | 133 +++++++++++++--------------------- libs/main/math/pimathvector.h | 27 ++++--- 2 files changed, 68 insertions(+), 92 deletions(-) diff --git a/libs/main/math/pimathmatrix.h b/libs/main/math/pimathmatrix.h index 1e263e15..05f7a551 100644 --- a/libs/main/math/pimathmatrix.h +++ b/libs/main/math/pimathmatrix.h @@ -53,20 +53,15 @@ class PIP_EXPORT PIMathMatrixT { static_assert(Cols > 0, "Column count must be > 0"); public: /** - * @brief Constructor that calls the private resize method - * - * @return identitied matrix of type PIMathMatrixT + * @brief Constructs PIMathMatrixT that is filled by \a new_value */ - PIMathMatrixT() { resize(Rows, Cols); } + PIMathMatrixT(const Type &new_value = Type()) {PIMM_FOR m[r][c] = new_value;} /** - * @brief Constructor that calls the private resize method - * - * @param val is the PIVector with which the matrix is ​​filled - * @return identitied matrix of type PIMathMatrixT + * @brief Contructs PIMathMatrixT from PIVector */ PIMathMatrixT(const PIVector &val) { - resize(Rows, Cols); + assert(Rows*Cols == val.size()); int i = 0; PIMM_FOR m[r][c] = val[i++]; } @@ -91,31 +86,19 @@ public: return tm; } - /** - * @brief Creates a matrix that is filled with elements - * - * @param v is a parameter the type and value of which is selected and later filled into the matrix - * @return filled matrix of type PIMathMatrixT - */ - static _CMatrix filled(const Type &v) { - _CMatrix tm; - PIMM_FOR tm.m[r][c] = v; - return tm; - } - /** * @brief Method which returns number of columns in matrix * * @return type uint shows number of columns */ - uint cols() const { return Cols; } + constexpr uint cols() const {return Cols;} /** * @brief Method which returns number of rows in matrix * * @return type uint shows number of rows */ - uint rows() const { return Rows; } + constexpr uint rows() const {return Rows;} /** * @brief Method which returns the selected column in PIMathVectorT format. @@ -177,13 +160,8 @@ public: * @param r1 is the number of the second selected row * @return matrix type _CMatrix */ - _CMatrix &swapRows(uint r0, uint r1) { - Type t; - PIMM_FOR_C { - t = m[r0][i]; - m[r0][i] = m[r1][i]; - m[r1][i] = t; - } + _CMatrix &swapRows(uint rf, uint rs) { + PIMM_FOR_C piSwap(m[rf][i], m[rs][i]); return *this; } @@ -195,13 +173,8 @@ public: * @param c1 is the number of the second selected column * @return matrix type _CMatrix */ - _CMatrix &swapCols(uint c0, uint c1) { - Type t; - PIMM_FOR_R { - t = m[i][c0]; - m[i][c0] = m[i][c1]; - m[i][c1] = t; - } + _CMatrix &swapCols(uint cf, uint cs) { + PIMM_FOR_R piSwap(m[i][cf], m[i][cs]); return *this; } @@ -221,7 +194,7 @@ public: * * @return true if matrix is square, else false */ - bool isSquare() const { return cols() == rows(); } + constexpr bool isSquare() const { return Rows == Cols; } /** * @brief Method which checks if main diagonal of matrix consists of ones and another elements are zeros @@ -243,30 +216,41 @@ public: return true; } - /** - * @brief Full access to elements reference by row "row" and col "col". - * If you enter an index out of the border of the matrix there will be "undefined behavior" - * - * @param row is a parameter that shows the row number of the matrix of the selected element - * @param col is a parameter that shows the column number of the matrix of the selected element - * @return reference to element of matrix by row "row" and col "col" - */ - Type &at(uint row, uint col) { return m[row][col]; } /** - * @brief Full access to element by row "row" and col "col". + * @brief Read-only access to element by \a row and \a col. * If you enter an index out of the border of the matrix there will be "undefined behavior" * - * @param row is a parameter that shows the row number of the matrix of the selected element - * @param col is a parameter that shows the column number of the matrix of the selected element - * @return element of matrix by row "row" and col "col" + * @param row of matrix + * @param col of matrix + * @return copy of element of matrix */ Type at(uint row, uint col) const { return m[row][col]; } + /** + * @brief Full access to element by \a row and \a col. + * If you enter an index out of the border of the matrix there will be "undefined behavior" + * + * @param row of matrix + * @param col of matrix + * @return element of matrix + */ + inline Type & element(uint row, uint col) {return m[row][col];} + + /** + * @brief Read-only access to element by \a row and \a col. + * If you enter an index out of the border of the matrix there will be "undefined behavior" + * + * @param row of matrix + * @param col of matrix + * @return element of matrix + */ + inline const Type & element(uint row, uint col) const {return m[row][col];} + /** * @brief Full access to the matrix row pointer. If you enter an index out of the border of the matrix there will be "undefined behavior" * - * @param row is a row of necessary matrix + * @param row of matrix * @return matrix row pointer */ Type *operator[](uint row) { return m[row]; } @@ -274,26 +258,15 @@ public: /** * @brief Read-only access to the matrix row pointer. If you enter an index out of the border of the matrix there will be "undefined behavior" * - * @param row is a row of necessary matrix + * @param row of matrix * @return matrix row pointer */ - const Type *operator[](uint row) const { return m[row]; } + const Type *operator[](uint row) const {return m[row];} /** - * @brief Matrix assignment to matrix "sm" + * @brief Matrix compare * - * @param sm matrix for the assigment - * @return matrix equal with sm - */ - _CMatrix &operator=(const _CMatrix &sm) { - memcpy(m, sm.m, sizeof(Type) * Cols * Rows); - return *this; - } - - /** - * @brief Compare with matrix "sm" - * - * @param sm matrix for the compare + * @param sm matrix for compare * @return if matrices are equal true, else false */ bool operator==(const _CMatrix &sm) const { @@ -302,9 +275,9 @@ public: } /** - * @brief Compare with matrix "sm" + * @brief Matrix negative compare * - * @param sm matrix for the compare + * @param sm matrix for compare * @return if matrices are not equal true, else false */ bool operator!=(const _CMatrix &sm) const { return !(*this == sm); } @@ -314,28 +287,31 @@ public: * * @param sm matrix for the addition assigment */ - void operator+=(const _CMatrix &sm) { PIMM_FOR m[r][c] += sm.m[r][c]; } + void operator+=(const _CMatrix &sm) {PIMM_FOR m[r][c] += sm.m[r][c];} /** * @brief Subtraction assignment with matrix "sm" * * @param sm matrix for the subtraction assigment */ - void operator-=(const _CMatrix &sm) { PIMM_FOR m[r][c] -= sm.m[r][c]; } + void operator-=(const _CMatrix &sm) {PIMM_FOR m[r][c] -= sm.m[r][c];} /** * @brief Multiplication assignment with value "v" * * @param v value for the multiplication assigment */ - void operator*=(const Type &v) { PIMM_FOR m[r][c] *= v; } + void operator*=(const Type &v) {PIMM_FOR m[r][c] *= v;} /** * @brief Division assignment with value "v" * * @param v value for the division assigment */ - void operator/=(const Type &v) { PIMM_FOR m[r][c] /= v; } + void operator/=(const Type &v) { + assert(piAbs(v) > PIMATHVECTOR_ZERO_CMP); + PIMM_FOR m[r][c] /= v; + } /** * @brief Matrix substraction @@ -391,6 +367,7 @@ public: * @return the result of matrix division */ _CMatrix operator/(const Type &v) const { + assert(piAbs(v) > PIMATHVECTOR_ZERO_CMP); _CMatrix tm = _CMatrix(*this); PIMM_FOR tm.m[r][c] /= v; return tm; @@ -535,22 +512,12 @@ public: } private: - void resize(uint rows_, uint cols_, const Type &new_value = Type()) { - r_ = rows_; - c_ = cols_; - PIMM_FOR m[r][c] = new_value; - } - - int c_, r_; Type m[Rows][Cols]; - }; #pragma pack(pop) - - #ifdef PIP_STD_IOSTREAM template inline std::ostream & operator <<(std::ostream & s, const PIMathMatrixT & m) { diff --git a/libs/main/math/pimathvector.h b/libs/main/math/pimathvector.h index 4f89a7b9..a19ae5e3 100644 --- a/libs/main/math/pimathvector.h +++ b/libs/main/math/pimathvector.h @@ -56,10 +56,14 @@ public: return tv; } - uint size() const {return Size;} + constexpr uint size() const {return Size;} _CVector & fill(const Type & v) {PIMV_FOR c[i] = v; return *this;} _CVector & move(const Type & v) {PIMV_FOR c[i] += v; return *this;} _CVector & move(const _CVector & v) {PIMV_FOR c[i] += v[i]; return *this;} + _CVector & swapElements(uint f, uint s) { + piSwap(c[f], c[s]); + return *this; + } Type lengthSqr() const { Type tv(0); PIMV_FOR tv += c[i] * c[i]; @@ -99,13 +103,15 @@ public: bool isNull() const {PIMV_FOR if (c[i] != Type(0)) return false; return true;} bool isOrtho(const _CVector & v) const {return ((*this) ^ v) == Type(0);} - Type & at(uint index) {return c[index];} - Type at(uint index) const {return c[index];} Type & operator [](uint index) {return c[index];} - Type operator [](uint index) const {return c[index];} + const Type & operator [](uint index) const {return c[index];} + Type at(uint index) const {return c[index];} + _CVector & operator =(const Type & v) {PIMV_FOR c[i] = v; return *this;} + bool operator ==(const _CVector & v) const {PIMV_FOR if (c[i] != v[i]) return false; return true;} bool operator !=(const _CVector & v) const {return !(*this == c);} + void operator +=(const _CVector & v) {PIMV_FOR c[i] += v[i];} void operator -=(const _CVector & v) {PIMV_FOR c[i] -= v[i];} void operator *=(const Type & v) {PIMV_FOR c[i] *= v;} @@ -287,8 +293,8 @@ public: PIMV_FOR c[i] += v[i]; return *this; } - _CVector & swapElements(uint fe, uint se) { - piSwap(c[fe], c[se]); + _CVector & swapElements(uint f, uint s) { + piSwap(c[f], c[s]); return *this; } Type lengthSqr() const { @@ -340,12 +346,15 @@ public: bool isValid() const {return !c.isEmpty();} bool isOrtho(const _CVector & v) const {return dot(v) == Type(0);} - Type & at(uint index) {return c[index];} - Type at(uint index) const {return c[index];} Type & operator [](uint index) {return c[index];} - Type operator [](uint index) const {return c[index];} + const Type & operator [](uint index) const {return c[index];} + Type at(uint index) const {return c[index];} + + _CVector & operator =(const Type & v) {PIMV_FOR c[i] = v; return *this;} + bool operator ==(const _CVector & v) const {return c == v.c;} bool operator !=(const _CVector & v) const {return c != v.c;} + void operator +=(const _CVector & v) { assert(c.size() == v.size()); PIMV_FOR c[i] += v[i]; From f5652efc32315eae8f8324f0d8246b3e1f8910d0 Mon Sep 17 00:00:00 2001 From: andrey Date: Thu, 22 Oct 2020 16:48:46 +0300 Subject: [PATCH 54/98] refactoring PIMathMatrix --- libs/main/math/pimathmatrix.h | 92 +++++++++++++++++------------------ 1 file changed, 45 insertions(+), 47 deletions(-) diff --git a/libs/main/math/pimathmatrix.h b/libs/main/math/pimathmatrix.h index 05f7a551..b495d90d 100644 --- a/libs/main/math/pimathmatrix.h +++ b/libs/main/math/pimathmatrix.h @@ -301,7 +301,9 @@ public: * * @param v value for the multiplication assigment */ - void operator*=(const Type &v) {PIMM_FOR m[r][c] *= v;} + void operator*=(const Type &v) { + PIMM_FOR m[r][c] *= v; + } /** * @brief Division assignment with value "v" @@ -654,11 +656,10 @@ class PIMathMatrix; /// Matrix -#define PIMM_FOR(c, r) for (uint c = 0; c < _V2D::cols_; ++c) for (uint r = 0; r < _V2D::rows_; ++r) -#define PIMM_FOR_I(c, r) for (uint r = 0; r < _V2D::rows_; ++r) for (uint c = 0; c < _V2D::cols_; ++c) -#define PIMM_FOR_A(v) for (uint v = 0; v < _V2D::mat.size(); ++v) -#define PIMM_FOR_C(v) for (uint v = 0; v < _V2D::cols_; ++v) -#define PIMM_FOR_R(v) for (uint v = 0; v < _V2D::rows_; ++v) +#define PIMM_FOR for (uint r = 0; r < _V2D::rows_; ++r) for (uint c = 0; c < _V2D::cols_; ++c) +#define PIMM_FOR_A for (uint i = 0; i < _V2D::mat.size(); ++i) +#define PIMM_FOR_C for (uint i = 0; i < _V2D::cols_; ++i) +#define PIMM_FOR_R for (uint i = 0; i < _V2D::rows_; ++i) //! \brief A class that works with matrix operations, the input data of which is the data type of the matrix //! @tparam There are can be basic C++ language data and different classes where the arithmetic operators(=, +=, -=, *=, /=, ==, !=, +, -, *, /) @@ -667,7 +668,6 @@ template class PIP_EXPORT PIMathMatrix : public PIVector2D { typedef PIVector2D _V2D; typedef PIMathMatrix _CMatrix; - typedef PIMathVector _CMCol; public: /** * @brief Constructor of class PIMathMatrix, which creates a matrix @@ -688,7 +688,7 @@ public: PIMathMatrix(const uint cols, const uint rows, const PIVector &val) { _V2D::resize(rows, cols); int i = 0; - PIMM_FOR_I(c, r) _V2D::element(r, c) = val[i++]; + PIMM_FOR _V2D::element(r, c) = val[i++]; } /** @@ -699,7 +699,11 @@ public: PIMathMatrix(const PIVector > &val) { if (!val.isEmpty()) { _V2D::resize(val.size(), val[0].size()); - PIMM_FOR_I(c, r) _V2D::element(r, c) = val[r][c]; + for (uint r = 0; r < _V2D::rows_; ++r) { + assert(val[r].size() == _V2D::cols_); + for (uint c = 0; c < _V2D::cols_; ++c) + _V2D::element(r, c) = val[r][c]; + } } } @@ -711,7 +715,7 @@ public: PIMathMatrix(const PIVector2D &val) { if (!val.isEmpty()) { _V2D::resize(val.rows(), val.cols()); - PIMM_FOR_I(c, r) _V2D::element(r, c) = val.element(r, c); + PIMM_FOR _V2D::element(r, c) = val.element(r, c); } } @@ -728,26 +732,13 @@ public: return tm; } - /** - * @brief Creates a matrix filled by zeros - * - * @param cols is number of matrix column uint type - * @param rows is number of matrix row uint type - * @return zero matrix(cols,rows) - */ - static _CMatrix zero(const uint cols, const uint rows) { - _CMatrix tm(cols, rows); - tm.fill(Type(0)); - return tm; - } - /** * @brief Creates a row matrix of every element that is equal to every element of the vector * * @param val is the vector type PIMathVector * @return row matrix of every element that is equal to every element of the vector */ - static _CMatrix matrixRow(const PIMathVector &val) { return _CMatrix(val.size(), 1, val.toVector()); } + static _CMatrix matrixRow(const PIMathVector &val) {return _CMatrix(val.size(), 1, val.toVector());} /** * @brief Creates a column matrix of every element that is equal to every element of the vector @@ -755,18 +746,19 @@ public: * @param val is the vector type PIMathVector * @return column matrix of every element that is equal to every element of the vector */ - static _CMatrix matrixCol(const PIMathVector &val) { return _CMatrix(1, val.size(), val.toVector()); } + static _CMatrix matrixCol(const PIMathVector &val) {return _CMatrix(1, val.size(), val.toVector());} /** * @brief Set the selected column in matrix. If there are more elements of the vector than elements in the column of the matrix - * or index larger than the number of columns otherwise there will be "undefined behavior" + * or index larger than the number of columns otherwise there will be "undefined behavior" * * @param index is the number of the selected column * @param v is a vector of the type _CMCol that needs to fill the column * @return matrix type _CMatrix */ - _CMatrix &setCol(uint index, const _CMCol &v) { - PIMM_FOR_R(i) _V2D::element(i, index) = v[i]; + _CMatrix &setCol(uint index, const PIMathVector &v) { + assert(_V2D::rows == v.size()); + PIMM_FOR_R _V2D::element(i, index) = v[i]; return *this; } @@ -777,8 +769,9 @@ public: * @param v is a vector of the type _CMCol that needs to fill the row * @return matrix type _CMatrix */ - _CMatrix &setRow(uint index, const _CMCol &v) { - PIMM_FOR_C(i) _V2D::element(index, i) = v[i]; + _CMatrix &setRow(uint index, const PIMathVector &v) { + assert(_V2D::cols == v.size()); + PIMM_FOR_C _V2D::element(index, i) = v[i]; return *this; } @@ -791,7 +784,7 @@ public: * @return matrix type _CMatrix */ _CMatrix &swapCols(uint r0, uint r1) { - PIMM_FOR_C(i) { piSwap(_V2D::element(i, r0), _V2D::element(i, r1)); } + PIMM_FOR_C piSwap(_V2D::element(i, r0), _V2D::element(i, r1)); return *this; } @@ -804,7 +797,7 @@ public: * @return matrix type _CMatrix */ _CMatrix &swapRows(uint c0, uint c1) { - PIMM_FOR_R(i) { piSwap(_V2D::element(c0, i), _V2D::element(c1, i)); } + PIMM_FOR_R piSwap(_V2D::element(c0, i), _V2D::element(c1, i)); return *this; } @@ -815,7 +808,7 @@ public: * @return filled matrix type _CMatrix */ _CMatrix &fill(const Type &v) { - PIMM_FOR_A(i) _V2D::mat[i] = v; + PIMM_FOR_A _V2D::mat[i] = v; return *this; } @@ -832,7 +825,7 @@ public: * @return true if matrix is identity, else false */ bool isIdentity() const { - PIMM_FOR(c, r) if ((c == r) ? _V2D::element(r, c) != Type(1) : _V2D::element(r, c) != Type(0))return false; + PIMM_FOR if ((c == r) ? _V2D::element(r, c) != Type(1) : _V2D::element(r, c) != Type(0))return false; return true; } @@ -842,7 +835,7 @@ public: * @return true if matrix elements equal to zero, else false */ bool isNull() const { - PIMM_FOR_A(i) if (_V2D::mat[i] != Type(0)) return false; + PIMM_FOR_A if (_V2D::mat[i] != Type(0)) return false; return true; } @@ -861,7 +854,7 @@ public: void operator+=(const _CMatrix &sm) { assert(_V2D::rows() == sm.rows()); assert(_V2D::cols() == sm.cols()); - PIMM_FOR_A(i) _V2D::mat[i] += sm.mat[i]; + PIMM_FOR_A _V2D::mat[i] += sm.mat[i]; } /** @@ -872,7 +865,7 @@ public: void operator-=(const _CMatrix &sm) { assert(_V2D::rows() == sm.rows()); assert(_V2D::cols() == sm.cols()); - PIMM_FOR_A(i) _V2D::mat[i] -= sm.mat[i]; + PIMM_FOR_A _V2D::mat[i] -= sm.mat[i]; } /** @@ -880,14 +873,19 @@ public: * * @param v value for the multiplication assigment */ - void operator*=(const Type &v) { PIMM_FOR_A(i) _V2D::mat[i] *= v; } + void operator*=(const Type &v) { + PIMM_FOR_A _V2D::mat[i] *= v; + } /** * @brief Division assignment with value "v" * * @param v value for the division assigment */ - void operator/=(const Type &v) { PIMM_FOR_A(i) _V2D::mat[i] /= v; } + void operator/=(const Type &v) { + assert(piAbs(v) > PIMATHVECTOR_ZERO_CMP); + PIMM_FOR_A _V2D::mat[i] /= v; + } /** * @brief Matrix substraction @@ -896,7 +894,7 @@ public: */ _CMatrix operator-() const { _CMatrix tm(*this); - PIMM_FOR_A(i) tm.mat[i] = -_V2D::mat[i]; + PIMM_FOR_A tm.mat[i] = -_V2D::mat[i]; return tm; } @@ -910,7 +908,7 @@ public: _CMatrix tm(*this); assert(tm.rows() == sm.rows()); assert(tm.cols() == sm.cols()); - PIMM_FOR_A(i) tm.mat[i] += sm.mat[i]; + PIMM_FOR_A tm.mat[i] += sm.mat[i]; return tm; } @@ -924,7 +922,7 @@ public: _CMatrix tm(*this); assert(tm.rows() == sm.rows()); assert(tm.cols() == sm.cols()); - PIMM_FOR_A(i) tm.mat[i] -= sm.mat[i]; + PIMM_FOR_A tm.mat[i] -= sm.mat[i]; return tm; } @@ -936,7 +934,7 @@ public: */ _CMatrix operator*(const Type &v) const { _CMatrix tm(*this); - PIMM_FOR_A(i) tm.mat[i] *= v; + PIMM_FOR_A tm.mat[i] *= v; return tm; } @@ -947,8 +945,9 @@ public: * @return the result of matrix division */ _CMatrix operator/(const Type &v) const { + assert(piAbs(v) > PIMATHVECTOR_ZERO_CMP); _CMatrix tm(*this); - PIMM_FOR_A(i) tm.mat[i] /= v; + PIMM_FOR_A tm.mat[i] /= v; return tm; } @@ -1042,7 +1041,7 @@ public: * @param sv is a vector multiplier * @return copy of inverted matrix */ - _CMatrix &invert(bool *ok = 0, _CMCol *sv = 0) { + _CMatrix &invert(bool *ok = 0, PIMathVector *sv = 0) { if (!isSquare()) { if (ok != 0) *ok = false; return *this; @@ -1116,7 +1115,7 @@ public: */ _CMatrix transposed() const { _CMatrix tm(_V2D::rows_, _V2D::cols_); - PIMM_FOR(c, r) tm.element(c, r) = _V2D::element(r, c); + PIMM_FOR tm.element(c, r) = _V2D::element(r, c); return tm; } }; @@ -1276,7 +1275,6 @@ PIMathMatrix > hermitian(const PIMathMatrix > &m) { } #undef PIMM_FOR -#undef PIMM_FOR_I #undef PIMM_FOR_A #undef PIMM_FOR_C #undef PIMM_FOR_R From fbe850abf0732ca7f423afb46eb429f0a1fd7cab Mon Sep 17 00:00:00 2001 From: andrey Date: Thu, 22 Oct 2020 17:29:58 +0300 Subject: [PATCH 55/98] template math functions in pimathmatrix.h and pimathvector.h and pimathbase.h add PIMathMatrixT::rotate for matrix 2x2 --- libs/main/math/pimathbase.h | 20 +++++++++----------- libs/main/math/pimathmatrix.h | 16 ++++++++++++++-- libs/main/math/pimathvector.h | 14 +++++++------- main.cpp | 4 ++++ 4 files changed, 34 insertions(+), 20 deletions(-) diff --git a/libs/main/math/pimathbase.h b/libs/main/math/pimathbase.h index 0841ac4c..553437f5 100644 --- a/libs/main/math/pimathbase.h +++ b/libs/main/math/pimathbase.h @@ -98,9 +98,6 @@ const double rad2deg = M_180_PI; inline int sign(const float & x) {return (x < 0.) ? -1 : (x > 0. ? 1 : 0);} inline int sign(const double & x) {return (x < 0.) ? -1 : (x > 0. ? 1 : 0);} inline int pow2(const int p) {return 1 << p;} -inline int sqr(const int v) {return v * v;} -inline float sqr(const float & v) {return v * v;} -inline double sqr(const double & v) {return v * v;} inline double sinc(const double & v) {if (v == 0.) return 1.; double t = M_PI * v; return sin(t) / t;} PIP_EXPORT double piJ0(const double & v); @@ -109,22 +106,23 @@ PIP_EXPORT double piJn(int n, const double & v); PIP_EXPORT double piY0(const double & v); PIP_EXPORT double piY1(const double & v); PIP_EXPORT double piYn(int n, const double & v); -inline double toDb(double val) {return 10. * log10(val);} -inline double fromDb(double val) {return pow(10., val / 10.);} -inline double toRad(double deg) {return deg * M_PI_180;} -inline double toDeg(double rad) {return rad * M_180_PI;} + +template inline constexpr T toDb(T val) {return T(10.) * std::log10(val);} +template inline constexpr T fromDb(T val) {return std::pow(T(10.), val / T(10.));} +template inline constexpr T toRad(T deg) {return deg * T(M_PI_180);} +template inline constexpr T toDeg(T rad) {return rad * T(M_180_PI);} +template inline constexpr T sqr(const T & v) {return v * v;} // [-1 ; 1] PIP_EXPORT double randomd(); // [-1 ; 1] normal PIP_EXPORT double randomn(double dv = 0., double sv = 1.); - -inline PIVector abs(const PIVector & v) { - PIVector result; +template inline PIVector piAbs(const PIVector & v) { + PIVector result; result.resize(v.size()); for (uint i = 0; i < v.size(); i++) - result[i] = fabs(v[i]); + result[i] = piAbs(v[i]); return result; } diff --git a/libs/main/math/pimathmatrix.h b/libs/main/math/pimathmatrix.h index b495d90d..2d9dffd1 100644 --- a/libs/main/math/pimathmatrix.h +++ b/libs/main/math/pimathmatrix.h @@ -425,7 +425,7 @@ public: for (uint k = i; k < Cols; ++k) smat.m[k][j] -= mul * smat.m[k][i]; } if (i < Cols - 1) { - if (fabs(smat.m[i + 1][i + 1]) < Type(1E-200)) { + if (piAbs(smat.m[i + 1][i + 1]) < Type(1E-200)) { if (ok != 0) *ok = false; return *this; } @@ -469,7 +469,7 @@ public: for (uint k = 0; k < Cols; ++k) mtmp.m[k][j] -= mul * mtmp.m[k][i]; } if (i < Cols - 1) { - if (fabs(smat.m[i + 1][i + 1]) < Type(1E-200)) { + if (piAbs(smat.m[i + 1][i + 1]) < Type(1E-200)) { if (ok != 0) *ok = false; return *this; } @@ -513,6 +513,18 @@ public: return tm; } + _CMatrix rotate(Type angle) { + static_assert(Rows == 2 && Cols == 2, "Works only with 2x2 matrix"); + Type c = std::cos(angle); + Type s = std::sin(angle); + PIMathMatrixT<2u, 2u> tm; + tm[0][0] = tm[1][1] = c; + tm[0][1] = -s; + tm[1][0] = s; + *this = *this * tm; + return *this; + } + private: Type m[Rows][Cols]; }; diff --git a/libs/main/math/pimathvector.h b/libs/main/math/pimathvector.h index a19ae5e3..547b03bb 100644 --- a/libs/main/math/pimathvector.h +++ b/libs/main/math/pimathvector.h @@ -69,7 +69,7 @@ public: PIMV_FOR tv += c[i] * c[i]; return tv; } - Type length() const {return sqrt(lengthSqr());} + Type length() const {return std::sqrt(lengthSqr());} Type manhattanLength() const { Type tv(0); PIMV_FOR tv += piAbs(c[i]); @@ -82,10 +82,10 @@ public: } Type angleSin(const _CVector & v) const { Type tv = angleCos(v); - return sqrt(Type(1) - tv * tv); + return std::sqrt(Type(1) - tv * tv); } - Type angleRad(const _CVector & v) const {return acos(angleCos(v));} - Type angleDeg(const _CVector & v) const {return toDeg(angleRad(v));} + Type angleRad(const _CVector & v) const {return std::acos(angleCos(v));} + Type angleDeg(const _CVector & v) const {return toDeg(angleRad(v));} Type angleElevation(const _CVector & v) const {return 90.0 - angleDeg(v - *this);} _CVector projection(const _CVector & v) { Type tv = v.length(); @@ -302,7 +302,7 @@ public: PIMV_FOR tv += c[i] * c[i]; return tv; } - Type length() const {return sqrt(lengthSqr());} + Type length() const {return std::sqrt(lengthSqr());} Type manhattanLength() const { Type tv(0); PIMV_FOR tv += piAbs(c[i]); @@ -317,9 +317,9 @@ public: Type angleSin(const _CVector & v) const { assert(c.size() == v.size()); Type tv = angleCos(v); - return sqrt(Type(1) - tv * tv); + return std::sqrt(Type(1) - tv * tv); } - Type angleRad(const _CVector & v) const {return acos(angleCos(v));} + Type angleRad(const _CVector & v) const {return std::acos(angleCos(v));} Type angleDeg(const _CVector & v) const {return toDeg(angleRad(v));} _CVector projection(const _CVector & v) { assert(c.size() == v.size()); diff --git a/main.cpp b/main.cpp index 10dfb678..0f49cc37 100644 --- a/main.cpp +++ b/main.cpp @@ -45,5 +45,9 @@ int main() { PIMathVectord v2({3,2,1}); piCout << v; piCout << v2; + PIMathMatrixT22d m = PIMathMatrixT22d::identity(); + piCout << m; + m.rotate(toRad(90.)); + piCout << m; return 0; } From 91c1487a7e73186beab3df61ecfe180a855697c7 Mon Sep 17 00:00:00 2001 From: andrey Date: Thu, 22 Oct 2020 17:45:42 +0300 Subject: [PATCH 56/98] toDeg and toRad --- libs/main/math/pimathbase.h | 8 ++++++-- libs/main/math/pimathvector.h | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/libs/main/math/pimathbase.h b/libs/main/math/pimathbase.h index 553437f5..d270c619 100644 --- a/libs/main/math/pimathbase.h +++ b/libs/main/math/pimathbase.h @@ -109,8 +109,12 @@ PIP_EXPORT double piYn(int n, const double & v); template inline constexpr T toDb(T val) {return T(10.) * std::log10(val);} template inline constexpr T fromDb(T val) {return std::pow(T(10.), val / T(10.));} -template inline constexpr T toRad(T deg) {return deg * T(M_PI_180);} -template inline constexpr T toDeg(T rad) {return rad * T(M_180_PI);} +inline constexpr float toRad(float deg) {return deg * M_PI_180;} +inline constexpr double toRad(double deg) {return deg * M_PI_180;} +inline constexpr long double toRad(long double deg) {return deg * M_PI_180;} +inline constexpr float toDeg(float rad) {return rad * M_180_PI;} +inline constexpr double toDeg(double rad) {return rad * M_180_PI;} +inline constexpr long double toDeg(long double rad) {return rad * M_180_PI;} template inline constexpr T sqr(const T & v) {return v * v;} // [-1 ; 1] diff --git a/libs/main/math/pimathvector.h b/libs/main/math/pimathvector.h index 547b03bb..a98cef49 100644 --- a/libs/main/math/pimathvector.h +++ b/libs/main/math/pimathvector.h @@ -85,7 +85,7 @@ public: return std::sqrt(Type(1) - tv * tv); } Type angleRad(const _CVector & v) const {return std::acos(angleCos(v));} - Type angleDeg(const _CVector & v) const {return toDeg(angleRad(v));} + Type angleDeg(const _CVector & v) const {return toDeg(angleRad(v));} Type angleElevation(const _CVector & v) const {return 90.0 - angleDeg(v - *this);} _CVector projection(const _CVector & v) { Type tv = v.length(); From c79f39ad2a2d37c297681a55e7063d5e6bc4cb17 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Thu, 22 Oct 2020 18:03:22 +0300 Subject: [PATCH 57/98] cosmetic --- libs/main/core/piobject.h | 2 +- libs/main/core/piobject_macros.h | 136 +++++++++++++++++++++++-------- libs/main/core/pistring_std.h | 8 +- libs/main/math/pimathbase.h | 21 ++--- libs/main/math/pimathmatrix.h | 2 +- 5 files changed, 118 insertions(+), 51 deletions(-) diff --git a/libs/main/core/piobject.h b/libs/main/core/piobject.h index e85b30c0..939ebb0e 100644 --- a/libs/main/core/piobject.h +++ b/libs/main/core/piobject.h @@ -1,7 +1,7 @@ /*! \file piobject.h * \brief Base object * - * This file declare PIObject class and associated macros + * This file declare PIObject class */ /* PIP - Platform Independent Primitives diff --git a/libs/main/core/piobject_macros.h b/libs/main/core/piobject_macros.h index 261c4531..1f0d27a5 100644 --- a/libs/main/core/piobject_macros.h +++ b/libs/main/core/piobject_macros.h @@ -1,7 +1,7 @@ -/*! \file piobject.h +/*! \file piobject_macros.h * \brief Base object * - * This file declare PIObject class and associated macros + * This file declare macros for PIObject */ /* PIP - Platform Independent Primitives @@ -25,8 +25,6 @@ #ifndef PIOBJECT_MACROS_H #define PIOBJECT_MACROS_H -//#include "piobject_macros.h" - #ifdef DOXYGEN @@ -385,43 +383,63 @@ #define EVENT_VHANDLER0(ret, name) \ EH_INIT0(ret, name) \ - static ret __stat_eh_##name##__(void * __o__) {return ((__PIObject__*)__o__)->name();} \ + static ret __stat_eh_##name##__(void * __o__) { \ + return ((__PIObject__*)__o__)->name();} \ virtual ret name() #define EVENT_VHANDLER1(ret, name, a0, n0) \ EH_INIT1(ret, name, a0, n0) \ - static ret __stat_eh_##name##__(void * __o__, a0 n0) {return ((__PIObject__*)__o__)->name(n0);} \ - static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0) {return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0));} \ + static ret __stat_eh_##name##__(void * __o__, a0 n0) { \ + return ((__PIObject__*)__o__)->name(n0);} \ + static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0) { \ + return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0));} \ virtual ret name(a0 n0) #define EVENT_VHANDLER2(ret, name, a0, n0, a1, n1) \ EH_INIT2(ret, name, a0, n0, a1, n1) \ - static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1) {return ((__PIObject__*)__o__)->name(n0, n1);} \ - static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0, const PIVariantSimple & v1) {return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1));} \ + 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 PIVariantSimple & v0, const PIVariantSimple & v1) { \ + return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1));} \ virtual ret name(a0 n0, a1 n1) #define EVENT_VHANDLER3(ret, name, a0, n0, a1, n1, a2, n2) \ EH_INIT3(ret, name, a0, n0, a1, n1, a2, n2) \ - static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1, a2 n2) {return ((__PIObject__*)__o__)->name(n0, n1, n2);} \ - static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2) {return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1), __VVALUE(a2, v2));} \ + 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 PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2) { \ + return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1), __VVALUE(a2, v2));} \ virtual ret name(a0 n0, a1 n1, a2 n2) #define EVENT_VHANDLER4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) \ EH_INIT4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) \ - static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1, a2 n2, a3 n3) {return ((__PIObject__*)__o__)->name(n0, n1, n2, n3);} \ - static ret __stat_eh_v_##name##__(void * __o__, const 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));} \ + 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 PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2, const PIVariantSimple & v3) { \ + return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1), __VVALUE(a2, v2), __VVALUE(a3, v3));} \ virtual ret name(a0 n0, a1 n1, a2 n2, a3 n3) #define EVENT_VHANDLER EVENT_VHANDLER0 -#define EVENT0(name) EVENT_HANDLER0(void, name) {static uint eid = PIStringAscii(#name).hash(); PIObject::raiseEvent(this, eid);} -#define EVENT1(name, a0, n0) EVENT_HANDLER1(void, name, a0, n0) {static uint eid = PIStringAscii(#name).hash(); PIObject::raiseEvent(this, eid, n0);} -#define EVENT2(name, a0, n0, a1, n1) EVENT_HANDLER2(void, name, a0, n0, a1, n1) {static uint eid = PIStringAscii(#name).hash(); PIObject::raiseEvent(this, eid, n0, n1);} -#define EVENT3(name, a0, n0, a1, n1, a2, n2) EVENT_HANDLER3(void, name, a0, n0, a1, n1, a2, n2) {static uint eid = PIStringAscii(#name).hash(); PIObject::raiseEvent(this, eid, n0, n1, n2);} -#define EVENT4(name, a0, n0, a1, n1, a2, n2, a3, n3) EVENT_HANDLER4(void, name, a0, n0, a1, n1, a2, n2, a3, n3) {static uint eid = PIStringAscii(#name).hash(); PIObject::raiseEvent(this, eid, n0, n1, n2, n3);} +#define EVENT0(name) EVENT_HANDLER0(void, name) { \ + static uint eid = PIStringAscii(#name).hash(); PIObject::raiseEvent(this, eid);} + +#define EVENT1(name, a0, n0) EVENT_HANDLER1(void, name, a0, n0) { \ + static uint eid = PIStringAscii(#name).hash(); PIObject::raiseEvent(this, eid, n0);} + +#define EVENT2(name, a0, n0, a1, n1) EVENT_HANDLER2(void, name, a0, n0, a1, n1) { \ + static uint eid = PIStringAscii(#name).hash(); PIObject::raiseEvent(this, eid, n0, n1);} + +#define EVENT3(name, a0, n0, a1, n1, a2, n2) EVENT_HANDLER3(void, name, a0, n0, a1, n1, a2, n2) { \ + static uint eid = PIStringAscii(#name).hash(); PIObject::raiseEvent(this, eid, n0, n1, n2);} + +#define EVENT4(name, a0, n0, a1, n1, a2, n2, a3, n3) EVENT_HANDLER4(void, name, a0, n0, a1, n1, a2, n2, a3, n3) { \ + static uint eid = PIStringAscii(#name).hash(); PIObject::raiseEvent(this, eid, n0, n1, n2, n3);} + #define EVENT EVENT0 + #define RAISE_EVENT0(src, event) (src)->event(); #define RAISE_EVENT1(src, event, v0) (src)->event(v0); #define RAISE_EVENT2(src, event, v0, v1) (src)->event(v0, v1); @@ -429,35 +447,81 @@ #define RAISE_EVENT4(src, event, v0, v1, v2, v3) (src)->event(v0, v1, v2, v3); #define RAISE_EVENT RAISE_EVENT0 -#define CONNECTU(src, event, dest, handler) PIObject::piConnectU(src, PIStringAscii(#event), dest, dest, PIStringAscii(#handler), LOCATION); -#define CONNECTU_QUEUED(src, event, dest, handler, performer) PIObject::piConnectU(src, PIStringAscii(#event), dest, dest, PIStringAscii(#handler), LOCATION, performer); -#define CONNECTL(src, event, functor) PIObject::piConnectLS(src, PIStringAscii(#event), PIObject::__newFunctor(&(src)->__stat_eh_##event##__, functor), LOCATION); -#define CONNECT0(ret, src, event, dest, handler) PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*))(&(dest)->__stat_eh_##handler##__), (void*)(void(*)(void*))(&(src)->__stat_eh_##event##__), 0, LOCATION); -#define CONNECT1(ret, a0, src, event, dest, handler) PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0))(&(dest)->__stat_eh_##handler##__), (void*)(void(*)(void*, a0))(&(src)->__stat_eh_##event##__), 1, LOCATION); -#define CONNECT2(ret, a0, a1, src, event, dest, handler) PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0, a1))(&(dest)->__stat_eh_##handler##__), (void*)(void(*)(void*, a0, a1))(&(src)->__stat_eh_##event##__), 2, LOCATION); -#define CONNECT3(ret, a0, a1, a2, src, event, dest, handler) PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0, a1, a2))(&(dest)->__stat_eh_##handler##__), (void*)(void(*)(void*, a0, a1, a2))(&(src)->__stat_eh_##event##__), 3, LOCATION); -#define CONNECT4(ret, a0, a1, a2, a3, src, event, dest, handler) PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0, a1, a2, a3))(&(dest)->__stat_eh_##handler##__), (void*)(void(*)(void*, a0, a1, a2, a3))(&(src)->__stat_eh_##event##__), 4, LOCATION); +#define CONNECTU(src, event, dest, handler) \ + PIObject::piConnectU(src, PIStringAscii(#event), dest, dest, PIStringAscii(#handler), LOCATION); + +#define CONNECTU_QUEUED(src, event, dest, handler, performer) \ + PIObject::piConnectU(src, PIStringAscii(#event), dest, dest, PIStringAscii(#handler), LOCATION, performer); + +#define CONNECTL(src, event, functor) \ + PIObject::piConnectLS(src, PIStringAscii(#event), PIObject::__newFunctor(&(src)->__stat_eh_##event##__, functor), LOCATION); + + +#define CONNECT0(ret, src, event, dest, handler) \ + PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*))(&(dest)->__stat_eh_##handler##__), \ + (void*)(void(*)(void*))(&(src)->__stat_eh_##event##__), 0, LOCATION); + +#define CONNECT1(ret, a0, src, event, dest, handler) \ + PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0))(&(dest)->__stat_eh_##handler##__), \ + (void*)(void(*)(void*, a0))(&(src)->__stat_eh_##event##__), 1, LOCATION); + +#define CONNECT2(ret, a0, a1, src, event, dest, handler) \ + PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0, a1))(&(dest)->__stat_eh_##handler##__), \ + (void*)(void(*)(void*, a0, a1))(&(src)->__stat_eh_##event##__), 2, LOCATION); + +#define CONNECT3(ret, a0, a1, a2, src, event, dest, handler) \ + PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0, a1, a2))(&(dest)->__stat_eh_##handler##__), \ + (void*)(void(*)(void*, a0, a1, a2))(&(src)->__stat_eh_##event##__), 3, LOCATION); + +#define CONNECT4(ret, a0, a1, a2, a3, src, event, dest, handler) \ + PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0, a1, a2, a3))(&(dest)->__stat_eh_##handler##__), \ + (void*)(void(*)(void*, a0, a1, a2, a3))(&(src)->__stat_eh_##event##__), 4, LOCATION); + #define CONNECT CONNECT0 -#define WEAK_CONNECT0(ret, src, event, dest, handler) PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*))(&(dest)->__stat_eh_##handler##__), 0, 0, LOCATION); -#define WEAK_CONNECT1(ret, a0, src, event, dest, handler) PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0))(&(dest)->__stat_eh_##handler##__), 0, 1, LOCATION); -#define WEAK_CONNECT2(ret, a0, a1, src, event, dest, handler) PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0, a1))(&(dest)->__stat_eh_##handler##__), 0, 2, LOCATION); -#define WEAK_CONNECT3(ret, a0, a1, a2, src, event, dest, handler) PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0, a1, a2))(&(dest)->__stat_eh_##handler##__), 0, 3, LOCATION); -#define WEAK_CONNECT4(ret, a0, a1, a2, a3, src, event, dest, handler) PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0, a1, a2, a3))(&(dest)->__stat_eh_##handler##__), 0, 4, LOCATION); + +#define WEAK_CONNECT0(ret, src, event, dest, handler) \ + PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*))(&(dest)->__stat_eh_##handler##__), 0, 0, LOCATION); + +#define WEAK_CONNECT1(ret, a0, src, event, dest, handler) \ + PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0))(&(dest)->__stat_eh_##handler##__), 0, 1, LOCATION); + +#define WEAK_CONNECT2(ret, a0, a1, src, event, dest, handler) \ + PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0, a1))(&(dest)->__stat_eh_##handler##__), 0, 2, LOCATION); + +#define WEAK_CONNECT3(ret, a0, a1, a2, src, event, dest, handler) \ + PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0, a1, a2))(&(dest)->__stat_eh_##handler##__), 0, 3, LOCATION); + +#define WEAK_CONNECT4(ret, a0, a1, a2, a3, src, event, dest, handler) \ + PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0, a1, a2, a3))(&(dest)->__stat_eh_##handler##__), 0, 4, LOCATION); + #define WEAK_CONNECT WEAK_CONNECT0 -#define DISCONNECT0(ret, src, event, dest, handler) PIObject::piDisconnect(src, PIStringAscii(#event), dest, (void*)(ret(*)(void*))(&(dest)->__stat_eh_##handler##__)); -#define DISCONNECT1(ret, a0, src, event, dest, handler) PIObject::piDisconnect(src, PIStringAscii(#event), dest, (void*)(ret(*)(void*, a0))(&(dest)->__stat_eh_##handler##__)); -#define DISCONNECT2(ret, a0, a1, src, event, dest, handler) PIObject::piDisconnect(src, PIStringAscii(#event), dest, (void*)(ret(*)(void*, a0, a1))(&(dest)->__stat_eh_##handler##__)); -#define DISCONNECT3(ret, a0, a1, a2, src, event, dest, handler) PIObject::piDisconnect(src, PIStringAscii(#event), dest, (void*)(ret(*)(void*, a0, a1, a2))(&(dest)->__stat_eh_##handler##__)); -#define DISCONNECT4(ret, a0, a1, a2, a3, src, event, dest, handler) PIObject::piDisconnect(src, PIStringAscii(#event), dest, (void*)(ret(*)(void*, a0, a1, a2, a3))(&(dest)->__stat_eh_##handler##__)); + +#define DISCONNECT0(ret, src, event, dest, handler) \ + PIObject::piDisconnect(src, PIStringAscii(#event), dest, (void*)(ret(*)(void*))(&(dest)->__stat_eh_##handler##__)); + +#define DISCONNECT1(ret, a0, src, event, dest, handler) \ + PIObject::piDisconnect(src, PIStringAscii(#event), dest, (void*)(ret(*)(void*, a0))(&(dest)->__stat_eh_##handler##__)); + +#define DISCONNECT2(ret, a0, a1, src, event, dest, handler) \ + PIObject::piDisconnect(src, PIStringAscii(#event), dest, (void*)(ret(*)(void*, a0, a1))(&(dest)->__stat_eh_##handler##__)); + +#define DISCONNECT3(ret, a0, a1, a2, src, event, dest, handler) \ + PIObject::piDisconnect(src, PIStringAscii(#event), dest, (void*)(ret(*)(void*, a0, a1, a2))(&(dest)->__stat_eh_##handler##__)); + +#define DISCONNECT4(ret, a0, a1, a2, a3, src, event, dest, handler) \ + PIObject::piDisconnect(src, PIStringAscii(#event), dest, (void*)(ret(*)(void*, a0, a1, a2, a3))(&(dest)->__stat_eh_##handler##__)); + #define DISCONNECT DISCONNECT0 + #define HANDLER(handler) __stat_eh_##handler##__ #define __PIOBJECT_SIGNATURE__ 0xabcdbadc + #endif diff --git a/libs/main/core/pistring_std.h b/libs/main/core/pistring_std.h index 8d1d05e1..909c5348 100644 --- a/libs/main/core/pistring_std.h +++ b/libs/main/core/pistring_std.h @@ -1,5 +1,5 @@ -/*! \file pistring.h - * \brief String +/*! \file pistring_std.h + * \brief STD for PIString * * This file declare std operators and string conversions */ @@ -23,11 +23,12 @@ */ #ifndef PISTRING_STD_H #define PISTRING_STD_H + + #include #ifdef QNX typedef std::basic_string wstring; #endif - #include "pistringlist.h" @@ -97,4 +98,5 @@ inline std::ostream & operator <<(std::ostream & s, const PIStringList & v) { return s; } + #endif // PISTRING_STD_H diff --git a/libs/main/math/pimathbase.h b/libs/main/math/pimathbase.h index d270c619..ee845dd8 100644 --- a/libs/main/math/pimathbase.h +++ b/libs/main/math/pimathbase.h @@ -95,8 +95,9 @@ const double deg2rad = M_PI_180; const double rad2deg = M_180_PI; -inline int sign(const float & x) {return (x < 0.) ? -1 : (x > 0. ? 1 : 0);} -inline int sign(const double & x) {return (x < 0.) ? -1 : (x > 0. ? 1 : 0);} +inline int sign(const float & x) {return (x < 0.f) ? -1 : (x > 0.f ? 1 : 0);} +inline int sign(const double & x) {return (x < 0. ) ? -1 : (x > 0. ? 1 : 0);} +inline int sign(const ldouble & x) {return (x < 0.L) ? -1 : (x > 0.L ? 1 : 0);} inline int pow2(const int p) {return 1 << p;} inline double sinc(const double & v) {if (v == 0.) return 1.; double t = M_PI * v; return sin(t) / t;} @@ -107,15 +108,15 @@ PIP_EXPORT double piY0(const double & v); PIP_EXPORT double piY1(const double & v); PIP_EXPORT double piYn(int n, const double & v); -template inline constexpr T toDb(T val) {return T(10.) * std::log10(val);} -template inline constexpr T fromDb(T val) {return std::pow(T(10.), val / T(10.));} -inline constexpr float toRad(float deg) {return deg * M_PI_180;} -inline constexpr double toRad(double deg) {return deg * M_PI_180;} -inline constexpr long double toRad(long double deg) {return deg * M_PI_180;} -inline constexpr float toDeg(float rad) {return rad * M_180_PI;} -inline constexpr double toDeg(double rad) {return rad * M_180_PI;} -inline constexpr long double toDeg(long double rad) {return rad * M_180_PI;} +inline constexpr float toRad(float deg) {return deg * M_PI_180;} +inline constexpr double toRad(double deg) {return deg * M_PI_180;} +inline constexpr ldouble toRad(ldouble deg) {return deg * M_PI_180;} +inline constexpr float toDeg(float rad) {return rad * M_180_PI;} +inline constexpr double toDeg(double rad) {return rad * M_180_PI;} +inline constexpr ldouble toDeg(ldouble rad) {return rad * M_180_PI;} template inline constexpr T sqr(const T & v) {return v * v;} +template inline constexpr T toDb (T val) {return T(10.) * std::log10(val);} +template inline constexpr T fromDb(T val) {return std::pow(T(10.), val / T(10.));} // [-1 ; 1] PIP_EXPORT double randomd(); diff --git a/libs/main/math/pimathmatrix.h b/libs/main/math/pimathmatrix.h index 2d9dffd1..8f4304b0 100644 --- a/libs/main/math/pimathmatrix.h +++ b/libs/main/math/pimathmatrix.h @@ -809,7 +809,7 @@ public: * @return matrix type _CMatrix */ _CMatrix &swapRows(uint c0, uint c1) { - PIMM_FOR_R piSwap(_V2D::element(c0, i), _V2D::element(c1, i)); + PIMM_FOR_R piSwap(_V2D::element(c0, i), _V2D::element(c1, i)); return *this; } From fa85f414db3e799d043755f469460d77b6fb50b0 Mon Sep 17 00:00:00 2001 From: andrey Date: Thu, 22 Oct 2020 18:56:01 +0300 Subject: [PATCH 58/98] fix tests and pimathmatrix.h --- libs/main/math/pimathmatrix.h | 4 +- tests/math/testpimathmatrix.cpp | 844 +++++++++++++++---------------- tests/math/testpimathmatrixt.cpp | 799 ++++++++++++++--------------- 3 files changed, 794 insertions(+), 853 deletions(-) diff --git a/libs/main/math/pimathmatrix.h b/libs/main/math/pimathmatrix.h index 8f4304b0..94cf9480 100644 --- a/libs/main/math/pimathmatrix.h +++ b/libs/main/math/pimathmatrix.h @@ -769,7 +769,7 @@ public: * @return matrix type _CMatrix */ _CMatrix &setCol(uint index, const PIMathVector &v) { - assert(_V2D::rows == v.size()); + assert(_V2D::rows() == v.size()); PIMM_FOR_R _V2D::element(i, index) = v[i]; return *this; } @@ -782,7 +782,7 @@ public: * @return matrix type _CMatrix */ _CMatrix &setRow(uint index, const PIMathVector &v) { - assert(_V2D::cols == v.size()); + assert(_V2D::cols() == v.size()); PIMM_FOR_C _V2D::element(index, i) = v[i]; return *this; } diff --git a/tests/math/testpimathmatrix.cpp b/tests/math/testpimathmatrix.cpp index fb7109fb..05de2e14 100644 --- a/tests/math/testpimathmatrix.cpp +++ b/tests/math/testpimathmatrix.cpp @@ -2,554 +2,554 @@ #include "pimathmatrix.h" bool cmpSquareMatrixWithValue(PIMathMatrix matrix, double val, int num) { - bool b = true; - for(int i = 0; i < num; i++) { - for(int j = 0; j < num; j++) { - if(matrix.element(i, j) != val) { - b = false; - } - } - } - return b; + bool b = true; + for(int i = 0; i < num; i++) { + for(int j = 0; j < num; j++) { + if(matrix.element(i, j) != val) { + b = false; + } + } + } + return b; } TEST(PIMathMatrix_Test, identity) { - auto matrix = PIMathMatrix::identity(3, 3); - for(int i = 0; i < 3; i++) { - for(int j = 0; j < 3; j++) { - if(i != j) { - if(matrix[i][j] != 0.0){ - ASSERT_TRUE(false); - } - } - else { - if(matrix[i][i] != 1.0){ - ASSERT_TRUE(false); - } - } - } - } - ASSERT_TRUE(true); + auto matrix = PIMathMatrix::identity(3, 3); + for(int i = 0; i < 3; i++) { + for(int j = 0; j < 3; j++) { + if(i != j) { + if(matrix[i][j] != 0.0){ + ASSERT_TRUE(false); + } + } + else { + if(matrix[i][i] != 1.0){ + ASSERT_TRUE(false); + } + } + } + } + ASSERT_TRUE(true); } TEST(PIMathMatrixT_Test, element) { - auto matrix = PIMathMatrix::identity(3, 3); - for(int i = 0; i < 3; i++){ - for(int j = 0; j < 3; j++){ - if(i != j){ - if(matrix[i][j] != 0.0){ - ASSERT_TRUE(false); - } - } - else { - if(matrix.element(i,i) != 1.0) { - ASSERT_TRUE(false); - } - } - } - } - ASSERT_TRUE(true); + auto matrix = PIMathMatrix::identity(3, 3); + for(int i = 0; i < 3; i++){ + for(int j = 0; j < 3; j++){ + if(i != j){ + if(matrix[i][j] != 0.0){ + ASSERT_TRUE(false); + } + } + else { + if(matrix.element(i,i) != 1.0) { + ASSERT_TRUE(false); + } + } + } + } + ASSERT_TRUE(true); } TEST(PIMathMatrix_Test, matrixRow) { - PIMathVector vector; - vector.resize(3, 3.0); - auto matrix = PIMathMatrix::matrixRow(vector); - for(uint i = 0; i < vector.size(); i++) { - if(matrix[0][i] != 3.0) { - ASSERT_TRUE(false); - } - } - ASSERT_TRUE(true); + PIMathVector vector; + vector.resize(3, 3.0); + auto matrix = PIMathMatrix::matrixRow(vector); + for(uint i = 0; i < vector.size(); i++) { + if(matrix[0][i] != 3.0) { + ASSERT_TRUE(false); + } + } + ASSERT_TRUE(true); } TEST(PIMathMatrix_Test, matrixCol) { - PIMathVector vector; - vector.resize(3, 3.0); - auto matrix = PIMathMatrix::matrixCol(vector); - for(uint i = 0; i < vector.size(); i++) { - if(matrix[i][0] != 3.0) { - ASSERT_TRUE(false); - } - } - ASSERT_TRUE(true); + PIMathVector vector; + vector.resize(3, 3.0); + auto matrix = PIMathMatrix::matrixCol(vector); + for(uint i = 0; i < vector.size(); i++) { + if(matrix[i][0] != 3.0) { + ASSERT_TRUE(false); + } + } + ASSERT_TRUE(true); } TEST(PIMathMatrix_Test, setCol) { - PIMathVector vector; - vector.resize(3, 3.0); - auto matrix = PIMathMatrix::matrixCol(vector); - vector.fill(10.0); - matrix.setCol(0, vector); - for(uint i = 0; i < vector.size(); i++) { - if(matrix[i][0] != 10.0) { - ASSERT_TRUE(false); - } - } - ASSERT_TRUE(true); + PIMathVector vector; + vector.resize(3, 3.0); + auto matrix = PIMathMatrix::matrixCol(vector); + vector.fill(10.0); + matrix.setCol(0, vector); + for(uint i = 0; i < vector.size(); i++) { + if(matrix[i][0] != 10.0) { + ASSERT_TRUE(false); + } + } + ASSERT_TRUE(true); } TEST(PIMathMatrix_Test, setRow) { - PIMathVector vector; - vector.resize(3, 3.0); - auto matrix = PIMathMatrix::matrixRow(vector); - vector.fill(10.0); - matrix.setRow(0, vector); - for(uint i = 0; i < vector.size(); i++) { - if(matrix[0][i] != 10.0) { - ASSERT_TRUE(false); - } - } - ASSERT_TRUE(true); + PIMathVector vector; + vector.resize(3, 3.0); + auto matrix = PIMathMatrix::matrixRow(vector); + vector.fill(10.0); + matrix.setRow(0, vector); + for(uint i = 0; i < vector.size(); i++) { + if(matrix[0][i] != 10.0) { + ASSERT_TRUE(false); + } + } + ASSERT_TRUE(true); } TEST(PIMathMatrix_Test, swapCols) { - PIMathMatrix origMatr; - PIMathMatrix matrix1; - PIMathVector vector; - uint i1 = 0; uint i2 = 1; - double a1[3], a2[3], a3[3]; - double b1[3], b2[3], b3[3]; - vector.resize(3, 3.0); - vector.at(0) = 3.0; - vector.at(1) = 6.0; - vector.at(2) = 8.0; - matrix1 = origMatr.identity(3, 3); - matrix1.setCol(0, vector); - vector.at(0) = 2.0; - vector.at(1) = 1.0; - vector.at(2) = 4.0; - matrix1.setCol(1, vector); - vector.at(0) = 6.0; - vector.at(1) = 2.0; - vector.at(2) = 5.0; - matrix1.setCol(2, vector); - for(int i = 0; i < 3; i++) { - a1[i] = matrix1.element(i, 0); - a2[i] = matrix1.element(i, 1); - a3[i] = matrix1.element(i, 2); - } - matrix1.swapCols(i1, i2); - for(int i = 0; i < 3; i++) { - b1[i] = matrix1.element(i, 0); - b2[i] = matrix1.element(i, 1); - b3[i] = matrix1.element(i, 2); - } - ASSERT_TRUE((memcmp(a1, b2, sizeof(b1)) == 0) && (memcmp(a2, b1, sizeof(b1)) == 0) && (memcmp(a3, b3, sizeof(b1)) == 0)); + PIMathMatrix origMatr; + PIMathMatrix matrix1; + PIMathVector vector; + uint i1 = 0; uint i2 = 1; + double a1[3], a2[3], a3[3]; + double b1[3], b2[3], b3[3]; + vector.resize(3, 3.0); + vector[0] = 3.0; + vector[1] = 6.0; + vector[2] = 8.0; + matrix1 = origMatr.identity(3, 3); + matrix1.setCol(0, vector); + vector[0] = 2.0; + vector[1] = 1.0; + vector[2] = 4.0; + matrix1.setCol(1, vector); + vector[0] = 6.0; + vector[1] = 2.0; + vector[2] = 5.0; + matrix1.setCol(2, vector); + for(int i = 0; i < 3; i++) { + a1[i] = matrix1.element(i, 0); + a2[i] = matrix1.element(i, 1); + a3[i] = matrix1.element(i, 2); + } + matrix1.swapCols(i1, i2); + for(int i = 0; i < 3; i++) { + b1[i] = matrix1.element(i, 0); + b2[i] = matrix1.element(i, 1); + b3[i] = matrix1.element(i, 2); + } + ASSERT_TRUE((memcmp(a1, b2, sizeof(b1)) == 0) && (memcmp(a2, b1, sizeof(b1)) == 0) && (memcmp(a3, b3, sizeof(b1)) == 0)); } TEST(PIMathMatrix_Test, swapRows) { - PIMathMatrix origMatr; - PIMathMatrix matrix1; - PIMathVector vector; - uint i1 = 0; uint i2 = 1; - double a1[3], a2[3], a3[3]; - double b1[3], b2[3], b3[3]; - vector.resize(3, 3.0); - vector.at(0) = 3.0; - vector.at(1) = 6.0; - vector.at(2) = 8.0; - matrix1 = origMatr.identity(3, 3); - matrix1.setCol(0, vector); - vector.at(0) = 2.0; - vector.at(1) = 1.0; - vector.at(2) = 4.0; - matrix1.setCol(1, vector); - vector.at(0) = 6.0; - vector.at(1) = 2.0; - vector.at(2) = 5.0; - matrix1.setCol(2, vector); - for(int i = 0; i < 3; i++) { - a1[i] = matrix1.element(0, i); - a2[i] = matrix1.element(1, i); - a3[i] = matrix1.element(2, i); - } - matrix1.swapRows(i1, i2); - for(int i = 0; i < 3; i++) { - b1[i] = matrix1.element(0, i); - b2[i] = matrix1.element(1, i); - b3[i] = matrix1.element(2, i); - } - ASSERT_TRUE((memcmp(a1, b2, sizeof(b1)) == 0) && (memcmp(a2, b1, sizeof(b1)) == 0) && (memcmp(a3, b3, sizeof(b1)) == 0)); + PIMathMatrix origMatr; + PIMathMatrix matrix1; + PIMathVector vector; + uint i1 = 0; uint i2 = 1; + double a1[3], a2[3], a3[3]; + double b1[3], b2[3], b3[3]; + vector.resize(3, 3.0); + vector[0] = 3.0; + vector[1] = 6.0; + vector[2] = 8.0; + matrix1 = origMatr.identity(3, 3); + matrix1.setCol(0, vector); + vector[0] = 2.0; + vector[1] = 1.0; + vector[2] = 4.0; + matrix1.setCol(1, vector); + vector[0] = 6.0; + vector[1] = 2.0; + vector[2] = 5.0; + matrix1.setCol(2, vector); + for(int i = 0; i < 3; i++) { + a1[i] = matrix1.element(0, i); + a2[i] = matrix1.element(1, i); + a3[i] = matrix1.element(2, i); + } + matrix1.swapRows(i1, i2); + for(int i = 0; i < 3; i++) { + b1[i] = matrix1.element(0, i); + b2[i] = matrix1.element(1, i); + b3[i] = matrix1.element(2, i); + } + ASSERT_TRUE((memcmp(a1, b2, sizeof(b1)) == 0) && (memcmp(a2, b1, sizeof(b1)) == 0) && (memcmp(a3, b3, sizeof(b1)) == 0)); } TEST(PIMathMatrix_Test, fill) { - PIMathMatrix matrix(3, 3, 5.0); - matrix.fill(7.0); - ASSERT_TRUE(cmpSquareMatrixWithValue(matrix, 7.0, 3)); + PIMathMatrix matrix(3, 3, 5.0); + matrix.fill(7.0); + ASSERT_TRUE(cmpSquareMatrixWithValue(matrix, 7.0, 3)); } TEST(PIMathMatrix_Test, isSquareTrue) { - PIMathMatrix matrix(3, 3, 1.0); - ASSERT_TRUE(matrix.isSquare()); + PIMathMatrix matrix(3, 3, 1.0); + ASSERT_TRUE(matrix.isSquare()); } TEST(PIMathMatrix_Test, isSquareFalse) { - PIMathMatrix matrix(2, 4, 1.0); - ASSERT_FALSE(matrix.isSquare()); + PIMathMatrix matrix(2, 4, 1.0); + ASSERT_FALSE(matrix.isSquare()); } TEST(PIMathMatrix_Test, isIdentityTrue) { - auto matrix = PIMathMatrix::identity(3, 3); - ASSERT_TRUE(matrix.isIdentity()); + auto matrix = PIMathMatrix::identity(3, 3); + ASSERT_TRUE(matrix.isIdentity()); } TEST(PIMathMatrix_Test, isIdentityFalse) { - PIMathMatrix matrix(3, 3, 5.0); - ASSERT_FALSE(matrix.isIdentity()); + PIMathMatrix matrix(3, 3, 5.0); + ASSERT_FALSE(matrix.isIdentity()); } TEST(PIMathMatrix_Test, isNullTrue) { - PIMathMatrix matrix(3, 3, 0.0); - ASSERT_TRUE(matrix.isNull()); + PIMathMatrix matrix(3, 3, 0.0); + ASSERT_TRUE(matrix.isNull()); } TEST(PIMathMatrix_Test, isNullFalse) { - PIMathMatrix matrix(3, 3, 5.0); - ASSERT_FALSE(matrix.isNull()); + PIMathMatrix matrix(3, 3, 5.0); + ASSERT_FALSE(matrix.isNull()); } TEST(PIMathMatrix_Test, isValidTrue) { - PIMathMatrix matrix(3, 3, 1.62); - ASSERT_TRUE(matrix.isValid()); + PIMathMatrix matrix(3, 3, 1.62); + ASSERT_TRUE(matrix.isValid()); } TEST(PIMathMatrix_Test, isValidFalse) { - PIMathMatrix matrix; - ASSERT_FALSE(matrix.isValid()); + PIMathMatrix matrix; + ASSERT_FALSE(matrix.isValid()); } TEST(PIMathMatrix_Test, operator_Assignment) { - PIMathMatrix matrix1(3, 3, 5.72); - PIMathMatrix matrix2(3, 3, 7.12); - matrix1 = matrix2; - ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1, 7.12, 3)); + PIMathMatrix matrix1(3, 3, 5.72); + PIMathMatrix matrix2(3, 3, 7.12); + matrix1 = matrix2; + ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1, 7.12, 3)); } TEST(PIMathMatrix_Test, operator_EqualTrue) { - PIMathMatrix matrix1(2, 2, 2.0); - PIMathMatrix matrix2(2, 2, 2.0); - matrix1.element(0, 0) = 5.1; - matrix1.element(0, 1) = 1.21; - matrix1.element(1, 1) = 0.671; - matrix1.element(1, 0) = 2.623; - matrix2.element(0, 0) = 5.1; - matrix2.element(0, 1) = 1.21; - matrix2.element(1, 1) = 0.671; - matrix2.element(1, 0) = 2.623; - ASSERT_TRUE(matrix1 == matrix2); + PIMathMatrix matrix1(2, 2, 2.0); + PIMathMatrix matrix2(2, 2, 2.0); + matrix1.element(0, 0) = 5.1; + matrix1.element(0, 1) = 1.21; + matrix1.element(1, 1) = 0.671; + matrix1.element(1, 0) = 2.623; + matrix2.element(0, 0) = 5.1; + matrix2.element(0, 1) = 1.21; + matrix2.element(1, 1) = 0.671; + matrix2.element(1, 0) = 2.623; + ASSERT_TRUE(matrix1 == matrix2); } TEST(PIMathMatrix_Test, operator_EqualFalse) { - PIMathMatrix matrix1(2, 2, 2.0); - PIMathMatrix matrix2(2, 2, 2.0); - matrix1.element(0, 0) = 5.1; - matrix1.element(0, 1) = 1.21; - matrix1.element(1, 1) = 0.671; - matrix1.element(1, 0) = 2.623; - matrix2.element(0, 0) = 5.1; - matrix2.element(0, 1) = 1.21; - matrix2.element(1, 1) = 665.671; - matrix2.element(1, 0) = 2.623; - ASSERT_FALSE(matrix1 == matrix2); + PIMathMatrix matrix1(2, 2, 2.0); + PIMathMatrix matrix2(2, 2, 2.0); + matrix1.element(0, 0) = 5.1; + matrix1.element(0, 1) = 1.21; + matrix1.element(1, 1) = 0.671; + matrix1.element(1, 0) = 2.623; + matrix2.element(0, 0) = 5.1; + matrix2.element(0, 1) = 1.21; + matrix2.element(1, 1) = 665.671; + matrix2.element(1, 0) = 2.623; + ASSERT_FALSE(matrix1 == matrix2); } TEST(PIMathMatrix_Test, operator_Not_EqualTrue) { - PIMathMatrix matrix1(2, 2, 2.0); - PIMathMatrix matrix2(2, 2, 2.0); - matrix1.element(0, 0) = 5.1; - matrix1.element(0, 1) = 1.21; - matrix1.element(1, 1) = 0.671; - matrix1.element(1, 0) = 2.623; - matrix2.element(0, 0) = 5.1; - matrix2.element(0, 1) = 1.21; - matrix2.element(1, 1) = 665.671; - matrix2.element(1, 0) = 2.623; - ASSERT_TRUE(matrix1 != matrix2); + PIMathMatrix matrix1(2, 2, 2.0); + PIMathMatrix matrix2(2, 2, 2.0); + matrix1.element(0, 0) = 5.1; + matrix1.element(0, 1) = 1.21; + matrix1.element(1, 1) = 0.671; + matrix1.element(1, 0) = 2.623; + matrix2.element(0, 0) = 5.1; + matrix2.element(0, 1) = 1.21; + matrix2.element(1, 1) = 665.671; + matrix2.element(1, 0) = 2.623; + ASSERT_TRUE(matrix1 != matrix2); } TEST(PIMathMatrix_Test, operator_Not_EqualFalse) { - PIMathMatrix matrix1(2, 2, 2.0); - PIMathMatrix matrix2(2, 2, 2.0); - matrix1.element(0, 0) = 5.1; - matrix1.element(0, 1) = 1.21; - matrix1.element(1, 1) = 0.671; - matrix1.element(1, 0) = 2.623; - matrix2.element(0, 0) = 5.1; - matrix2.element(0, 1) = 1.21; - matrix2.element(1, 1) = 0.671; - matrix2.element(1, 0) = 2.623; - ASSERT_FALSE(matrix1 != matrix2); + PIMathMatrix matrix1(2, 2, 2.0); + PIMathMatrix matrix2(2, 2, 2.0); + matrix1.element(0, 0) = 5.1; + matrix1.element(0, 1) = 1.21; + matrix1.element(1, 1) = 0.671; + matrix1.element(1, 0) = 2.623; + matrix2.element(0, 0) = 5.1; + matrix2.element(0, 1) = 1.21; + matrix2.element(1, 1) = 0.671; + matrix2.element(1, 0) = 2.623; + ASSERT_FALSE(matrix1 != matrix2); } TEST(PIMathMatrix_Test, operator_Addition_Aassignment) { - PIMathMatrix matrix1(3, 3, 6.72); - PIMathMatrix matrix2(3, 3, 1.0); - matrix1 += matrix2; - ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1, 7.72, 3)); + PIMathMatrix matrix1(3, 3, 6.72); + PIMathMatrix matrix2(3, 3, 1.0); + matrix1 += matrix2; + ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1, 7.72, 3)); } TEST(PIMathMatrix_Test, operator_Subtraction_Assignment) { - PIMathMatrix matrix1(3, 3, 1.0); - PIMathMatrix matrix2(3, 3, 6.72); - matrix1 -= matrix2; - ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1, -5.72, 3)); + PIMathMatrix matrix1(3, 3, 1.0); + PIMathMatrix matrix2(3, 3, 6.72); + matrix1 -= matrix2; + ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1, -5.72, 3)); } TEST(PIMathMatrix_Test, operator_Multiplication_Assignment) { - PIMathMatrix matrix1(3, 3, 6.72); - matrix1 *= 2.0; - ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1, 13.44, 3)); + PIMathMatrix matrix1(3, 3, 6.72); + matrix1 *= 2.0; + ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1, 13.44, 3)); } TEST(PIMathMatrix_Test, operator_Division_Assignment) { - PIMathMatrix matrix1(3, 3, 6.72); - matrix1 /= 2.0; - ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1, 3.36, 3)); + PIMathMatrix matrix1(3, 3, 6.72); + matrix1 /= 2.0; + ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1, 3.36, 3)); } TEST(PIMathMatrix_Test, operator_Addition) { - PIMathMatrix matrix1(3, 3, 6.72); - PIMathMatrix matrix2(3, 3, 8.28); - ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1 + matrix2, 15.0, 3)); + PIMathMatrix matrix1(3, 3, 6.72); + PIMathMatrix matrix2(3, 3, 8.28); + ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1 + matrix2, 15.0, 3)); } TEST(PIMathMatrix_Test, operator_Subtraction) { - PIMathMatrix matrix1(3, 3, 6.0); - PIMathMatrix matrix2(3, 3, 5.0); - ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1 - matrix2, 1.0, 3)); + PIMathMatrix matrix1(3, 3, 6.0); + PIMathMatrix matrix2(3, 3, 5.0); + ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1 - matrix2, 1.0, 3)); } TEST(PIMathMatrix_Test, operator_Multiplication) { - PIMathMatrix matrix1(3, 3, 6.72); - PIMathMatrix matrix2(3, 3, 5.0); - matrix2 = matrix1*4.0; - ASSERT_TRUE(cmpSquareMatrixWithValue(matrix2, 26.88, 3)); + PIMathMatrix matrix1(3, 3, 6.72); + PIMathMatrix matrix2(3, 3, 5.0); + matrix2 = matrix1*4.0; + ASSERT_TRUE(cmpSquareMatrixWithValue(matrix2, 26.88, 3)); } TEST(PIMathMatrix_Test, operator_Division) { - PIMathMatrix matrix1(3, 3, 6.72); - PIMathMatrix matrix2(3, 3, 5.0); - matrix2 = matrix1/4.0; - ASSERT_TRUE(cmpSquareMatrixWithValue(matrix2, 1.68, 3)); + PIMathMatrix matrix1(3, 3, 6.72); + PIMathMatrix matrix2(3, 3, 5.0); + matrix2 = matrix1/4.0; + ASSERT_TRUE(cmpSquareMatrixWithValue(matrix2, 1.68, 3)); } TEST(PIMathMatrix_Test, determinantIfSquare) { - double d; - double i = 59.0; - PIMathMatrix matrix(3, 3, 0.0); - PIMathVector vector; - vector.resize(3, 3.0); - vector.at(0) = 3.0; - vector.at(1) = 6.0; - vector.at(2) = 8.0; - matrix.setCol(0, vector); - vector.at(0) = 2.0; - vector.at(1) = 1.0; - vector.at(2) = 4.0; - matrix.setCol(1, vector); - vector.at(0) = 6.0; - vector.at(1) = 2.0; - vector.at(2) = 5.0; - matrix.setCol(2, vector); - d = matrix.determinant(); - ASSERT_DOUBLE_EQ(d, i); + double d; + double i = 59.0; + PIMathMatrix matrix(3, 3, 0.0); + PIMathVector vector; + vector.resize(3, 3.0); + vector[0] = 3.0; + vector[1] = 6.0; + vector[2] = 8.0; + matrix.setCol(0, vector); + vector[0] = 2.0; + vector[1] = 1.0; + vector[2] = 4.0; + matrix.setCol(1, vector); + vector[0] = 6.0; + vector[1] = 2.0; + vector[2] = 5.0; + matrix.setCol(2, vector); + d = matrix.determinant(); + ASSERT_DOUBLE_EQ(d, i); } TEST(PIMathMatrix_Test, determinantIfNotSquare) { - PIMathMatrix matrix(3, 5, 1.0); - matrix.element(1,1) = 5.0; - ASSERT_FALSE(matrix.determinant()); + PIMathMatrix matrix(3, 5, 1.0); + matrix.element(1,1) = 5.0; + ASSERT_FALSE(matrix.determinant()); } TEST(PIMathMatrix_Test, trace) { - PIMathMatrix matrix(3, 3, 0.0); - double t; - double i = 9.0; - PIMathVector vector; - vector.resize(3, 3.0); - vector.at(0) = 3.0; - vector.at(1) = 6.0; - vector.at(2) = 8.0; - matrix.setCol(0, vector); - vector.at(0) = 2.0; - vector.at(1) = 1.0; - vector.at(2) = 4.0; - matrix.setCol(1, vector); - vector.at(0) = 6.0; - vector.at(1) = 2.0; - vector.at(2) = 5.0; - matrix.setCol(2, vector); - t = matrix.trace(); - ASSERT_DOUBLE_EQ(t, i); + PIMathMatrix matrix(3, 3, 0.0); + double t; + double i = 9.0; + PIMathVector vector; + vector.resize(3, 3.0); + vector[0] = 3.0; + vector[1] = 6.0; + vector[2] = 8.0; + matrix.setCol(0, vector); + vector[0] = 2.0; + vector[1] = 1.0; + vector[2] = 4.0; + matrix.setCol(1, vector); + vector[0] = 6.0; + vector[1] = 2.0; + vector[2] = 5.0; + matrix.setCol(2, vector); + t = matrix.trace(); + ASSERT_DOUBLE_EQ(t, i); } TEST(PIMathMatrix_Test, traceIfNotSquare) { - PIMathMatrix matrix(3, 5, 1.0); - matrix.element(1,1) = 5.0; - ASSERT_FALSE(matrix.trace()); + PIMathMatrix matrix(3, 5, 1.0); + matrix.element(1,1) = 5.0; + ASSERT_FALSE(matrix.trace()); } TEST(PIMathMatrix_Test, toUpperTriangular) { - PIMathMatrix matrix(3, 3, 0.0); - double d1, d2 = 1; - int i; - PIMathVector vector; - vector.resize(3, 3.0); - vector.at(0) = 3.0; - vector.at(1) = 6.0; - vector.at(2) = 8.0; - matrix.setCol(0, vector); - vector.at(0) = 2.0; - vector.at(1) = 1.0; - vector.at(2) = 4.0; - matrix.setCol(1, vector); - vector.at(0) = 6.0; - vector.at(1) = 2.0; - vector.at(2) = 5.0; - matrix.setCol(2, vector); - d1 = matrix.determinant(); - matrix.toUpperTriangular(); - for(i = 0; i < 3; i++) - { - d2 = d2 * matrix.element(i, i); - } - ASSERT_DOUBLE_EQ(d1, d2); + PIMathMatrix matrix(3, 3, 0.0); + double d1, d2 = 1; + int i; + PIMathVector vector; + vector.resize(3, 3.0); + vector[0] = 3.0; + vector[1] = 6.0; + vector[2] = 8.0; + matrix.setCol(0, vector); + vector[0] = 2.0; + vector[1] = 1.0; + vector[2] = 4.0; + matrix.setCol(1, vector); + vector[0] = 6.0; + vector[1] = 2.0; + vector[2] = 5.0; + matrix.setCol(2, vector); + d1 = matrix.determinant(); + matrix.toUpperTriangular(); + for(i = 0; i < 3; i++) + { + d2 = d2 * matrix.element(i, i); + } + ASSERT_DOUBLE_EQ(d1, d2); } TEST(PIMathMatrix_Test, invert) { - double d1, d2; - PIMathMatrix matrix1(3, 3, 0.0); - PIMathMatrix matrix2(3, 3, 0.0); - PIMathMatrix matrix3(3, 3, 0.0); - PIMathMatrix matrix4(3, 3, 0.0); - PIMathVector vector; - vector.resize(3, 3.0); - vector.at(0) = 3.0; - vector.at(1) = 6.0; - vector.at(2) = 8.0; - matrix1.setCol(0, vector); - vector.at(0) = 2.0; - vector.at(1) = 1.0; - vector.at(2) = 4.0; - matrix1.setCol(1, vector); - vector.at(0) = 6.0; - vector.at(1) = 2.0; - vector.at(2) = 5.0; - matrix1.setCol(2, vector); - d1 = matrix1.determinant(); - matrix2 = matrix1; - matrix2.invert(); - d2 = matrix2.determinant(); - matrix4.invert(); - ASSERT_TRUE((matrix3 == matrix4) && (round((1/d1)*10000)/10000 == round(d2*10000)/10000)); + double d1, d2; + PIMathMatrix matrix1(3, 3, 0.0); + PIMathMatrix matrix2(3, 3, 0.0); + PIMathMatrix matrix3(3, 3, 0.0); + PIMathMatrix matrix4(3, 3, 0.0); + PIMathVector vector; + vector.resize(3, 3.0); + vector[0] = 3.0; + vector[1] = 6.0; + vector[2] = 8.0; + matrix1.setCol(0, vector); + vector[0] = 2.0; + vector[1] = 1.0; + vector[2] = 4.0; + matrix1.setCol(1, vector); + vector[0] = 6.0; + vector[1] = 2.0; + vector[2] = 5.0; + matrix1.setCol(2, vector); + d1 = matrix1.determinant(); + matrix2 = matrix1; + matrix2.invert(); + d2 = matrix2.determinant(); + matrix4.invert(); + ASSERT_TRUE((matrix3 == matrix4) && (round((1/d1)*10000)/10000 == round(d2*10000)/10000)); } TEST(PIMathMatrix_Test, inverted) { - double d1, d2; - PIMathMatrix matrix1(3, 3, 0.0); - PIMathMatrix matrix2(3, 3, 0.0); - PIMathMatrix matrix3(3, 3, 0.0); - PIMathMatrix matrix4(3, 3, 0.0); - PIMathVector vector; - vector.resize(3, 3.0); - vector.at(0) = 3.0; - vector.at(1) = 6.0; - vector.at(2) = 8.0; - matrix1.setCol(0, vector); - vector.at(0) = 2.0; - vector.at(1) = 1.0; - vector.at(2) = 4.0; - matrix1.setCol(1, vector); - vector.at(0) = 6.0; - vector.at(1) = 2.0; - vector.at(2) = 5.0; - matrix1.setCol(2, vector); - d1 = matrix1.determinant(); - matrix2 = matrix1; - matrix1 = matrix2.invert(); - d2 = matrix1.determinant(); - matrix3 = matrix4.invert(); - ASSERT_TRUE((matrix3 == matrix4) && (round((1/d1)*10000)/10000 == round(d2*10000)/10000)); + double d1, d2; + PIMathMatrix matrix1(3, 3, 0.0); + PIMathMatrix matrix2(3, 3, 0.0); + PIMathMatrix matrix3(3, 3, 0.0); + PIMathMatrix matrix4(3, 3, 0.0); + PIMathVector vector; + vector.resize(3, 3.0); + vector[0] = 3.0; + vector[1] = 6.0; + vector[2] = 8.0; + matrix1.setCol(0, vector); + vector[0] = 2.0; + vector[1] = 1.0; + vector[2] = 4.0; + matrix1.setCol(1, vector); + vector[0] = 6.0; + vector[1] = 2.0; + vector[2] = 5.0; + matrix1.setCol(2, vector); + d1 = matrix1.determinant(); + matrix2 = matrix1; + matrix1 = matrix2.invert(); + d2 = matrix1.determinant(); + matrix3 = matrix4.invert(); + ASSERT_TRUE((matrix3 == matrix4) && (round((1/d1)*10000)/10000 == round(d2*10000)/10000)); } TEST(PIMathMatrix_Test, transposed) { - PIMathMatrix origMatr; - double d1, d2; - PIMathMatrix matrix1; - PIMathMatrix matrix2; - PIMathMatrix matrix3; - PIMathVector vector; - vector.resize(3, 3.0); - vector.at(0) = 3.0; - vector.at(1) = 6.0; - vector.at(2) = 8.0; - matrix1 = origMatr.identity(3, 3); - matrix1.setCol(0, vector); - vector.at(0) = 2.0; - vector.at(1) = 1.0; - vector.at(2) = 4.0; - matrix1.setCol(1, vector); - vector.at(0) = 6.0; - vector.at(1) = 2.0; - vector.at(2) = 5.0; - matrix1.setCol(2, vector); - d1 = matrix1.determinant(); - matrix2 = matrix1.transposed(); - d2 = matrix2.determinant(); - matrix3 = matrix2.transposed(); - ASSERT_TRUE((d1 == d2) && (matrix1 == matrix3)); + PIMathMatrix origMatr; + double d1, d2; + PIMathMatrix matrix1; + PIMathMatrix matrix2; + PIMathMatrix matrix3; + PIMathVector vector; + vector.resize(3, 3.0); + vector[0] = 3.0; + vector[1] = 6.0; + vector[2] = 8.0; + matrix1 = origMatr.identity(3, 3); + matrix1.setCol(0, vector); + vector[0] = 2.0; + vector[1] = 1.0; + vector[2] = 4.0; + matrix1.setCol(1, vector); + vector[0] = 6.0; + vector[1] = 2.0; + vector[2] = 5.0; + matrix1.setCol(2, vector); + d1 = matrix1.determinant(); + matrix2 = matrix1.transposed(); + d2 = matrix2.determinant(); + matrix3 = matrix2.transposed(); + ASSERT_TRUE((d1 == d2) && (matrix1 == matrix3)); } TEST(PIMathMatrix_Test, matrixMultiplication) { - PIMathMatrix matrix1(2, 2, 1.5); - PIMathMatrix matrix2(2, 2, 2.5); - ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1 * matrix2, 7.5, 2)); + PIMathMatrix matrix1(2, 2, 1.5); + PIMathMatrix matrix2(2, 2, 2.5); + ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1 * matrix2, 7.5, 2)); } TEST(PIMathMatrix_Test, matrixAndVectorMultiplication) { - PIMathMatrix matrix1(2, 2, 1.5); - PIMathVector vector; - vector.resize(2, 2.5); - for(uint i = 0; i < 2; i++) { - if((matrix1 * vector)[i] != 7.5) { - ASSERT_TRUE(false); - } - } - ASSERT_TRUE(true); + PIMathMatrix matrix1(2, 2, 1.5); + PIMathVector vector; + vector.resize(2, 2.5); + for(uint i = 0; i < 2; i++) { + if((matrix1 * vector)[i] != 7.5) { + ASSERT_TRUE(false); + } + } + ASSERT_TRUE(true); } TEST(PIMathMatrix_Test, vectorAndMatrixMultiplication) { - PIMathMatrix matrix1(2, 2, 1.5); - PIMathVector vector; - vector.resize(2, 2.5); - for(uint i = 0; i < 2; i++) { - if((vector * matrix1)[i] != 7.5) { - ASSERT_TRUE(false); - } - } - ASSERT_TRUE(true); + PIMathMatrix matrix1(2, 2, 1.5); + PIMathVector vector; + vector.resize(2, 2.5); + for(uint i = 0; i < 2; i++) { + if((vector * matrix1)[i] != 7.5) { + ASSERT_TRUE(false); + } + } + ASSERT_TRUE(true); } TEST(PIMathMatrix_Test, valAndMatrixMultiplication) { - PIMathMatrix matrix1(3, 3, 1.5); - ASSERT_TRUE(cmpSquareMatrixWithValue(25.0*matrix1, 37.5, 3)); + PIMathMatrix matrix1(3, 3, 1.5); + ASSERT_TRUE(cmpSquareMatrixWithValue(25.0*matrix1, 37.5, 3)); } TEST(PIMathMatrix_Test, hermitian) { - complex val; - complex res; - val.imag(1.0); - val.real(1.0); - PIMathMatrix> matrix(3, 3, val); - res.imag(-1.0); - res.real(1.0); - auto matr = hermitian(matrix); - for(uint i = 0; i < 3; i++) { - for(uint j = 0; j < 3; j++) { - if(matr.element(i, j) != res) { - ASSERT_TRUE(false); - } - } - } - ASSERT_TRUE(true); + complex val; + complex res; + val.imag(1.0); + val.real(1.0); + PIMathMatrix> matrix(3, 3, val); + res.imag(-1.0); + res.real(1.0); + auto matr = hermitian(matrix); + for(uint i = 0; i < 3; i++) { + for(uint j = 0; j < 3; j++) { + if(matr.element(i, j) != res) { + ASSERT_TRUE(false); + } + } + } + ASSERT_TRUE(true); } diff --git a/tests/math/testpimathmatrixt.cpp b/tests/math/testpimathmatrixt.cpp index df96a01c..210ad947 100644 --- a/tests/math/testpimathmatrixt.cpp +++ b/tests/math/testpimathmatrixt.cpp @@ -5,558 +5,499 @@ const uint rows = 3; const uint cols = 3; bool cmpSquareMatrixWithValue(PIMathMatrixT matrix, double val, int num) { - bool b = true; - for(int i = 0; i < num; i++) { - for(int j = 0; j < num; j++) { - if(matrix.at(i, j) != val) { - b = false; - } - } - } - return b; + bool b = true; + for(int i = 0; i < num; i++) { + for(int j = 0; j < num; j++) { + if(matrix.at(i, j) != val) { + b = false; + } + } + } + return b; } TEST(PIMathMatrixT_Test, identity) { - auto matrix = PIMathMatrixT::identity(); - for(int i = 0; i < 3; i++){ - for(int j = 0; j < 3; j++){ - if(i != j){ - if(matrix[i][j] != 0.0){ - ASSERT_TRUE(false); - } - } - else { - if(matrix[i][i] != 1.0){ - ASSERT_TRUE(false); - } - } - } - } - ASSERT_TRUE(true); + auto matrix = PIMathMatrixT::identity(); + for(int i = 0; i < 3; i++){ + for(int j = 0; j < 3; j++){ + if(i != j){ + if(matrix[i][j] != 0.0){ + ASSERT_TRUE(false); + } + } + else { + if(matrix[i][i] != 1.0){ + ASSERT_TRUE(false); + } + } + } + } + ASSERT_TRUE(true); } TEST(PIMathMatrixT_Test, at) { - auto matrix1 = PIMathMatrixT::identity(); - for(uint i = 0; i < rows; i++) { - if(matrix1.at(i,i) != 1.0) { - ASSERT_TRUE(false); - } - } - ASSERT_TRUE(true); + auto matrix1 = PIMathMatrixT::identity(); + for(uint i = 0; i < rows; i++) { + if(matrix1.at(i,i) != 1.0) { + ASSERT_TRUE(false); + } + } + ASSERT_TRUE(true); } TEST(PIMathMatrixT_Test, filled) { - auto matr = PIMathMatrixT::filled(1.0); - ASSERT_TRUE(cmpSquareMatrixWithValue(matr, 1.0, rows)); + auto matr = PIMathMatrixT(1.0); + ASSERT_TRUE(cmpSquareMatrixWithValue(matr, 1.0, rows)); } TEST(PIMathMatrixT_Test, cols) { - PIMathMatrixT matr; - ASSERT_EQ(cols,matr.cols()); + PIMathMatrixT matr; + ASSERT_EQ(cols,matr.cols()); } TEST(PIMathMatrixT_Test, rows) { - PIMathMatrixT matr; - ASSERT_EQ(rows,matr.rows()); + PIMathMatrixT matr; + ASSERT_EQ(rows,matr.rows()); } TEST(PIMathMatrixT_Test, col) { - PIMathMatrixT matr; - PIMathVectorT vect; - uint g = 2; - matr.at(0,0) = 3; - matr.at(0,1) = 6; - matr.at(0,2) = 8; - matr.at(1,0) = 2; - matr.at(1,1) = 1; - matr.at(1,2) = 4; - matr.at(2,0) = 6; - matr.at(2,1) = 2; - matr.at(2,2) = 5; - vect = matr.col(g); - for(uint i = 0; i < matr.cols(); i++) { - if(matr.at(i, g) != vect.at(i)) { - ASSERT_TRUE(false); - } - } - ASSERT_TRUE(true); + PIMathMatrixT matr; + PIMathVectorT vect; + uint g = 2; + matr.element(0,0) = 3; + matr.element(0,1) = 6; + matr.element(0,2) = 8; + matr.element(1,0) = 2; + matr.element(1,1) = 1; + matr.element(1,2) = 4; + matr.element(2,0) = 6; + matr.element(2,1) = 2; + matr.element(2,2) = 5; + vect = matr.col(g); + for(uint i = 0; i < matr.cols(); i++) { + if(matr.element(i, g) != vect[i]) { + ASSERT_TRUE(false); + } + } + ASSERT_TRUE(true); } TEST(PIMathMatrixT_Test, row) { - PIMathMatrixT matr; - PIMathVectorT vect; - uint g = 2; - matr.at(0,0) = 3; - matr.at(0,1) = 6; - matr.at(0,2) = 8; - matr.at(1,0) = 2; - matr.at(1,1) = 1; - matr.at(1,2) = 4; - matr.at(2,0) = 6; - matr.at(2,1) = 2; - matr.at(2,2) = 5; - vect = matr.row(g); - for(uint i = 0; i < matr.rows(); i++) { - if(matr.at(g, i) != vect.at(i)) { - ASSERT_TRUE(false); - } - } - ASSERT_TRUE(true); + PIMathMatrixT matr; + PIMathVectorT vect; + uint g = 2; + matr.element(0,0) = 3; + matr.element(0,1) = 6; + matr.element(0,2) = 8; + matr.element(1,0) = 2; + matr.element(1,1) = 1; + matr.element(1,2) = 4; + matr.element(2,0) = 6; + matr.element(2,1) = 2; + matr.element(2,2) = 5; + vect = matr.row(g); + for(uint i = 0; i < matr.rows(); i++) { + if(matr.element(g, i) != vect[i]) { + ASSERT_TRUE(false); + } + } + ASSERT_TRUE(true); } TEST(PIMathMatrixT_Test, setCol) { - PIMathMatrixT matr; - PIMathVectorT vect; - vect.at(0) = 1.0; - vect.at(1) = 3.0; - vect.at(2) = 5.0; - uint g = 1; - matr.setCol(g, vect); - for(uint i = 0; i < vect.size(); i++) { - if(matr.at(i, g) != vect.at(i)) { - ASSERT_TRUE(false); - } - } - ASSERT_TRUE(true); + PIMathMatrixT matr; + PIMathVectorT vect; + vect[0] = 1.0; + vect[1] = 3.0; + vect[2] = 5.0; + uint g = 1; + matr.setCol(g, vect); + for(uint i = 0; i < vect.size(); i++) { + if(matr.element(i, g) != vect[i]) { + ASSERT_TRUE(false); + } + } + ASSERT_TRUE(true); } TEST(PIMathMatrixT_Test, setRow) { - PIMathMatrixT matr; - PIMathVectorT vect; - vect.at(0) = 1.0; - vect.at(1) = 3.0; - vect.at(2) = 5.0; - uint g = 1; - matr.setRow(g, vect); - for(uint i = 0; i < vect.size(); i++) { - if(matr.at(g,i) != vect.at(i)) { - ASSERT_TRUE(false); - } - } - ASSERT_TRUE(true); + PIMathMatrixT matr; + PIMathVectorT vect; + vect[0] = 1.0; + vect[1] = 3.0; + vect[2] = 5.0; + uint g = 1; + matr.setRow(g, vect); + for(uint i = 0; i < vect.size(); i++) { + if(matr.element(g,i) != vect[i]) { + ASSERT_TRUE(false); + } + } + ASSERT_TRUE(true); } TEST(PIMathMatrixT_Test, swapCols) { - PIMathMatrixT matr; - int g1 = 1, g2 = 2; - matr.at(0,0) = 3; - matr.at(0,1) = 6; - matr.at(0,2) = 8; - matr.at(1,0) = 2; - matr.at(1,1) = 1; - matr.at(1,2) = 4; - matr.at(2,0) = 6; - matr.at(2,1) = 2; - matr.at(2,2) = 5; - const PIMathVectorT before_Vect1 = matr.col(g1); - const PIMathVectorT before_Vect2 = matr.col(g2); - matr.swapCols(g1, g2); - const PIMathVectorT after_Vect1 = matr.col(g1); - const PIMathVectorT after_Vect2 = matr.col(g2); - if((before_Vect1 == after_Vect2) && (before_Vect2 == after_Vect1)) { - ASSERT_TRUE(true); - } - else { - ASSERT_TRUE(false); - } + PIMathMatrixT matr; + int g1 = 1, g2 = 2; + matr.element(0,0) = 3; + matr.element(0,1) = 6; + matr.element(0,2) = 8; + matr.element(1,0) = 2; + matr.element(1,1) = 1; + matr.element(1,2) = 4; + matr.element(2,0) = 6; + matr.element(2,1) = 2; + matr.element(2,2) = 5; + const PIMathVectorT before_Vect1 = matr.col(g1); + const PIMathVectorT before_Vect2 = matr.col(g2); + matr.swapCols(g1, g2); + const PIMathVectorT after_Vect1 = matr.col(g1); + const PIMathVectorT after_Vect2 = matr.col(g2); + if((before_Vect1 == after_Vect2) && (before_Vect2 == after_Vect1)) { + ASSERT_TRUE(true); + } + else { + ASSERT_TRUE(false); + } } TEST(PIMathMatrixT_Test, swapRows) { - PIMathMatrixT matr; - int g1 = 1, g2 = 2; - matr.at(0,0) = 3; - matr.at(0,1) = 6; - matr.at(0,2) = 8; - matr.at(1,0) = 2; - matr.at(1,1) = 1; - matr.at(1,2) = 4; - matr.at(2,0) = 6; - matr.at(2,1) = 2; - matr.at(2,2) = 5; - const PIMathVectorT before_Vect1 = matr.row(g1); - const PIMathVectorT before_Vect2 = matr.row(g2); - matr.swapRows(g1, g2); - const PIMathVectorT after_Vect1 = matr.row(g1); - const PIMathVectorT after_Vect2 = matr.row(g2); - if((before_Vect1 == after_Vect2) && (before_Vect2 == after_Vect1)) { - ASSERT_TRUE(true); - } - else { - ASSERT_TRUE(false); - } + PIMathMatrixT matr; + int g1 = 1, g2 = 2; + matr.element(0,0) = 3; + matr.element(0,1) = 6; + matr.element(0,2) = 8; + matr.element(1,0) = 2; + matr.element(1,1) = 1; + matr.element(1,2) = 4; + matr.element(2,0) = 6; + matr.element(2,1) = 2; + matr.element(2,2) = 5; + const PIMathVectorT before_Vect1 = matr.row(g1); + const PIMathVectorT before_Vect2 = matr.row(g2); + matr.swapRows(g1, g2); + const PIMathVectorT after_Vect1 = matr.row(g1); + const PIMathVectorT after_Vect2 = matr.row(g2); + if((before_Vect1 == after_Vect2) && (before_Vect2 == after_Vect1)) { + ASSERT_TRUE(true); + } + else { + ASSERT_TRUE(false); + } } TEST(PIMathMatrixT_Test, fill) { - PIMathMatrixT matr; - PIMathMatrixT matrix1; - double g = 1.0; - matr.fill(g); - for(uint i = 0; i < cols; i++) { - for(uint j = 0; j < rows; j++) { - matrix1.at(j,i) = g; - } - } - ASSERT_TRUE(matr == matrix1); + PIMathMatrixT matr; + PIMathMatrixT matrix1; + double g = 1.0; + matr.fill(g); + for(uint i = 0; i < cols; i++) { + for(uint j = 0; j < rows; j++) { + matrix1.element(j,i) = g; + } + } + ASSERT_TRUE(matr == matrix1); } TEST(PIMathMatrixT_Test, isSquareTrue) { - PIMathMatrixT matrix1; - ASSERT_TRUE(matrix1.isSquare()); + PIMathMatrixT matrix1; + ASSERT_TRUE(matrix1.isSquare()); } TEST(PIMathMatrixT_Test, isSquareFalse) { - const uint new_Cols = 4; - PIMathMatrixT matrix2; - ASSERT_FALSE(matrix2.isSquare()); + const uint new_Cols = 4; + PIMathMatrixT matrix2; + ASSERT_FALSE(matrix2.isSquare()); } TEST(PIMathMatrixT_Test, isIdentityTrue) { - auto matrix1 = PIMathMatrixT::identity(); - ASSERT_TRUE(matrix1.isIdentity()); + auto matrix1 = PIMathMatrixT::identity(); + ASSERT_TRUE(matrix1.isIdentity()); } TEST(PIMathMatrixT_Test, isIdentityFalse) { - auto matrix1 = PIMathMatrixT::filled(2.5); - ASSERT_FALSE(matrix1.isIdentity()); + auto matrix1 = PIMathMatrixT(2.5); + ASSERT_FALSE(matrix1.isIdentity()); } TEST(PIMathMatrixT_Test, isNullTrue) { - PIMathMatrixT matrix1; - ASSERT_TRUE(matrix1.isNull()); + PIMathMatrixT matrix1; + ASSERT_TRUE(matrix1.isNull()); } TEST(PIMathMatrixT_Test, isNullFalse) { - auto matrix1 = PIMathMatrixT::identity(); - ASSERT_FALSE(matrix1.isNull()); + auto matrix1 = PIMathMatrixT::identity(); + ASSERT_FALSE(matrix1.isNull()); } TEST(PIMathMatrixT_Test, operator_Assignment) { - PIMathMatrixT matrix1; - auto matrix2 = PIMathMatrixT::filled(6.72); - matrix1 = matrix2; - ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1, 6.72, rows)); + PIMathMatrixT matrix1; + auto matrix2 = PIMathMatrixT(6.72); + matrix1 = matrix2; + ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1, 6.72, rows)); } TEST(PIMathMatrixT_Test, operator_EqualTrue) { - PIMathMatrixT matrix1; - PIMathMatrixT matrix2; - matrix1.at(0, 0) = 5.1; - matrix1.at(0, 1) = 1.21; - matrix1.at(1, 1) = 0.671; - matrix1.at(1, 0) = 2.623; - matrix2.at(0, 0) = 5.1; - matrix2.at(0, 1) = 1.21; - matrix2.at(1, 1) = 0.671; - matrix2.at(1, 0) = 2.623; - ASSERT_TRUE(matrix1 == matrix2); + PIMathMatrixT matrix1; + PIMathMatrixT matrix2; + matrix1.element(0, 0) = 5.1; + matrix1.element(0, 1) = 1.21; + matrix1.element(1, 1) = 0.671; + matrix1.element(1, 0) = 2.623; + matrix2.element(0, 0) = 5.1; + matrix2.element(0, 1) = 1.21; + matrix2.element(1, 1) = 0.671; + matrix2.element(1, 0) = 2.623; + ASSERT_TRUE(matrix1 == matrix2); } TEST(PIMathMatrixT_Test, operator_EqualFalse) { - PIMathMatrixT matrix1; - PIMathMatrixT matrix2; - matrix1.at(0, 0) = 5.1; - matrix1.at(0, 1) = 1.21; - matrix1.at(1, 1) = 0.671; - matrix1.at(1, 0) = 2.623; - matrix2.at(0, 0) = 5.1; - matrix2.at(0, 1) = 1.21; - matrix2.at(1, 1) = 665.671; - matrix2.at(1, 0) = 2.623; - ASSERT_FALSE(matrix1 == matrix2); + PIMathMatrixT matrix1; + PIMathMatrixT matrix2; + matrix1.element(0, 0) = 5.1; + matrix1.element(0, 1) = 1.21; + matrix1.element(1, 1) = 0.671; + matrix1.element(1, 0) = 2.623; + matrix2.element(0, 0) = 5.1; + matrix2.element(0, 1) = 1.21; + matrix2.element(1, 1) = 665.671; + matrix2.element(1, 0) = 2.623; + ASSERT_FALSE(matrix1 == matrix2); } TEST(PIMathMatrixT_Test, operator_Not_EqualTrue) { - PIMathMatrixT matrix1; - PIMathMatrixT matrix2; - matrix1.at(0, 0) = 5.1; - matrix1.at(0, 1) = 1.21; - matrix1.at(1, 1) = 0.671; - matrix1.at(1, 0) = 2.623; - matrix2.at(0, 0) = 5.1; - matrix2.at(0, 1) = 1.21; - matrix2.at(1, 1) = 665.671; - matrix2.at(1, 0) = 2.623; - ASSERT_TRUE(matrix1 != matrix2); + PIMathMatrixT matrix1; + PIMathMatrixT matrix2; + matrix1.element(0, 0) = 5.1; + matrix1.element(0, 1) = 1.21; + matrix1.element(1, 1) = 0.671; + matrix1.element(1, 0) = 2.623; + matrix2.element(0, 0) = 5.1; + matrix2.element(0, 1) = 1.21; + matrix2.element(1, 1) = 665.671; + matrix2.element(1, 0) = 2.623; + ASSERT_TRUE(matrix1 != matrix2); } TEST(PIMathMatrixT_Test, operator_Not_EqualFalse) { - PIMathMatrixT matrix1; - PIMathMatrixT matrix2; - matrix1.at(0, 0) = 5.1; - matrix1.at(0, 1) = 1.21; - matrix1.at(1, 1) = 0.671; - matrix1.at(1, 0) = 2.623; - matrix2.at(0, 0) = 5.1; - matrix2.at(0, 1) = 1.21; - matrix2.at(1, 1) = 0.671; - matrix2.at(1, 0) = 2.623; - ASSERT_FALSE(matrix1 != matrix2); + PIMathMatrixT matrix1; + PIMathMatrixT matrix2; + matrix1.element(0, 0) = 5.1; + matrix1.element(0, 1) = 1.21; + matrix1.element(1, 1) = 0.671; + matrix1.element(1, 0) = 2.623; + matrix2.element(0, 0) = 5.1; + matrix2.element(0, 1) = 1.21; + matrix2.element(1, 1) = 0.671; + matrix2.element(1, 0) = 2.623; + ASSERT_FALSE(matrix1 != matrix2); } TEST(PIMathMatrixT_Test, operator_Addition_Assignment) { - auto matrix1 = PIMathMatrixT::filled(6.72) ; - auto matrix2 = PIMathMatrixT::filled(1.0) ; - matrix1 += matrix2; - ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1, 7.72, rows)); + auto matrix1 = PIMathMatrixT(6.72) ; + auto matrix2 = PIMathMatrixT(1.0) ; + matrix1 += matrix2; + ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1, 7.72, rows)); } TEST(PIMathMatrixT_Test, operator_Subtraction_Assignment) { - auto matrix1 = PIMathMatrixT::filled(1.0); - auto matrix2 = PIMathMatrixT::filled(6.72); - matrix1 -= matrix2; - ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1, -5.72, rows)); + auto matrix1 = PIMathMatrixT(1.0); + auto matrix2 = PIMathMatrixT(6.72); + matrix1 -= matrix2; + ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1, -5.72, rows)); } TEST(PIMathMatrixT_Test, operator_Multiplication_Assignment) { - auto matrix1 = PIMathMatrixT::filled(6.72); - matrix1 *= 2.0; - ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1, 13.44, rows)); + auto matrix1 = PIMathMatrixT(6.72); + matrix1 *= 2.0; + ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1, 13.44, rows)); } TEST(PIMathMatrixT_Test, operator_Division_Assignment) { - auto matrix1 = PIMathMatrixT::filled(6.72); - matrix1 /= 2.0; - ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1, 3.36, rows)); + auto matrix1 = PIMathMatrixT(6.72); + matrix1 /= 2.0; + ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1, 3.36, rows)); } TEST(PIMathMatrixT_Test, operator_Addition) { - auto matrix1 = PIMathMatrixT::filled(6.72); - auto matrix2 = PIMathMatrixT::filled(8.28); - ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1 + matrix2, 15.0, rows)); + auto matrix1 = PIMathMatrixT(6.72); + auto matrix2 = PIMathMatrixT(8.28); + ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1 + matrix2, 15.0, rows)); } TEST(PIMathMatrixT_Test, operator_Subtraction) { - auto matrix1 = PIMathMatrixT::filled(6.0); - auto matrix2 = PIMathMatrixT::filled(5.0); - ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1 - matrix2, 1.0, rows)); + auto matrix1 = PIMathMatrixT(6.0); + auto matrix2 = PIMathMatrixT(5.0); + ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1 - matrix2, 1.0, rows)); } TEST(PIMathMatrixT_Test, operator_Multiplication) { - auto matrix1 = PIMathMatrixT::filled(6.72); - ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1 * 4.0, 26.88, rows)); + auto matrix1 = PIMathMatrixT(6.72); + ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1 * 4.0, 26.88, rows)); } TEST(PIMathMatrixT_Test, operator_Division) { - auto matrix1 = PIMathMatrixT::filled(6.72); - ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1 / 4.0, 1.68, rows)); + auto matrix1 = PIMathMatrixT(6.72); + ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1 / 4.0, 1.68, rows)); } TEST(PIMathMatrixT_Test, determinantIfSquare) { - double d; - double i = 59.0; - PIMathMatrixT matr; - matr.at(0,0) = 3; - matr.at(0,1) = 6; - matr.at(0,2) = 8; - matr.at(1,0) = 2; - matr.at(1,1) = 1; - matr.at(1,2) = 4; - matr.at(2,0) = 6; - matr.at(2,1) = 2; - matr.at(2,2) = 5; - d = matr.determinant(); - ASSERT_DOUBLE_EQ(i, d); + double d; + double i = 59.0; + PIMathMatrixT matr; + matr.element(0,0) = 3; + matr.element(0,1) = 6; + matr.element(0,2) = 8; + matr.element(1,0) = 2; + matr.element(1,1) = 1; + matr.element(1,2) = 4; + matr.element(2,0) = 6; + matr.element(2,1) = 2; + matr.element(2,2) = 5; + d = matr.determinant(); + ASSERT_DOUBLE_EQ(i, d); } TEST(PIMathMatrixT_Test, determinantIfNotSquare) { - PIMathMatrixT matr; - matr.at(0,0) = 3; - matr.at(0,1) = 6; - matr.at(0,2) = 8; - matr.at(1,0) = 2; - matr.at(1,1) = 1; - matr.at(1,2) = 4; - matr.at(2,0) = 6; - matr.at(2,1) = 2; - matr.at(2,2) = 5; - ASSERT_FALSE(matr.determinant()); + PIMathMatrixT matr; + matr.element(0,0) = 3; + matr.element(0,1) = 6; + matr.element(0,2) = 8; + matr.element(1,0) = 2; + matr.element(1,1) = 1; + matr.element(1,2) = 4; + matr.element(2,0) = 6; + matr.element(2,1) = 2; + matr.element(2,2) = 5; + ASSERT_FALSE(matr.determinant()); } TEST(PIMathMatrixT_Test, invert) { - PIMathMatrixT matrix1; - PIMathMatrixT matrix2; - PIMathMatrixT matrix3; - PIMathMatrixT matr; - double d1, d2; - matr.at(0,0) = 3; - matr.at(0,1) = 6; - matr.at(0,2) = 8; - matr.at(1,0) = 2; - matr.at(1,1) = 1; - matr.at(1,2) = 4; - matr.at(2,0) = 6; - matr.at(2,1) = 2; - matr.at(2,2) = 5; - matrix2 = matr; - matr.invert(); - d1 = matr.determinant(); - d2 = matrix2.determinant(); - matrix3 = matrix1; - matrix1.invert(); - ASSERT_TRUE((matrix1 == matrix3) && (d1 == 1/d2)); + PIMathMatrixT matrix1; + PIMathMatrixT matrix2; + PIMathMatrixT matrix3; + PIMathMatrixT matr; + double d1, d2; + matr.element(0,0) = 3; + matr.element(0,1) = 6; + matr.element(0,2) = 8; + matr.element(1,0) = 2; + matr.element(1,1) = 1; + matr.element(1,2) = 4; + matr.element(2,0) = 6; + matr.element(2,1) = 2; + matr.element(2,2) = 5; + matrix2 = matr; + matr.invert(); + d1 = matr.determinant(); + d2 = matrix2.determinant(); + matrix3 = matrix1; + matrix1.invert(); + ASSERT_TRUE((matrix1 == matrix3) && (d1 == 1/d2)); } TEST(PIMathMatrixT_Test, inverted) { - PIMathMatrixT matrix1; - PIMathMatrixT matrix2; - PIMathMatrixT matrix3; - PIMathMatrixT matr; - double d1, d2; - matrix1 = matr.identity(); - matr.at(0,0) = 3; - matr.at(0,1) = 6; - matr.at(0,2) = 8; - matr.at(1,0) = 2; - matr.at(1,1) = 1; - matr.at(1,2) = 4; - matr.at(2,0) = 6; - matr.at(2,1) = 2; - matr.at(2,2) = 5; - matrix2 = matr.inverted(); - d1 = matr.determinant(); - d2 = matrix2.determinant(); - matrix3 = matrix1.inverted(); - ASSERT_TRUE((matrix1 == matrix3) && (round((1/d1)*10000)/10000 == round(d2*10000)/10000)); + PIMathMatrixT matrix1; + PIMathMatrixT matrix2; + PIMathMatrixT matrix3; + PIMathMatrixT matr; + double d1, d2; + matrix1 = matr.identity(); + matr.element(0,0) = 3; + matr.element(0,1) = 6; + matr.element(0,2) = 8; + matr.element(1,0) = 2; + matr.element(1,1) = 1; + matr.element(1,2) = 4; + matr.element(2,0) = 6; + matr.element(2,1) = 2; + matr.element(2,2) = 5; + matrix2 = matr.inverted(); + d1 = matr.determinant(); + d2 = matrix2.determinant(); + matrix3 = matrix1.inverted(); + ASSERT_TRUE((matrix1 == matrix3) && (round((1/d1)*10000)/10000 == round(d2*10000)/10000)); } TEST(PIMathMatrixT_Test, toUpperTriangular) { - PIMathMatrixT matrix; - double d1, d2 = 1; - PIMathMatrixT matr; - matr.at(0,0) = 3; - matr.at(0,1) = 6; - matr.at(0,2) = 8; - matr.at(1,0) = 2; - matr.at(1,1) = 1; - matr.at(1,2) = 4; - matr.at(2,0) = 6; - matr.at(2,1) = 2; - matr.at(2,2) = 5; - matrix = matr.toUpperTriangular(); - d1 = matrix.determinant(); - for(uint i = 0; i < cols; i++) - { - d2 = d2*matrix.at(i,i); - } - ASSERT_DOUBLE_EQ(d1, d2); + PIMathMatrixT matrix; + double d1, d2 = 1; + PIMathMatrixT matr; + matr.element(0,0) = 3; + matr.element(0,1) = 6; + matr.element(0,2) = 8; + matr.element(1,0) = 2; + matr.element(1,1) = 1; + matr.element(1,2) = 4; + matr.element(2,0) = 6; + matr.element(2,1) = 2; + matr.element(2,2) = 5; + matrix = matr.toUpperTriangular(); + d1 = matrix.determinant(); + for(uint i = 0; i < cols; i++) + { + d2 = d2*matrix.at(i,i); + } + ASSERT_DOUBLE_EQ(d1, d2); } TEST(PIMathMatrixT_Test, transposed) { - PIMathMatrixT matrix1; - PIMathMatrixT matrix2; - PIMathMatrixT matr; - double d1, d2; - matr.at(0,0) = 3; - matr.at(0,1) = 6; - matr.at(0,2) = 8; - matr.at(1,0) = 2; - matr.at(1,1) = 1; - matr.at(1,2) = 4; - matr.at(2,0) = 6; - matr.at(2,1) = 2; - matr.at(2,2) = 5; - d1 = matr.determinant(); - matrix1 = matr.transposed(); - d2 = matrix1.determinant(); - matrix2 = matrix1.transposed(); - ASSERT_TRUE((d1 == d2) && (matr == matrix2)); -} - -TEST(PIMathMatrixT_Test, scaleX_two) { - double factor = 5.64; - PIMathMatrixT<2u, 2u, double> matrix = PIMathMatrixT<2u, 2u, double>::scaleX(factor); - ASSERT_TRUE((1.0 == matrix.at(1u,1u)) && (factor == matrix.at(0u,0u))); -} - -TEST(PIMathMatrixT_Test, scaleY_two) { - double factor = 5.64; - PIMathMatrixT<2u, 2u, double> matrix = PIMathMatrixT<2u, 2u, double>::scaleY(factor); - ASSERT_TRUE((factor == matrix.at(1u,1u)) && (1.0 == matrix.at(0u,0u))); + PIMathMatrixT matrix1; + PIMathMatrixT matrix2; + PIMathMatrixT matr; + double d1, d2; + matr.element(0,0) = 3; + matr.element(0,1) = 6; + matr.element(0,2) = 8; + matr.element(1,0) = 2; + matr.element(1,1) = 1; + matr.element(1,2) = 4; + matr.element(2,0) = 6; + matr.element(2,1) = 2; + matr.element(2,2) = 5; + d1 = matr.determinant(); + matrix1 = matr.transposed(); + d2 = matrix1.determinant(); + matrix2 = matrix1.transposed(); + ASSERT_TRUE((d1 == d2) && (matr == matrix2)); } TEST(PIMathMatrixT_Test, rotation_2x2) { - double angle = 1.0; - PIMathMatrixT<2u, 2u, double> matrix = PIMathMatrixT<2u, 2u, double>::rotation(angle); - double c = cos(angle); - double s = sin(angle); - ASSERT_TRUE((c == matrix.at(1u,1u)) && (c == matrix.at(0u,0u)) && (-s == matrix.at(0u,1u)) && (s == matrix.at(1u,0u))); -} - -TEST(PIMathMatrixT_Test, rotation_3x3) { - double angle = 1.0; - PIMathMatrixT<3u, 3u, double> matrix = PIMathMatrixT<3u, 3u, double>::rotation(angle); - ASSERT_TRUE(cmpSquareMatrixWithValue(matrix, 0.0, rows)); -} - -TEST(PIMathMatrixT_Test, rotationX) { - double angle = 1.0; - double c = cos(angle); - double s = sin(angle); - PIMathMatrixT<3u, 3u, double> matrix = PIMathMatrixT<3u, 3u, double>::rotationX(angle); - ASSERT_TRUE((1.0 == matrix.at(0u,0u)) && (c == matrix.at(1u,1u)) && (c == matrix.at(2u,2u)) && (s == matrix.at(2u,1u)) && (-s == matrix.at(1u,2u))); -} - -TEST(PIMathMatrixT_Test, rotationY) { - double angle = 1.0; - double c = cos(angle); - double s = sin(angle); - PIMathMatrixT<3u, 3u, double> matrix = PIMathMatrixT<3u, 3u, double>::rotationY(angle); - ASSERT_TRUE((1.0 == matrix.at(1u,1u)) && (c == matrix.at(0u,0u)) && (c == matrix.at(2u,2u)) && (s == matrix.at(0u,2u)) && (-s == matrix.at(2u,0u))); -} - -TEST(PIMathMatrixT_Test, rotationZ) { - double angle = 1.0; - double c = cos(angle); - double s = sin(angle); - PIMathMatrixT<3u, 3u, double> matrix = PIMathMatrixT<3u, 3u, double>::rotationZ(angle); - ASSERT_TRUE((1.0 == matrix.at(2u,2u)) && (c == matrix.at(0u,0u)) && (c == matrix.at(1u,1u)) && (s == matrix.at(1u,0u)) && (-s == matrix.at(0u,1u))); -} - -TEST(PIMathMatrixT_Test, scaleX_three) { - double factor = 23.65; - PIMathMatrixT<3u, 3u, double> matrix = PIMathMatrixT<3u, 3u, double>::scaleX(factor); - ASSERT_TRUE((1.0 == matrix.at(2u,2u)) && (factor == matrix.at(0u,0u)) && (1.0 == matrix.at(1u,1u))); -} - -TEST(PIMathMatrixT_Test, scaleY_three) { - double factor = 23.65; - PIMathMatrixT<3u, 3u, double> matrix = PIMathMatrixT<3u, 3u, double>::scaleY(factor); - ASSERT_TRUE((1.0 == matrix.at(2u,2u)) && (1.0 == matrix.at(0u,0u)) && (factor == matrix.at(1u,1u))); -} - -TEST(PIMathMatrixT_Test, scaleZ_three) { - double factor = 23.65; - PIMathMatrixT<3u, 3u, double> matrix = PIMathMatrixT<3u, 3u, double>::scaleZ(factor); - ASSERT_TRUE((factor == matrix.at(2u,2u)) && (1.0 == matrix.at(0u,0u)) && (1.0 == matrix.at(1u,1u))); + double angle = 1.0; + auto matrix = PIMathMatrixT<2u, 2u, double>::identity(); + matrix.rotate(angle); + double c = cos(angle); + double s = sin(angle); + ASSERT_TRUE((c == matrix.at(1u,1u)) && (c == matrix.at(0u,0u)) && (-s == matrix.at(0u,1u)) && (s == matrix.at(1u,0u))); } TEST(PIMathMatrixT_Test, matrixMultiplication) { - auto matrix1 = PIMathMatrixT::filled(1.5); - auto matrix2 = PIMathMatrixT::filled(2.5); - ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1 * matrix2, 11.25, 3)); + auto matrix1 = PIMathMatrixT(1.5); + auto matrix2 = PIMathMatrixT(2.5); + ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1 * matrix2, 11.25, 3)); } TEST(PIMathMatrixT_Test, matrixAndVectorMultiplication) { - auto matrix1 = PIMathMatrixT::filled(1.5); - auto vector = PIMathVectorT::filled(2.5); - for(uint i = 0; i < 2; i++) { - if((matrix1 * vector)[i] != 11.25) { - ASSERT_TRUE(false); - } - } - ASSERT_TRUE(true); + auto matrix1 = PIMathMatrixT(1.5); + auto vector = PIMathVectorT(2.5); + for(uint i = 0; i < 2; i++) { + if((matrix1 * vector)[i] != 11.25) { + ASSERT_TRUE(false); + } + } + ASSERT_TRUE(true); } TEST(PIMathMatrixT_Test, vectorAndMatrixMultiplication) { - auto matrix1 = PIMathMatrixT::filled(1.5); - auto vector = PIMathVectorT::filled(2.5); - for(uint i = 0; i < 2; i++) { - if((vector * matrix1)[i] != 11.25) { - ASSERT_TRUE(false); - } - } + auto matrix1 = PIMathMatrixT(1.5); + auto vector = PIMathVectorT(2.5); + for(uint i = 0; i < 2; i++) { + if((vector * matrix1)[i] != 11.25) { + ASSERT_TRUE(false); + } + } } TEST(PIMathMatrixT_Test, valAndMatrixMultiplication) { - auto matrix1 = PIMathMatrixT::filled(1.5); - ASSERT_TRUE(cmpSquareMatrixWithValue(25.0*matrix1, 37.5, 3)); + auto matrix1 = PIMathMatrixT(1.5); + ASSERT_TRUE(cmpSquareMatrixWithValue(25.0*matrix1, 37.5, 3)); } From 0189f28f43f9582796b1c9f0b0959324713b78d0 Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 23 Oct 2020 15:10:57 +0300 Subject: [PATCH 59/98] PIMathMatrix add trace, assert for non square matrix, assert in operator * --- libs/main/math/pimathmatrix.h | 70 ++++++++++++++++---------------- tests/math/testpimathmatrix.cpp | 12 ------ tests/math/testpimathmatrixt.cpp | 14 ------- 3 files changed, 34 insertions(+), 62 deletions(-) diff --git a/libs/main/math/pimathmatrix.h b/libs/main/math/pimathmatrix.h index 94cf9480..f1fedb55 100644 --- a/libs/main/math/pimathmatrix.h +++ b/libs/main/math/pimathmatrix.h @@ -393,6 +393,20 @@ public: return ret; } + /** + * @brief Trace of the matrix is calculated. Works only with square matrix, nonzero matrices and invertible matrix + * + * @return matrix trace + */ + Type trace() const { + static_assert(Rows == Cols, "Works only with square matrix"); + Type ret = Type(0); + for (uint i = 0; i < Cols; ++i) { + ret += m[i][i]; + } + return ret; + } + /** * @brief Transforming matrix to upper triangular. Works only with square matrix, nonzero matrices and invertible matrix * @@ -400,10 +414,7 @@ public: * @return copy of transformed upper triangular matrix */ _CMatrix &toUpperTriangular(bool *ok = 0) { - if (Cols != Rows) { - if (ok != 0) *ok = false; - return *this; - } + static_assert(Rows == Cols, "Works only with square matrix"); _CMatrix smat(*this); bool ndet; uint crow; @@ -443,7 +454,7 @@ public: * @return copy of inverted matrix */ _CMatrix &invert(bool *ok = 0) { - static_assert(Cols == Rows, "Only square matrix invertable"); + static_assert(Rows == Cols, "Works only with square matrix"); _CMatrix mtmp = _CMatrix::identity(), smat(*this); bool ndet; uint crow; @@ -972,8 +983,8 @@ public: Type determinant(bool *ok = 0) const { _CMatrix m(*this); bool k; - Type ret = Type(0); m.toUpperTriangular(&k); + Type ret = Type(0); if (ok) *ok = k; if (!k) return ret; ret = Type(1); @@ -987,19 +998,14 @@ public: /** * @brief Trace of the matrix is calculated. Works only with square matrix, nonzero matrices and invertible matrix * - * @param ok is a parameter with which we can find out if the method worked correctly * @return matrix trace */ - Type trace(bool *ok = 0) const { + Type trace() const { + assert(isSquare()); Type ret = Type(0); - if (!isSquare()) { - if (ok != 0) *ok = false; - return ret; - } for (uint i = 0; i < _V2D::cols_; ++i) { ret += _V2D::element(i, i); } - if (ok != 0) *ok = true; return ret; } @@ -1010,10 +1016,7 @@ public: * @return copy of transformed upper triangular matrix */ _CMatrix &toUpperTriangular(bool *ok = 0) { - if (!isSquare()) { - if (ok != 0) *ok = false; - return *this; - } + assert(isSquare()); _CMatrix smat(*this); bool ndet; uint crow; @@ -1054,10 +1057,7 @@ public: * @return copy of inverted matrix */ _CMatrix &invert(bool *ok = 0, PIMathVector *sv = 0) { - if (!isSquare()) { - if (ok != 0) *ok = false; - return *this; - } + assert(isSquare()); _CMatrix mtmp = _CMatrix::identity(_V2D::cols_, _V2D::rows_), smat(*this); bool ndet; uint crow; @@ -1196,14 +1196,13 @@ inline PIByteArray &operator>>(PIByteArray &s, PIMathMatrix &v) { template inline PIMathMatrix operator*(const PIMathMatrix &fm, const PIMathMatrix &sm) { - uint cr = fm.cols(), rows0 = fm.rows(), cols1 = sm.cols(); - PIMathMatrix tm(cols1, rows0); - if (fm.cols() != sm.rows()) return tm; + assert(fm.cols() == sm.rows()); + PIMathMatrix tm(sm.cols(), fm.rows()); Type t; - for (uint j = 0; j < rows0; ++j) { - for (uint i = 0; i < cols1; ++i) { + for (uint j = 0; j < fm.rows(); ++j) { + for (uint i = 0; i < sm.cols(); ++i) { t = Type(0); - for (uint k = 0; k < cr; ++k) + for (uint k = 0; k < fm.cols(); ++k) t += fm.element(j, k) * sm.element(k, i); tm.element(j, i) = t; } @@ -1221,13 +1220,12 @@ inline PIMathMatrix operator*(const PIMathMatrix &fm, template inline PIMathVector operator*(const PIMathMatrix &fm, const PIMathVector &sv) { - uint c = fm.cols(), r = fm.rows(); - PIMathVector tv(r); - if (c != sv.size()) return tv; + assert(fm.cols() == sv.size()); + PIMathVector tv(fm.rows()); Type t; - for (uint j = 0; j < r; ++j) { + for (uint j = 0; j < fm.rows(); ++j) { t = Type(0); - for (uint i = 0; i < c; ++i) + for (uint i = 0; i < fm.cols(); ++i) t += fm.element(j, i) * sv[i]; tv[j] = t; } @@ -1244,12 +1242,12 @@ inline PIMathVector operator*(const PIMathMatrix &fm, template inline PIMathVector operator*(const PIMathVector &sv, const PIMathMatrix &fm) { - uint c = fm.cols(), r = fm.rows(); - PIMathVector tv(c); + PIMathVector tv(fm.cols()); + assert(fm.rows() == sv.size()); Type t; - for (uint j = 0; j < c; ++j) { + for (uint j = 0; j < fm.cols(); ++j) { t = Type(0); - for (uint i = 0; i < r; ++i) + for (uint i = 0; i < fm.rows(); ++i) t += fm.element(i, j) * sv[i]; tv[j] = t; } diff --git a/tests/math/testpimathmatrix.cpp b/tests/math/testpimathmatrix.cpp index 05de2e14..94f3076b 100644 --- a/tests/math/testpimathmatrix.cpp +++ b/tests/math/testpimathmatrix.cpp @@ -355,12 +355,6 @@ TEST(PIMathMatrix_Test, determinantIfSquare) { ASSERT_DOUBLE_EQ(d, i); } -TEST(PIMathMatrix_Test, determinantIfNotSquare) { - PIMathMatrix matrix(3, 5, 1.0); - matrix.element(1,1) = 5.0; - ASSERT_FALSE(matrix.determinant()); -} - TEST(PIMathMatrix_Test, trace) { PIMathMatrix matrix(3, 3, 0.0); double t; @@ -383,12 +377,6 @@ TEST(PIMathMatrix_Test, trace) { ASSERT_DOUBLE_EQ(t, i); } -TEST(PIMathMatrix_Test, traceIfNotSquare) { - PIMathMatrix matrix(3, 5, 1.0); - matrix.element(1,1) = 5.0; - ASSERT_FALSE(matrix.trace()); -} - TEST(PIMathMatrix_Test, toUpperTriangular) { PIMathMatrix matrix(3, 3, 0.0); double d1, d2 = 1; diff --git a/tests/math/testpimathmatrixt.cpp b/tests/math/testpimathmatrixt.cpp index 210ad947..5f3a20bf 100644 --- a/tests/math/testpimathmatrixt.cpp +++ b/tests/math/testpimathmatrixt.cpp @@ -356,20 +356,6 @@ TEST(PIMathMatrixT_Test, determinantIfSquare) { ASSERT_DOUBLE_EQ(i, d); } -TEST(PIMathMatrixT_Test, determinantIfNotSquare) { - PIMathMatrixT matr; - matr.element(0,0) = 3; - matr.element(0,1) = 6; - matr.element(0,2) = 8; - matr.element(1,0) = 2; - matr.element(1,1) = 1; - matr.element(1,2) = 4; - matr.element(2,0) = 6; - matr.element(2,1) = 2; - matr.element(2,2) = 5; - ASSERT_FALSE(matr.determinant()); -} - TEST(PIMathMatrixT_Test, invert) { PIMathMatrixT matrix1; PIMathMatrixT matrix2; From f951593c6203216a2693673146c9f31dafca652b Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 23 Oct 2020 15:11:38 +0300 Subject: [PATCH 60/98] version --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8f00c155..95c9f964 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ project(pip) set(pip_MAJOR 2) set(pip_MINOR 14) set(pip_REVISION 0) -set(pip_SUFFIX alpha) +set(pip_SUFFIX beta) set(pip_COMPANY SHS) set(pip_DOMAIN org.SHS) From 173b8c9413013618da3cf28b8caea2452f4c3a05 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Wed, 28 Oct 2020 14:14:55 +0300 Subject: [PATCH 61/98] missing OpenCL in FindPIP --- cmake/FindPIP.cmake | 2 +- libs/main/opencl/piopencl.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/FindPIP.cmake b/cmake/FindPIP.cmake index 17cc3f3a..809998e5 100644 --- a/cmake/FindPIP.cmake +++ b/cmake/FindPIP.cmake @@ -22,7 +22,7 @@ include(SHSTKMacros) shstk_set_find_dirs(pip) -set(__libs "usb;crypt;console;fftw;compress;io_utils;cloud;lua") +set(__libs "usb;crypt;console;fftw;compress;io_utils;opencl;cloud;lua") if (BUILDING_pip) #set(_libs "pip;pip_usb;pip_console;pip_crypt;pip_fftw;pip_compress;pip_opencl;pip_io_utils;pip_cloud;pip_lua") diff --git a/libs/main/opencl/piopencl.h b/libs/main/opencl/piopencl.h index 51be9a6a..6b9ce2ee 100644 --- a/libs/main/opencl/piopencl.h +++ b/libs/main/opencl/piopencl.h @@ -189,7 +189,7 @@ private: }; -PICout operator <<(PICout s, const PIOpenCL::KernelArg & v); +PIP_OPENCL_EXPORT PICout operator <<(PICout s, const PIOpenCL::KernelArg & v); #endif // PIOPENCL_H From 673cf40d2442d5a6ddf154d9e8663334995a824d Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Wed, 28 Oct 2020 14:16:20 +0300 Subject: [PATCH 62/98] deploy_tool Qt additional modules start --- utils/deploy_tool/main.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/utils/deploy_tool/main.cpp b/utils/deploy_tool/main.cpp index dbee6b7d..f196b358 100644 --- a/utils/deploy_tool/main.cpp +++ b/utils/deploy_tool/main.cpp @@ -67,7 +67,7 @@ void usage() { "[-p ] [-s ] [--ignore ] [-S ] " "[-l ] [-D ] [--dpkg-workdir ] [-L | -W | -M ] " "[--name-tool ] [-d ] [-q ] [-a ] [-S ] " - "[-P ] [--qt-plugins ] -o [ ...]\"" << NewLine; + "[-P ] [--qt-plugins ] [--qt-modules ] -o [ ...]\"" << NewLine; piCout << Green << Bold << "Details:"; piCout << Bold << "Debug control"; piCout << "-h, --help " << Green << "- display this message and exit"; @@ -92,10 +92,11 @@ void usage() { piCout << "-S " << Green << "- set Qt styles (e.g. \"oxygen,breeze\"), default \"*\""; piCout << "-P " << Green << "- set Qt platforms (e.g. \"win,mini\"), default by host system"; piCout << "--qt-plugins " << Green << "- set Qt plugins description"; + piCout << "--qt-modules " << Green << "- additional Qt modules, may be separated by \"" DELIM "\" (e.g. \"Sql" DELIM "Xml\")"; piCout << ""; piCout << Bold << "Output control"; piCout << "-o " << Green << "- path for libraries copy to"; - piCout << "-p " << Green << "- path for Qt plugins, default \"/plugins\""; + piCout << "-p " << Green << "- path for Qt plugins, default \"\""; piCout << "--dependencies " << Green << "- search dependencies by , print them and copy missing libraries"; piCout << "--prefix " << Green << "- print before dependencies"; piCout << ""; @@ -129,7 +130,7 @@ QtDep qt_deps[] = { int depth = 8; bool fake = false, is_ldd = true, is_deps = false, need_qt = false; PIString ldd, readelf, objdump, otool, dpkg, nametool, strip, out_dir, qt_dir, out_plugins_dir, dpkg_workdir; -PIStringList styles, lib_dirs, add_libs, platforms, sqldrivers, input_files, plugin_libs; +PIStringList styles, lib_dirs, add_libs, platforms, sqldrivers, input_files, plugin_libs, qt_add_libs; PISet all_libs, miss_libs, all_deps, frameworks, framework_libs, miss_frameworks, qt_plugins, ignore_libs; PIMap qt_filters; @@ -590,6 +591,9 @@ int main(int argc, char * argv[]) { qt_filters["platforms"] = platforms; qt_filters["styles" ] = styles ; + qt_add_libs = cli.argumentValue("qt-modules").split(DELIM); + need_qt = !qt_add_libs.isEmpty(); + auto it = qt_filters.makeIterator(); while (it.next()) it.valueRef().forEachInplace([](PIString i)->PIString{ From dd4f21c3e0681ecee0a31f0c4d79c8d443fdeeee Mon Sep 17 00:00:00 2001 From: andrey Date: Wed, 28 Oct 2020 17:12:40 +0300 Subject: [PATCH 63/98] add at() to PIVector2D --- libs/main/containers/pivector2d.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libs/main/containers/pivector2d.h b/libs/main/containers/pivector2d.h index 8946a6cc..b55adbe5 100644 --- a/libs/main/containers/pivector2d.h +++ b/libs/main/containers/pivector2d.h @@ -160,6 +160,7 @@ public: inline T & element(size_t row, size_t col) {return mat[row * cols_ + col];} inline const T & element(size_t row, size_t col) const {return mat[row * cols_ + col];} + inline const T & at(size_t row, size_t col) const {return mat[row * cols_ + col];} inline Row operator[](size_t index) {return Row(this, index);} inline RowConst operator[](size_t index) const {return RowConst(this, index);} inline T * data(size_t index = 0) {return mat.data(index);} From 3e7344c95fb5788495ec92f6fd9d458c71292e28 Mon Sep 17 00:00:00 2001 From: peri4 Date: Wed, 28 Oct 2020 18:07:53 +0300 Subject: [PATCH 64/98] deploy_tool "qt-modules" feature works on Windows (maybe on *nix). On MacOS - no(( --- utils/deploy_tool/main.cpp | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/utils/deploy_tool/main.cpp b/utils/deploy_tool/main.cpp index f196b358..98dccabb 100644 --- a/utils/deploy_tool/main.cpp +++ b/utils/deploy_tool/main.cpp @@ -128,8 +128,9 @@ QtDep qt_deps[] = { int depth = 8; -bool fake = false, is_ldd = true, is_deps = false, need_qt = false; +bool fake = false, is_ldd = true, is_deps = false, need_qt = false, make_qt_format = true; PIString ldd, readelf, objdump, otool, dpkg, nametool, strip, out_dir, qt_dir, out_plugins_dir, dpkg_workdir; +PIString qt_pref, qt_suff; PIStringList styles, lib_dirs, add_libs, platforms, sqldrivers, input_files, plugin_libs, qt_add_libs; PISet all_libs, miss_libs, all_deps, frameworks, framework_libs, miss_frameworks, qt_plugins, ignore_libs; PIMap qt_filters; @@ -182,17 +183,22 @@ PIString execute(const PIString & cmd) { void checkQtLib(PIString lib) { - if (lib.startsWith("lib")) lib.cutLeft(3); - if (lib.startsWith("qt5")) lib.cutLeft(3); - if (lib.startsWith("qt")) lib.cutLeft(2); - if (lib.find(".")) lib = lib.left(lib.find(".")); - //piCout << "checkQt" << lib; + PIString pref, suff; + if (lib.startsWith("lib")) {pref += "lib"; lib.cutLeft(3);} + if (lib.startsWith("qt5")) {pref += "Qt5"; lib.cutLeft(3);} + if (lib.startsWith("qt" )) {pref += "Qt" ; lib.cutLeft(2);} + if (lib.find('.') >= 0) {suff = lib.right(lib.size_s() - lib.find('.')); lib = lib.left(lib.find('.'));} for (int i = 0; ; ++i) { if (qt_deps[i].lib.isEmpty()) break; if (qt_deps[i].lib == lib) { qt_plugins << qt_deps[i].plugins; //piCout << "add qt plugins" << qt_deps[i].plugins << "now" << qt_plugins; need_qt = true; + if (make_qt_format) { + make_qt_format = false; + qt_pref = pref; + qt_suff = suff; + } break; } } @@ -485,6 +491,7 @@ int main(int argc, char * argv[]) { cli.addArgument("Styles", true); cli.addArgument("Platforms", true); cli.addArgument("qt-plugins", PIChar('\0'), true); + cli.addArgument("qt-modules", PIChar('\0'), true); cli.addArgument("ldd", true); cli.addArgument("Lreadelf", true); cli.addArgument("Wobjdump", true); @@ -620,8 +627,15 @@ int main(int argc, char * argv[]) { } }); //piCout << files; - if (depth > 0) + if (depth > 0) { input_files.forEach([&](const PIString & f){procLdd(f);}); + qt_add_libs.forEach([&](const PIString & f){ + PIString l = findLib(qt_pref + f + qt_suff); + if (l.isEmpty()) return; + procLdd(l, true); + checkQtLib(f.toLowerCase()); + }); + } piForeach (PIString & s, add_libs) { if (s.isEmpty()) continue; PIString alib = findLib(s); From 77031172a6f5c42e541b288bbab33eba75f42e7b Mon Sep 17 00:00:00 2001 From: Stepan Fomenko Date: Mon, 2 Nov 2020 15:53:14 +0300 Subject: [PATCH 65/98] Fix row check & remove matrix couts --- tests/math/testpivector2d.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/tests/math/testpivector2d.cpp b/tests/math/testpivector2d.cpp index 37f77e8f..ae66b01c 100644 --- a/tests/math/testpivector2d.cpp +++ b/tests/math/testpivector2d.cpp @@ -30,12 +30,7 @@ protected: } void resize_reduce_is_data_stay_consistent(int newRowsCount, int newColsCount) { - piCout << "Before:"; - piCout << vec; - piCout << ""; vec.resize(newRowsCount, newColsCount, 0); - piCout << "After:"; - piCout << vec; assert_fill_with(vec, newRowsCount, newColsCount); } @@ -43,8 +38,9 @@ protected: vec.resize(newRowsCount, newColsCount, 0); assert_fill_with(vec, ROWS_COUNT_INIT, COLS_COUNT_INIT); - for (int r = ROWS_COUNT_INIT; r < newRowsCount; ++r) { - for (int c = COLS_COUNT_INIT; c < newColsCount; ++c) { + for (int r = 0; r < newRowsCount; ++r) { + for (int c = 0; c < newColsCount; ++c) { + if (r < ROWS_COUNT_INIT || c < COLS_COUNT_INIT) continue; ASSERT_EQ(vec.element(r, c), 0); } } From 24d9d66c24d0f3276f207d094d0b7241a37472b1 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Tue, 3 Nov 2020 12:00:27 +0300 Subject: [PATCH 66/98] version 2.14.1 --- CMakeLists.txt | 4 ++-- libs/main/math/pievaluator.cpp | 8 ++++++-- libs/main/math/pievaluator.h | 5 ++++- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 95c9f964..c7bcfe58 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,8 +3,8 @@ cmake_policy(SET CMP0017 NEW) # need include() with .cmake project(pip) set(pip_MAJOR 2) set(pip_MINOR 14) -set(pip_REVISION 0) -set(pip_SUFFIX beta) +set(pip_REVISION 1) +set(pip_SUFFIX ) set(pip_COMPANY SHS) set(pip_DOMAIN org.SHS) diff --git a/libs/main/math/pievaluator.cpp b/libs/main/math/pievaluator.cpp index 06e3fbf2..87414136 100644 --- a/libs/main/math/pievaluator.cpp +++ b/libs/main/math/pievaluator.cpp @@ -330,8 +330,10 @@ void PIEvaluator::makeOutput(PIString & string) { void PIEvaluator::findUnknownVariables() { PIString cvar; unknownVars.clear(); + usedVars.clear(); for (int i = 0; i < currentString.length(); i++) { - if (elements[i].var_num == -666) cvar += currentString[i]; + if (elements[i].var_num >= 0) usedVars << content.variable(elements[i].var_num).name; + else if (elements[i].var_num == -666) cvar += currentString[i]; else { if (cvar.length() == 0) continue; unknownVars << cvar; @@ -340,6 +342,7 @@ void PIEvaluator::findUnknownVariables() { } if (cvar.length() > 0) unknownVars << cvar; unknownVars.removeDuplicates(); + usedVars.removeDuplicates(); } @@ -1196,7 +1199,7 @@ complexd PIEvaluator::evaluate() { PIByteArray PIEvaluator::save() const { PIByteArray ret; - ret << content << currentVariables << unknownVars << instructions << currentString << lastError << out << correct; + ret << content << currentVariables << unknownVars << instructions << currentString << lastError << out << correct << usedVars; return ret; } @@ -1204,5 +1207,6 @@ PIByteArray PIEvaluator::save() const { void PIEvaluator::load(PIByteArray ba) { if (ba.size() <= 4) return; ba >> content >> currentVariables >> unknownVars >> instructions >> currentString >> lastError >> out >> correct; + if (ba.size() >= 4) ba >> usedVars; variables = currentVariables; } diff --git a/libs/main/math/pievaluator.h b/libs/main/math/pievaluator.h index 94ff6250..5433fb57 100644 --- a/libs/main/math/pievaluator.h +++ b/libs/main/math/pievaluator.h @@ -176,6 +176,9 @@ public: //! Returns all unknown variables founded in last expression passed to \a check() function const PIStringList & unknownVariables() const {return unknownVars;} + //! Returns all used variables founded in last expression passed to \a check() function + const PIStringList & usedVariables() const {return usedVars;} + //! Returns processed last expression passed to \a check() function const PIString & expression() const {return currentString;} @@ -220,7 +223,7 @@ private: PIDeque elements; PIVector currentVariables, variables, tmpvars, * kvars; PIVector instructions; - PIStringList unknownVars; + PIStringList unknownVars, usedVars; PIString currentString, lastError; complexd out; bool correct; From a6954fd7bcf0ccf5cbc3f98405a8e70019b92953 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Tue, 3 Nov 2020 13:08:18 +0300 Subject: [PATCH 67/98] PIEvaluator::usedVariables() now returns without i, pi, e --- libs/main/math/pievaluator.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libs/main/math/pievaluator.cpp b/libs/main/math/pievaluator.cpp index 87414136..ebd42eed 100644 --- a/libs/main/math/pievaluator.cpp +++ b/libs/main/math/pievaluator.cpp @@ -343,6 +343,9 @@ void PIEvaluator::findUnknownVariables() { if (cvar.length() > 0) unknownVars << cvar; unknownVars.removeDuplicates(); usedVars.removeDuplicates(); + usedVars.removeOne("i"); + usedVars.removeOne("pi"); + usedVars.removeOne("e"); } From 9c5c3b5732fbf340973a563c8935da3fd6e01278 Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 6 Nov 2020 14:10:59 +0300 Subject: [PATCH 68/98] move esp32 components --- .../components/pip => esp-idf}/CMakeLists.txt | 21 ++++--------------- .../components/pip => esp-idf}/main.cpp | 0 .../esp-idf => esp-idf}/miniz.patch | 0 3 files changed, 4 insertions(+), 17 deletions(-) rename {esp32_component/esp-idf/components/pip => esp-idf}/CMakeLists.txt (59%) rename {esp32_component/esp-idf/components/pip => esp-idf}/main.cpp (100%) rename {esp32_component/esp-idf => esp-idf}/miniz.patch (100%) diff --git a/esp32_component/esp-idf/components/pip/CMakeLists.txt b/esp-idf/CMakeLists.txt similarity index 59% rename from esp32_component/esp-idf/components/pip/CMakeLists.txt rename to esp-idf/CMakeLists.txt index 751927f8..56ffa116 100644 --- a/esp32_component/esp-idf/components/pip/CMakeLists.txt +++ b/esp-idf/CMakeLists.txt @@ -1,20 +1,7 @@ set(COMPONENT_SRCS "main.cpp") -set(COMPONENT_ADD_INCLUDEDIRS "pip/lib/main") -list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/lib/main/auxiliary") -list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/lib/main/code") -list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/lib/main/console") -list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/lib/main/containers") -list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/lib/main/core") -list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/lib/main/crypt") -list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/lib/main/geo") -list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/lib/main/io_devices") -list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/lib/main/io_utils") -list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/lib/main/math") -list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/lib/main/opencl") -list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/lib/main/resources") -list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/lib/main/system") -list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/lib/main/thread") -list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/lib/main/introspection") +set(COMPONENT_ADD_INCLUDEDIRS "../libs/main") +list(APPEND COMPONENT_ADD_INCLUDEDIRS "../libs/main/containers") +list(APPEND COMPONENT_ADD_INCLUDEDIRS "../libs/main/core") set(COMPONENT_PRIV_REQUIRES pthread lwip freertos vfs spiffs) register_component() set(PIP_FREERTOS ON) @@ -44,6 +31,6 @@ add_compile_options(${IDF_CXX_COMPILE_OPTIONS}) add_definitions(-DESP_PLATFORM) add_definitions(-DGCC_NOT_5_2_0=0) add_definitions(-DHAVE_CONFIG_H) -add_subdirectory(pip) +include(../CMakeLists.txt) target_link_libraries(${COMPONENT_TARGET} pip pip_crypt pip_io_utils pip_compress) diff --git a/esp32_component/esp-idf/components/pip/main.cpp b/esp-idf/main.cpp similarity index 100% rename from esp32_component/esp-idf/components/pip/main.cpp rename to esp-idf/main.cpp diff --git a/esp32_component/esp-idf/miniz.patch b/esp-idf/miniz.patch similarity index 100% rename from esp32_component/esp-idf/miniz.patch rename to esp-idf/miniz.patch From ae08ff72eacfa2056750cce18c010b080dbd8a5f Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 6 Nov 2020 14:34:35 +0300 Subject: [PATCH 69/98] static lib --- CMakeLists.txt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c7bcfe58..127e3f78 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -121,11 +121,6 @@ macro(pip_find_lib NAME) endif() endmacro() -if (DEFINED ENV{QNX_HOST} OR PIP_FREERTOS) - set(STATIC_LIB ON) -endif() - - # Version list(APPEND HDRS "${CMAKE_CURRENT_BINARY_DIR}/pip_version.h") From 0614c3df96979adb769e8b8003135a86697659e3 Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 6 Nov 2020 15:10:24 +0300 Subject: [PATCH 70/98] cmake fixes --- CMakeLists.txt | 21 +++------------------ esp-idf/CMakeLists.txt | 4 ++-- 2 files changed, 5 insertions(+), 20 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 127e3f78..22cb279c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -439,24 +439,9 @@ if (NOT CROSSTOOLS) endif() else() - - set(PIP_MSG_crypt "yes") - set(PIP_MSG_compress "yes") - set(PIP_MODULES pip) - add_definitions(-DPIP_CRYPT) - add_library(pip_crypt ${pip_LIB_TYPE} ${CPP_LIB_CRYPT}) - target_link_libraries(pip_crypt pip) - list(APPEND PIP_MODULES pip_crypt) - set(IO_UTILS_LIBS pip) - add_library(pip_io_utils ${pip_LIB_TYPE} ${CPP_LIB_IO_UTILS}) - list(APPEND IO_UTILS_LIBS pip_crypt) - target_link_libraries(pip_io_utils ${IO_UTILS_LIBS}) - list(APPEND PIP_MODULES pip_io_utils) - add_definitions(-DPIP_COMPRESS) - add_library(pip_compress ${pip_LIB_TYPE} ${CPP_LIB_COMPRESS}) - target_link_libraries(pip_compress pip) - list(APPEND PIP_MODULES pip_compress) - + pip_module(crypt "sodium" "PIP crypt support" "" "") + pip_module(compress "zlib" "PIP compression support" "" "") + pip_module(io_utils "pip_crypt" "PIP I/O support" "" " (+crypt)") endif() endif() diff --git a/esp-idf/CMakeLists.txt b/esp-idf/CMakeLists.txt index 56ffa116..56d96be8 100644 --- a/esp-idf/CMakeLists.txt +++ b/esp-idf/CMakeLists.txt @@ -31,6 +31,6 @@ add_compile_options(${IDF_CXX_COMPILE_OPTIONS}) add_definitions(-DESP_PLATFORM) add_definitions(-DGCC_NOT_5_2_0=0) add_definitions(-DHAVE_CONFIG_H) -include(../CMakeLists.txt) +add_subdirectory(.. pip) -target_link_libraries(${COMPONENT_TARGET} pip pip_crypt pip_io_utils pip_compress) +target_link_libraries(${COMPONENT_TARGET} PIP::Crypt PIP::IOUtils PIP::Compress) From 2898c5647665c5963486f29eab6ae1c67ff4ed7a Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 6 Nov 2020 15:19:25 +0300 Subject: [PATCH 71/98] esp32 pip --- esp-idf/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esp-idf/CMakeLists.txt b/esp-idf/CMakeLists.txt index 56d96be8..bc695488 100644 --- a/esp-idf/CMakeLists.txt +++ b/esp-idf/CMakeLists.txt @@ -32,5 +32,5 @@ add_definitions(-DESP_PLATFORM) add_definitions(-DGCC_NOT_5_2_0=0) add_definitions(-DHAVE_CONFIG_H) add_subdirectory(.. pip) - +find_package(PIP REQUIRED) target_link_libraries(${COMPONENT_TARGET} PIP::Crypt PIP::IOUtils PIP::Compress) From 9497b1bbb7831e027e52f5322f8eb80371ab169c Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 6 Nov 2020 15:39:14 +0300 Subject: [PATCH 72/98] PIVariantSimple freertos fix --- libs/main/core/pivariantsimple.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libs/main/core/pivariantsimple.h b/libs/main/core/pivariantsimple.h index 63130902..d5b27e5f 100644 --- a/libs/main/core/pivariantsimple.h +++ b/libs/main/core/pivariantsimple.h @@ -27,7 +27,9 @@ #include "pistring.h" #include - +#ifdef PIP_FREERTOS +#include "pivariant.h" +#endif class __VariantFunctionsBase__ { public: @@ -57,7 +59,11 @@ template class __VariantFunctions__/*::value>::type>*/: public __VariantFunctionsBase__ { public: __VariantFunctionsBase__ * instance() final {static __VariantFunctions__ ret; return &ret;} +#ifdef PIP_FREERTOS + PIString typeName() const final {static PIString ret(PIVariant(T()).typeName()); return ret;} +#else PIString typeName() const final {static PIString ret(typeid(T).name()); return ret;} +#endif 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")*/;} From 0c6e6358b248da9a6b51990e1b3748ab69d4162b Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 6 Nov 2020 15:47:01 +0300 Subject: [PATCH 73/98] register PIVariant std::function --- libs/main/core/pivariant.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libs/main/core/pivariant.h b/libs/main/core/pivariant.h index bea37f17..b3bf5183 100644 --- a/libs/main/core/pivariant.h +++ b/libs/main/core/pivariant.h @@ -751,7 +751,8 @@ REGISTER_VARIANT(PIPointd) REGISTER_VARIANT(PIRectd) REGISTER_VARIANT(PIMathVectord) REGISTER_VARIANT(PIMathMatrixd) - +typedef std::function KeySlot; +REGISTER_VARIANT(KeySlot) inline PIByteArray & operator <<(PIByteArray & s, const PIVariant & v) { s << v._content << int(v._type); From 3457d87299f88d182ce22a9269139fcb74da8807 Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 6 Nov 2020 16:06:25 +0300 Subject: [PATCH 74/98] __VariantFunctions__ > --- libs/main/core/pivariant.h | 2 -- libs/main/core/pivariantsimple.h | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/libs/main/core/pivariant.h b/libs/main/core/pivariant.h index b3bf5183..8f222b63 100644 --- a/libs/main/core/pivariant.h +++ b/libs/main/core/pivariant.h @@ -751,8 +751,6 @@ REGISTER_VARIANT(PIPointd) REGISTER_VARIANT(PIRectd) REGISTER_VARIANT(PIMathVectord) REGISTER_VARIANT(PIMathMatrixd) -typedef std::function KeySlot; -REGISTER_VARIANT(KeySlot) inline PIByteArray & operator <<(PIByteArray & s, const PIVariant & v) { s << v._content << int(v._type); diff --git a/libs/main/core/pivariantsimple.h b/libs/main/core/pivariantsimple.h index d5b27e5f..002b982a 100644 --- a/libs/main/core/pivariantsimple.h +++ b/libs/main/core/pivariantsimple.h @@ -73,6 +73,20 @@ public: //void fromData(void *& ptr, PIByteArray ba) final {ba >> *(T*)ptr;} }; +template<> +class __VariantFunctions__ >: public __VariantFunctionsBase__ { +public: + __VariantFunctionsBase__ * instance() final {static __VariantFunctions__ > ret; return &ret;} + PIString typeName() const final {static PIString ret("std::function"); return ret;} + uint hash() const final {static uint ret = typeName().hash(); return ret;} + void newT(void *& ptr, const void * value) final {ptr = (void*)(new std::function(*(const std::function *)value)); /*printf(" * new\n")*/;} + void newNullT(void *& ptr) final {ptr = (void*)(new std::function ());/* printf(" * new null\n")*/;} + void assignT(void *& ptr, const void * value) final {*(std::function *)ptr = *(const std::function *)value; /*printf(" * =\n")*/;} + void deleteT(void *& ptr) final {delete (std::function *)(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: From 9d313f4c0aa4eac7e8b89f5d5dbe382934bca994 Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 6 Nov 2020 16:09:22 +0300 Subject: [PATCH 75/98] register pivariant for PIKbdListener Events --- libs/main/console/pikbdlistener.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libs/main/console/pikbdlistener.h b/libs/main/console/pikbdlistener.h index c1bf9906..7c6d0d33 100644 --- a/libs/main/console/pikbdlistener.h +++ b/libs/main/console/pikbdlistener.h @@ -252,5 +252,8 @@ inline PIByteArray & operator >>(PIByteArray & s, PIKbdListener::KeyEvent & v) { inline PIByteArray & operator >>(PIByteArray & s, PIKbdListener::MouseEvent & v) {int a(0); s >> v.x >> v.y >> a >> v.buttons >> v.modifiers; v.action = (PIKbdListener::MouseAction)a; return s;} inline PIByteArray & operator >>(PIByteArray & s, PIKbdListener::WheelEvent & v) {uchar d(0); s >> (*(PIKbdListener::MouseEvent*)&v) >> d; v.direction = d; return s;} +REGISTER_NS_VARIANT(PIKbdListener, KeyEvent) +REGISTER_NS_VARIANT(PIKbdListener, MouseEvent) +REGISTER_NS_VARIANT(PIKbdListener, WheelEvent) #endif // PIKBDLISTENER_H From 6124452ac684eb63b4878cebbbe23956a9700165 Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 6 Nov 2020 16:16:14 +0300 Subject: [PATCH 76/98] REGISTER_PIVARIANTSIMPLE --- libs/main/console/pikbdlistener.h | 6 +-- libs/main/core/pivariantsimple.h | 81 ++++++++----------------------- 2 files changed, 23 insertions(+), 64 deletions(-) diff --git a/libs/main/console/pikbdlistener.h b/libs/main/console/pikbdlistener.h index 7c6d0d33..185d21a3 100644 --- a/libs/main/console/pikbdlistener.h +++ b/libs/main/console/pikbdlistener.h @@ -252,8 +252,8 @@ inline PIByteArray & operator >>(PIByteArray & s, PIKbdListener::KeyEvent & v) { inline PIByteArray & operator >>(PIByteArray & s, PIKbdListener::MouseEvent & v) {int a(0); s >> v.x >> v.y >> a >> v.buttons >> v.modifiers; v.action = (PIKbdListener::MouseAction)a; return s;} inline PIByteArray & operator >>(PIByteArray & s, PIKbdListener::WheelEvent & v) {uchar d(0); s >> (*(PIKbdListener::MouseEvent*)&v) >> d; v.direction = d; return s;} -REGISTER_NS_VARIANT(PIKbdListener, KeyEvent) -REGISTER_NS_VARIANT(PIKbdListener, MouseEvent) -REGISTER_NS_VARIANT(PIKbdListener, WheelEvent) +REGISTER_PIVARIANTSIMPLE(PIKbdListener::KeyEvent) +REGISTER_PIVARIANTSIMPLE(PIKbdListener::MouseEvent) +REGISTER_PIVARIANTSIMPLE(PIKbdListener::WheelEvent) #endif // PIKBDLISTENER_H diff --git a/libs/main/core/pivariantsimple.h b/libs/main/core/pivariantsimple.h index 002b982a..0336dc9b 100644 --- a/libs/main/core/pivariantsimple.h +++ b/libs/main/core/pivariantsimple.h @@ -31,6 +31,7 @@ #include "pivariant.h" #endif + class __VariantFunctionsBase__ { public: virtual __VariantFunctionsBase__ * instance() {return 0;} @@ -40,23 +41,11 @@ public: virtual void newNullT(void *& ptr) {;} virtual void assignT(void *& ptr, const void * value) {;} virtual void deleteT(void *& ptr) {;} - //virtual PIByteArray toData(const void * ptr) const {return PIByteArray();} - //virtual void fromData(void *& ptr, PIByteArray ba) {;} - //static PIMap & registered() {static PIMap ret; return ret;} }; -/* -template -class __VariantFunctions__: public __VariantFunctionsBase__ { -public: - __VariantFunctionsBase__ * instance() final {static __VariantFunctions__ ret; return &ret;} - PIString typeName() const final {static PIString ret(typeid(T).name()); return ret;} - uint hash() const final {static uint ret = typeName().hash(); return ret;} -}; -*/ template -class __VariantFunctions__/*::value>::type>*/: public __VariantFunctionsBase__ { +class __VariantFunctions__: public __VariantFunctionsBase__ { public: __VariantFunctionsBase__ * instance() final {static __VariantFunctions__ ret; return &ret;} #ifdef PIP_FREERTOS @@ -65,26 +54,10 @@ public: PIString typeName() const final {static PIString ret(typeid(T).name()); return ret;} #endif 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;} -}; - -template<> -class __VariantFunctions__ >: public __VariantFunctionsBase__ { -public: - __VariantFunctionsBase__ * instance() final {static __VariantFunctions__ > ret; return &ret;} - PIString typeName() const final {static PIString ret("std::function"); return ret;} - uint hash() const final {static uint ret = typeName().hash(); return ret;} - void newT(void *& ptr, const void * value) final {ptr = (void*)(new std::function(*(const std::function *)value)); /*printf(" * new\n")*/;} - void newNullT(void *& ptr) final {ptr = (void*)(new std::function ());/* printf(" * new null\n")*/;} - void assignT(void *& ptr, const void * value) final {*(std::function *)ptr = *(const std::function *)value; /*printf(" * =\n")*/;} - void deleteT(void *& ptr) final {delete (std::function *)(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;} + void newT(void *& ptr, const void * value) final {ptr = (void*)(new T(*(const T*)value));} + void newNullT(void *& ptr) final {ptr = (void*)(new T());} + void assignT(void *& ptr, const void * value) final {*(T*)ptr = *(const T*)value;} + void deleteT(void *& ptr) final {delete (T*)(ptr);} }; @@ -135,27 +108,6 @@ public: return ret; } - /* - PIByteArray save() const { - if (!ptr || !f) return PIByteArray(); - PIByteArray ret; - ret << f->hash(); - ret.append(f->toData(ptr)); - return ret; - } - - bool load(PIByteArray ba) { - if (ba.size_s() < 4) return false; - uint h(0); ba >> h; - destroy(); - f = __VariantFunctionsBase__::registered().value(h, 0); - if (!f) return false; - f->newNullT(ptr); - f->fromData(ptr, ba); - return true; - } - */ - private: template bool isMyType() const { @@ -177,13 +129,20 @@ private: }; -/* -#define REGISTER_PIVARIANTSIMPLE_STREAM(Type) \ - STATIC_INITIALIZER_BEGIN \ - __VariantFunctionsBase__ * f = __VariantFunctions__().instance(); \ - __VariantFunctionsBase__::registered()[f->hash()] = f; \ - STATIC_INITIALIZER_END -*/ +#define REGISTER_PIVARIANTSIMPLE(Type) \ + template<> \ + class __VariantFunctions__: public __VariantFunctionsBase__ { \ + public: \ + __VariantFunctionsBase__ * instance() final {static __VariantFunctions__ ret; return &ret;} \ + PIString typeName() const final {static PIString ret(#Type); return ret;} \ + uint hash() const final {static uint ret = typeName().hash(); return ret;} \ + void newT(void *& ptr, const void * value) final {ptr = (void*)(new Type(*(const Type *)value));} \ + void newNullT(void *& ptr) final {ptr = (void*)(new Type());} \ + void assignT(void *& ptr, const void * value) final {*(Type *)ptr = *(const Type *)value;} \ + void deleteT(void *& ptr) final {delete (Type *)(ptr);} \ + }; + +REGISTER_PIVARIANTSIMPLE(std::function) #endif // PIVARIANTSIMPLE_H From 80efa4b094964f1c9bb0042698d7d89c08c6430b Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 6 Nov 2020 16:20:31 +0300 Subject: [PATCH 77/98] remove esp_spi_flash.h --- libs/main/system/pisysteminfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/main/system/pisysteminfo.cpp b/libs/main/system/pisysteminfo.cpp index aec6aeb2..8035ea86 100644 --- a/libs/main/system/pisysteminfo.cpp +++ b/libs/main/system/pisysteminfo.cpp @@ -24,7 +24,7 @@ #ifdef ESP_PLATFORM # include "esp_system.h" -# include "esp_spi_flash.h" +//# include "esp_spi_flash.h" #endif #define SALT_SIZE 8 From de756491d8f01404ef73387e38c186a2a5847eca Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 6 Nov 2020 16:22:28 +0300 Subject: [PATCH 78/98] esp_flash_get_chip_size --- libs/main/system/pisysteminfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/main/system/pisysteminfo.cpp b/libs/main/system/pisysteminfo.cpp index 8035ea86..4b428690 100644 --- a/libs/main/system/pisysteminfo.cpp +++ b/libs/main/system/pisysteminfo.cpp @@ -198,7 +198,7 @@ PIVector PISystemInfo::mountInfo(bool ignore_cache) { esp_chip_info_t chip_info; esp_chip_info(&chip_info); m.device = ((chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded SPI flash" : "external SPI flash"); - m.space_all = spi_flash_get_chip_size(); + m.space_all = esp_flash_get_chip_size(); m.mount_point = "/"; ret << m; #endif From 58c7f74de63da6a3c7ea00e7132a35e693e7447d Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 6 Nov 2020 16:25:13 +0300 Subject: [PATCH 79/98] esp_flash.h --- libs/main/system/pisysteminfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/main/system/pisysteminfo.cpp b/libs/main/system/pisysteminfo.cpp index 4b428690..4edc0b21 100644 --- a/libs/main/system/pisysteminfo.cpp +++ b/libs/main/system/pisysteminfo.cpp @@ -24,7 +24,7 @@ #ifdef ESP_PLATFORM # include "esp_system.h" -//# include "esp_spi_flash.h" +# include "esp_flash.h" #endif #define SALT_SIZE 8 From 04c08742acf4d6008799ed5aa79dd14f5854963f Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 6 Nov 2020 17:23:09 +0300 Subject: [PATCH 80/98] esp --- esp-idf/CMakeLists.txt | 32 ++++++++++++++++---------------- libs/compress/picompress.cpp | 2 +- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/esp-idf/CMakeLists.txt b/esp-idf/CMakeLists.txt index bc695488..094639c1 100644 --- a/esp-idf/CMakeLists.txt +++ b/esp-idf/CMakeLists.txt @@ -2,26 +2,26 @@ set(COMPONENT_SRCS "main.cpp") set(COMPONENT_ADD_INCLUDEDIRS "../libs/main") list(APPEND COMPONENT_ADD_INCLUDEDIRS "../libs/main/containers") list(APPEND COMPONENT_ADD_INCLUDEDIRS "../libs/main/core") -set(COMPONENT_PRIV_REQUIRES pthread lwip freertos vfs spiffs) +set(COMPONENT_PRIV_REQUIRES pthread lwip freertos vfs spi_flash libsodium) register_component() set(PIP_FREERTOS ON) set(LIB OFF) set(INCLUDE_DIRS ${IDF_INCLUDE_DIRECTORIES}) -list(APPEND INCLUDE_DIRS "../newlib/platform_include") -list(APPEND INCLUDE_DIRS "../newlib/include") -list(APPEND INCLUDE_DIRS "../libsodium/libsodium/src/libsodium/include") -list(APPEND INCLUDE_DIRS "../libsodium/port_include") -list(APPEND INCLUDE_DIRS "../heap/include") -list(APPEND INCLUDE_DIRS "../esp_rom/include/esp32") -list(APPEND INCLUDE_DIRS "../driver/include") -list(APPEND INCLUDE_DIRS "../spi_flash/include") -list(APPEND INCLUDE_DIRS "../spiffs/include") -list(APPEND INCLUDE_DIRS "../soc/include") -list(APPEND INCLUDE_DIRS "../soc/esp32/include") -list(APPEND INCLUDE_DIRS "../freertos/include") -list(APPEND INCLUDE_DIRS "../lwip/lwip/src/include") -list(APPEND INCLUDE_DIRS "../lwip/port/esp32/include") -list(APPEND INCLUDE_DIRS "../vfs/include") +list(APPEND INCLUDE_DIRS $ENV{IDF_PATH}/components/newlib/platform_include) +list(APPEND INCLUDE_DIRS $ENV{IDF_PATH}/components/newlib/include) +list(APPEND INCLUDE_DIRS $ENV{IDF_PATH}/components/libsodium/libsodium/src/libsodium/include) +list(APPEND INCLUDE_DIRS $ENV{IDF_PATH}/components/libsodium/port_include) +list(APPEND INCLUDE_DIRS $ENV{IDF_PATH}/components/heap/include) +list(APPEND INCLUDE_DIRS $ENV{IDF_PATH}/components/esp_rom/include/esp32) +list(APPEND INCLUDE_DIRS $ENV{IDF_PATH}/components/driver/include) +list(APPEND INCLUDE_DIRS $ENV{IDF_PATH}/components/spi_flash/include) +list(APPEND INCLUDE_DIRS $ENV{IDF_PATH}/components/spiffs/include) +list(APPEND INCLUDE_DIRS $ENV{IDF_PATH}/components/soc/include) +list(APPEND INCLUDE_DIRS $ENV{IDF_PATH}/components/soc/esp32/include) +list(APPEND INCLUDE_DIRS $ENV{IDF_PATH}/components/freertos/include) +list(APPEND INCLUDE_DIRS $ENV{IDF_PATH}/components/lwip/lwip/src/include) +list(APPEND INCLUDE_DIRS $ENV{IDF_PATH}/components/lwip/port/esp32/include) +list(APPEND INCLUDE_DIRS $ENV{IDF_PATH}/components/vfs/include) include_directories(${INCLUDE_DIRS}) include_directories(${CMAKE_CURRENT_BINARY_DIR}/pip) #message("IDF_COMPILE_DEFINITIONS = ${IDF_COMPILE_DEFINITIONS}") diff --git a/libs/compress/picompress.cpp b/libs/compress/picompress.cpp index 16c0dcaa..b9d73a51 100644 --- a/libs/compress/picompress.cpp +++ b/libs/compress/picompress.cpp @@ -20,7 +20,7 @@ #include "picompress.h" #ifdef PIP_COMPRESS # ifdef FREERTOS -# include "rom/miniz.h" +# include "esp32/rom/miniz.h" # define compress2 mz_compress2 # define Z_OK MZ_OK # define uncompress mz_uncompress From 555dc74086fc85dd6ec3dcfc3cd500e4b7c938cf Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 6 Nov 2020 17:29:53 +0300 Subject: [PATCH 81/98] esp --- libs/main/system/pisysteminfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/main/system/pisysteminfo.cpp b/libs/main/system/pisysteminfo.cpp index 4edc0b21..fba3ad48 100644 --- a/libs/main/system/pisysteminfo.cpp +++ b/libs/main/system/pisysteminfo.cpp @@ -198,7 +198,7 @@ PIVector PISystemInfo::mountInfo(bool ignore_cache) { esp_chip_info_t chip_info; esp_chip_info(&chip_info); m.device = ((chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded SPI flash" : "external SPI flash"); - m.space_all = esp_flash_get_chip_size(); + m.space_all = esp_flash_get_size(); m.mount_point = "/"; ret << m; #endif From 56223ad67e0ff7a37c39f00a4b1038263805e88b Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 6 Nov 2020 17:32:20 +0300 Subject: [PATCH 82/98] esp --- libs/main/system/pisysteminfo.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/main/system/pisysteminfo.cpp b/libs/main/system/pisysteminfo.cpp index fba3ad48..9a1271f7 100644 --- a/libs/main/system/pisysteminfo.cpp +++ b/libs/main/system/pisysteminfo.cpp @@ -24,7 +24,7 @@ #ifdef ESP_PLATFORM # include "esp_system.h" -# include "esp_flash.h" +# include "esp_spi_flash.h" #endif #define SALT_SIZE 8 @@ -198,7 +198,7 @@ PIVector PISystemInfo::mountInfo(bool ignore_cache) { esp_chip_info_t chip_info; esp_chip_info(&chip_info); m.device = ((chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded SPI flash" : "external SPI flash"); - m.space_all = esp_flash_get_size(); + m.space_all = esp_flash_get_chip_size(); m.mount_point = "/"; ret << m; #endif From 102380a325e9b0943e5539e03894bd0f0bd9a623 Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 6 Nov 2020 17:33:56 +0300 Subject: [PATCH 83/98] esp --- libs/main/system/pisysteminfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/main/system/pisysteminfo.cpp b/libs/main/system/pisysteminfo.cpp index 9a1271f7..aec6aeb2 100644 --- a/libs/main/system/pisysteminfo.cpp +++ b/libs/main/system/pisysteminfo.cpp @@ -198,7 +198,7 @@ PIVector PISystemInfo::mountInfo(bool ignore_cache) { esp_chip_info_t chip_info; esp_chip_info(&chip_info); m.device = ((chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded SPI flash" : "external SPI flash"); - m.space_all = esp_flash_get_chip_size(); + m.space_all = spi_flash_get_chip_size(); m.mount_point = "/"; ret << m; #endif From ba0ea994dae86c5233de95fbe14a74e84165be9c Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 6 Nov 2020 17:36:33 +0300 Subject: [PATCH 84/98] esp --- esp-idf/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esp-idf/CMakeLists.txt b/esp-idf/CMakeLists.txt index 094639c1..bcdca08c 100644 --- a/esp-idf/CMakeLists.txt +++ b/esp-idf/CMakeLists.txt @@ -26,7 +26,7 @@ include_directories(${INCLUDE_DIRS}) include_directories(${CMAKE_CURRENT_BINARY_DIR}/pip) #message("IDF_COMPILE_DEFINITIONS = ${IDF_COMPILE_DEFINITIONS}") #message("IDF_INCLUDE_DIRECTORIES = ${IDF_INCLUDE_DIRECTORIES}") -add_compile_options(${IDF_COMPILE_OPTIONS}) +add_compile_options(${IDF_COMPILE_OPTIONS} -DESP_PLATFORM -DPIP_FREERTOS) add_compile_options(${IDF_CXX_COMPILE_OPTIONS}) add_definitions(-DESP_PLATFORM) add_definitions(-DGCC_NOT_5_2_0=0) From 488663c5a4ff25ee799f3134d8eca98ca36a6053 Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 6 Nov 2020 17:40:21 +0300 Subject: [PATCH 85/98] esp --- esp-idf/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/esp-idf/CMakeLists.txt b/esp-idf/CMakeLists.txt index bcdca08c..f39b114d 100644 --- a/esp-idf/CMakeLists.txt +++ b/esp-idf/CMakeLists.txt @@ -26,7 +26,7 @@ include_directories(${INCLUDE_DIRS}) include_directories(${CMAKE_CURRENT_BINARY_DIR}/pip) #message("IDF_COMPILE_DEFINITIONS = ${IDF_COMPILE_DEFINITIONS}") #message("IDF_INCLUDE_DIRECTORIES = ${IDF_INCLUDE_DIRECTORIES}") -add_compile_options(${IDF_COMPILE_OPTIONS} -DESP_PLATFORM -DPIP_FREERTOS) +add_compile_options(${IDF_COMPILE_OPTIONS}) add_compile_options(${IDF_CXX_COMPILE_OPTIONS}) add_definitions(-DESP_PLATFORM) add_definitions(-DGCC_NOT_5_2_0=0) @@ -34,3 +34,4 @@ add_definitions(-DHAVE_CONFIG_H) add_subdirectory(.. pip) find_package(PIP REQUIRED) target_link_libraries(${COMPONENT_TARGET} PIP::Crypt PIP::IOUtils PIP::Compress) +target_compile_definitions(${COMPONENT_TARGET} PRIVATE ESP_PLATFORM PIP_FREERTOS) From 1dd16cf29ae69e0c313d7cac8a0e26eec8584aab Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 6 Nov 2020 17:54:07 +0300 Subject: [PATCH 86/98] esp32 --- libs/main/console/piscreentypes.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libs/main/console/piscreentypes.h b/libs/main/console/piscreentypes.h index cce0e6fd..0409cd0d 100644 --- a/libs/main/console/piscreentypes.h +++ b/libs/main/console/piscreentypes.h @@ -25,6 +25,7 @@ #include "pip_console_export.h" #include "pivariant.h" +#include "pivariantsimple.h" class PIScreenTile; @@ -145,5 +146,6 @@ inline PIByteArray & operator >>(PIByteArray & s, PIScreenTypes::Cell & v) {s >> inline PIByteArray & operator <<(PIByteArray & s, const PIScreenTypes::TileEvent & v) {s << v.type << v.data; return s;} inline PIByteArray & operator >>(PIByteArray & s, PIScreenTypes::TileEvent & v) {s >> v.type >> v.data; return s;} +REGISTER_PIVARIANTSIMPLE(PIScreenTypes::TileEvent) #endif // PISCREENTYPES_H From 285c73e966443e619770ac49bfdde95c33798ece Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 6 Nov 2020 17:55:34 +0300 Subject: [PATCH 87/98] esp --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 22cb279c..4ae1c13e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -439,8 +439,8 @@ if (NOT CROSSTOOLS) endif() else() - pip_module(crypt "sodium" "PIP crypt support" "" "") - pip_module(compress "zlib" "PIP compression support" "" "") + pip_module(crypt "" "PIP crypt support" "" "") + pip_module(compress "" "PIP compression support" "" "") pip_module(io_utils "pip_crypt" "PIP I/O support" "" " (+crypt)") endif() endif() From c47c63c8b35660382652b6d185328a745dc04c2b Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 6 Nov 2020 18:17:13 +0300 Subject: [PATCH 88/98] rename esp pip --- {esp-idf => esp-pip}/CMakeLists.txt | 0 {esp-idf => esp-pip}/main.cpp | 0 {esp-idf => esp-pip}/miniz.patch | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename {esp-idf => esp-pip}/CMakeLists.txt (100%) rename {esp-idf => esp-pip}/main.cpp (100%) rename {esp-idf => esp-pip}/miniz.patch (100%) diff --git a/esp-idf/CMakeLists.txt b/esp-pip/CMakeLists.txt similarity index 100% rename from esp-idf/CMakeLists.txt rename to esp-pip/CMakeLists.txt diff --git a/esp-idf/main.cpp b/esp-pip/main.cpp similarity index 100% rename from esp-idf/main.cpp rename to esp-pip/main.cpp diff --git a/esp-idf/miniz.patch b/esp-pip/miniz.patch similarity index 100% rename from esp-idf/miniz.patch rename to esp-pip/miniz.patch From ce636245c725ae2abdf640a43c018c0dc85cfeec Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 6 Nov 2020 18:20:56 +0300 Subject: [PATCH 89/98] esp includes --- esp-pip/CMakeLists.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/esp-pip/CMakeLists.txt b/esp-pip/CMakeLists.txt index f39b114d..00e1f1fb 100644 --- a/esp-pip/CMakeLists.txt +++ b/esp-pip/CMakeLists.txt @@ -1,7 +1,19 @@ set(COMPONENT_SRCS "main.cpp") set(COMPONENT_ADD_INCLUDEDIRS "../libs/main") +list(APPEND COMPONENT_ADD_INCLUDEDIRS "../libs/main/cloud") +list(APPEND COMPONENT_ADD_INCLUDEDIRS "../libs/main/code") +list(APPEND COMPONENT_ADD_INCLUDEDIRS "../libs/main/compress") +list(APPEND COMPONENT_ADD_INCLUDEDIRS "../libs/main/console") list(APPEND COMPONENT_ADD_INCLUDEDIRS "../libs/main/containers") list(APPEND COMPONENT_ADD_INCLUDEDIRS "../libs/main/core") +list(APPEND COMPONENT_ADD_INCLUDEDIRS "../libs/main/crypt") +list(APPEND COMPONENT_ADD_INCLUDEDIRS "../libs/main/geo") +list(APPEND COMPONENT_ADD_INCLUDEDIRS "../libs/main/io_devices") +list(APPEND COMPONENT_ADD_INCLUDEDIRS "../libs/main/io_utils") +list(APPEND COMPONENT_ADD_INCLUDEDIRS "../libs/main/math") +list(APPEND COMPONENT_ADD_INCLUDEDIRS "../libs/main/resources") +list(APPEND COMPONENT_ADD_INCLUDEDIRS "../libs/main/system") +list(APPEND COMPONENT_ADD_INCLUDEDIRS "../libs/main/thread") set(COMPONENT_PRIV_REQUIRES pthread lwip freertos vfs spi_flash libsodium) register_component() set(PIP_FREERTOS ON) From 5c0ef7173af9cb4a8a3edc1edadf4b6303c3e042 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Sun, 15 Nov 2020 11:40:47 +0300 Subject: [PATCH 90/98] pip_code_model macro now automatic add CMAKE_CURRENT_SOURCE_DIR to relative pathes, no ABSOLUTE need PIOpenCL first working version --- CMakeLists.txt | 2 +- cmake/PIPMacros.cmake | 16 ++-- libs/main/opencl/piopencl.h | 44 ++++++++++- libs/opencl/piopencl.cpp | 146 ++++++++++++++++++++++++++++++++++-- 4 files changed, 187 insertions(+), 21 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ae1c13e..3ebfa3fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_policy(SET CMP0017 NEW) # need include() with .cmake project(pip) set(pip_MAJOR 2) set(pip_MINOR 14) -set(pip_REVISION 1) +set(pip_REVISION 2) set(pip_SUFFIX ) set(pip_COMPANY SHS) set(pip_DOMAIN org.SHS) diff --git a/cmake/PIPMacros.cmake b/cmake/PIPMacros.cmake index acd97207..32b6822b 100644 --- a/cmake/PIPMacros.cmake +++ b/cmake/PIPMacros.cmake @@ -1,11 +1,11 @@ #[[ - pip_code_model( file0 [file1 ...] [OPTIONS opt0 [opt1 ...] ] [ABSOLUTE]) + pip_code_model( file0 [file1 ...] [OPTIONS opt0 [opt1 ...] ]) Generate code model files for source files file0 [file1 ...] Options you can see by exec "pip_cmg -h" - If not ABSOLUTE source files will be prepended by CMAKE_CURRENT_SOURCE_DIR + Relative files pathes read from CMAKE_CURRENT_SOURCE_DIR You should add ${} to your target @@ -53,15 +53,13 @@ macro(pip_code_model RESULT) set(CCM_OUT ${CMAKE_CURRENT_BINARY_DIR}/ccm_${PROJECT_NAME}.cpp) set(${RESULT} ${${RESULT}} ${CCM_OUT}) set(CCM_FILES) - if (ABS) - foreach(csrc ${CCM_SRC}) + foreach(csrc ${CCM_SRC}) + if (IS_ABSOLUTE "${csrc}") list(APPEND CCM_FILES "${csrc}") - endforeach() - else() - foreach(csrc ${CCM_SRC}) + else() list(APPEND CCM_FILES "${CMAKE_CURRENT_SOURCE_DIR}/${csrc}") - endforeach() - endif() + endif() + endforeach() #message(STATUS "CCM = ${RESULT}") if(NOT DEFINED PIP_DLL_DIR) set(PIP_DLL_DIR ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/libs/main/opencl/piopencl.h b/libs/main/opencl/piopencl.h index 6b9ce2ee..6ec71fa6 100644 --- a/libs/main/opencl/piopencl.h +++ b/libs/main/opencl/piopencl.h @@ -50,6 +50,12 @@ public: AccessNone, }; + enum Direction { + Input = 0x01, + Output = 0x02, + InputOutput = Input | Output, + }; + enum TypeQualifier { TypeConst, TypeRestrict, @@ -74,6 +80,7 @@ public: KernelArg(); AddressQualifier address_qualifier; AccessQualifier access_qualifier; + Direction direction; TypeQualifier type_qualifier; PIString arg_name; PIString type_name; @@ -84,6 +91,8 @@ public: private: friend class Kernel; void init(void * _k, uint index); + int bytes; + void * buffer, * data; }; struct PIP_OPENCL_EXPORT Device { @@ -116,10 +125,12 @@ public: class PIP_OPENCL_EXPORT Context { friend class Program; + friend class Kernel; public: ~Context(); static Context * create(const DeviceList & dl); static Context * create(const Device & d) {return create(DeviceList() << d);} + static Context * create(const PIString & part_name); Program * createProgram(const PIString & source, PIString * error = 0); private: Context(); @@ -135,7 +146,7 @@ public: public: ~Program(); const PIString & sourceCode() const {return source_;} - const Kernel * kernel(int index = 0) const {return kernels_[index];} + Kernel * kernel(int index = 0) const {return kernels_[index];} const PIVector & kernels() const {return kernels_;} private: Program(); @@ -150,22 +161,49 @@ public: class PIP_OPENCL_EXPORT Kernel { friend class Program; public: + bool execute(); + void setExecuteRange(int size) {setExecuteRanges(PIVector() << size);} + void setExecuteRanges(const PIVector & ranges); const PIString & name() const {return name_;} const PIVector & args() const {return args_;} - template bool setArgValue(int index, const T & value) {return setArgValueV(index, PIVariant::fromValue(value));} + template bool setArgValue(int index, const T & value) {return setArgValueS(index, PIVariant::fromValue(value));} template bool setArgValue(const PIString & arg, const T & value) {return setArgValue(argIndex(arg), value);} + template bool bindArgValue(int index, PIVector & value, PIOpenCL::Direction dir) { + T def; + return bindArgValueV(index, value.size() * sizeof(T), value.data(), sizeof(def), &def, dir); + } + template bool bindArgValue(const PIString & arg, PIVector & value, PIOpenCL::Direction dir) { + return bindArgValue(argIndex(arg), value, dir); + } + template bool bindArgValue(int index, PIDeque & value, PIOpenCL::Direction dir) { + T def; + return bindArgValueV(index, value.size() * sizeof(T), value.data(), sizeof(def), &def, dir); + } + template bool bindArgValue(const PIString & arg, PIDeque & value, PIOpenCL::Direction dir) { + return bindArgValue(argIndex(arg), value, dir); + } + template bool bindArgValue(int index, PIVector2D & value, PIOpenCL::Direction dir) { + T def; + return bindArgValueV(index, value.size() * sizeof(T), value.data(), sizeof(def), &def, dir); + } + template bool bindArgValue(const PIString & arg, PIVector2D & value, PIOpenCL::Direction dir) { + return bindArgValue(argIndex(arg), value, dir); + } private: Kernel(); ~Kernel(); void zero(); bool init(); - bool setArgValueV(int index, const PIVariant & value); + bool setArgValueS(int index, const PIVariant & value); + bool bindArgValueV(int index, uint bytes, void * value, uint def_bytes, void * def_data, PIOpenCL::Direction dir); int argIndex(const PIString & an) const; KernelArg argByName(const PIString & an) const; Context * context_; Program * program_; PIString name_; PIVector args_; + PIVector buffers_; + PIVector dims; PRIVATE_DECLARATION(PIP_OPENCL_EXPORT) }; diff --git a/libs/opencl/piopencl.cpp b/libs/opencl/piopencl.cpp index 8f7313c5..e7ab8316 100644 --- a/libs/opencl/piopencl.cpp +++ b/libs/opencl/piopencl.cpp @@ -195,6 +195,17 @@ PIOpenCL::Context * PIOpenCL::Context::create(const PIOpenCL::DeviceList & dl) { } +PIOpenCL::Context * PIOpenCL::Context::create(const PIString & part_name) { + PIString pn = part_name.toLowerCase(); + PIVector dl = PIOpenCL::devices(); + piForeachC (Device & d, dl) { + if (d.displayText().toLowerCase().contains(pn)) + return create(d); + } + return 0; +} + + PIOpenCL::Program * PIOpenCL::Context::createProgram(const PIString & source, PIString * error) { if (error) error->clear(); if (source.isEmpty()) { @@ -310,6 +321,36 @@ bool PIOpenCL::Program::initKernels(PIVector kerns) { +bool PIOpenCL::Kernel::execute() { + if (dims.isEmpty()) { + piCout << "[PIOpenCL::Kernel]" << "Error: empty range"; + return false; + } + cl_int ret = 0; + piCout << "execute" << dims; + ret = clEnqueueNDRangeKernel(context_->PRIVATEWB->queue, PRIVATE->kernel, dims.size(), 0, dims.data(), 0, 0, 0, 0); + if (ret != 0) { + piCout << "[PIOpenCL::Kernel]" << "clEnqueueNDRangeKernel error" << ret; + return false; + } + piForeachC (KernelArg & ka, args_) { + if (ka.direction == Output || ka.direction == InputOutput) { + ret = clEnqueueReadBuffer(context_->PRIVATEWB->queue, (cl_mem)(ka.buffer), CL_TRUE, 0, ka.bytes, ka.data, 0, 0, 0); + if (ret != 0) { + piCout << "[PIOpenCL::Kernel]" << "clEnqueueWriteBuffer" << ka.type_name << ka.arg_name << "error" << ret; + return false; + } + } + } + return true; +} + + +void PIOpenCL::Kernel::setExecuteRanges(const PIVector & ranges) { + dims = ranges.toType(); +} + + PIOpenCL::Kernel::Kernel() { zero(); //piCout << "new Kernel" << this; @@ -318,6 +359,10 @@ PIOpenCL::Kernel::Kernel() { PIOpenCL::Kernel::~Kernel() { //piCout << "del Kernel" << this; + piForeachC (void * b, buffers_) { + clReleaseMemObject((cl_mem)b); + } + buffers_.clear(); if (PRIVATE->kernel) clReleaseKernel(PRIVATE->kernel); } @@ -349,17 +394,88 @@ bool PIOpenCL::Kernel::init() { ka.init(PRIVATE->kernel, i); args_ << ka; } - piCout << "kname" << kname << na; + //piCout << "kname" << kname << na; return true; } -bool PIOpenCL::Kernel::setArgValueV(int index, const PIVariant & value) { +template +void setArgV(cl_kernel k, int index, T v) { + //piCout << "setArgV" << k << index <= args_.size_s()) { piCout << "[PIOpenCL::Kernel]" << "setArgValue invalid index" << index; return false; } + KernelArg & ka(args_[index]); + if (ka.dims > 0) { + piCout << "[PIOpenCL::Kernel]" << "setArgValue set scalar to \"" << ka.type_name << ka.arg_name << "\""; + return false; + } + switch (ka.arg_type) { + case Char : setArgV(PRIVATE->kernel, index, (cl_char)(value.toInt())); break; + case UChar : setArgV(PRIVATE->kernel, index, (cl_uchar)(value.toInt())); break; + case Short : setArgV(PRIVATE->kernel, index, (cl_short)(value.toInt())); break; + case UShort: setArgV(PRIVATE->kernel, index, (cl_ushort)(value.toInt())); break; + case Int : setArgV(PRIVATE->kernel, index, (cl_int)(value.toInt())); break; + case UInt : setArgV(PRIVATE->kernel, index, (cl_uint)(value.toInt())); break; + case Long : setArgV(PRIVATE->kernel, index, (cl_long)(value.toLLong())); break; + case ULong : setArgV(PRIVATE->kernel, index, (cl_ulong)(value.toLLong())); break; + case Float : setArgV(PRIVATE->kernel, index, (cl_float)(value.toFloat())); break; + case Double: setArgV(PRIVATE->kernel, index, (cl_double)(value.toDouble())); break; + default: break; + } + return true; +} + +bool PIOpenCL::Kernel::bindArgValueV(int index, uint bytes, void * value, uint def_bytes, void * def_data, Direction dir) { + if (index < 0 || index >= args_.size_s()) { + piCout << "[PIOpenCL::Kernel]" << "bindArgValue invalid index" << index; + return false; + } + KernelArg & ka(args_[index]); + if (ka.dims <= 0) { + piCout << "[PIOpenCL::Kernel]" << "bindArgValue set vector to \"" << ka.type_name << ka.arg_name << "\""; + return false; + } + cl_int ret = 0; + cl_mem_flags f = CL_MEM_COPY_HOST_PTR; + ka.direction = dir; + //piCout << "acc" << ka.type_name << ka.arg_name << ka.access_qualifier << bytes << value; + switch (ka.direction) { + case Input : f |= CL_MEM_READ_ONLY ; break; + case Output : f |= CL_MEM_WRITE_ONLY; break; + case InputOutput: f |= CL_MEM_READ_WRITE; break; + default: break; + } + cl_mem mem = clCreateBuffer(context_->PRIVATEWB->context, f, bytes, value, &ret); + if (ret != 0) { + piCout << "[PIOpenCL::Kernel]" << "clCreateBuffer" << ka.type_name << ka.arg_name << "error" << ret; + return false; + } + buffers_ << (void*)mem; + ka.bytes = bytes; + ka.data = value; + ka.buffer = (void*)mem; + if (ka.direction == Input || ka.direction == InputOutput) { + ret = clEnqueueWriteBuffer(context_->PRIVATEWB->queue, mem, CL_TRUE, 0, bytes, value, 0, 0, 0); + if (ret != 0) { + piCout << "[PIOpenCL::Kernel]" << "clEnqueueWriteBuffer" << ka.type_name << ka.arg_name << "error" << ret; + return false; + } + } + if (ka.direction == Output || ka.direction == InputOutput) { + ret = clEnqueueFillBuffer(context_->PRIVATEWB->queue, mem, def_data, def_bytes, 0, bytes, 0, 0, 0); + if (ret != 0) { + piCout << "[PIOpenCL::Kernel]" << "clEnqueueFillBuffer" << ka.type_name << ka.arg_name << "error" << ret; + return false; + } + } + clSetKernelArg(PRIVATE->kernel, index, sizeof(mem), &mem); return true; } @@ -389,6 +505,8 @@ PIOpenCL::KernelArg::KernelArg() { is_pointer = false; arg_type = Float; dims = 1; + bytes = 0; + buffer = data = 0; } @@ -441,14 +559,26 @@ void PIOpenCL::KernelArg::init(void * _k, uint index) { case CL_KERNEL_ARG_TYPE_VOLATILE: type_qualifier = TypeVolatile; break; case CL_KERNEL_ARG_TYPE_NONE : type_qualifier = TypeNone; break; } - base_type_name = type_name; is_pointer = false; - if (type_name.endsWith("*")) { - is_pointer = true; - base_type_name.cutRight(1); + base_type_name = type_name; + base_type_name.removeAll("__global"); + dims = piMaxi(0, base_type_name.entries('*') + base_type_name.entries('[')); + base_type_name.removeAll('*'); + while (base_type_name.contains('[')) { + int i = base_type_name.find('['); + base_type_name.remove(i, base_type_name.find(']') - i + 1); } - dims = piMaxi(1, base_type_name.right(1).toInt()); - if (dims > 1) base_type_name.cutRight(1); + if (base_type_name == "char" ) arg_type = Char ; + if (base_type_name == "uchar" ) arg_type = UChar ; + if (base_type_name == "short") arg_type = Short; + if (base_type_name == "ushort") arg_type = UShort; + if (base_type_name == "int" ) arg_type = Int ; + if (base_type_name == "uint" ) arg_type = UInt ; + if (base_type_name == "long" ) arg_type = Long ; + if (base_type_name == "ulong" ) arg_type = ULong ; + if (base_type_name == "float" ) arg_type = Float ; + if (base_type_name == "double") arg_type = Double; + //piCout << type_name << base_type_name; } From efe2cbe4b60aa70d3cb4a722ac6ca314676a9364 Mon Sep 17 00:00:00 2001 From: andrey Date: Mon, 16 Nov 2020 13:27:24 +0300 Subject: [PATCH 91/98] FindPIP.cmake fix for SMSDK --- cmake/FindPIP.cmake | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmake/FindPIP.cmake b/cmake/FindPIP.cmake index 809998e5..fab2610e 100644 --- a/cmake/FindPIP.cmake +++ b/cmake/FindPIP.cmake @@ -21,6 +21,10 @@ cmake_policy(SET CMP0011 NEW) # don`t affect includer policies include(SHSTKMacros) shstk_set_find_dirs(pip) +if(PIP_DIR) + list(APPEND pip_LIBDIR "${PIP_DIR}/lib") + list(APPEND pip_INCDIR "${PIP_DIR}/include/pip") +endif() set(__libs "usb;crypt;console;fftw;compress;io_utils;opencl;cloud;lua") From 65d2f6b6e4ca375ddb0855463ffae174dfc3b323 Mon Sep 17 00:00:00 2001 From: andrey Date: Mon, 16 Nov 2020 13:49:45 +0300 Subject: [PATCH 92/98] FindPIP.cmake SMSDK fix --- cmake/FindPIP.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/FindPIP.cmake b/cmake/FindPIP.cmake index fab2610e..72f4e88c 100644 --- a/cmake/FindPIP.cmake +++ b/cmake/FindPIP.cmake @@ -24,6 +24,7 @@ shstk_set_find_dirs(pip) if(PIP_DIR) list(APPEND pip_LIBDIR "${PIP_DIR}/lib") list(APPEND pip_INCDIR "${PIP_DIR}/include/pip") + list(APPEND pip_BINDIR "${PIP_DIR}/bin") endif() set(__libs "usb;crypt;console;fftw;compress;io_utils;opencl;cloud;lua") From e0e8266b59e148c493a8b39a5be2b5c537c722d5 Mon Sep 17 00:00:00 2001 From: andrey Date: Wed, 25 Nov 2020 12:39:15 +0300 Subject: [PATCH 93/98] PIPropertyStorage: add return values and documentation in some functions --- CMakeLists.txt | 4 +- libs/main/core/pipropertystorage.cpp | 55 +++++++++++++++++++--------- libs/main/core/pipropertystorage.h | 46 ++++++++++++++++++----- 3 files changed, 76 insertions(+), 29 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3ebfa3fb..63499225 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,8 +2,8 @@ cmake_minimum_required(VERSION 3.0) cmake_policy(SET CMP0017 NEW) # need include() with .cmake project(pip) set(pip_MAJOR 2) -set(pip_MINOR 14) -set(pip_REVISION 2) +set(pip_MINOR 15) +set(pip_REVISION 0) set(pip_SUFFIX ) set(pip_COMPANY SHS) set(pip_DOMAIN org.SHS) diff --git a/libs/main/core/pipropertystorage.cpp b/libs/main/core/pipropertystorage.cpp index 679d374b..246ba6c9 100644 --- a/libs/main/core/pipropertystorage.cpp +++ b/libs/main/core/pipropertystorage.cpp @@ -28,41 +28,54 @@ bool PIPropertyStorage::isPropertyExists(const PIString & _name) const { } -void PIPropertyStorage::addProperty(const PIPropertyStorage::Property & p) { +bool PIPropertyStorage::addProperty(const PIPropertyStorage::Property & p) { for (uint i = 0; i < props.size(); ++i) if (props[i].name == p.name) { props[i] = p; - return; + return false; } props << p; + return true; } -void PIPropertyStorage::addProperty(PIPropertyStorage::Property && p) { +bool PIPropertyStorage::addProperty(PIPropertyStorage::Property && p) { for (uint i = 0; i < props.size(); ++i) if (props[i].name == p.name) { props[i] = std::move(p); - return; + return false; } props << std::move(p); + return true; } -void PIPropertyStorage::removeProperty(const PIString & _name) { - for (uint i = 0; i < props.size(); ++i) +bool PIPropertyStorage::addProperty(const PIString & _name, const PIVariant & _def_value, const PIString & _comment, int _flags) { + return addProperty(Property(_name, _comment, _def_value, _flags)); +} + + +bool PIPropertyStorage::removeProperty(const PIString & _name) { + for (uint i = 0; i < props.size(); ++i) { if (props[i].name == _name) { props.remove(i); - return; + return true; } + } + return false; } -void PIPropertyStorage::removePropertiesByFlag(int flag) { - for (int i = 0; i < props.size_s(); ++i) +int PIPropertyStorage::removePropertiesByFlag(int flag) { + int ret = 0; + for (int i = 0; i < props.size_s(); ++i) { if ((props[i].flags & flag) == flag) { props.remove(i); --i; + ret++; } + } + return ret; } @@ -99,30 +112,36 @@ PIVariant PIPropertyStorage::propertyValueByName(const PIString & name) const { } -void PIPropertyStorage::setPropertyValue(const PIString & name, const PIVariant & value) { - for (uint i = 0; i < props.size(); ++i) +bool PIPropertyStorage::setPropertyValue(const PIString & name, const PIVariant & value) { + for (uint i = 0; i < props.size(); ++i) { if (props[i].name == name) { props[i].value = value; - return; + return true; } + } + return false; } -void PIPropertyStorage::setPropertyComment(const PIString & name, const PIString & comment) { - for (uint i = 0; i < props.size(); ++i) +bool PIPropertyStorage::setPropertyComment(const PIString & name, const PIString & comment) { + for (uint i = 0; i < props.size(); ++i) { if (props[i].name == name) { props[i].comment = comment; - return; + return true; } + } + return false; } -void PIPropertyStorage::setPropertyFlags(const PIString & name, int flags) { - for (uint i = 0; i < props.size(); ++i) +bool PIPropertyStorage::setPropertyFlags(const PIString & name, int flags) { + for (uint i = 0; i < props.size(); ++i) { if (props[i].name == name) { props[i].flags = flags; - return; + return true; } + } + return false; } diff --git a/libs/main/core/pipropertystorage.h b/libs/main/core/pipropertystorage.h index 9dc4098c..31f01cd3 100644 --- a/libs/main/core/pipropertystorage.h +++ b/libs/main/core/pipropertystorage.h @@ -110,24 +110,49 @@ public: PIVector & properties() {return props;} const PIVector & properties() const {return props;} const PIPropertyStorage & propertyStorage() const {return *this;} + + /** + * @brief Check if property with \a name exists + * @return "true" if property exists + */ bool isPropertyExists(const PIString & _name) const; + + /** + * @brief Remove all properties + */ void clearProperties() {props.clear();} /** * @brief Add property if name isn't present in storage, otherwrise update existing property with same name. - * + * @return "true" if new property added, else if update existing property return "false" * @param p to copy in storage */ - void addProperty(const Property & p); - void addProperty(Property && p); + bool addProperty(const Property & p); + bool addProperty(Property && p); /** * @brief First of all construct Property with method params. After then add property if name isn't present * in storage, otherwrise update existing property with same name. + * @return "true" if new property added, else if update existing property return "false" + */ + bool addProperty(const PIString & _name, const PIVariant & _def_value, const PIString & _comment = PIString(), int _flags = 0); + + /** + * @brief Remove property with \a name + * @return "true" if property exists and removed + */ + bool removeProperty(const PIString & _name); + + /** + * @brief Remove properties wich has \a flag set + * @return removed properties count + */ + int removePropertiesByFlag(int flag); + + /** + * @brief Merge other \a properties_ into this + * @param flag_ignore - properties wich has this flag set will be ignored in merge */ - void addProperty(const PIString & _name, const PIVariant & _def_value, const PIString & _comment = PIString(), int _flags = 0) {addProperty(Property(_name, _comment, _def_value, _flags));} - void removeProperty(const PIString & _name); - void removePropertiesByFlag(int flag); void updateProperties(const PIVector & properties_, int flag_ignore = 0); /** @@ -151,24 +176,27 @@ public: * * @param name of property to set value * @param value to set + * @return "true" if property exists and updated */ - void setPropertyValue(const PIString & name, const PIVariant & value); + bool setPropertyValue(const PIString & name, const PIVariant & value); /** * @brief Set comment of property with specific name if name is present in storage. * * @param name of property to set comment * @param comment to set + * @return "true" if property exists and updated */ - void setPropertyComment(const PIString & name, const PIString & comment); + bool setPropertyComment(const PIString & name, const PIString & comment); /** * @brief Set flags of property with specific name if name is present in storage. * * @param name of property to set flags * @param flags to set + * @return "true" if property exists and updated */ - void setPropertyFlags(const PIString & name, int flags); + bool setPropertyFlags(const PIString & name, int flags); PIPropertyStorage & operator <<(const PIPropertyStorage::Property & p) {props << p; return *this;} PIPropertyStorage & operator <<(const PIVector & p) {props << p; return *this;} From 5de87eeed151edbc41127d286d5432a5fca7e91e Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Thu, 3 Dec 2020 21:38:30 +0300 Subject: [PATCH 94/98] PIVariant::fromValue fix PIOpenCL new Buffer class --- libs/main/core/pivariant.h | 2 + libs/main/opencl/piopencl.h | 92 ++++++++++++++----- libs/opencl/piopencl.cpp | 177 +++++++++++++++++++++++++----------- 3 files changed, 191 insertions(+), 80 deletions(-) diff --git a/libs/main/core/pivariant.h b/libs/main/core/pivariant.h index 8f222b63..77313cf4 100644 --- a/libs/main/core/pivariant.h +++ b/libs/main/core/pivariant.h @@ -661,6 +661,7 @@ template<> inline PIVariantTypes::Color PIVariant::value() const {return toColor template<> inline PIVariantTypes::IODevice PIVariant::value() const {return toIODevice();} template<> inline PIPointd PIVariant::value() const {return toPoint();} template<> inline PIRectd PIVariant::value() const {return toRect();} +template<> inline PIVariant PIVariant::value() const {return *this;} template<> inline PIVariant PIVariant::fromValue(const bool & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const char & v) {return PIVariant(v);} @@ -691,6 +692,7 @@ template<> inline PIVariant PIVariant::fromValue(const PIPointd & v) {return PIV template<> inline PIVariant PIVariant::fromValue(const PIRectd & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const PIMathVectord & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const PIMathMatrixd & v) {return PIVariant(v);} +template<> inline PIVariant PIVariant::fromValue(const PIVariant & v) {return PIVariant(v);} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivBool;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivChar;} diff --git a/libs/main/opencl/piopencl.h b/libs/main/opencl/piopencl.h index 6ec71fa6..5c531054 100644 --- a/libs/main/opencl/piopencl.h +++ b/libs/main/opencl/piopencl.h @@ -31,11 +31,13 @@ public: struct Device; struct Platform; class Context; + class Buffer; class Program; class Kernel; typedef PIVector DeviceList; + enum AddressQualifier { AddressGlobal, AddressLocal, @@ -76,6 +78,7 @@ public: Double, }; + struct PIP_OPENCL_EXPORT KernelArg { KernelArg(); AddressQualifier address_qualifier; @@ -91,10 +94,9 @@ public: private: friend class Kernel; void init(void * _k, uint index); - int bytes; - void * buffer, * data; }; + struct PIP_OPENCL_EXPORT Device { Device() {id = platform_id = 0; max_compute_units = max_clock_frequency = 0; max_memory_size = 0;} bool isValid() const {return id != 0;} @@ -110,6 +112,7 @@ public: ullong max_memory_size; }; + struct PIP_OPENCL_EXPORT Platform { Platform() {id = 0;} bool isValid() const {return id != 0;} @@ -123,7 +126,9 @@ public: PIVector devices; }; + class PIP_OPENCL_EXPORT Context { + friend class Buffer; friend class Program; friend class Kernel; public: @@ -132,17 +137,71 @@ public: static Context * create(const Device & d) {return create(DeviceList() << d);} static Context * create(const PIString & part_name); Program * createProgram(const PIString & source, PIString * error = 0); + template Buffer * createBuffer(PIOpenCL::Direction dir, PIVector & container) { + T def = T(); + return createBuffer(dir, &container, Buffer::cVector , PIByteArray(&def, sizeof(T)), container.size()); + } + template Buffer * createBuffer(PIOpenCL::Direction dir, PIDeque & container) { + T def = T(); + return createBuffer(dir, &container, Buffer::cDeque , PIByteArray(&def, sizeof(T)), container.size()); + } + template Buffer * createBuffer(PIOpenCL::Direction dir, PIVector2D & container) { + T def = T(); + return createBuffer(dir, &container, Buffer::cVector2D, PIByteArray(&def, sizeof(T)), container.size()); + } + template Buffer * createBuffer(PIOpenCL::Direction dir, uint elements) { + T def = T(); + Buffer * ret = createBuffer(dir, 0, Buffer::cNone, PIByteArray(&def, sizeof(T)), elements); + if (ret) + ret->clear(); + return ret; + } private: Context(); void zero(); void deletePrograms(); + void deleteBuffers(); + Buffer * createBuffer(PIOpenCL::Direction dir, void * container, int type, PIByteArray def, uint elements); PIVector programs_; + PIVector buffers_; PRIVATE_DECLARATION(PIP_OPENCL_EXPORT) }; + + class PIP_OPENCL_EXPORT Buffer { + friend class Context; + friend class Kernel; + public: + ~Buffer(); + bool resize(uint new_elements); + void clear(); + void copyToContainer(); + void copyFromContainer(); + private: + enum Container { + cNone, + cVector, + cDeque, + cVector2D, + }; + Buffer(); + void zero(); + bool init(); + void * containerData(); + Context * context_; + Direction dir; + Container type; + void * container; + PIByteArray def; + uint elements; + PRIVATE_DECLARATION(PIP_OPENCL_EXPORT) + }; + + class PIP_OPENCL_EXPORT Program { friend class Context; friend class Kernel; + friend class Buffer; public: ~Program(); const PIString & sourceCode() const {return source_;} @@ -158,8 +217,10 @@ public: PRIVATE_DECLARATION(PIP_OPENCL_EXPORT) }; + class PIP_OPENCL_EXPORT Kernel { friend class Program; + friend class Buffer; public: bool execute(); void setExecuteRange(int size) {setExecuteRanges(PIVector() << size);} @@ -168,45 +229,26 @@ public: const PIVector & args() const {return args_;} template bool setArgValue(int index, const T & value) {return setArgValueS(index, PIVariant::fromValue(value));} template bool setArgValue(const PIString & arg, const T & value) {return setArgValue(argIndex(arg), value);} - template bool bindArgValue(int index, PIVector & value, PIOpenCL::Direction dir) { - T def; - return bindArgValueV(index, value.size() * sizeof(T), value.data(), sizeof(def), &def, dir); - } - template bool bindArgValue(const PIString & arg, PIVector & value, PIOpenCL::Direction dir) { - return bindArgValue(argIndex(arg), value, dir); - } - template bool bindArgValue(int index, PIDeque & value, PIOpenCL::Direction dir) { - T def; - return bindArgValueV(index, value.size() * sizeof(T), value.data(), sizeof(def), &def, dir); - } - template bool bindArgValue(const PIString & arg, PIDeque & value, PIOpenCL::Direction dir) { - return bindArgValue(argIndex(arg), value, dir); - } - template bool bindArgValue(int index, PIVector2D & value, PIOpenCL::Direction dir) { - T def; - return bindArgValueV(index, value.size() * sizeof(T), value.data(), sizeof(def), &def, dir); - } - template bool bindArgValue(const PIString & arg, PIVector2D & value, PIOpenCL::Direction dir) { - return bindArgValue(argIndex(arg), value, dir); - } + bool setArgValue(const PIString & arg, const PIVariant & value) {return setArgValueS(argIndex(arg), value);} + bool bindArgValue(int index, Buffer * buffer); + bool bindArgValue(const PIString & arg, Buffer * buffer) {return bindArgValue(argIndex(arg), buffer);} private: Kernel(); ~Kernel(); void zero(); bool init(); bool setArgValueS(int index, const PIVariant & value); - bool bindArgValueV(int index, uint bytes, void * value, uint def_bytes, void * def_data, PIOpenCL::Direction dir); int argIndex(const PIString & an) const; KernelArg argByName(const PIString & an) const; Context * context_; Program * program_; PIString name_; PIVector args_; - PIVector buffers_; PIVector dims; PRIVATE_DECLARATION(PIP_OPENCL_EXPORT) }; + static void init(); static const PIVector & platforms(); static const PIVector devices(); diff --git a/libs/opencl/piopencl.cpp b/libs/opencl/piopencl.cpp index e7ab8316..40ea7e19 100644 --- a/libs/opencl/piopencl.cpp +++ b/libs/opencl/piopencl.cpp @@ -15,6 +15,11 @@ PRIVATE_DEFINITION_START(PIOpenCL::Context) PRIVATE_DEFINITION_END(PIOpenCL::Context) +PRIVATE_DEFINITION_START(PIOpenCL::Buffer) + cl_mem buffer; +PRIVATE_DEFINITION_END(PIOpenCL::Buffer) + + PRIVATE_DEFINITION_START(PIOpenCL::Program) cl_program program; PRIVATE_DEFINITION_END(PIOpenCL::Program) @@ -141,6 +146,7 @@ PIOpenCL::Context::Context() { PIOpenCL::Context::~Context() { piCout << "destroy context" << this; deletePrograms(); + deleteBuffers(); if (PRIVATE->queue) clReleaseCommandQueue(PRIVATE->queue); if (PRIVATE->context) @@ -151,6 +157,7 @@ PIOpenCL::Context::~Context() { void PIOpenCL::Context::zero() { programs_.clear(); + buffers_.clear(); PRIVATE->context = 0; PRIVATE->queue = 0; PRIVATE->devices.clear(); @@ -158,7 +165,7 @@ void PIOpenCL::Context::zero() { void PIOpenCL::Context::deletePrograms() { - piCout << "context: delete" << programs_.size() << "progs"; + piCout << "context: delete" << programs_.size() << "programs"; PIVector ptdl = programs_; programs_.clear(); piForeach (Program * p, ptdl) { @@ -167,6 +174,16 @@ void PIOpenCL::Context::deletePrograms() { } +void PIOpenCL::Context::deleteBuffers() { + piCout << "context: delete" << buffers_.size() << "buffers"; + PIVector btdl = buffers_; + buffers_.clear(); + piForeach (Buffer * b, btdl) { + if (b) delete b; + } +} + + PIOpenCL::Context * PIOpenCL::Context::create(const PIOpenCL::DeviceList & dl) { if (dl.isEmpty()) return 0; Context * rc = 0; @@ -275,6 +292,105 @@ PIOpenCL::Program * PIOpenCL::Context::createProgram(const PIString & source, PI } +PIOpenCL::Buffer * PIOpenCL::Context::createBuffer(PIOpenCL::Direction dir, void * container, int type, PIByteArray def, uint elements) { + Buffer * ret = new Buffer(); + ret->context_ = this; + ret->dir = dir; + ret->type = (Buffer::Container)type; + ret->container = container; + ret->def = def; + ret->elements = elements; + if (!ret->init()) { + delete ret; + return 0; + } + buffers_ << ret; + return ret; +} + + + + +PIOpenCL::Buffer::Buffer() { + zero(); +} + + +PIOpenCL::Buffer::~Buffer() { + if (context_) + context_->buffers_.removeAll(this); + if (PRIVATE->buffer) + clReleaseMemObject(PRIVATE->buffer); + zero(); +} + + +void PIOpenCL::Buffer::zero() { + type = cNone; + container = 0; + elements = 0; + PRIVATE->buffer = 0; +} + + +bool PIOpenCL::Buffer::init() { + cl_int ret = 0; + cl_mem_flags f = container ? CL_MEM_COPY_HOST_PTR : 0; + switch (dir) { + case Input : f |= CL_MEM_READ_ONLY ; break; + case Output : f |= CL_MEM_WRITE_ONLY; break; + case InputOutput: f |= CL_MEM_READ_WRITE; break; + default: break; + } + PRIVATE->buffer = clCreateBuffer(context_->PRIVATEWB->context, f, elements * def.size(), container ? containerData() : 0, &ret); + if (ret != 0) { + piCout << "[PIOpenCL::Buffer]" << "clCreateBuffer error" << ret; + return false; + } + return true; +} + + +void * PIOpenCL::Buffer::containerData() { + if (type == cNone || !container) return 0; + switch (type) { + case cVector : return ((PIVector *)container)->data(); + case cDeque : return ((PIDeque *)container)->data(); + case cVector2D: return ((PIVector2D*)container)->data(); + default: break; + } + return 0; +} + + +void PIOpenCL::Buffer::clear() { + if (!PRIVATE->buffer) return; + if (def.isEmpty() || elements == 0) return; + cl_int ret = clEnqueueFillBuffer(context_->PRIVATEWB->queue, PRIVATE->buffer, def.data(), def.size_s(), 0, elements * def.size(), 0, 0, 0); + if (ret != 0) { + piCout << "[PIOpenCL::Buffer]" << "clEnqueueFillBuffer error" << ret; + } +} + + +void PIOpenCL::Buffer::copyToContainer() { + if (!PRIVATE->buffer || !container) return; + cl_int ret = clEnqueueReadBuffer(context_->PRIVATEWB->queue, PRIVATE->buffer, CL_TRUE, 0, elements * def.size(), containerData(), 0, 0, 0); + if (ret != 0) { + piCout << "[PIOpenCL::Buffer]" << "clEnqueueReadBuffer error" << ret; + } +} + + +void PIOpenCL::Buffer::copyFromContainer() { + if (!PRIVATE->buffer || !container) return; + cl_int ret = clEnqueueWriteBuffer(context_->PRIVATEWB->queue, PRIVATE->buffer, CL_TRUE, 0, elements * def.size(), containerData(), 0, 0, 0); + if (ret != 0) { + piCout << "[PIOpenCL::Buffer]" << "clEnqueueWriteBuffer error" << ret; + } +} + + PIOpenCL::Program::Program() { @@ -326,22 +442,11 @@ bool PIOpenCL::Kernel::execute() { piCout << "[PIOpenCL::Kernel]" << "Error: empty range"; return false; } - cl_int ret = 0; - piCout << "execute" << dims; - ret = clEnqueueNDRangeKernel(context_->PRIVATEWB->queue, PRIVATE->kernel, dims.size(), 0, dims.data(), 0, 0, 0, 0); + cl_int ret = clEnqueueNDRangeKernel(context_->PRIVATEWB->queue, PRIVATE->kernel, dims.size(), 0, dims.data(), 0, 0, 0, 0); if (ret != 0) { piCout << "[PIOpenCL::Kernel]" << "clEnqueueNDRangeKernel error" << ret; return false; } - piForeachC (KernelArg & ka, args_) { - if (ka.direction == Output || ka.direction == InputOutput) { - ret = clEnqueueReadBuffer(context_->PRIVATEWB->queue, (cl_mem)(ka.buffer), CL_TRUE, 0, ka.bytes, ka.data, 0, 0, 0); - if (ret != 0) { - piCout << "[PIOpenCL::Kernel]" << "clEnqueueWriteBuffer" << ka.type_name << ka.arg_name << "error" << ret; - return false; - } - } - } return true; } @@ -359,10 +464,6 @@ PIOpenCL::Kernel::Kernel() { PIOpenCL::Kernel::~Kernel() { //piCout << "del Kernel" << this; - piForeachC (void * b, buffers_) { - clReleaseMemObject((cl_mem)b); - } - buffers_.clear(); if (PRIVATE->kernel) clReleaseKernel(PRIVATE->kernel); } @@ -432,50 +533,18 @@ bool PIOpenCL::Kernel::setArgValueS(int index, const PIVariant & value) { } -bool PIOpenCL::Kernel::bindArgValueV(int index, uint bytes, void * value, uint def_bytes, void * def_data, Direction dir) { +bool PIOpenCL::Kernel::bindArgValue(int index, Buffer * buffer) { + if (!buffer) return false; if (index < 0 || index >= args_.size_s()) { piCout << "[PIOpenCL::Kernel]" << "bindArgValue invalid index" << index; return false; } KernelArg & ka(args_[index]); if (ka.dims <= 0) { - piCout << "[PIOpenCL::Kernel]" << "bindArgValue set vector to \"" << ka.type_name << ka.arg_name << "\""; + piCout << "[PIOpenCL::Kernel]" << "bindArgValue set buffer to \"" << ka.type_name << ka.arg_name << "\""; return false; } - cl_int ret = 0; - cl_mem_flags f = CL_MEM_COPY_HOST_PTR; - ka.direction = dir; - //piCout << "acc" << ka.type_name << ka.arg_name << ka.access_qualifier << bytes << value; - switch (ka.direction) { - case Input : f |= CL_MEM_READ_ONLY ; break; - case Output : f |= CL_MEM_WRITE_ONLY; break; - case InputOutput: f |= CL_MEM_READ_WRITE; break; - default: break; - } - cl_mem mem = clCreateBuffer(context_->PRIVATEWB->context, f, bytes, value, &ret); - if (ret != 0) { - piCout << "[PIOpenCL::Kernel]" << "clCreateBuffer" << ka.type_name << ka.arg_name << "error" << ret; - return false; - } - buffers_ << (void*)mem; - ka.bytes = bytes; - ka.data = value; - ka.buffer = (void*)mem; - if (ka.direction == Input || ka.direction == InputOutput) { - ret = clEnqueueWriteBuffer(context_->PRIVATEWB->queue, mem, CL_TRUE, 0, bytes, value, 0, 0, 0); - if (ret != 0) { - piCout << "[PIOpenCL::Kernel]" << "clEnqueueWriteBuffer" << ka.type_name << ka.arg_name << "error" << ret; - return false; - } - } - if (ka.direction == Output || ka.direction == InputOutput) { - ret = clEnqueueFillBuffer(context_->PRIVATEWB->queue, mem, def_data, def_bytes, 0, bytes, 0, 0, 0); - if (ret != 0) { - piCout << "[PIOpenCL::Kernel]" << "clEnqueueFillBuffer" << ka.type_name << ka.arg_name << "error" << ret; - return false; - } - } - clSetKernelArg(PRIVATE->kernel, index, sizeof(mem), &mem); + clSetKernelArg(PRIVATE->kernel, index, sizeof(buffer->PRIVATEWB->buffer), &(buffer->PRIVATEWB->buffer)); return true; } @@ -505,8 +574,6 @@ PIOpenCL::KernelArg::KernelArg() { is_pointer = false; arg_type = Float; dims = 1; - bytes = 0; - buffer = data = 0; } From 3c543e79f051f9177182fd79a5af456e925c573a Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Sun, 6 Dec 2020 13:09:29 +0300 Subject: [PATCH 95/98] PISerial patch - close on read error --- CMakeLists.txt | 2 +- libs/main/io_devices/piserial.cpp | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 63499225..f1273c74 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_policy(SET CMP0017 NEW) # need include() with .cmake project(pip) set(pip_MAJOR 2) set(pip_MINOR 15) -set(pip_REVISION 0) +set(pip_REVISION 1) set(pip_SUFFIX ) set(pip_COMPANY SHS) set(pip_DOMAIN org.SHS) diff --git a/libs/main/io_devices/piserial.cpp b/libs/main/io_devices/piserial.cpp index 07fdded6..203d8e2a 100644 --- a/libs/main/io_devices/piserial.cpp +++ b/libs/main/io_devices/piserial.cpp @@ -709,7 +709,16 @@ int PISerial::readDevice(void * read_to, int max_size) { return PRIVATE->readed; #else if (!canRead()) return -1; - return ::read(fd, read_to, max_size); + int ret = ::read(fd, read_to, max_size); + if (ret < 0) { + int err = errno; + if (err == EBADF || err == EFAULT || err == EINVAL || err == EIO) { + PIThread::stop(false); + close(); + return 0; + } + } + return ret; #endif } From 587d90f269d6821ef5c4b7ba8d5301e8c91f2d4d Mon Sep 17 00:00:00 2001 From: andrey Date: Wed, 23 Dec 2020 16:52:27 +0300 Subject: [PATCH 96/98] fix plugin path in picout --- libs/main/system/piplugin.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/main/system/piplugin.cpp b/libs/main/system/piplugin.cpp index aaa01c55..ed91f87d 100644 --- a/libs/main/system/piplugin.cpp +++ b/libs/main/system/piplugin.cpp @@ -255,7 +255,7 @@ bool PIPluginLoader::load(const PIString & name) { if (!lib.load(findLibrary(name))) { unload(); error = LibraryLoadError; - error_str = "Load plugin \"" + name + "\" error: can`t load lib: " + lib.lastError(); + error_str = "Load plugin \"" + lib.path() + "\" error: can`t load lib: " + lib.lastError(); if (messages) piCout << error_str; return false; } @@ -264,14 +264,14 @@ bool PIPluginLoader::load(const PIString & name) { if (!func_loader_version) { unload(); error = MissingSymbols; - error_str = "Load plugin \"" + name + "\" error: can`t find " + STR(__PIP_PLUGIN_LOADER_VERSION_FUNC__); + error_str = "Load plugin \"" + lib.path() + "\" error: can`t find " + STR(__PIP_PLUGIN_LOADER_VERSION_FUNC__); if (messages) piCout << error_str; return false; } if (__PIP_PLUGIN_LOADER_VERSION__ != func_loader_version()) { unload(); error = InvalidLoaderVersion; - error_str = "Load plugin \"" + name + "\" error: invalid loader version: application = " + PIString::fromNumber(func_loader_version()) + error_str = "Load plugin \"" + lib.path() + "\" error: invalid loader version: application = " + PIString::fromNumber(func_loader_version()) + ", plugin = " + PIString::fromNumber(__PIP_PLUGIN_LOADER_VERSION__); if (messages) piCout << error_str; return false; @@ -281,7 +281,7 @@ bool PIPluginLoader::load(const PIString & name) { if (pversion != lversion) { unload(); error = InvalidUserVersion; - error_str = "Load plugin \"" + name + "\" error: invalid user version: application = " + lversion + ", plugin = " + pversion; + error_str = "Load plugin \"" + lib.path() + "\" error: invalid user version: application = " + lversion + ", plugin = " + pversion; if (messages) piCout << error_str; return false; } From 493b211886baef96ed9ec0ccd2f8aa0dca74c0fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A4=D0=BE=D0=BC=D0=B5=D0=BD=D0=BA=D0=BE=20=D0=A1=D1=82?= =?UTF-8?q?=D0=B5=D0=BF=D0=B0=D0=BD=20=D0=92=D0=BB=D0=B0=D0=B4=D0=B8=D0=BC?= =?UTF-8?q?=D0=B8=D1=80=D0=BE=D0=B2=D0=B8=D1=87?= Date: Tue, 12 Jan 2021 13:53:32 +0300 Subject: [PATCH 97/98] Configure address and undefined sanitizers & fix delete UB --- libs/main/core/piinit.cpp | 2 +- tests/CMakeLists.txt | 12 +++++++++--- tests/suppr.txt | 2 ++ 3 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 tests/suppr.txt diff --git a/libs/main/core/piinit.cpp b/libs/main/core/piinit.cpp index 90eacfa1..38e64be8 100644 --- a/libs/main/core/piinit.cpp +++ b/libs/main/core/piinit.cpp @@ -282,7 +282,7 @@ PIInit::PIInit() { PIInit::~PIInit() { - if (file_charset) delete file_charset; + if (file_charset) delete[] file_charset; file_charset = 0; PIResourcesStorage::instance()->clear(); #ifdef WINDOWS diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index bebb15da..e55ddcbe 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,19 +1,25 @@ include(DownloadGTest) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/suppr.txt ${CMAKE_CURRENT_BINARY_DIR} COPYONLY) + macro(pip_test NAME LIBS) file(GLOB _CPPS "${NAME}/*.cpp") file(GLOB _HDRS "${NAME}/*.h") set(_target pip_${NAME}_test) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PIP_ROOT_BINARY_DIR}") add_executable(${_target} ${_CPPS} ${_HDRS}) - target_link_libraries(${_target} pip ${LIBS} gtest_main gmock_main) + if (NOT WIN32 AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + target_compile_options(${_target} PRIVATE -fsanitize=address,undefined) + target_link_options(${_target} PRIVATE -fsanitize=address,undefined) + endif() + target_link_libraries(${_target} pip ${LIBS} gtest_main gmock_main asan) add_test(NAME ${_target} COMMAND tests) - add_custom_target(${_target}_perform ALL COMMAND ${_target}) + add_custom_target(${_target}_perform ALL + COMMAND ${CMAKE_COMMAND} -E env "LSAN_OPTIONS=suppressions=suppr.txt" $) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY) list(APPEND PIP_TESTS_LIST "${NAME}") set(PIP_TESTS_LIST ${PIP_TESTS_LIST} PARENT_SCOPE) endmacro() -# Concurrent tests pip_test(concurrent "") pip_test(math "") diff --git a/tests/suppr.txt b/tests/suppr.txt new file mode 100644 index 00000000..ccdc4da6 --- /dev/null +++ b/tests/suppr.txt @@ -0,0 +1,2 @@ +leak:ConditionVariable::SetUp +leak:ConditionLock_ \ No newline at end of file From 1dc827f16a1d49e5f0c3868990e4ec14ec53f1ff Mon Sep 17 00:00:00 2001 From: Stepan Fomenko Date: Wed, 20 Jan 2021 16:52:57 +0300 Subject: [PATCH 98/98] Fix windows build tests --- tests/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e55ddcbe..49d5005d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -11,8 +11,9 @@ macro(pip_test NAME LIBS) if (NOT WIN32 AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") target_compile_options(${_target} PRIVATE -fsanitize=address,undefined) target_link_options(${_target} PRIVATE -fsanitize=address,undefined) + target_link_libraries(${_target} asan) endif() - target_link_libraries(${_target} pip ${LIBS} gtest_main gmock_main asan) + target_link_libraries(${_target} pip ${LIBS} gtest_main gmock_main) add_test(NAME ${_target} COMMAND tests) add_custom_target(${_target}_perform ALL COMMAND ${CMAKE_COMMAND} -E env "LSAN_OPTIONS=suppressions=suppr.txt" $)