review fixes

This commit is contained in:
2026-02-18 22:00:21 +03:00
parent d8cadce026
commit 98d93865f0
4 changed files with 71 additions and 271 deletions

View File

@@ -835,8 +835,8 @@ public:
//! piCout << v.contains({1,4}); // true
//! piCout << v.contains({1,5}); // false
//! \endcode
//! \~\sa \a every(), \a any(), \a entries(), \a forEach()
inline bool contains(const PIVector<T> & v, ssize_t start = 0) const {
//! \~\sa \a every(), \a any(), \a entries(), \a forEach(), \a contains()
inline bool containsAll(const PIVector<T> & v, ssize_t start = 0) const {
if (start < 0) {
start = piv_size + start;
if (start < 0) start = 0;
@@ -854,6 +854,24 @@ public:
return true;
}
//! \~english Tests if any element of `v` exists in the array.
//! \~russian Проверяет наличие хотя бы одного из элементов `v` в массиве.
//! \~\sa \a containsAll(), \a contains()
inline bool containsAny(const PIVector<T> & v, ssize_t start = 0) const {
if (start < 0) {
start = piv_size + start;
if (start < 0) start = 0;
}
for (const T & e: v) {
for (size_t i = start; i < piv_size; ++i) {
if (e == piv_data[i]) {
return true;
}
}
}
return false;
}
//! \~english Count elements equal `e` in the array.
//! \~russian Подсчитывает количество элементов, совпадающих с элементом `e` в массиве.
//! \~\details
@@ -1349,8 +1367,8 @@ public:
alloc(piv_size + v.piv_size);
if (os > 0) {
memmove(reinterpret_cast<void *>(piv_data + index + v.piv_size),
reinterpret_cast<const void *>(piv_data + index),
os * sizeof(T));
reinterpret_cast<const void *>(piv_data + index),
os * sizeof(T));
}
newT(piv_data + index, v.piv_data, v.piv_size);
return *this;
@@ -1372,8 +1390,8 @@ public:
alloc(piv_size + init_list.size());
if (os > 0) {
memmove(reinterpret_cast<void *>(piv_data + index + init_list.size()),
reinterpret_cast<const void *>(piv_data + index),
os * sizeof(T));
reinterpret_cast<const void *>(piv_data + index),
os * sizeof(T));
}
newT(piv_data + index, init_list.begin(), init_list.size());
return *this;

View File

