PIVector and PIDeque takeRange

This commit is contained in:
Бычков Андрей
2022-08-25 17:35:49 +03:00
parent 8370351ff3
commit 1bc9f5ed19
2 changed files with 88 additions and 17 deletions

View File

@@ -1310,12 +1310,14 @@ public:
std::is_trivially_copyable<T1>::value
, int>::type = 0>
inline PIDeque<T> & _resizeRaw(size_t new_size) {
#if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
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));
}
#endif
alloc_forward(new_size);
return *this;
}
@@ -1479,21 +1481,19 @@ public:
deleteT(pid_data + pid_start + index, pid_size - index);
pid_size = index;
}
return *this;
}
size_t os = pid_size - index - count;
deleteT(pid_data + pid_start + index, count);
if (os <= index) {
if (os > 0) {
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));
size_t os = pid_size - index - count;
deleteT(pid_data + pid_start + index, count);
if (os <= index) {
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));
}
pid_start += count;
}
pid_start += count;
pid_size -= count;
}
pid_size -= count;
return *this;
}
@@ -2543,6 +2543,45 @@ public:
return ret;
}
//! \~english Cut sub-array of this array.
//! \~russian Вырезает подмассив, то есть кусок из текущего массива.
//! \~english
//! \param index - index of this array where sub-array starts
//! \param count - sub-array size
//! \~russian
//! \param index - индекс в текущем массиве, откуда начинётся подмассив
//! \param count - размер подмассива
//! \~\details
//! \~english
//! Index must be in range from `0` to `size()-1`.
//! If sub-array size more than this array size, than ends early.
//! \~russian
//! Индекс начала должен лежать в диапазоне от `0` до `size()-1`.
//! Если заданный размер подмассива превышает размер текущего массива,
//! то вернется подмассив меньшего размера (`size()-index-1`).
inline PIDeque<T> takeRange(size_t index, size_t count) {
PIDeque<T> ret;
if (index >= pid_size || count == 0) return ret;
if (index + count > pid_size) count = pid_size - index;
ret.alloc_forward(count);
memcpy((void*)(ret.pid_data + ret.pid_start), (const void*)(pid_data + pid_start + index), count * sizeof(T));
size_t os = pid_size - index - count;
if (os <= index) {
if (os > 0) {
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));
}
pid_start += count;
}
pid_size -= count;
return ret;
}
private:
inline void _reset() {
pid_size = 0;

View File

@@ -1431,12 +1431,12 @@ public:
deleteT(piv_data + index, piv_size - index);
piv_size = index;
}
return *this;
} else {
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));
piv_size -= count;
}
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));
piv_size -= count;
return *this;
}
@@ -2461,6 +2461,38 @@ public:
return ret;
}
//! \~english Cut sub-array of this array.
//! \~russian Вырезает подмассив, то есть кусок из текущего массива.
//! \~english
//! \param index - index of this array where sub-array starts
//! \param count - sub-array size
//! \~russian
//! \param index - индекс в текущем массиве, откуда начинётся подмассив
//! \param count - размер подмассива
//! \~\details
//! \~english
//! Index must be in range from `0` to `size()-1`.
//! If sub-array size more than this array size, than ends early.
//! \~russian
//! Индекс начала должен лежать в диапазоне от `0` до `size()-1`.
//! Если заданный размер подмассива превышает размер текущего массива,
//! то вернется подмассив меньшего размера (`size()-index-1`).
inline PIVector<T> takeRange(size_t index, size_t count) {
PIVector<T> ret;
if (index >= piv_size || count == 0) return ret;
if (index + count > piv_size) count = piv_size - index;
ret.alloc(count);
memcpy((void*)ret.piv_data, (const void*)(piv_data + index), count * sizeof(T));
size_t os = piv_size - index - count;
if (os > 0) {
memmove((void*)(piv_data + index), (const void*)(piv_data + index + count), os * sizeof(T));
piv_size -= count;
} else {
piv_size = index;
}
return ret;
}
private:
inline void _reset() {
piv_size = 0;