diff --git a/libs/main/containers/pideque.h b/libs/main/containers/pideque.h index ba86f423..3e0fc460 100644 --- a/libs/main/containers/pideque.h +++ b/libs/main/containers/pideque.h @@ -205,14 +205,13 @@ public: PIINTROSPECTION_CONTAINER_FREE(T, (pid_rsize)) deleteT(pid_data + pid_start, pid_size); dealloc(); - _reset(); } //! \~english Assign operator. //! \~russian Оператор присваивания. inline PIDeque & operator =(const PIDeque & other) { if (this == &other) return *this; - deleteT(pid_data + pid_start, pid_size); + clear(); alloc_forward(other.pid_size); newT(pid_data + pid_start, other.pid_data + other.pid_start, pid_size); return *this; @@ -1175,7 +1174,7 @@ public: PIDeque getRange(size_t index, size_t count) const { if (index >= pid_size || count == 0) return PIDeque(); if (index + count > pid_size) count = pid_size - index; - return PIDeque(&(pid_data[pid_start + index]), count); + return PIDeque(pid_data + pid_start + index, count); } //! \~english Clear array, remove all elements. @@ -1189,7 +1188,7 @@ public: !std::is_trivially_copyable::value , int>::type = 0> inline PIDeque & clear() { - deleteT(&(pid_data[pid_start]), pid_size); + deleteT(pid_data + pid_start, pid_size); pid_size = 0; pid_start = (pid_rsize - pid_size) / 2; return *this; @@ -1277,7 +1276,7 @@ public: inline PIDeque & resize(size_t new_size, const T & e = T()) { if (new_size == 0) return clear(); if (new_size < pid_size) { - deleteT(&(pid_data[new_size + pid_start]), pid_size - new_size); + deleteT(pid_data + pid_start + new_size, pid_size - new_size); pid_size = new_size; }else if (new_size > pid_size) { expand(new_size, e); @@ -1299,7 +1298,7 @@ public: inline PIDeque & resize(size_t new_size, std::function f) { if (new_size == 0) return clear(); if (new_size < pid_size) { - deleteT(&(pid_data[new_size + pid_start]), pid_size - new_size); + deleteT(pid_data + pid_start + new_size, pid_size - new_size); pid_size = new_size; } else if (new_size > pid_size) { expand(new_size, f); @@ -1366,12 +1365,12 @@ public: alloc_forward(pid_size + 1); if (index < pid_size - 1) { size_t os = pid_size - index - 1; - memmove((void*)(&(pid_data[index + pid_start + 1])), (const void*)(&(pid_data[index + pid_start])), os * sizeof(T)); + memmove((void*)(pid_data + pid_start + index + 1), (const void*)(pid_data + pid_start + index), os * sizeof(T)); } } else { alloc_backward(pid_size + 1, -1); if (index > 0) { - memmove((void*)(&(pid_data[pid_start])), (const void*)(&(pid_data[pid_start + 1])), index * sizeof(T)); + memmove((void*)(pid_data + pid_start), (const void*)(pid_data + pid_start + 1), index * sizeof(T)); } } elementNew(pid_data + pid_start + index, e); @@ -1392,12 +1391,12 @@ public: alloc_forward(pid_size + 1); if (index < pid_size - 1) { size_t os = pid_size - index - 1; - memmove((void*)(&(pid_data[index + pid_start + 1])), (const void*)(&(pid_data[index + pid_start])), os * sizeof(T)); + memmove((void*)(pid_data + pid_start + index + 1), (const void*)(pid_data + pid_start + index), os * sizeof(T)); } } else { alloc_backward(pid_size + 1, -1); if (index > 0) { - memmove((void*)(&(pid_data[pid_start])), (const void*)(&(pid_data[pid_start + 1])), index * sizeof(T)); + memmove((void*)(pid_data + pid_start), (const void*)(pid_data + pid_start + 1), index * sizeof(T)); } } elementNew(pid_data + pid_start + index, std::move(e)); @@ -1423,12 +1422,12 @@ public: ssize_t os = pid_size - index; alloc_forward(pid_size + v.pid_size); if (os > 0) { - memmove((void*)(&(pid_data[index + pid_start + v.pid_size])), (const void*)(&(pid_data[index + pid_start])), os * sizeof(T)); + memmove((void*)(pid_data + pid_start + index + v.pid_size), (const void*)(pid_data + pid_start + index), os * sizeof(T)); } } else { alloc_backward(pid_size + v.pid_size, -v.pid_size); if (index > 0) { - memmove((void*)(&(pid_data[pid_start])), (const void*)(&(pid_data[pid_start + v.pid_size])), index * sizeof(T)); + memmove((void*)(pid_data + pid_start), (const void*)(pid_data + pid_start + v.pid_size), index * sizeof(T)); } } newT(pid_data + pid_start + index, v.pid_data + v.pid_start, v.pid_size); @@ -1446,17 +1445,18 @@ public: //! [списка инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list). //! \~\sa \a append(), \a prepend(), \a remove() inline PIDeque & insert(size_t index, std::initializer_list init_list) { + if (init_list.size() == 0) return *this; bool dir = init_list.size() > pid_size ? true : (index >= pid_rsize / 2 ? true : false); if (dir) { ssize_t os = ssize_t(pid_size) - index; alloc_forward(pid_size + init_list.size()); if (os > 0) { - memmove((void*)(&(pid_data[index + pid_start + init_list.size()])), (const void*)(&(pid_data[index + pid_start])), os * sizeof(T)); + memmove((void*)(pid_data + pid_start + index + init_list.size()), (const void*)(pid_data + pid_start + index), os * sizeof(T)); } } else { alloc_backward(pid_size + init_list.size(), -init_list.size()); if (index > 0) { - memmove((void*)(&(pid_data[pid_start])), (const void*)(&(pid_data[pid_start + init_list.size()])), index * sizeof(T)); + memmove((void*)(pid_data + pid_start), (const void*)(pid_data + pid_start + init_list.size()), index * sizeof(T)); } } newT(pid_data + pid_start + index, init_list.begin(), init_list.size()); @@ -1476,20 +1476,20 @@ public: if (count == 0) return *this; if (index + count >= pid_size) { if (index < pid_size) { - deleteT(&(pid_data[index + pid_start]), pid_size - index); + deleteT(pid_data + pid_start + index, pid_size - index); pid_size = index; } return *this; } size_t os = pid_size - index - count; - deleteT(&(pid_data[index + pid_start]), count); + deleteT(pid_data + pid_start + index, count); if (os <= index) { if (os > 0) { - memmove((void*)(&(pid_data[index + pid_start])), (const void*)(&(pid_data[index + pid_start + count])), os * sizeof(T)); + memmove((void*)(pid_data + pid_start + index), (const void*)(pid_data + pid_start + index + count), os * sizeof(T)); } } else { if (index > 0) { - memmove((void*)(&(pid_data[pid_start + count])), (const void*)(&(pid_data[pid_start])), index * sizeof(T)); + memmove((void*)(pid_data + pid_start + count), (const void*)(pid_data + pid_start), index * sizeof(T)); } pid_start += count; } @@ -1738,6 +1738,7 @@ public: //! [списка инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list). //! \~\sa \a push_back() inline PIDeque & push_back(std::initializer_list init_list) { + if (init_list.size() == 0) return *this; size_t ps = pid_size; alloc_forward(pid_size + init_list.size()); newT(pid_data + pid_start + ps, init_list.begin(), init_list.size()); @@ -2073,6 +2074,7 @@ public: template inline PIDeque toType() const { PIDeque ret(pid_size); + ret.reserve(pid_size); for (size_t i = 0; i < pid_size; ++i) { ret[i] = ST(pid_data[i + pid_start]); } @@ -2511,8 +2513,8 @@ private: inline size_t asize(ssize_t s) { if (s <= 0) return 0; - if (pid_rsize + pid_rsize >= size_t(s) && pid_rsize < size_t(s)) { - return pid_rsize + pid_rsize; + if (pid_rsize * 2 >= size_t(s) && pid_rsize < size_t(s)) { + return pid_rsize * 2; } size_t t = _PIContainerConstants::minCountPoT(); size_t s_ = s - 1; diff --git a/libs/main/containers/pivector.h b/libs/main/containers/pivector.h index 4d2e85e0..0fcea57f 100644 --- a/libs/main/containers/pivector.h +++ b/libs/main/containers/pivector.h @@ -211,7 +211,6 @@ public: inline PIVector & operator =(const PIVector & v) { if (this == &v) return *this; clear(); - deleteT(piv_data, piv_size); alloc(v.piv_size); newT(piv_data, v.piv_data, piv_size); return *this; @@ -1163,7 +1162,7 @@ public: PIVector getRange(size_t index, size_t count) const { if (index >= piv_size || count == 0) return PIVector(); if (index + count > piv_size) count = piv_size - index; - return PIVector(&(piv_data[index]), count); + return PIVector(piv_data + index, count); } //! \~english Clear array, remove all elements. @@ -1262,7 +1261,7 @@ public: //! \~\sa \a size(), \a clear() inline PIVector & resize(size_t new_size, const T & e = T()) { if (new_size < piv_size) { - deleteT(&(piv_data[new_size]), piv_size - new_size); + deleteT(piv_data + new_size, piv_size - new_size); piv_size = new_size; } else if (new_size > piv_size) { expand(new_size, e); @@ -1283,8 +1282,7 @@ public: //! \~\sa \a size(), \a clear() inline PIVector & resize(size_t new_size, std::function f) { if (new_size < piv_size) { - T * de = &(piv_data[new_size]); - deleteT(de, piv_size - new_size); + deleteT(piv_data + new_size, piv_size - new_size); piv_size = new_size; } else if (new_size > piv_size) { expand(new_size, f); @@ -1349,7 +1347,7 @@ public: alloc(piv_size + 1); if (index < piv_size - 1) { size_t os = piv_size - index - 1; - memmove((void*)(&(piv_data[index + 1])), (const void*)(&(piv_data[index])), os * sizeof(T)); + memmove((void*)(piv_data + index + 1), (const void*)(piv_data + index), os * sizeof(T)); } PIINTROSPECTION_CONTAINER_USED(T, 1) elementNew(piv_data + index, e); @@ -1366,7 +1364,7 @@ public: alloc(piv_size + 1); if (index < piv_size - 1) { size_t os = piv_size - index - 1; - memmove((void*)(&(piv_data[index + 1])), (const void*)(&(piv_data[index])), os * sizeof(T)); + memmove((void*)(piv_data + index + 1), (const void*)(piv_data + index), os * sizeof(T)); } PIINTROSPECTION_CONTAINER_USED(T, 1) elementNew(piv_data + index, std::move(e)); @@ -1390,7 +1388,7 @@ public: ssize_t os = piv_size - index; alloc(piv_size + v.piv_size); if (os > 0) { - memmove((void*)(&(piv_data[index + v.piv_size])), (const void*)(&(piv_data[index])), os * sizeof(T)); + memmove((void*)(piv_data + index + v.piv_size), (const void*)(piv_data + index), os * sizeof(T)); } newT(piv_data + index, v.piv_data, v.piv_size); return *this; @@ -1407,10 +1405,11 @@ public: //! [списка инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list). //! \~\sa \a append(), \a prepend(), \a remove() inline PIVector & insert(size_t index, std::initializer_list init_list) { + if (init_list.size() == 0) return *this; ssize_t os = piv_size - index; alloc(piv_size + init_list.size()); if (os > 0) { - memmove((void*)(&(piv_data[index + init_list.size()])), (const void*)(&(piv_data[index])), os * sizeof(T)); + memmove((void*)(piv_data + index + init_list.size()), (const void*)(piv_data + index), os * sizeof(T)); } newT(piv_data + index, init_list.begin(), init_list.size()); return *this; @@ -1429,14 +1428,14 @@ public: if (count == 0) return *this; if (index + count >= piv_size) { if (index < piv_size) { - deleteT(&(piv_data[index]), piv_size - index); + deleteT(piv_data + index, piv_size - index); piv_size = index; } return *this; } size_t os = piv_size - index - count; - deleteT(&(piv_data[index]), count); - memmove((void*)(&(piv_data[index])), (const void*)(&(piv_data[index + count])), os * sizeof(T)); + deleteT(piv_data + index, count); + memmove((void*)(piv_data + index), (const void*)(piv_data + index + count), os * sizeof(T)); piv_size -= count; return *this; } @@ -1680,6 +1679,7 @@ public: //! [списка инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list). //! \~\sa \a push_back() inline PIVector & push_back(std::initializer_list init_list) { + if (init_list.size() == 0) return *this; size_t ps = piv_size; alloc(piv_size + init_list.size()); newT(piv_data + ps, init_list.begin(), init_list.size()); @@ -1693,6 +1693,7 @@ public: //! \~russian Перегруженая функция. //! \~\sa \a push_back() inline PIVector & push_back(const PIVector & v) { + if (v.isEmpty()) return *this; #ifndef NDEBUG if (&v == this) { printf("error with PIVector<%s>::push_back\n", __PIP_TYPENAME__(T)); @@ -1815,8 +1816,7 @@ public: //! \endcode //! \~\sa \a push_back(), \a append(), \a prepend(), \a insert() inline PIVector & push_front(const T & e) { - insert(0, e); - return *this; + return insert(0, e); } //! \~english Appends the given element `e` to the begin of the array. @@ -1826,8 +1826,7 @@ public: //! \~russian Перегруженая функция. //! \~\sa \a push_front() inline PIVector & push_front(T && e) { - insert(0, std::move(e)); - return *this; + return insert(0, std::move(e)); } //! \~english Appends the given array `v` to the begin of the array. @@ -1842,8 +1841,7 @@ public: //! \endcode //! \~\sa \a push_front() inline PIVector & push_front(const PIVector & v) { - insert(0, v); - return *this; + return insert(0, v); } //! \~english Appends the given elements to the begin of the array. @@ -1857,8 +1855,7 @@ public: //! [списка инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list). //! \~\sa \a append() inline PIVector & push_front(std::initializer_list init_list) { - insert(0, init_list); - return *this; + return insert(0, init_list); } //! \~english Appends the given element `e` to the begin of the array. @@ -1927,7 +1924,7 @@ public: //! \~\sa \a pop_front(), \a take_back(), \a take_front() inline PIVector & pop_back() { if (piv_size == 0) return *this; - deleteT(&(piv_data[piv_size-1]), 1); + deleteT(piv_data + piv_size - 1, 1); piv_size = piv_size - 1; return *this; } @@ -1994,7 +1991,8 @@ public: //! \~\sa \a map() template inline PIVector toType() const { - PIVector ret; ret.reserve(piv_size); + PIVector ret; + ret.reserve(piv_size); for (size_t i = 0; i < piv_size; ++i) { ret << ST(piv_data[i]); } @@ -2341,7 +2339,7 @@ public: assert(rows*cols == piv_size); PIVector> ret; if (isEmpty()) return ret; - ret.resize(rows); + ret.expand(rows); if (order == ReshapeByRow) { for (size_t r = 0; r < rows; r++) { ret[r] = PIVector(&(piv_data[r*cols]), cols); @@ -2425,14 +2423,15 @@ public: private: inline void _reset() { - piv_size = piv_rsize = 0; + piv_size = 0; + piv_rsize = 0; piv_data = nullptr; } inline size_t asize(size_t s) { if (s == 0) return 0; - if (piv_rsize + piv_rsize >= s && piv_rsize < s) { - return piv_rsize + piv_rsize; + if (piv_rsize * 2 >= s && piv_rsize < s) { + return piv_rsize * 2; } ssize_t t = _PIContainerConstants::minCountPoT(), s_ = s - 1; while (s_ >> t) ++t; @@ -2517,9 +2516,10 @@ private: inline void elementDelete(T & from) {} inline void dealloc() { - if (piv_data != nullptr) free((uchar*)piv_data); - piv_data = nullptr; - piv_size = piv_rsize = 0; + if (piv_data != nullptr) { + free((void*)piv_data); + piv_data = nullptr; + } } inline void expand(size_t new_size, const T & e = T()) {