PIVector some optimize code #164

Merged
andrey merged 1 commits from vector into master 2022-08-22 20:18:08 +03:00

View File

@@ -127,7 +127,7 @@ public:
//! \~english Constructs an empty array. //! \~english Constructs an empty array.
//! \~russian Создает пустой массив. //! \~russian Создает пустой массив.
inline PIVector(): piv_data(0), piv_size(0), piv_rsize(0) { inline PIVector() {
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
} }
@@ -135,7 +135,7 @@ public:
//! This constructor reserve `size` and copy from `data` pointer. //! This constructor reserve `size` and copy from `data` pointer.
//! \~russian Создает массив из указателя на данные `data` и размер `size`. //! \~russian Создает массив из указателя на данные `data` и размер `size`.
//! То есть выделяет память для `size` элементов и копирует данные из указателя `data`. //! То есть выделяет память для `size` элементов и копирует данные из указателя `data`.
inline PIVector(const T * data, size_t size): piv_data(0), piv_size(0), piv_rsize(0) { inline PIVector(const T * data, size_t size) {
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
alloc(size); alloc(size);
newT(piv_data, data, piv_size); newT(piv_data, data, piv_size);
@@ -143,7 +143,7 @@ public:
//! \~english Copy constructor. //! \~english Copy constructor.
//! \~russian Копирующий конструктор. //! \~russian Копирующий конструктор.
inline PIVector(const PIVector<T> & v): piv_data(0), piv_size(0), piv_rsize(0) { inline PIVector(const PIVector<T> & v) {
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
alloc(v.piv_size); alloc(v.piv_size);
newT(piv_data, v.piv_data, piv_size); newT(piv_data, v.piv_data, piv_size);
@@ -158,7 +158,7 @@ public:
//! PIVector <int> v{1,2,3}; //! PIVector <int> v{1,2,3};
//! piCout << v; // {1, 2, 3} //! piCout << v; // {1, 2, 3}
//! \endcode //! \endcode
inline PIVector(std::initializer_list<T> init_list): piv_data(0), piv_size(0), piv_rsize(0) { inline PIVector(std::initializer_list<T> init_list) {
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
alloc(init_list.size()); alloc(init_list.size());
newT(piv_data, init_list.begin(), init_list.size()); newT(piv_data, init_list.begin(), init_list.size());
@@ -166,9 +166,9 @@ public:
//! \~english Contructs array with size `size` filled elements `e`. //! \~english Contructs array with size `size` filled elements `e`.
//! \~russian Создает массив из `size` элементов заполненных `e`. //! \~russian Создает массив из `size` элементов заполненных `e`.
inline PIVector(size_t size, const T & e = T()): piv_data(0), piv_size(0), piv_rsize(0) { inline PIVector(size_t size, const T & e = T()) {
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
resize(size, e); expand(size, e);
} }
//! \~english Contructs array with size `size` and elements created by function `f(size_t i)`. //! \~english Contructs array with size `size` and elements created by function `f(size_t i)`.
@@ -184,15 +184,18 @@ public:
//! PIVector <int> v(5, [](size_t i){return i*2;}); //! PIVector <int> v(5, [](size_t i){return i*2;});
//! piCout << v; // {0, 2, 4, 6, 8} //! piCout << v; // {0, 2, 4, 6, 8}
//! \endcode //! \endcode
inline PIVector(size_t size, std::function<T(size_t i)> f): piv_data(0), piv_size(0), piv_rsize(0) { inline PIVector(size_t size, std::function<T(size_t i)> f) {
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
resize(size, f); expand(size, f);
} }
//! \~english Move constructor. //! \~english Move constructor.
//! \~russian Перемещающий конструктор. //! \~russian Перемещающий конструктор.
inline PIVector(PIVector<T> && v): piv_data(v.piv_data), piv_size(v.piv_size), piv_rsize(v.piv_rsize) { inline PIVector(PIVector<T> && v) {
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
piv_data = v.piv_data;
piv_size = v.piv_size;
piv_rsize = v.piv_rsize;
v._reset(); v._reset();
} }
@@ -201,7 +204,6 @@ public:
PIINTROSPECTION_CONTAINER_FREE(T, (piv_rsize)) PIINTROSPECTION_CONTAINER_FREE(T, (piv_rsize))
deleteT(piv_data, piv_size); deleteT(piv_data, piv_size);
dealloc(); dealloc();
_reset();
} }
//! \~english Assign operator. //! \~english Assign operator.
@@ -1175,7 +1177,8 @@ public:
!std::is_trivially_copyable<T1>::value !std::is_trivially_copyable<T1>::value
, int>::type = 0> , int>::type = 0>
inline PIVector<T> & clear() { inline PIVector<T> & clear() {
resize(0); deleteT(piv_data, piv_size);
piv_size = 0;
return *this; return *this;
} }
template<typename T1 = T, typename std::enable_if< template<typename T1 = T, typename std::enable_if<
@@ -1259,17 +1262,10 @@ public:
//! \~\sa \a size(), \a clear() //! \~\sa \a size(), \a clear()
inline PIVector<T> & resize(size_t new_size, const T & e = T()) { inline PIVector<T> & resize(size_t new_size, const T & e = T()) {
if (new_size < piv_size) { if (new_size < piv_size) {
T * de = &(piv_data[new_size]); deleteT(&(piv_data[new_size]), piv_size - new_size);
deleteT(de, piv_size - new_size);
piv_size = new_size; piv_size = new_size;
} } else if (new_size > piv_size) {
if (new_size > piv_size) { expand(new_size, e);
size_t os = piv_size;
alloc(new_size);
PIINTROSPECTION_CONTAINER_USED(T, (new_size-os))
for (size_t i = os; i < new_size; ++i) {
elementNew(piv_data + i, e);
}
} }
return *this; return *this;
} }
@@ -1290,14 +1286,8 @@ public:
T * de = &(piv_data[new_size]); T * de = &(piv_data[new_size]);
deleteT(de, piv_size - new_size); deleteT(de, piv_size - new_size);
piv_size = new_size; piv_size = new_size;
} } else if (new_size > piv_size) {
if (new_size > piv_size) { expand(new_size, f);
size_t os = piv_size;
alloc(new_size);
PIINTROSPECTION_CONTAINER_USED(T, (new_size-os))
for (size_t i = os; i < new_size; ++i) {
elementNew(piv_data + i, f(i));
}
} }
return *this; return *this;
} }
@@ -1306,12 +1296,14 @@ public:
std::is_trivially_copyable<T1>::value std::is_trivially_copyable<T1>::value
, int>::type = 0> , int>::type = 0>
inline PIVector<T> & _resizeRaw(size_t new_size) { inline PIVector<T> & _resizeRaw(size_t new_size) {
#if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
if (new_size > piv_size) { if (new_size > piv_size) {
PIINTROSPECTION_CONTAINER_USED(T, (new_size-piv_size)); PIINTROSPECTION_CONTAINER_USED(T, (new_size-piv_size));
} }
if (new_size < piv_size) { if (new_size < piv_size) {
PIINTROSPECTION_CONTAINER_UNUSED(T, (piv_size-new_size)); PIINTROSPECTION_CONTAINER_UNUSED(T, (piv_size-new_size));
} }
#endif
alloc(new_size); alloc(new_size);
return *this; return *this;
} }
@@ -1436,7 +1428,10 @@ public:
inline PIVector<T> & remove(size_t index, size_t count = 1) { inline PIVector<T> & remove(size_t index, size_t count = 1) {
if (count == 0) return *this; if (count == 0) return *this;
if (index + count >= piv_size) { if (index + count >= piv_size) {
resize(index); if (index < piv_size) {
deleteT(&(piv_data[index]), piv_size - index);
piv_size = index;
}
return *this; return *this;
} }
size_t os = piv_size - index - count; size_t os = piv_size - index - count;
@@ -1932,7 +1927,8 @@ public:
//! \~\sa \a pop_front(), \a take_back(), \a take_front() //! \~\sa \a pop_front(), \a take_back(), \a take_front()
inline PIVector<T> & pop_back() { inline PIVector<T> & pop_back() {
if (piv_size == 0) return *this; if (piv_size == 0) return *this;
resize(piv_size - 1); deleteT(&(piv_data[piv_size-1]), 1);
piv_size = piv_size - 1;
return *this; return *this;
} }
@@ -2428,25 +2424,31 @@ public:
} }
private: private:
inline void _reset() {piv_size = piv_rsize = 0; piv_data = 0;} inline void _reset() {
piv_size = piv_rsize = 0;
piv_data = nullptr;
}
inline size_t asize(size_t s) { inline size_t asize(size_t s) {
if (s == 0) return 0; if (s == 0) return 0;
if (piv_rsize + piv_rsize >= s && piv_rsize < s) { if (piv_rsize + piv_rsize >= s && piv_rsize < s) {
return piv_rsize + piv_rsize; return piv_rsize + piv_rsize;
} }
ssize_t t = _PIContainerConstants<T>::minCountPoT(), s_ = s - 1; ssize_t t = _PIContainerConstants<T>::minCountPoT(), s_ = s - 1;
while (s_ >> t) while (s_ >> t) ++t;
++t;
return (1 << t); return (1 << t);
} }
template<typename T1 = T, typename std::enable_if< template<typename T1 = T, typename std::enable_if<
!std::is_trivially_copyable<T1>::value !std::is_trivially_copyable<T1>::value
, int>::type = 0> , int>::type = 0>
inline void newT(T * dst, const T * src, size_t s) { inline void newT(T * dst, const T * src, size_t s) {
PIINTROSPECTION_CONTAINER_USED(T, s) PIINTROSPECTION_CONTAINER_USED(T, s)
for (size_t i = 0; i < s; ++i) for (size_t i = 0; i < s; ++i) {
elementNew(dst + i, src[i]); elementNew(dst + i, src[i]);
}
} }
template<typename T1 = T, typename std::enable_if< template<typename T1 = T, typename std::enable_if<
std::is_trivially_copyable<T1>::value std::is_trivially_copyable<T1>::value
, int>::type = 0> , int>::type = 0>
@@ -2454,51 +2456,90 @@ private:
PIINTROSPECTION_CONTAINER_USED(T, s) PIINTROSPECTION_CONTAINER_USED(T, s)
memcpy((void*)(dst), (const void*)(src), s * sizeof(T)); memcpy((void*)(dst), (const void*)(src), s * sizeof(T));
} }
template<typename T1 = T, typename std::enable_if< template<typename T1 = T, typename std::enable_if<
!std::is_trivially_copyable<T1>::value !std::is_trivially_copyable<T1>::value
, int>::type = 0> , int>::type = 0>
inline void deleteT(T * d, size_t sz) { inline void deleteT(T * d, size_t sz) {
PIINTROSPECTION_CONTAINER_UNUSED(T, sz) PIINTROSPECTION_CONTAINER_UNUSED(T, sz)
if ((uchar*)d != 0) { if (d != nullptr) {
for (size_t i = 0; i < sz; ++i) { for (size_t i = 0; i < sz; ++i) {
elementDelete(d[i]); elementDelete(d[i]);
} }
} }
} }
template<typename T1 = T, typename std::enable_if< template<typename T1 = T, typename std::enable_if<
std::is_trivially_copyable<T1>::value std::is_trivially_copyable<T1>::value
, int>::type = 0> , int>::type = 0>
inline void deleteT(T * d, size_t sz) { inline void deleteT(T * d, size_t sz) {
PIINTROSPECTION_CONTAINER_UNUSED(T, sz) PIINTROSPECTION_CONTAINER_UNUSED(T, sz)
} }
template<typename T1 = T, typename std::enable_if< template<typename T1 = T, typename std::enable_if<
!std::is_trivially_copyable<T1>::value !std::is_trivially_copyable<T1>::value
, int>::type = 0> , int>::type = 0>
inline void elementNew(T * to, const T & from) {new(to)T(from);} inline void elementNew(T * to, const T & from) {
new(to)T(from);
}
template<typename T1 = T, typename std::enable_if< template<typename T1 = T, typename std::enable_if<
!std::is_trivially_copyable<T1>::value !std::is_trivially_copyable<T1>::value
, int>::type = 0> , int>::type = 0>
inline void elementNew(T * to, T && from) {new(to)T(std::move(from));} inline void elementNew(T * to, T && from) {
new(to)T(std::move(from));
}
template<typename T1 = T, typename std::enable_if< template<typename T1 = T, typename std::enable_if<
std::is_trivially_copyable<T1>::value std::is_trivially_copyable<T1>::value
, int>::type = 0> , int>::type = 0>
inline void elementNew(T1 * to, const T & from) {(*to) = from;} inline void elementNew(T1 * to, const T & from) {
(*to) = from;
}
template<typename T1 = T, typename std::enable_if< template<typename T1 = T, typename std::enable_if<
std::is_trivially_copyable<T1>::value std::is_trivially_copyable<T1>::value
, int>::type = 0> , int>::type = 0>
inline void elementNew(T * to, T && from) {(*to) = std::move(from);} inline void elementNew(T * to, T && from) {
(*to) = std::move(from);
}
template<typename T1 = T, typename std::enable_if< template<typename T1 = T, typename std::enable_if<
!std::is_trivially_copyable<T1>::value !std::is_trivially_copyable<T1>::value
, int>::type = 0> , int>::type = 0>
inline void elementDelete(T & from) {from.~T();} inline void elementDelete(T & from) {
from.~T();
}
template<typename T1 = T, typename std::enable_if< template<typename T1 = T, typename std::enable_if<
std::is_trivially_copyable<T1>::value std::is_trivially_copyable<T1>::value
, int>::type = 0> , int>::type = 0>
inline void elementDelete(T & from) {} inline void elementDelete(T & from) {}
inline void dealloc() { inline void dealloc() {
if ((uchar*)piv_data != 0) free((uchar*)piv_data); if (piv_data != nullptr) free((uchar*)piv_data);
piv_data = 0; piv_data = nullptr;
piv_size = piv_rsize = 0;
} }
inline void expand(size_t new_size, const T & e = T()) {
size_t os = piv_size;
alloc(new_size);
PIINTROSPECTION_CONTAINER_USED(T, (new_size-os))
for (size_t i = os; i < new_size; ++i) {
elementNew(piv_data + i, e);
}
}
inline void expand(size_t new_size, std::function<T(size_t i)> f) {
size_t os = piv_size;
alloc(new_size);
PIINTROSPECTION_CONTAINER_USED(T, (new_size-os))
for (size_t i = os; i < new_size; ++i) {
elementNew(piv_data + i, f(i));
}
}
inline void alloc(size_t new_size) { inline void alloc(size_t new_size) {
if (new_size <= piv_rsize) { if (new_size <= piv_rsize) {
piv_size = new_size; piv_size = new_size;
@@ -2519,8 +2560,9 @@ private:
piv_rsize = as; piv_rsize = as;
} }
T * piv_data; T * piv_data = nullptr;
size_t piv_size, piv_rsize; size_t piv_size = 0;
size_t piv_rsize = 0;
}; };