PIVector reverse, filter and reversed functions

PIVector lastIndexOf and lastIndexWhere correct behaviour
PIVector doc
picontainersmodule.h doc
This commit is contained in:
Andrey
2022-03-31 16:32:41 +03:00
parent 7ab16b641d
commit aa417be1d3
2 changed files with 123 additions and 21 deletions

View File

@@ -21,20 +21,43 @@
//! \~english This module contains various standart containers realization. //! \~english This module contains various standart containers realization.
//! \~russian Модуль содержит основные классы контейнеров. //! \~russian Модуль содержит основные классы контейнеров.
//! \~\details //! \~\details
//! Scope | Use //! \~english This includes:
//! ----- | ------- //! Class | Description
//! C++ | `#include <picontainersmodule.h>` //! ------------- | -----------
//! CMake | PIP //! \a PIVector | Linear array, fast back insert
//! \a PIDeque | Linear array, fast back and front insert
//! \a PIMap | Dictionary container, key/value array
//! \a PISet | Set container
//! \a PIStack | Stack
//! \a PIQueue | Queue
//! \a PIPair | Pair
//! \a PIVector2D | Linear 2D rectangle array
//! //!
//! \~english This includes //! \~russian В него входят:
//! \~russian В него входят //! Класс | Описание
//! \~ \a PIVector, \a PIDeque, \a PIMap, \a PISet, //! ------------- | -----------
//! \a PIStack, \a PIQueue, \a PIPair, \a PIVector2D. //! \a PIVector | Линейный массив, быстрое добавление в конец
//! \a PIDeque | Линейный массив, быстрое добавление вначало и конец
//! \a PIMap | Массив ключ/значение, словарь
//! \a PISet | Множество
//! \a PIStack | Стек
//! \a PIQueue | Очередь
//! \a PIPair | Пара
//! \a PIVector2D | Линейный двумерный прямоугольный массив
//!
//!
//! \~english \section cmake_build_containers Building with CMake
//! Use the `find_package()` command to locate PIP package:
//! \~russian \section cmake_build_containers Сборка с использованием CMake
//! Используйте команду `find_package()` для подключения PIP в CMake:
//! \~\code
//! find_package(PIP REQUIRED)
//! target_link_libraries(${PROJECT_NAME} PIP)
//! \endcode
//! //!
//! //!
//! \~english \section stl_iterators STL-Style Iterators //! \~english \section stl_iterators STL-Style Iterators
//! \~russian \section stl_iterators Итераторы в стиле STL //! \~russian \section stl_iterators Итераторы в стиле STL
//! \~\addindex stl_iterators
//! \~english //! \~english
//! \brief They are compatible with Qt's and STL's generic algorithms and are optimized for speed. //! \brief They are compatible with Qt's and STL's generic algorithms and are optimized for speed.
//! \details //! \details

View File