@@ -62,9 +62,6 @@ public:
//! \~english Constructs a 2D array with the given dimensions, filled with copies of `f`.
//! \~russian Создаёт двумерный массив заданного размера, заполненный копиями `f`.
//! \param rows Number of rows.
//! \param cols Number of columns.
//! \param f Value to fill the array with. Defaults to default-constructed T.
//! \details
//! \~english The underlying storage is a single contiguous block of memory of size `rows * cols`.
//! All elements are initialized with the value `f`.
@@ -79,9 +76,6 @@ public:
//! \~english Constructs a 2D array from an existing 1D vector, reshaping it.
//! \~russian Создаёт двумерный массив из существующего одномерного вектора, изменяя его форму.
//! \param rows Number of rows.
//! \param cols Number of columns.
//! \param v The source 1D vector. Its size must be at least `rows * cols`.
//! \details
//! \~english The constructor copies the data from `v` into the internal flat vector.
//! If `v` is larger than `rows * cols`, the excess elements are ignored (the vector is truncated).
@@ -94,9 +88,6 @@ public:
//! \~english Move constructs a 2D array from an existing 1D vector, reshaping it.
//! \~russian Конструктор перемещения из существующего одномерного вектора, изменяя его форму.
//! \param rows Number of rows.
//! \param cols Number of columns.
//! \param v The source 1D vector (rvalue reference). Its size must be at least `rows * cols`.
//! \details
//! \~english The data is moved from `v` into the internal flat vector, avoiding a copy.
//! After construction, `v` is left in a valid but unspecified state.
@@ -107,7 +98,8 @@ public:
//! \~english Constructs a 2D array from a vector of vectors (jagged array). Assumes all inner vectors have the same size.
//! \~russian Создаёт двумерный массив из вектора векторов (рваного массива). Предполагается, что все внутренние векторы имеют
//! одинаковый размер. \param v The source vector of vectors. \details
//! одинаковый размер.
//! \details
//! \~english If the input is empty, the constructed array is also empty. Otherwise, the number of columns is taken from the size of the
//! first inner vector. All inner vectors are concatenated in the internal flat storage.
//! \~russian Если входной массив пуст, создаётся пустой двумерный массив. В противном случае количество столбцов берётся из размера
@@ -220,8 +212,6 @@ public:
//! \~english Accesses the element at the given column index within the row.
//! \~russian Доступ к элементу по заданному индексу столбца в строке.
//! \param index Column index (must be less than size()).
//! \return Reference to the element.
//! \details
//! \~english No bounds checking is performed in release builds; use with caution.
//! \~russian В релизной сборке проверка границ не выполняется; используйте с осторожностью.
@@ -230,15 +220,11 @@ public:
//! \~english Const access to the element at the given column index within the row.
//! \~russian Константный доступ к элементу по заданному индексу столбца в строке.
//! \param index Column index (must be less than size()).
//! \return Const reference to the element.
//! \sa operator[] (non-const)
inline const T & operator[](size_t index) const { return (*p_)[st_ + index]; }
//! \~english Returns a pointer to the row data starting at an optional offset.
//! \~russian Возвращает указатель на данные строки, начиная с опционального смещения.
//! \param index Offset within the row (default 0).
//! \return Pointer to the first element at the given offset.
//! \details
//! \~english The pointer can be used for direct memory operations. It remains valid as long as the underlying 2D array is not
//! reallocated.
@@ -248,15 +234,11 @@ public:
//! \~english Returns a const pointer to the row data starting at an optional offset.
//! \~russian Возвращает константный указатель на данные строки, начиная с опционального смещения.
//! \param index Offset within the row (default 0).
//! \return Const pointer.
//! \sa data() (non-const)
inline const T * data(size_t index = 0) const { return p_->data(st_ + index); }
//! \~english Assigns the contents of another Row to this row.
//! \~russian Присваивает этой строке содержимое другой строки.
//! \param other Source row.
//! \return Reference to this row.
//! \details
//! \~english Only the minimum of the two row sizes is copied; if this row is shorter, excess elements in `other` are ignored.
//! \~russian Копируется только минимум из размеров двух строк; если эта строка короче, лишние элементы из `other` игнорируются.
@@ -270,8 +252,6 @@ public:
//! \~english Assigns the contents of a \a PIVector to this row.
//! \~russian Присваивает этой строке содержимое \a PIVector.
//! \param other Source vector.
//! \return Reference to this row.
//! \details
//! \~english Only the minimum of the row size and vector size is copied.
//! \~russian Копируется только минимум из размера строки и размера вектора.
@@ -284,15 +264,11 @@ public:
//! \~english Converts the row to a \a PIVector.
//! \~russian Преобразует строку в \a PIVector.
//! \return A new \a PIVector containing a copy of the row elements.
//! \sa PIVector::PIVector(const T*, size_t)
inline PIVector<T> toVector() const { return PIVector<T>(p_->data(st_), sz_); }
//! \~english Returns the first index of element `e` in the row, starting from `start`.
//! \~russian Возвращает первый индекс элемента `e` в строке, начиная с позиции `start`.
//! \param e Element to search for.
//! \param start Starting index (negative values count from the end). Default 0.
//! \return Index if found, -1 otherwise.
//! \details
//! \~english See \a PIVector::indexOf() for details on negative start handling.
//! \~russian Подробнее об обработке отрицательного `start` см. \a PIVector::indexOf().
@@ -307,9 +283,6 @@ public:
//! \~english Returns the last index of element `e` in the row, searching backwards from `start`.
//! \~russian Возвращает последний индекс элемента `e` в строке, выполняя поиск в обратном направлении от `start`.
//! \param e Element to search for.
//! \param start Starting index (negative values count from the end). Default -1 (last element).
//! \return Index if found, -1 otherwise.
//! \sa PIVector::lastIndexOf()
inline ssize_t lastIndexOf(const T & e, ssize_t start = -1) const {
ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start;
@@ -321,9 +294,6 @@ public:
//! \~english Returns the first index where the predicate `test` returns true, starting from `start`.
//! \~russian Возвращает первый индекс, для которого предикат `test` возвращает true, начиная с `start`.
//! \param test Predicate function: `bool(const T&)`.
//! \param start Starting index (negative values count from the end). Default 0.
//! \return Index if found, -1 otherwise.
//! \sa PIVector::indexWhere()
inline ssize_t indexWhere(std::function<bool(const T & e)> test, ssize_t start = 0) const {
if (start < 0) start = 0;
@@ -334,9 +304,9 @@ public:
}
//! \~english Returns the last index where the predicate `test` returns true, searching backwards from `start`.
//! \~russian Возвращает последний индекс, для которого предикат `test` возвращает true, выполняя поиск в обратном направлении от
//! `start`. \param test Predicate function: `bool(const T&)`. \param start Starting index (negative values count from the end).
//! Default -1. \return Index if found, -1 otherwise. \sa PIVector::lastIndexWhere()
//! \~russian Возвращает последний индекс, для которого предикат `test` возвращает true,
//! выполняя поиск в обратном направлении от `start`.
//! \sa PIVector::lastIndexWhere()
inline ssize_t lastIndexWhere(std::function<bool(const T & e)> test, ssize_t start = -1) const {
ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start;
for (ssize_t i = from; i >= 0; --i) {
@@ -360,7 +330,6 @@ public:
//! \~english Applies a function to each element of the row (read-only).
//! \~russian Применяет функцию к каждому элементу строки (только чтение).
//! \param func Function that takes a const reference to T.
//! \details
//! \~english The function can't modify the elements.
//! \~russian Функция не может изменять элементы.
@@ -373,7 +342,6 @@ public:
//! \~english Fills the row with copies of `value`.
//! \~russian Заполняет строку копиями `value`.
//! \param value Value to fill with.
//! \sa PIVector::fill()
inline void fill(const T & value) {
for (size_t i = 0; i < sz_; ++i) {
@@ -383,17 +351,11 @@ public:
//! \~english Checks if the row contains the element `e`.
//! \~russian Проверяет, содержит ли строка элемент `e`.
//! \param e Element to check.
//! \param start Starting index (negative allowed). Default 0.
//! \return \c true if found, \c false otherwise.
//! \sa PIVector::contains()
inline bool contains(const T & e, ssize_t start = 0) const { return indexOf(e, start) != -1; }
//! \~english Counts occurrences of `e` in the row.
//! \~russian Подсчитывает количество вхождений `e` в строке.
//! \param e Element to count.
//! \param start Starting index (negative allowed). Default 0.
//! \return Number of occurrences.
//! \sa PIVector::entries()
inline int entries(const T & e, ssize_t start = 0) const {
if (start < 0) start = 0;
@@ -406,9 +368,6 @@ public:
//! \~english Counts elements in the row that pass the `test`.
//! \~russian Подсчитывает элементы в строке, проходящие `test`.
//! \param test Predicate function.
//! \param start Starting index (negative allowed). Default 0.
//! \return Count of matching elements.
//! \sa PIVector::entries(std::function)
inline int entries(std::function<bool(const T & e)> test, ssize_t start = 0) const {
if (start < 0) start = 0;
@@ -421,8 +380,6 @@ public:
//! \~english Tests if any element in the row passes the `test`.
//! \~russian Проверяет, проходит ли какой-либо элемент в строке `test`.
//! \param test Predicate function.
//! \return \c true if at least one element satisfies the predicate.
//! \sa PIVector::any()
inline bool any(std::function<bool(const T & e)> test) const {
for (size_t i = 0; i < sz_; ++i) {
@@ -433,8 +390,6 @@ public:
//! \~english Tests if all elements in the row pass the `test`.
//! \~russian Проверяет, проходят ли все элементы в строке `test`.
//! \param test Predicate function.
//! \return \c true if all elements satisfy the predicate.
//! \sa PIVector::every()
inline bool every(std::function<bool(const T & e)> test) const {
for (size_t i = 0; i < sz_; ++i) {
@@ -472,7 +427,6 @@ public:
//! \~english Accesses the element at the given row index within the column.
//! \~russian Доступ к элементу по заданному индексу строки в столбце.
//! \param index Row index.
//! \return Reference to the element.
inline T & operator[](size_t index) { return (*p_)[index * step_ + col_]; }
@@ -482,8 +436,6 @@ public:
//! \~english Returns a pointer to the column data starting at an optional row offset.
//! \~russian Возвращает указатель на данные столбца, начиная с опционального смещения по строкам.
//! \param index Row offset (default 0).
//! \return Pointer to the element at the given row.
//! \details
//! \~english Note that column elements are not stored contiguously in memory, so this pointer cannot be used to iterate over the
//! whole column.
@@ -497,8 +449,6 @@ public:
//! \~english Assigns the contents of another Col to this column.
//! \~russian Присваивает этому столбцу содержимое другого столбца.
//! \param other Source column.
//! \return Reference to this column.
inline Col & operator=(const Col & other) {
if (p_ == other.p_ && col_ == other.col_) return *this;
const size_t sz = piMin<size_t>(sz_, other.sz_);
@@ -509,8 +459,6 @@ public:
//! \~english Assigns the contents of a \a PIVector to this column.
//! \~russian Присваивает этому столбцу содержимое \a PIVector.
//! \param other Source vector.
//! \return Reference to this column.
inline Col & operator=(const PIVector<T> & other) {
const size_t sz = piMin<size_t>(sz_, other.size());
for (size_t i = 0; i < sz; ++i)
@@ -520,7 +468,6 @@ public:
//! \~english Converts the column to a \a PIVector.
//! \~russian Преобразует столбец в \a PIVector.
//! \return A new \a PIVector containing a copy of the column elements.
inline PIVector<T> toVector() const {
PIVector<T> ret;
ret.reserve(sz_);
@@ -531,9 +478,6 @@ public:
//! \~english Returns the first index of element `e` in the row, starting from `start`.
//! \~russian Возвращает первый индекс элемента `e` в строке, начиная с позиции `start`.
//! \param e Element to search for.
//! \param start Starting index (negative values count from the end). Default 0.
//! \return Index if found, -1 otherwise.
//! \details
//! \~english See \a PIVector::indexOf() for details on negative start handling.
//! \~russian Подробнее об обработке отрицательного `start` см. \a PIVector::indexOf().
@@ -548,9 +492,6 @@ public:
//! \~english Returns the last index of element `e` in the row, searching backwards from `start`.
//! \~russian Возвращает последний индекс элемента `e` в строке, выполняя поиск в обратном направлении от `start`.
//! \param e Element to search for.
//! \param start Starting index (negative values count from the end). Default -1 (last element).
//! \return Index if found, -1 otherwise.
//! \sa PIVector::lastIndexOf()
inline ssize_t lastIndexOf(const T & e, ssize_t start = -1) const {
ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start;
@@ -562,9 +503,6 @@ public:
//! \~english Returns the first index where the predicate `test` returns true, starting from `start`.
//! \~russian Возвращает первый индекс, для которого предикат `test` возвращает true, начиная с `start`.
//! \param test Predicate function: `bool(const T&)`.
//! \param start Starting index (negative values count from the end). Default 0.
//! \return Index if found, -1 otherwise.
//! \sa PIVector::indexWhere()
inline ssize_t indexWhere(std::function<bool(const T & e)> test, ssize_t start = 0) const {
if (start < 0) start = 0;
@@ -575,9 +513,9 @@ public:
}
//! \~english Returns the last index where the predicate `test` returns true, searching backwards from `start`.
//! \~russian Возвращает последний индекс, для которого предикат `test` возвращает true, выполняя поиск в обратном направлении от
//! `start`. \param test Predicate function: `bool(const T&)`. \param start Starting index (negative values count from the end).
//! Default -1. \return Index if found, -1 otherwise. \sa PIVector::lastIndexWhere()
//! \~russian Возвращает последний индекс, для которого предикат `test` возвращает true,
//! выполняя поиск в обратном направлении от `start`.
//! \sa PIVector::lastIndexWhere()
inline ssize_t lastIndexWhere(std::function<bool(const T & e)> test, ssize_t start = -1) const {
ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start;
for (ssize_t i = from; i >= 0; --i) {
@@ -588,7 +526,6 @@ public:
//! \~english Applies a function to each element of the column (modifiable).
//! \~russian Применяет функцию к каждому элементу столбца (с возможностью изменения).
//! \param func Function that takes a reference to T.
//! \details
//! \~english The function can modify the elements.
//! \~russian Функция может изменять элементы.
@@ -601,7 +538,6 @@ public:
//! \~english Applies a function to each element of the column (read-only).
//! \~russian Применяет функцию к каждому элементу столбца (только чтение).
//! \param func Function that takes a const reference to T.
//! \details
//! \~english The function can't modify the elements.
//! \~russian Функция не может изменять элементы.
@@ -614,7 +550,6 @@ public:
//! \~english Fills the column with copies of `value`.
//! \~russian Заполняет столбец копиями `value`.
//! \param value Value to fill with.
//! \sa PIVector::fill()
inline void fill(const T & value) {
for (size_t i = 0; i < sz_; ++i) {
@@ -624,17 +559,11 @@ public:
//! \~english Checks if the column contains the element `e`.
//! \~russian Проверяет, содержит ли столбец элемент `e`.
//! \param e Element to check.
//! \param start Starting index (negative allowed). Default 0.
//! \return \c true if found, \c false otherwise.
//! \sa PIVector::contains()
inline bool contains(const T & e, ssize_t start = 0) const { return indexOf(e, start) != -1; }
//! \~english Counts occurrences of `e` in the column.
//! \~russian Подсчитывает количество вхождений `e` в столбце.
//! \param e Element to count.
//! \param start Starting index (negative allowed). Default 0.
//! \return Number of occurrences.
//! \sa PIVector::entries()
inline int entries(const T & e, ssize_t start = 0) const {
if (start < 0) start = 0;
@@ -647,9 +576,6 @@ public:
//! \~english Counts elements in the column that pass the `test`.
//! \~russian Подсчитывает элементы в столбце, проходящие `test`.
//! \param test Predicate function.
//! \param start Starting index (negative allowed). Default 0.
//! \return Count of matching elements.
//! \sa PIVector::entries(std::function)
inline int entries(std::function<bool(const T & e)> test, ssize_t start = 0) const {
if (start < 0) start = 0;
@@ -662,8 +588,6 @@ public:
//! \~english Tests if any element in the column passes the `test`.
//! \~russian Проверяет, проходит ли какой-либо элемент в столбце `test`.
//! \param test Predicate function.
//! \return \c true if at least one element satisfies the predicate.
//! \sa PIVector::any()
inline bool any(std::function<bool(const T & e)> test) const {
for (size_t i = 0; i < sz_; ++i) {
@@ -674,8 +598,6 @@ public:
//! \~english Tests if all elements in the column pass the `test`.
//! \~russian Проверяет, проходят ли все элементы в столбце `test`.
//! \param test Predicate function.
//! \return \c true if all elements satisfy the predicate.
//! \sa PIVector::every()
inline bool every(std::function<bool(const T & e)> test) const {
for (size_t i = 0; i < sz_; ++i) {
@@ -728,9 +650,6 @@ public:
//! \~english Returns the first index of element `e` in the row, starting from `start`.
//! \~russian Возвращает первый индекс элемента `e` в строке, начиная с позиции `start`.
//! \param e Element to search for.
//! \param start Starting index (negative values count from the end). Default 0.
//! \return Index if found, -1 otherwise.
//! \details
//! \~english See \a PIVector::indexOf() for details on negative start handling.
//! \~russian Подробнее об обработке отрицательного `start` см. \a PIVector::indexOf().
@@ -745,8 +664,6 @@ public:
//! \~english Returns the last index of element `e` in the row, searching backwards from `start`.
//! \~russian Возвращает последний индекс элемента `e` в строке, выполняя поиск в обратном направлении от `start`.
//! \param e Element to search for.
//! \param start Starting index (negative values count from the end). Default -1 (last element).
//! \return Index if found, -1 otherwise.
//! \sa PIVector::lastIndexOf()
inline ssize_t lastIndexOf(const T & e, ssize_t start = -1) const {
@@ -759,9 +676,6 @@ public:
//! \~english Returns the first index where the predicate `test` returns true, starting from `start`.
//! \~russian Возвращает первый индекс, для которого предикат `test` возвращает true, начиная с `start`.
//! \param test Predicate function: `bool(const T&)`.
//! \param start Starting index (negative values count from the end). Default 0.
//! \return Index if found, -1 otherwise.
//! \sa PIVector::indexWhere()
inline ssize_t indexWhere(std::function<bool(const T & e)> test, ssize_t start = 0) const {
if (start < 0) start = 0;
@@ -772,9 +686,9 @@ public:
}
//! \~english Returns the last index where the predicate `test` returns true, searching backwards from `start`.
//! \~russian Возвращает последний индекс, для которого предикат `test` возвращает true, выполняя поиск в обратном направлении от
//! `start`. \param test Predicate function: `bool(const T&)`. \param start Starting index (negative values count from the end).
//! Default -1. \return Index if found, -1 otherwise. \sa PIVector::lastIndexWhere()
//! \~russian Возвращает последний индекс, для которого предикат `test` возвращает true,
//! выполняя поиск в обратном направлении от `start`.
//! \sa PIVector::lastIndexWhere()
inline ssize_t lastIndexWhere(std::function<bool(const T & e)> test, ssize_t start = -1) const {
ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start;
for (ssize_t i = from; i >= 0; --i) {
@@ -785,7 +699,6 @@ public:
//! \~english Applies a function to each element of the row (read-only).
//! \~russian Применяет функцию к каждому элементу строки (только чтение).
//! \param func Function that takes a const reference to T.
//! \details
//! \~english The function can't modify the elements.
//! \~russian Функция не может изменять элементы.
@@ -798,17 +711,11 @@ public:
//! \~english Checks if the row contains the element `e`.
//! \~russian Проверяет, содержит ли строка элемент `e`.
//! \param e Element to check.
//! \param start Starting index (negative allowed). Default 0.
//! \return \c true if found, \c false otherwise.
//! \sa PIVector::contains()
inline bool contains(const T & e, ssize_t start = 0) const { return indexOf(e, start) != -1; }
//! \~english Counts occurrences of `e` in the row.
//! \~russian Подсчитывает количество вхождений `e` в строке.
//! \param e Element to count.
//! \param start Starting index (negative allowed). Default 0.
//! \return Number of occurrences.
//! \sa PIVector::entries()
inline int entries(const T & e, ssize_t start = 0) const {
if (start < 0) start = 0;
@@ -821,9 +728,6 @@ public:
//! \~english Counts elements in the row that pass the `test`.
//! \~russian Подсчитывает элементы в строке, проходящие `test`.
//! \param test Predicate function.
//! \param start Starting index (negative allowed). Default 0.
//! \return Count of matching elements.
//! \sa PIVector::entries(std::function)
inline int entries(std::function<bool(const T & e)> test, ssize_t start = 0) const {
if (start < 0) start = 0;
@@ -836,8 +740,6 @@ public:
//! \~english Tests if any element in the row passes the `test`.
//! \~russian Проверяет, проходит ли какой-либо элемент в строке `test`.
//! \param test Predicate function.
//! \return \c true if at least one element satisfies the predicate.
//! \sa PIVector::any()
inline bool any(std::function<bool(const T & e)> test) const {
for (size_t i = 0; i < sz_; ++i) {
@@ -848,8 +750,6 @@ public:
//! \~english Tests if all elements in the row pass the `test`.
//! \~russian Проверяет, проходят ли все элементы в строке `test`.
//! \param test Predicate function.
//! \return \c true if all elements satisfy the predicate.
//! \sa PIVector::every()
inline bool every(std::function<bool(const T & e)> test) const {
for (size_t i = 0; i < sz_; ++i) {
@@ -910,9 +810,6 @@ public:
//! \~english Returns the first index of element `e` in the row, starting from `start`.
//! \~russian Возвращает первый индекс элемента `e` в строке, начиная с позиции `start`.
//! \param e Element to search for.
//! \param start Starting index (negative values count from the end). Default 0.
//! \return Index if found, -1 otherwise.
//! \details
//! \~english See \a PIVector::indexOf() for details on negative start handling.
//! \~russian Подробнее об обработке отрицательного `start` см. \a PIVector::indexOf().
@@ -927,9 +824,6 @@ public:
//! \~english Returns the last index of element `e` in the row, searching backwards from `start`.
//! \~russian Возвращает последний индекс элемента `e` в строке, выполняя поиск в обратном направлении от `start`.
//! \param e Element to search for.
//! \param start Starting index (negative values count from the end). Default -1 (last element).
//! \return Index if found, -1 otherwise.
//! \sa PIVector::lastIndexOf()
inline ssize_t lastIndexOf(const T & e, ssize_t start = -1) const {
ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start;
@@ -941,9 +835,6 @@ public:
//! \~english Returns the first index where the predicate `test` returns true, starting from `start`.
//! \~russian Возвращает первый индекс, для которого предикат `test` возвращает true, начиная с `start`.
//! \param test Predicate function: `bool(const T&)`.
//! \param start Starting index (negative values count from the end). Default 0.
//! \return Index if found, -1 otherwise.
//! \sa PIVector::indexWhere()
inline ssize_t indexWhere(std::function<bool(const T & e)> test, ssize_t start = 0) const {
if (start < 0) start = 0;
@@ -954,9 +845,9 @@ public:
}
//! \~english Returns the last index where the predicate `test` returns true, searching backwards from `start`.
//! \~russian Возвращает последний индекс, для которого предикат `test` возвращает true, выполняя поиск в обратном направлении от
//! `start`. \param test Predicate function: `bool(const T&)`. \param start Starting index (negative values count from the end).
//! Default -1. \return Index if found, -1 otherwise. \sa PIVector::lastIndexWhere()
//! \~russian Возвращает последний индекс, для которого предикат `test` возвращает true,
//! выполняя поиск в обратном направлении от `start`.
//! \sa PIVector::lastIndexWhere()
inline ssize_t lastIndexWhere(std::function<bool(const T & e)> test, ssize_t start = -1) const {
ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start;
for (ssize_t i = from; i >= 0; --i) {
@@ -967,7 +858,6 @@ public:
//! \~english Applies a function to each element of the column (read-only).
//! \~russian Применяет функцию к каждому элементу столбца (только чтение).
//! \param func Function that takes a const reference to T.
//! \details
//! \~english The function can't modify the elements.
//! \~russian Функция не может изменять элементы.
@@ -980,17 +870,11 @@ public:
//! \~english Checks if the column contains the element `e`.
//! \~russian Проверяет, содержит ли столбец элемент `e`.
//! \param e Element to check.
//! \param start Starting index (negative allowed). Default 0.
//! \return \c true if found, \c false otherwise.
//! \sa PIVector::contains()
inline bool contains(const T & e, ssize_t start = 0) const { return indexOf(e, start) != -1; }
//! \~english Counts occurrences of `e` in the column.
//! \~russian Подсчитывает количество вхождений `e` в столбце.
//! \param e Element to count.
//! \param start Starting index (negative allowed). Default 0.
//! \return Number of occurrences.
//! \sa PIVector::entries()
inline int entries(const T & e, ssize_t start = 0) const {
if (start < 0) start = 0;
@@ -1003,9 +887,6 @@ public:
//! \~english Counts elements in the column that pass the `test`.
//! \~russian Подсчитывает элементы в столбце, проходящие `test`.
//! \param test Predicate function.
//! \param start Starting index (negative allowed). Default 0.
//! \return Count of matching elements.
//! \sa PIVector::entries(std::function)
inline int entries(std::function<bool(const T & e)> test, ssize_t start = 0) const {
if (start < 0) start = 0;
@@ -1018,8 +899,6 @@ public:
//! \~english Tests if any element in the column passes the `test`.
//! \~russian Проверяет, проходит ли какой-либо элемент в столбце `test`.
//! \param test Predicate function.
//! \return \c true if at least one element satisfies the predicate.
//! \sa PIVector::any()
inline bool any(std::function<bool(const T & e)> test) const {
for (size_t i = 0; i < sz_; ++i) {
@@ -1030,8 +909,6 @@ public:
//! \~english Tests if all elements in the column pass the `test`.
//! \~russian Проверяет, проходят ли все элементы в столбце `test`.
//! \param test Predicate function.
//! \return \c true if all elements satisfy the predicate.
//! \sa PIVector::every()
inline bool every(std::function<bool(const T & e)> test) const {
for (size_t i = 0; i < sz_; ++i) {
@@ -1043,9 +920,6 @@ public:
//! \~english Returns a reference to the element at the given row and column.
//! \~russian Возвращает ссылку на элемент по заданной строке и столбцу.
//! \param row Row index.
//! \param col Column index.
//! \return Reference to the element.
//! \details
//! \~english No bounds checking is performed.
//! \~russian Проверка границ не выполняется.
@@ -1062,8 +936,6 @@ public:
//! \~english Returns a proxy object for the row at the given index for modification.
//! \~russian Возвращает прокси-объект для строки по заданному индексу для модификации.
//! \param index Row index.
//! \return Row proxy.
//! \sa row(), Col
inline Row operator[](size_t index) { return Row(this, index); }
@@ -1073,8 +945,6 @@ public:
//! \~english Returns a pointer to the underlying flat data starting at an optional offset.
//! \~russian Возвращает указатель на внутренние плоские данные, начиная с опционального смещения.
//! \param index Flat index offset.
//! \return Pointer to data.
//! \sa PIVector::data()
inline T * data(size_t index = 0) { return mat.data(index); }
@@ -1094,8 +964,6 @@ public:
//! \~english Returns a proxy object for the column at the given index for modification.
//! \~russian Возвращает прокси-объект для столбца по заданному индексу для модификации.
//! \param index Column index.
//! \return Column proxy.
//! \sa col() const
inline Col col(size_t index) { return Col(this, index); }
@@ -1103,18 +971,6 @@ public:
//! \~russian Возвращает прокси-объект для столбца по заданному индексу только для чтения.
inline ColConst col(size_t index) const { return ColConst(this, index); }
//! \~english Replaces a row with the contents of another Row object.
//! \~russian Заменяет строку содержимым другого объекта Row.
//! \param row Row index.
//! \param other Source row.
//! \return Reference to this 2D array.
inline PIVector2D<T> & setRow(size_t row, const Row & other) {
const size_t sz = piMin<size_t>(cols_, other.sz_);
mat._copyRaw(mat.data(cols_ * row), other.data(), sz);
return *this;
}
//! \~english Replaces a row with the contents of a read-only RowConst object.
//! \~russian Заменяет строку содержимым объекта RowConst только для чтения.
inline PIVector2D<T> & setRow(size_t row, const RowConst & other) {
@@ -1133,8 +989,6 @@ public:
//! \~english Appends a new row to the bottom of the array from another Row object.
//! \~russian Добавляет новую строку в конец массива из другого объекта Row.
//! \param other Source row.
//! \return Reference to this array.
//! \details
//! \~english If the array was empty, its column count is set to the size of the source row.
//! Otherwise, only `min(cols(), other.size())` elements are copied; the rest of the new row is default-initialized.
@@ -1163,8 +1017,8 @@ public:
return *this;
}
//! \~english Appends a new column to the right of the array from a \a PIVector.
//! \~russian Добавляет новую строку в конец массива из \a PIVector.
//! \~english Appends a new column to the right of the array from a \a ColConst.
//! \~russian Добавляет новую строку в конец массива из \a ColConst.
inline PIVector2D<T> & addColumn(const ColConst & other) {
if (other.size() == 0) return *this;
if (size() == 0) {
@@ -1186,17 +1040,20 @@ public:
T * dst = mat.data(r * newCols);
memmove(dst, src, oldCols * sizeof(T));
if (r < other.size()) {
dst[oldCols] = other[r];
mat._copyRaw(&(dst[oldCols]), &(other[r]), 1);
} else {
dst[oldCols] = T();
const T tmp = T();
mat._copyRaw(&(dst[oldCols]), &tmp, 1);
}
}
mat[oldCols] = other[0];
mat._copyRaw(mat.data(oldCols), &(other[0]), 1);
cols_ = newCols;
cols_ = newCols;
return *this;
}
//! \~english Appends a new column to the right of the array from a \a PIVector.
//! \~russian Добавляет новую строку в конец массива из \a PIVector.
inline PIVector2D<T> & addColumn(const PIVector<T> & other) {
if (other.size() == 0) return *this;
if (size() == 0) {
@@ -1218,23 +1075,20 @@ public:
T * dst = mat.data(r * newCols);
memmove(dst, src, oldCols * sizeof(T));
if (r < other.size()) {
dst[oldCols] = other[r];
mat._copyRaw(&(dst[oldCols]), &(other[r]), 1);
} else {
dst[oldCols] = T();
const T tmp = T();
mat._copyRaw(&(dst[oldCols]), &tmp, 1);
}
}
mat[oldCols] = other[0];
mat._copyRaw(mat.data(oldCols), &(other[0]), 1);
cols_ = newCols;
cols_ = newCols;
return *this;
}
//! \~english Resizes the 2D array to new dimensions.
//! \~russian Изменяет размер двумерного массива.
//! \param rows New number of rows.
//! \param cols New number of columns.
//! \param f Value to fill newly created elements (if growing). Defaults to default-constructed T.
//! \return Reference to this array.
//! \details
//! \~english If the new dimensions are larger, new elements are appended and filled with copies of `f`.
//! If they are smaller, the array is truncated (excess elements are destroyed). The underlying memory may be reallocated.
@@ -1261,8 +1115,6 @@ public:
//! \~english Equality operator.
//! \~russian Оператор равенства.
//! \param t Another 2D array.
//! \return \c true if both arrays have the same dimensions and all elements are equal.
//! \sa PIVector::operator==
inline bool operator==(const PIVector2D<T> & t) const {
if (cols_ != t.cols_ || rows_ != t.rows_) return false;
@@ -1275,7 +1127,6 @@ public:
//! \~english Converts the 2D array to a vector of vectors (PIVector<PIVector<T>>).
//! \~russian Преобразует двумерный массив в вектор векторов (PIVector<PIVector<T>>).
//! \return A new vector where each element is a \a PIVector representing a row.
//! \details
//! \~english Each row vector is a copy of the corresponding row.
//! \~russian Каждый вектор-строка является копией соответствующей строки.
@@ -1302,7 +1153,6 @@ public:
//! \~english Swaps this 2D array with another.
//! \~russian Меняет местами этот двумерный массив с другим.
//! \param other Another array.
//! \details
//! \~english Swaps the flat vectors and the dimension members. Very fast, no memory allocation.
//! \~russian Обменивает внутренние плоские векторы и члены, хранящие размеры. Очень быстро, без выделения памяти.
@@ -1336,39 +1186,25 @@ public:
//! \~english Checks if the underlying flat vector contains the element `e`.
//! \~russian Проверяет, содержит ли внутренний плоский вектор элемент `e`.
//! \param e Element to check.
//! \param start Starting index (negative allowed). Default 0.
//! \return \c true if found, \c false otherwise.
//! \sa PIVector::contains()
inline bool contains(const T & e, ssize_t start = 0) const { return mat.contains(e, start); }
//! \~english Checks if the underlying flat vector contains all elements of `v`.
//! \~russian Проверяет, содержит ли внутренний плоский вектор все элементы `v`.
//! \param e Element to check.
//! \param start Starting index (negative allowed). Default 0.
//! \return \c true if found, \c false otherwise.
//! \sa PIVector::contains(const PIVector&)
inline bool contains(const PIVector<T> & v, ssize_t start = 0) const { return mat.contains(v, start); }
inline bool contains(const T & e) const { return mat.contains(e); }
//! \~english Counts occurrences of `e` in the underlying flat vector.
//! \~russian Подсчитывает количество вхождений `e` во внутреннем плоском векторе.
//! \sa PIVector::entries()
inline int entries(const T & e, ssize_t start = 0) const { return mat.entries(e, start); }
inline int entries(const T & e) const { return mat.entries(e); }
//! \~english Counts elements in the flat vector that pass the `test`.
//! \~russian Подсчитывает элементы в плоском векторе, проходящие `test`.
//! \sa PIVector::entries(std::function)
inline int entries(std::function<bool(const T & e)> test, ssize_t start = 0) const { return mat.entries(test, start); }
inline int entries(std::function<bool(const T & e)> test) const { return mat.entries(test); }
//! \~english Returns the first index (row, col) of `e` in the 2D array.
//! \~russian Возвращает первый индекс (строка, столбец) элемента `e` в двумерном массиве.
//! \param e Element to search for.
//! \param start Starting flat index (negative allowed). Default 0.
//! \return A \a PIPair<ssize_t, ssize_t> where first is row, second is column. If not found, both are -1.
//! \sa PIVector::indexOf()
inline PIPair<ssize_t, ssize_t> indexOf(const T & e, ssize_t start = 0) const {
ssize_t flat = mat.indexOf(e, start);
inline PIPair<ssize_t, ssize_t> indexOf(const T & e) const {
ssize_t flat = mat.indexOf(e);
if (flat < 0 || cols_ == 0) return PIPair<ssize_t, ssize_t>(-1, -1);
return PIPair<ssize_t, ssize_t>(flat / cols_, flat % cols_);
}
@@ -1413,7 +1249,6 @@ public:
//! \~english Fills the entire 2D array with copies of `e`.
//! \~russian Заполняет весь двумерный массив копиями `e`.
//! \return Reference to this array.
//! \sa PIVector::fill()
inline PIVector2D<T> & fill(const T & e = T()) {
mat.fill(e);
@@ -1422,8 +1257,6 @@ public:
//! \~english Fills the entire 2D array using a generator function `f` based on flat index.
//! \~russian Заполняет весь двумерный массив, используя функцию-генератор `f` на основе плоского индекса.
//! \param f Function taking a size_t flat index and returning a value of type T.
//! \return Reference to this array.
//! \sa PIVector::fill(std::function)
inline PIVector2D<T> & fill(std::function<T(size_t i)> f) {
mat.fill(f);
@@ -1447,7 +1280,6 @@ public:
//! \~english Returns a transposed 2D array (rows become columns and vice versa).
//! \~russian Возвращает транспонированный двумерный массив (строки становятся столбцами и наоборот).
//! \return A new 2D array with dimensions (cols, rows).
//! \details
//! \~english The element at (r, c) in the original becomes at (c, r) in the result.
//! \~russian Элемент (r, c) исходного массива становится элементом (c, r) в результате.
@@ -1468,7 +1300,6 @@ public:
//! \~english Reverses the order of rows in place.
//! \~russian Изменяет порядок строк на обратный на месте.
//! \return Reference to this array.
//! \sa reverseColumns(), PIVector::reverse()
inline PIVector2D<T> & reverseRows() {
const size_t half = rows_ / 2;
@@ -1484,7 +1315,6 @@ public:
//! \~english Reverses the order of columns in each row in place.
//! \~russian Изменяет порядок столбцов в каждой строке на обратный на месте.
//! \return Reference to this array.
//! \sa reverseRows(), PIVector::reverse()
inline PIVector2D<T> & reverseColumns() {
for (size_t r = 0; r < rows_; ++r) {
@@ -1499,19 +1329,14 @@ public:
//! \~english Returns a sub-2D array (a range of rows and columns).
//! \~russian Возвращает подмассив (диапазон строк и столбцов).
//! \param rowStart Starting row index.
//! \param rowCount Number of rows to take.
//! \param colStart Starting column index.
//! \param colCount Number of columns to take.
//! \return A new 2D array containing the specified range.
//! \details
//! \~english If the range exceeds the array boundaries, it is clipped. If rowCount or colCount is 0, an empty array is returned.
//! \~russian Если диапазон выходит за границы массива, он обрезается. Если rowCount или colCount равны 0, возвращается пустой массив.
//! \sa PIVector::getRange()
inline PIVector2D<T> getRange(size_t rowStart, size_t rowCount, size_t colStart, size_t colCount) const {
if (rowStart >= rows_ || colStart >= cols_ || rowCount == 0 || colCount == 0) return PIVector2D<T>();
size_t actualRowCount = piMin(rowCount, rows_ - rowStart);
size_t actualColCount = piMin(colCount, cols_ - colStart);
size_t actualRowCount = piMin<size_t>(rowCount, rows_ - rowStart);
size_t actualColCount = piMin<size_t>(colCount, cols_ - colStart);
PIVector2D<T> result(actualRowCount, actualColCount);
for (size_t r = 0; r < actualRowCount; ++r) {
@@ -1524,9 +1349,6 @@ public:
//! \~english Applies a function to each element and returns a new 2D array of a different type.
//! \~russian Применяет функцию к каждому элементу и возвращает новый двумерный массив другого типа.
//! \tparam ST Target element type.
//! \param f Mapping function: `ST(const T&)`.
//! \return A new \a PIVector2D<ST> with the same dimensions.
//! \details
//! \~english The original array is not modified.
//! \~russian Исходный массив не изменяется.
@@ -1538,9 +1360,6 @@ public:
//! \~english Applies a function (with row and col indices) to each element and returns a new 2D array.
//! \~russian Применяет функцию (с индексами строки и столбца) к каждому элементу и возвращает новый двумерный массив.
//! \tparam ST Target element type.
//! \param f Function: `ST(size_t row, size_t col, const T&)`.
//! \return A new \a PIVector2D<ST>.
//! \sa PIVector::mapIndexed()
template<typename ST>
inline PIVector2D<ST> mapIndexed(std::function<ST(size_t row, size_t col, const T & e)> f) const {
@@ -1556,8 +1375,6 @@ public:
//! \~english Applies a function to each row (modifiable).
//! \~russian Применяет функцию к каждой строке (с возможностью изменения).
//! \param f Function taking a \a Row.
//! \return Reference to this array.
//! \sa forEachRow() const, PIVector::forEach()
inline PIVector2D<T> & forEachRow(std::function<void(Row)> f) {
for (size_t r = 0; r < rows_; ++r)
@@ -1567,7 +1384,6 @@ public:
//! \~english Applies a function to each row (read-only).
//! \~russian Применяет функцию к каждой строке (только чтение).
//! \param f Function taking a \a RowConst.
inline void forEachRow(std::function<void(RowConst)> f) const {
for (size_t r = 0; r < rows_; ++r)
f(row(r));
@@ -1575,8 +1391,6 @@ public:
//! \~english Applies a function to each column (modifiable).
//! \~russian Применяет функцию к каждому столбцу (с возможностью изменения).
//! \param f Function taking a \a Col.
//! \return Reference to this array.
inline PIVector2D<T> & forEachColumn(std::function<void(Col)> f) {
for (size_t c = 0; c < cols_; ++c)
f(col(c));
@@ -1593,10 +1407,6 @@ public:
//! \~english Accumulates a value across all elements.
//! \~russian Аккумулирует значение по всем элементам.
//! \tparam ST Accumulator type.
//! \param f Reduction function: `ST(const T&, const ST&)`.
//! \param initial Initial accumulator value. Defaults to default-constructed ST.
//! \return The accumulated result.
//! \sa PIVector::reduce()
template<typename ST>
inline ST reduce(std::function<ST(const T & e, const ST & acc)> f, const ST & initial = ST()) const {
@@ -1605,10 +1415,6 @@ public:
//! \~english Accumulates a value across all elements with indices.
//! \~russian Аккумулирует значение по всем элементам с индексами.
//! \tparam ST Accumulator type.
//! \param f Function: `ST(size_t row, size_t col, const T&, const ST&)`.
//! \param initial Initial accumulator value.
//! \return The accumulated result.
//! \sa PIVector::reduceIndexed()
template<typename ST>
inline ST reduceIndexed(std::function<ST(size_t row, size_t col, const T & e, const ST & acc)> f, const ST & initial = ST()) const {
@@ -1623,8 +1429,6 @@ public:
//! \~english Removes a row from the 2D array.
//! \~russian Удаляет строку из двумерного массива.
//! \param row Index of row to remove (must be less than rows()).
//! \return Reference to this array.
//! \details
//! \~english The elements of the specified row are destroyed, and all subsequent rows are shifted up.
//! If the last row is removed and the array becomes empty, \a cols() is set to 0.
@@ -1633,8 +1437,7 @@ public:
//! \sa removeColumn(), PIVector::remove()
inline PIVector2D<T> & removeRow(size_t row) {
if (row >= rows_) return *this;
size_t startIdx = row * cols_;
mat.remove(startIdx, cols_);
mat.remove(row * cols_, cols_);
rows_--;
if (rows_ == 0) cols_ = 0;
return *this;
@@ -1642,8 +1445,6 @@ public:
//! \~english Removes a column from the 2D array.
//! \~russian Удаляет столбец из двумерного массива.
//! \param col Index of column to remove (must be less than cols()).
//! \return Reference to this array.
//! \details
//! \~english This operation is more expensive than removing a row because elements must be moved.
//! \~russian Эта операция дороже, чем удаление строки, поскольку требуется перемещение элементов.
@@ -1663,35 +1464,29 @@ public:
//! \~english Removes all rows that satisfy a condition.
//! \~russian Удаляет все строки, удовлетворяющие условию.
//! \param test Predicate taking a \a RowConst.
//! \return Reference to this array.
//! \details
//! \~english Rows are removed from the bottom to avoid index shifting issues.
//! \~russian Строки удаляются снизу вверх, чтобы избежать проблем со смещением индексов.
//! \sa removeColumnsWhere(), PIVector::removeWhere()
inline PIVector2D<T> & removeRowsWhere(std::function<bool(const RowConst &)> test) {
ssize_t r = rows_ - 1;
while (r >= 0) {
ssize_t r = rows_;
while (--r >= 0) {
if (test(RowConst(this, r))) {
removeRow(r);
}
--r;
}
return *this;
}
//! \~english Removes all columns that satisfy a condition.
//! \~russian Удаляет все столбцы, удовлетворяющие условию.
//! \param test Predicate taking a \a ColConst.
//! \return Reference to this array.
//! \sa removeRowsWhere()
inline PIVector2D<T> & removeColumnsWhere(std::function<bool(const ColConst &)> test) {
ssize_t c = cols_ - 1;
while (c >= 0) {
ssize_t c = cols_;
while (--c >= 0) {
if (test(ColConst(this, c))) {
removeColumn(c);
}
--c;
}
return *this;
}
@@ -1699,8 +1494,6 @@ public:
//! \~english Returns a new 2D array containing only the rows that pass the test.
//! \~russian Возвращает новый двумерный массив, содержащий только строки, прошедшие проверку.
//! \param test Predicate taking a \a RowConst.
//! \return Filtered array.
//! \sa filterColumns(), PIVector::filter()
inline PIVector2D<T> filterRows(std::function<bool(const RowConst &)> test) const {
PIVector2D<T> result;
@@ -1715,8 +1508,6 @@ public:
//! \~english Returns a new 2D array containing only the columns that pass the test.
//! \~russian Возвращает новый двумерный массив, содержащий только столбцы, прошедшие проверку.
//! \param test Predicate taking a \a ColConst.
//! \return Filtered array.
//! \sa filterRows()
inline PIVector2D<T> filterColumns(std::function<bool(const ColConst &)> test) const {
if (isEmpty()) return PIVector2D<T>();
@@ -1735,13 +1526,6 @@ public:
return result;
}
//! \~english Returns a new plain array containing only the elements that pass the test.
//! \~russian Возвращает новый одноменый массив, содержащий только элементы, прошедшие проверку.
//! \param test Predicate taking a const T&.
//! \return PIVector<T> with the filtered elements (or empty).
//! \sa PIVector::filter()
inline PIVector<T> filterElements(std::function<bool(const T &)> test) const { return mat.filter(test); }
protected:
size_t rows_, cols_;
PIVector<T> mat;