@@ -822,12 +822,36 @@ public:
//! \endcode //! \endcode
inline const T * data(size_t index = 0) const {return &(piv_data[index]);} inline const T * data(size_t index = 0) const {return &(piv_data[index]);}
//! \~\brief
//! \~english Creates 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`).
PIVector<T> getRange(size_t index, size_t count) const { PIVector<T> getRange(size_t index, size_t count) const {
if (index >= piv_size || count == 0) return PIVector<T>(); if (index >= piv_size || count == 0) return PIVector<T>();
if (index + count > piv_size) count = piv_size - index; if (index + count > piv_size) count = piv_size - index;
return PIVector(&(piv_data[index]), count); return PIVector(&(piv_data[index]), count);
} }
//! \~\brief
//! \~english Clear array, remove all elements.
//! \~russian Очищает массив, удаляет все элементы.
//! \~\details
//! \~english Note: reserved memory will not be released.
//! \~russian Замечание: зарезервированная память не освободится.
//! \~\sa \a resize
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>
@@ -844,6 +868,16 @@ public:
return *this; return *this;
} }
//! \~\brief
//! \~english Assigns element 'f' to all items in the array.
//! \~russian Заполняет весь массив копиями элемента 'f'.
//! \~\details
//! \code
//! PIVector<int> v{1, 3, 5};
//! v.fill(7);
//! piCout << v; // 7, 7, 7
//! \endcode
//! \~\sa \a resize
inline PIVector<T> & fill(const T & f = T()) { inline PIVector<T> & fill(const T & f = T()) {
deleteT(piv_data, piv_size); deleteT(piv_data, piv_size);
PIINTROSPECTION_CONTAINER_USED(T, piv_size) PIINTROSPECTION_CONTAINER_USED(T, piv_size)
@@ -852,6 +886,17 @@ public:
} }
return *this; return *this;
} }
//! \~\brief
//! \~english Assigns result of function 'f(size_t i)' to all items in the array.
//! \~russian Заполняет весь массив результатом вызова функции 'f(size_t i)'.
//! \~\details
//! \code
//! PIVector<int> v{1, 3, 5};
//! v.fill([](size_t i){return i*2;});
//! piCout << v; // 0, 2, 4
//! \endcode
//! \~\sa \a resize
inline PIVector<T> & fill(std::function<T(size_t i)> f) { inline PIVector<T> & fill(std::function<T(size_t i)> f) {
deleteT(piv_data, piv_size); deleteT(piv_data, piv_size);
PIINTROSPECTION_CONTAINER_USED(T, piv_size) PIINTROSPECTION_CONTAINER_USED(T, piv_size)
@@ -861,7 +906,17 @@ public:
return *this; return *this;
} }
//! \~\brief
//! \~english Same as \a fill.
//! \~russian Тоже самое что и \a fill.
//! \~\sa \a fill, \a resize
inline PIVector<T> & assign(const T & f = T()) {return fill(f);} inline PIVector<T> & assign(const T & f = T()) {return fill(f);}
//! \~\brief
//! \~english First does `resize(new_size)` then `fill(f)`.
//! \~russian Сначала делает `resize(new_size)` затем `fill(f)`.
//! \~\sa \a fill, \a resize
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>
@@ -994,10 +1049,23 @@ public:
return *this; return *this;
} }
inline PIVector<T> & enlarge(llong piv_size) { inline PIVector<T> & reverse() {
size_t s2 = piv_size/2;
for (size_t i = 0; i < s2; ++i) {
piSwap<T>(piv_data[i], piv_data[piv_size-i-1]);
}
return *this;
}
inline PIVector<T> reversed() const {
PIVector<T> ret(*this);
return ret.reverse();
}
inline PIVector<T> & enlarge(llong piv_size, const T & e = T()) {
llong ns = size_s() + piv_size; llong ns = size_s() + piv_size;
if (ns <= 0) clear(); if (ns <= 0) clear();
else resize(size_t(ns)); else resize(size_t(ns), e);
return *this; return *this;
} }
@@ -1015,7 +1083,7 @@ public:
return *this; return *this;
} }
inline PIVector<T> & removeAll(const T & e) { inline PIVector<T> & removeAll(const T & e) {
for (ssize_t i = 0; i < ssize_t(piv_size); ++i) { for (ssize_t i = 0; i < size_s(); ++i) {
if (piv_data[i] == e) { if (piv_data[i] == e) {
remove(i); remove(i);
--i; --i;
@@ -1024,7 +1092,7 @@ public:
return *this; return *this;
} }
inline PIVector<T> & removeWhere(std::function<bool(const T & e)> test) { inline PIVector<T> & removeWhere(std::function<bool(const T & e)> test) {
for (ssize_t i = 0; i < ssize_t(piv_size); ++i) { for (ssize_t i = 0; i < size_s(); ++i) {
if (test(piv_data[i])) { if (test(piv_data[i])) {
remove(i); remove(i);
--i; --i;
@@ -1093,7 +1161,7 @@ public:
inline T take_front() {T e(front()); pop_front(); return e;} inline T take_front() {T e(front()); pop_front(); return e;}
template <typename ST> template <typename ST>
PIVector<ST> toType() const { inline PIVector<ST> toType() const {
PIVector<ST> ret(piv_size); PIVector<ST> ret(piv_size);
for (size_t i = 0; i < piv_size; ++i) { for (size_t i = 0; i < piv_size; ++i) {
ret[i] = ST(piv_data[i]); ret[i] = ST(piv_data[i]);
@@ -1101,20 +1169,30 @@ public:
return ret; return ret;
} }
const PIVector<T> & forEach(std::function<void(const T & e)> f) const { inline PIVector<T> filter(std::function<bool(const T & e)> test) const {
PIVector<T> ret;
for (size_t i = 0; i < piv_size; ++i) {
if (test(piv_data[i])) ret << piv_data[i];
}
return ret;
}
inline const PIVector<T> & forEach(std::function<void(const T & e)> f) const {
for (size_t i = 0; i < piv_size; ++i) { for (size_t i = 0; i < piv_size; ++i) {
f(piv_data[i]); f(piv_data[i]);
} }
return *this; return *this;
} }
PIVector<T> copyForEach(std::function<T(const T & e)> f) const {
inline PIVector<T> copyForEach(std::function<T(const T & e)> f) const {
PIVector<T> ret; ret.reserve(piv_size); PIVector<T> ret; ret.reserve(piv_size);
for (size_t i = 0; i < piv_size; ++i) { for (size_t i = 0; i < piv_size; ++i) {
ret << f(piv_data[i]); ret << f(piv_data[i]);
} }
return ret; return ret;
} }
PIVector<T> & forEachInplace(std::function<T(const T & e)> f) {
inline PIVector<T> & forEachInplace(std::function<T(const T & e)> f) {
for (size_t i = 0; i < piv_size; ++i) { for (size_t i = 0; i < piv_size; ++i) {
piv_data[i] = f(piv_data[i]); piv_data[i] = f(piv_data[i]);
} }
@@ -1122,18 +1200,19 @@ public:
} }
template <typename ST> template <typename ST>
PIVector<ST> map(std::function<ST(const T & e)> f) const { inline PIVector<ST> map(std::function<ST(const T & e)> f) const {
PIVector<ST> ret; ret.reserve(piv_size); PIVector<ST> ret; ret.reserve(piv_size);
for (size_t i = 0; i < piv_size; ++i) { for (size_t i = 0; i < piv_size; ++i) {
ret << f(piv_data[i]); ret << f(piv_data[i]);
} }
return ret; return ret;
} }
template <typename ST>
PIVector<ST> toType(std::function<ST(const T & e)> f) const {return map(f);}
template <typename ST> template <typename ST>
ST reduce(std::function<ST(const T & e, const ST & acc)> f, const ST & initial = ST()) const { inline PIVector<ST> toType(std::function<ST(const T & e)> f) const {return map(f);}
template <typename ST>
inline ST reduce(std::function<ST(const T & e, const ST & acc)> f, const ST & initial = ST()) const {
ST ret(initial); ST ret(initial);
for (size_t i = 0; i < piv_size; ++i) { for (size_t i = 0; i < piv_size; ++i) {
ret = f(piv_data[i], ret); ret = f(piv_data[i], ret);