From 1b5a3591854395a0d3038420f0c1d2722feaeaca Mon Sep 17 00:00:00 2001 From: "andrey.bychkov" Date: Fri, 27 Feb 2026 19:21:24 +0300 Subject: [PATCH] fix filterColumns and Doxygen comments --- libs/main/containers/pivector2d.h | 223 ++++++++++++++++++------------ plans/doxygen_example.md | 2 + 2 files changed, 137 insertions(+), 88 deletions(-) diff --git a/libs/main/containers/pivector2d.h b/libs/main/containers/pivector2d.h index e8191aa4..f1b019ea 100644 --- a/libs/main/containers/pivector2d.h +++ b/libs/main/containers/pivector2d.h @@ -55,13 +55,28 @@ public: //! \~english Index structure for 2D array elements (row, column). //! \~russian Структура индекса для элементов двумерного массива (строка, столбец). struct Index { + //! \~english Row index in the 2D array. + //! \~russian Индекс строки в двумерном массиве. ssize_t row = -1; + //! \~english Column index in the 2D array. + //! \~russian Индекс столбца в двумерном массиве. ssize_t col = -1; + //! \~english Default constructor. Initializes row and col to -1 (invalid index). + //! \~russian Конструктор по умолчанию. Инициализирует row и col значениями -1 (некорректный индекс). inline Index() = default; + //! \~english Constructs an Index with the given row and column values. + //! \~russian Создаёт Index с заданными значениями строки и столбца. inline Index(ssize_t r, ssize_t c): row(r), col(c) {} + //! \~english Checks if the index is valid (both row and column are non-negative). + //! \~russian Проверяет, является ли индекс корректным (строка и столбец неотрицательны). + //! \~\sa isNotValid() inline bool isValid() const { return row >= 0 && col >= 0; } + + //! \~english Checks if the index is invalid (either row or column is negative). + //! \~russian Проверяет, является ли индекс некорректным (строка или столбец отрицательны). + //! \~\sa isValid() inline bool isNotValid() const { return !isValid(); } }; @@ -70,7 +85,7 @@ public: //! \details //! \~english After this constructor, \a rows() and \a cols() return 0, and \a isEmpty() returns true. //! \~russian После этого конструктора \a rows() и \a cols() возвращают 0, а \a isEmpty() возвращает true. - //! \sa PIVector::PIVector() + //! \~\sa PIVector::PIVector() inline PIVector2D() { rows_ = cols_ = 0; } //! \~english Constructs a 2D array with the given dimensions, filled with copies of `f`. @@ -80,7 +95,7 @@ public: //! All elements are initialized with the value `f`. //! \~russian Внутреннее хранилище представляет собой единый непрерывный блок памяти размером `rows * cols`. //! Все элементы инициализируются значением `f`. - //! \sa PIVector::PIVector(size_t, const T&) + //! \~\sa PIVector::PIVector(size_t, const T&) inline PIVector2D(size_t rows, size_t cols, const T & f = T()) { rows_ = rows; cols_ = cols; @@ -96,7 +111,7 @@ public: //! \~russian Конструктор копирует данные из `v` во внутренний плоский вектор. //! Если `v` больше, чем `rows * cols`, лишние элементы игнорируются (вектор обрезается). //! Если `v` меньше, остальные значения будут заполнены из конструктора по умолчанию T() - //! \sa PIVector::PIVector(const PIVector&), reshape() + //! \~\sa PIVector::PIVector(const PIVector&), reshape() inline PIVector2D(size_t rows, size_t cols, const PIVector & v): rows_(rows), cols_(cols), mat(v) { mat.resize(rows * cols); } //! \~english Move constructs a 2D array from an existing 1D vector, reshaping it. @@ -106,7 +121,7 @@ public: //! After construction, `v` is left in a valid but unspecified state. //! \~russian Данные перемещаются из `v` во внутренний плоский вектор, что позволяет избежать копирования. //! После завершения конструктора `v` остаётся в корректном, но неопределённом состоянии. - //! \sa PIVector::PIVector(PIVector&&) + //! \~\sa PIVector::PIVector(PIVector&&) inline PIVector2D(size_t rows, size_t cols, PIVector && v): rows_(rows), cols_(cols), mat(std::move(v)) { mat.resize(rows * cols); } //! \~english Constructs a 2D array from a vector of vectors (jagged array). Assumes all inner vectors have the same size. @@ -136,7 +151,7 @@ public: //! \details //! \~english The result is always non-negative. If the array is empty, returns 0. //! \~russian Результат всегда неотрицательный. Если массив пуст, возвращает 0. - //! \sa cols(), size(), PIVector::size() + //! \~\sa cols(), size(), PIVector::size() inline size_t rows() const { return rows_; } //! \~english Returns the number of columns in the 2D array. @@ -145,7 +160,7 @@ public: //! \details //! \~english The result is always non-negative. If the array is empty, returns 0. //! \~russian Результат всегда неотрицательный. Если массив пуст, возвращает 0. - //! \sa rows(), size(), PIVector::size() + //! \~\sa rows(), size(), PIVector::size() inline size_t cols() const { return cols_; } //! \~english Returns the total number of elements (`rows * cols`). @@ -154,19 +169,19 @@ public: //! \details //! \~english This is equivalent to the size of the underlying flat vector. //! \~russian Это эквивалентно размеру внутреннего плоского вектора. - //! \sa rows(), cols(), PIVector::size() + //! \~\sa rows(), cols(), PIVector::size() inline size_t size() const { return mat.size(); } //! \~english Returns the total number of elements as a signed value. //! \~russian Возвращает общее количество элементов в виде знакового числа. //! \return Signed size. - //! \sa size(), PIVector::size_s() + //! \~\sa size(), PIVector::size_s() inline ssize_t size_s() const { return mat.size_s(); } //! \~english Returns the total number of elements (same as \a size()). //! \~russian Возвращает общее количество элементов (то же, что и \a size()). //! \return Total number of elements. - //! \sa size(), PIVector::length() + //! \~\sa size(), PIVector::length() inline size_t length() const { return mat.length(); } //! \~english Returns the number of elements that the underlying container has currently allocated space for. @@ -184,13 +199,13 @@ public: //! \details //! \~english An empty array has both rows and columns equal to 0. //! \~russian Пустой массив имеет и строки, и столбцы равные 0. - //! \sa isNotEmpty(), PIVector::isEmpty() + //! \~\sa isNotEmpty(), PIVector::isEmpty() inline bool isEmpty() const { return mat.isEmpty(); } //! \~english Checks if the array has at least one element. //! \~russian Проверяет, не пуст ли массив. //! \return \c true if the array is not empty, \c false otherwise. - //! \sa isEmpty(), PIVector::isNotEmpty() + //! \~\sa isEmpty(), PIVector::isNotEmpty() inline bool isNotEmpty() const { return mat.isNotEmpty(); } class RowConst; @@ -206,7 +221,7 @@ public: //! \details //! \~english Returned by const \a operator[] or \a row(). Provides const access to row elements. //! \~russian Возвращается константными версиями \a operator[] или \a row(). Предоставляет константный доступ к элементам строки. - //! \sa Row, ColConst + //! \~\sa Row, ColConst class RowConst { friend class PIVector2D; @@ -216,6 +231,9 @@ public: const size_t st_, sz_; public: + //! \~english Copy constructor from modifiable Row to read-only RowConst. + //! \~russian Конструктор копирования из модифицируемого класса Row в константный RowConst. + //! \~\sa Row inline RowConst(const PIVector2D::Row & r): p_(r.p_), st_(r.st_), sz_(r.sz_) {} //! \~english Size of the row (number of columns). @@ -239,7 +257,7 @@ public: //! \details //! \~english See \a PIVector::indexOf() for details on negative start handling. //! \~russian Подробнее об обработке отрицательного `start` см. \a PIVector::indexOf(). - //! \sa PIVector::indexOf() + //! \~\sa PIVector::indexOf() inline ssize_t indexOf(const T & e, ssize_t start = 0) const { if (start < 0) start = 0; for (size_t i = (size_t)start; i < sz_; ++i) { @@ -251,7 +269,7 @@ public: //! \~english Returns the last index of element `e` in the row, searching backwards from `start`. //! \~russian Возвращает последний индекс элемента `e` в строке, выполняя поиск в обратном направлении от `start`. //! \return Index if found, -1 otherwise. - //! \sa PIVector::lastIndexOf() + //! \~\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; for (ssize_t i = from; i >= 0; --i) { @@ -262,7 +280,7 @@ public: //! \~english Returns the first index where the predicate `test` returns true, starting from `start`. //! \~russian Возвращает первый индекс, для которого предикат `test` возвращает true, начиная с `start`. - //! \sa PIVector::indexWhere() + //! \~\sa PIVector::indexWhere() inline ssize_t indexWhere(std::function test, ssize_t start = 0) const { if (start < 0) start = 0; for (size_t i = (size_t)start; i < sz_; ++i) { @@ -274,7 +292,7 @@ public: //! \~english Returns the last index where the predicate `test` returns true, searching backwards from `start`. //! \~russian Возвращает последний индекс, для которого предикат `test` возвращает true, //! выполняя поиск в обратном направлении от `start`. - //! \sa PIVector::lastIndexWhere() + //! \~\sa PIVector::lastIndexWhere() inline ssize_t lastIndexWhere(std::function 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) { @@ -288,7 +306,7 @@ public: //! \details //! \~english The function can't modify the elements. //! \~russian Функция не может изменять элементы. - //! \sa forEach (modifiable) + //! \~\sa forEach (modifiable) inline void forEach(std::function func) const { for (size_t i = 0; i < sz_; ++i) { func((*p_)[st_ + i]); @@ -297,12 +315,12 @@ public: //! \~english Checks if the row contains the element `e`. //! \~russian Проверяет, содержит ли строка элемент `e`. - //! \sa PIVector::contains() + //! \~\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` в строке. - //! \sa PIVector::entries() + //! \~\sa PIVector::entries() inline int entries(const T & e, ssize_t start = 0) const { if (start < 0) start = 0; int count = 0; @@ -314,7 +332,7 @@ public: //! \~english Counts elements in the row that pass the `test`. //! \~russian Подсчитывает элементы в строке, проходящие `test`. - //! \sa PIVector::entries(std::function) + //! \~\sa PIVector::entries(std::function) inline int entries(std::function test, ssize_t start = 0) const { if (start < 0) start = 0; int count = 0; @@ -326,7 +344,7 @@ public: //! \~english Tests if any element in the row passes the `test`. //! \~russian Проверяет, проходит ли какой-либо элемент в строке `test`. - //! \sa PIVector::any() + //! \~\sa PIVector::any() inline bool any(std::function test) const { for (size_t i = 0; i < sz_; ++i) { if (test((*p_)[st_ + i])) return true; @@ -336,7 +354,7 @@ public: //! \~english Tests if all elements in the row pass the `test`. //! \~russian Проверяет, проходят ли все элементы в строке `test`. - //! \sa PIVector::every() + //! \~\sa PIVector::every() inline bool every(std::function test) const { for (size_t i = 0; i < sz_; ++i) { if (!test((*p_)[st_ + i])) return false; @@ -353,7 +371,7 @@ public: //! \details //! \~english Returned by const \a col(). Provides const access to column elements. //! \~russian Возвращается константной версией \a col(). Предоставляет константный доступ к элементам столбца. - //! \sa Col, RowConst + //! \~\sa Col, RowConst class ColConst { friend class PIVector2D; @@ -363,6 +381,9 @@ public: const size_t step_, col_, sz_; public: + //! \~english Copy constructor from modifiable Col to read-only ColConst. + //! \~russian Конструктор копирования из модифицируемого класса Col в константный ColConst. + //! \~\sa Col inline ColConst(const PIVector2D::Col & c): p_(c.p_), step_(c.step_), col_(c.col_), sz_(c.sz_) {} //! \~english Size of the column (number of rows). @@ -392,7 +413,7 @@ public: //! \details //! \~english See \a PIVector::indexOf() for details on negative start handling. //! \~russian Подробнее об обработке отрицательного `start` см. \a PIVector::indexOf(). - //! \sa PIVector::indexOf() + //! \~\sa PIVector::indexOf() inline ssize_t indexOf(const T & e, ssize_t start = 0) const { if (start < 0) start = 0; for (size_t i = (size_t)start; i < sz_; ++i) { @@ -403,7 +424,7 @@ public: //! \~english Returns the last index of element `e` in the row, searching backwards from `start`. //! \~russian Возвращает последний индекс элемента `e` в строке, выполняя поиск в обратном направлении от `start`. - //! \sa PIVector::lastIndexOf() + //! \~\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; for (ssize_t i = from; i >= 0; --i) { @@ -414,7 +435,7 @@ public: //! \~english Returns the first index where the predicate `test` returns true, starting from `start`. //! \~russian Возвращает первый индекс, для которого предикат `test` возвращает true, начиная с `start`. - //! \sa PIVector::indexWhere() + //! \~\sa PIVector::indexWhere() inline ssize_t indexWhere(std::function test, ssize_t start = 0) const { if (start < 0) start = 0; for (size_t i = (size_t)start; i < sz_; ++i) { @@ -426,7 +447,7 @@ public: //! \~english Returns the last index where the predicate `test` returns true, searching backwards from `start`. //! \~russian Возвращает последний индекс, для которого предикат `test` возвращает true, //! выполняя поиск в обратном направлении от `start`. - //! \sa PIVector::lastIndexWhere() + //! \~\sa PIVector::lastIndexWhere() inline ssize_t lastIndexWhere(std::function 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) { @@ -440,7 +461,7 @@ public: //! \details //! \~english The function can't modify the elements. //! \~russian Функция не может изменять элементы. - //! \sa forEach (modifiable) + //! \~\sa forEach (modifiable) inline void forEach(std::function func) const { for (size_t i = 0; i < sz_; ++i) { func((*p_)[i * step_ + col_]); @@ -449,12 +470,12 @@ public: //! \~english Checks if the column contains the element `e`. //! \~russian Проверяет, содержит ли столбец элемент `e`. - //! \sa PIVector::contains() + //! \~\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` в столбце. - //! \sa PIVector::entries() + //! \~\sa PIVector::entries() inline int entries(const T & e, ssize_t start = 0) const { if (start < 0) start = 0; int count = 0; @@ -466,7 +487,7 @@ public: //! \~english Counts elements in the column that pass the `test`. //! \~russian Подсчитывает элементы в столбце, проходящие `test`. - //! \sa PIVector::entries(std::function) + //! \~\sa PIVector::entries(std::function) inline int entries(std::function test, ssize_t start = 0) const { if (start < 0) start = 0; int count = 0; @@ -478,7 +499,7 @@ public: //! \~english Tests if any element in the column passes the `test`. //! \~russian Проверяет, проходит ли какой-либо элемент в столбце `test`. - //! \sa PIVector::any() + //! \~\sa PIVector::any() inline bool any(std::function test) const { for (size_t i = 0; i < sz_; ++i) { if (test((*p_)[i * step_ + col_])) return true; @@ -488,7 +509,7 @@ public: //! \~english Tests if all elements in the column pass the `test`. //! \~russian Проверяет, проходят ли все элементы в столбце `test`. - //! \sa PIVector::every() + //! \~\sa PIVector::every() inline bool every(std::function test) const { for (size_t i = 0; i < sz_; ++i) { if (!test((*p_)[i * step_ + col_])) return false; @@ -525,7 +546,7 @@ public: //! \details //! \~english No bounds checking is performed; use with caution. //! \~russian Проверка границ не выполняется; используйте с осторожностью. - //! \sa PIVector::operator[] + //! \~\sa PIVector::operator[] inline T & operator[](size_t index) { return (*p_)[this->st_ + index]; } //! \~english Returns a pointer to the row data starting at an optional offset. @@ -542,7 +563,7 @@ public: //! \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` игнорируются. - //! \sa PIVector::operator= + //! \~\sa PIVector::operator= inline Row & operator=(const Row & other) { if (p_ == other.p_ && this->st_ == other.st_) return *this; const size_t sz = piMin(this->sz_, other.sz_); @@ -555,7 +576,7 @@ public: //! \details //! \~english Only the minimum of the row size and vector size is copied. //! \~russian Копируется только минимум из размера строки и размера вектора. - //! \sa PIVector::operator= + //! \~\sa PIVector::operator= inline Row & operator=(const PIVector & other) { const size_t sz = piMin(this->sz_, other.size()); p_->_copyRaw(p_->data(this->st_), other.data(), sz); @@ -568,7 +589,7 @@ public: //! \details //! \~english The function can modify the elements. //! \~russian Функция может изменять элементы. - //! \sa PIVector::forEach() + //! \~\sa PIVector::forEach() inline void forEach(std::function func) { for (size_t i = 0; i < this->sz_; ++i) { func((*p_)[this->st_ + i]); @@ -577,7 +598,7 @@ public: //! \~english Fills the row with copies of `value`. //! \~russian Заполняет строку копиями `value`. - //! \sa PIVector::fill() + //! \~\sa PIVector::fill() inline void fill(const T & value) { for (size_t i = 0; i < this->sz_; ++i) { (*p_)[this->st_ + i] = value; @@ -645,7 +666,7 @@ public: //! \details //! \~english The function can modify the elements. //! \~russian Функция может изменять элементы. - //! \sa PIVector::forEach() + //! \~\sa PIVector::forEach() inline void forEach(std::function func) { for (size_t i = 0; i < this->sz_; ++i) { func((*p_)[i * this->step_ + this->col_]); @@ -654,7 +675,7 @@ public: //! \~english Fills the column with copies of `value`. //! \~russian Заполняет столбец копиями `value`. - //! \sa PIVector::fill() + //! \~\sa PIVector::fill() inline void fill(const T & value) { for (size_t i = 0; i < this->sz_; ++i) { (*p_)[i * this->step_ + this->col_] = value; @@ -668,7 +689,7 @@ public: //! \details //! \~english No bounds checking is performed. //! \~russian Проверка границ не выполняется. - //! \sa at() (const version), PIVector::operator[] + //! \~\sa at() (const version), PIVector::operator[] inline T & element(size_t row, size_t col) { return mat[row * cols_ + col]; } //! \~english Returns a const reference to the element at the given row and column. @@ -704,7 +725,7 @@ public: //! \~english Returns a proxy object for the row at the given index for modification. //! \~russian Возвращает прокси-объект для строки по заданному индексу для модификации. - //! \sa row(), Col + //! \~\sa row(), Col inline Row operator[](size_t index) { return Row(this, index); } //! \~english Returns a proxy object for the row at the given index for read-only access. @@ -713,7 +734,7 @@ public: //! \~english Returns a pointer to the underlying flat data starting at an optional offset. //! \~russian Возвращает указатель на внутренние плоские данные, начиная с опционального смещения. - //! \sa PIVector::data() + //! \~\sa PIVector::data() inline T * data(size_t index = 0) { return mat.data(index); } //! \~english Returns a const pointer to the underlying flat data starting at an optional offset. @@ -723,7 +744,7 @@ public: //! \~english Returns a proxy object for the row at the given index for modification. //! \~russian Возвращает прокси-объект для строки по заданному индексу для модификации. - //! \sa operator[] + //! \~\sa operator[] inline Row row(size_t index) { return Row(this, index); } //! \~english Returns a proxy object for the row at the given index for read-only access. @@ -732,7 +753,7 @@ public: //! \~english Returns a proxy object for the column at the given index for modification. //! \~russian Возвращает прокси-объект для столбца по заданному индексу для модификации. - //! \sa col() const + //! \~\sa col() const inline Col col(size_t index) { return Col(this, index); } //! \~english Returns a proxy object for the column at the given index for read-only access. @@ -762,14 +783,13 @@ public: //! Otherwise, only `min(cols(), other.size())` elements are copied; the rest of the new row is default-initialized. //! \~russian Если массив был пуст, количество столбцов устанавливается равным размеру исходной строки. //! В противном случае копируется только `min(cols(), other.size())` элементов; остальные элементы новой строки инициализируются по - //! умолчанию. \sa PIVector::push_back() + //! умолчанию. + //! \~\sa PIVector::push_back() inline PIVector2D & addRow(const RowConst & other) { if (cols_ == 0) cols_ = other.sz_; - const size_t sz = piMin(cols_, other.sz_); - const size_t ps = mat.size(); - mat.resize(mat.size() + cols_); - mat._copyRaw(mat.data(ps), other.data(), sz); + mat.append(other.toVector()); rows_++; + mat.resize(rows_ * cols_); return *this; } @@ -783,6 +803,14 @@ public: return *this; } + //! \~english Appends \a count new empty rows to the bottom of the array, filled with value \a f. + //! \~russian Добавляет \a count новых пустых строк в конец массива, заполненных значением \a f. + //! \details + //! \~english If the array was empty (no columns defined), the column count is set to 1. + //! The new rows are filled with the default value \a f. + //! \~russian Если массив был пуст (количество столбцов не определено), количество столбцов устанавливается равным 1. + //! Новые строки заполняются значением по умолчанию \a f. + //! \~\sa addRow(), appendColumns() inline PIVector2D & appendRows(size_t count, const T & f = T()) { if (count == 0) return *this; if (cols_ == 0) ++cols_; @@ -791,6 +819,14 @@ public: return *this; } + //! \~english Appends \a count new empty columns to the end of each row of the array. + //! \~russian Добавляет \a count новых пустых столбцов в конец каждой строки массива. + //! \details + //! \~english If the array was empty (rows not defined), the array becomes a single row with \a count columns. + //! If the array already has rows, new elements are inserted at the end of each existing row. + //! \~russian Если массив был пуст (строки не определены), массив становится одной строкой с \a count столбцов. + //! Если массив уже содержит строки, новые элементы добавляются в конец каждой существующей строки. + //! \~\sa appendRows(), addColumn() inline PIVector2D & appendColumns(size_t count, const T & f = T()) { if (count == 0) return *this; if (rows_ == 0) { @@ -810,6 +846,14 @@ public: return *this; } + //! \~english Deletes `count` rows starting from the specified row index. + //! \~russian Удаляет `count` строк, начиная с указанного индекса строки. + //! \details + //! \~english Removes the specified rows from the array and updates the row count. If all elements are deleted (array becomes empty), + //! both rows and columns are set to 0. + //! \~russian Удаляет указанные строки из массива и обновляет количество строк. Если все элементы удалены (массив становится пустым), + //! количество строк и столбцов устанавливается в 0. + //! \~\sa deleteColumns() inline PIVector2D & deleteRows(size_t row_start, size_t count) { if (row_start >= rows_ || count == 0) return *this; mat.remove(row_start * cols_, cols_ * count); @@ -822,6 +866,14 @@ public: return *this; } + //! \~english Removes the specified columns from the array and updates the column count. + //! \~russian Удаляет указанные столбцы из массива и обновляет количество столбцов. + //! \details + //! \~english Removes \a count columns starting from \a col_start. If \a col_start is out of range or \a count is 0, + //! the function does nothing. If \a count extends beyond the last column, only available columns are deleted. + //! \~russian Удаляет \a count столбцов начиная с \a col_start. Если \a col_start выходит за границы или \a count равен 0, + //! функция ничего не делает. Если \a count выходит за последний столбец, удаляются только доступные столбцы. + //! \~\sa removeColumn(), deleteRows() inline PIVector2D & deleteColumns(size_t col_start, size_t count) { if (col_start >= cols_ || rows_ == 0) return *this; count = piMin(count, cols_ - col_start); @@ -898,7 +950,7 @@ public: //! PIVector2D mat(2, 3, 0); // 2x3 matrix filled with 0 //! mat.resize(3, 4, 1); // becomes 3x4, new elements filled with 1 //! \endcode - //! \sa PIVector::resize() + //! \~\sa PIVector::resize() inline PIVector2D & resize(size_t rows, size_t cols, const T & f = T()) { if (rows == rows_ && cols == cols_) return *this; if (rows_ == 0 || cols_ == 0) { @@ -929,7 +981,7 @@ public: //! \~english Equality operator. //! \~russian Оператор равенства. - //! \sa PIVector::operator== + //! \~\sa PIVector::operator== inline bool operator==(const PIVector2D & t) const { if (cols_ != t.cols_ || rows_ != t.rows_) return false; return mat == t.mat; @@ -944,7 +996,7 @@ public: //! \details //! \~english Each row vector is a copy of the corresponding row. //! \~russian Каждый вектор-строка является копией соответствующей строки. - //! \sa fromVectors(), PIVector::PIVector(const T*, size_t) + //! \~\sa fromVectors(), PIVector::PIVector(const T*, size_t) inline PIVector> toVectors() const { PIVector> ret; ret.reserve(rows_); @@ -970,7 +1022,7 @@ public: //! \details //! \~english Swaps the flat vectors and the dimension members. Very fast, no memory allocation. //! \~russian Обменивает внутренние плоские векторы и члены, хранящие размеры. Очень быстро, без выделения памяти. - //! \sa PIVector::swap() + //! \~\sa PIVector::swap() inline void swap(PIVector2D & other) { mat.swap(other.mat); piSwap(rows_, other.rows_); @@ -991,7 +1043,7 @@ public: //! \details //! \~english The capacity of the underlying flat vector may remain unchanged. //! \~russian Ёмкость внутреннего плоского вектора может остаться неизменной. - //! \sa PIVector::clear() + //! \~\sa PIVector::clear() inline void clear() { rows_ = cols_ = 0; mat.clear(); @@ -1000,23 +1052,23 @@ public: //! \~english Checks if the underlying flat vector contains the element `e`. //! \~russian Проверяет, содержит ли внутренний плоский вектор элемент `e`. - //! \sa PIVector::contains() + //! \~\sa PIVector::contains() 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() + //! \~\sa PIVector::entries() 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) + //! \~\sa PIVector::entries(std::function) inline int entries(std::function test) const { return mat.entries(test); } //! \~english Returns the first index (row, col) of `e` in the 2D array. //! \~russian Возвращает первый индекс (строка, столбец) элемента `e` в двумерном массиве. - //! \sa PIVector::indexOf() + //! \~\sa PIVector::indexOf() inline Index indexOf(const T & e) const { ssize_t flat = mat.indexOf(e); if (flat < 0 || cols_ == 0) return Index{-1, -1}; @@ -1025,7 +1077,7 @@ public: //! \~english Returns the first index (row, col) in the 2D array that passes the `test`. //! \~russian Возвращает первый индекс (строка, столбец) в двумерном массиве, проходящий `test`. - //! \sa PIVector::indexWhere() + //! \~\sa PIVector::indexWhere() inline Index indexWhere(std::function test, ssize_t start = 0) const { ssize_t flat = mat.indexWhere(test, start); if (flat < 0 || cols_ == 0) return Index{-1, -1}; @@ -1034,7 +1086,7 @@ public: //! \~english Returns the last index (row, col) of `e` in the 2D array. //! \~russian Возвращает последний индекс (строка, столбец) элемента `e` в двумерном массиве. - //! \sa PIVector::lastIndexOf() + //! \~\sa PIVector::lastIndexOf() inline Index lastIndexOf(const T & e, ssize_t start = -1) const { ssize_t flat = mat.lastIndexOf(e, start); if (flat < 0 || cols_ == 0) return Index{-1, -1}; @@ -1043,7 +1095,7 @@ public: //! \~english Returns the last index (row, col) in the 2D array that passes the `test`. //! \~russian Возвращает последний индекс (строка, столбец) в двумерном массиве, проходящий `test`. - //! \sa PIVector::lastIndexWhere() + //! \~\sa PIVector::lastIndexWhere() inline Index lastIndexWhere(std::function test, ssize_t start = -1) const { ssize_t flat = mat.lastIndexWhere(test, start); if (flat < 0 || cols_ == 0) return Index{-1, -1}; @@ -1053,17 +1105,17 @@ public: //! \~english Tests if any element in the flat vector passes the `test`. //! \~russian Проверяет, проходит ли какой-либо элемент в плоском векторе `test`. - //! \sa PIVector::any() + //! \~\sa PIVector::any() inline bool any(std::function test) const { return mat.any(test); } //! \~english Tests if all elements in the flat vector pass the `test`. //! \~russian Проверяет, проходят ли все элементы в плоском векторе `test`. - //! \sa PIVector::every() + //! \~\sa PIVector::every() inline bool every(std::function test) const { return mat.every(test); } //! \~english Fills the entire 2D array with copies of `e`. //! \~russian Заполняет весь двумерный массив копиями `e`. - //! \sa PIVector::fill() + //! \~\sa PIVector::fill() inline PIVector2D & fill(const T & e = T()) { mat.fill(e); return *this; @@ -1071,7 +1123,7 @@ public: //! \~english Fills the entire 2D array using a generator function `f` based on flat index. //! \~russian Заполняет весь двумерный массив, используя функцию-генератор `f` на основе плоского индекса. - //! \sa PIVector::fill(std::function) + //! \~\sa PIVector::fill(std::function) inline PIVector2D & fill(std::function f) { mat.fill(f); return *this; @@ -1083,7 +1135,7 @@ public: //! \~english Assigns new size and fills with value. //! \~russian Задаёт новый размер и заполняет значением. - //! \sa PIVector::assign(size_t, const T&) + //! \~\sa PIVector::assign(size_t, const T&) inline PIVector2D & assign(size_t rows, size_t cols, const T & f = T()) { mat.assign(rows * cols, f); rows_ = rows; @@ -1114,7 +1166,7 @@ public: //! \~english Reverses the order of rows in place. //! \~russian Изменяет порядок строк на обратный на месте. - //! \sa reverseColumns(), PIVector::reverse() + //! \~\sa reverseColumns(), PIVector::reverse() inline PIVector2D & reverseRows() { const size_t half = rows_ / 2; for (size_t i = 0; i < half; ++i) { @@ -1129,7 +1181,7 @@ public: //! \~english Reverses the order of columns in each row in place. //! \~russian Изменяет порядок столбцов в каждой строке на обратный на месте. - //! \sa reverseRows(), PIVector::reverse() + //! \~\sa reverseRows(), PIVector::reverse() inline PIVector2D & reverseColumns() { for (size_t r = 0; r < rows_; ++r) { Row currentRow = row(r); @@ -1146,7 +1198,7 @@ public: //! \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() + //! \~\sa PIVector::getRange() inline PIVector2D 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(); const size_t actualRowCount = piMin(rowCount, rows_ - rowStart); @@ -1166,7 +1218,7 @@ public: //! \details //! \~english The original array is not modified. //! \~russian Исходный массив не изменяется. - //! \sa PIVector::map() + //! \~\sa PIVector::map() template inline PIVector2D map(std::function f) const { return PIVector2D(rows_, cols_, mat.template map(f)); @@ -1174,7 +1226,7 @@ public: //! \~english Applies a function (with row and col indices) to each element and returns a new 2D array. //! \~russian Применяет функцию (с индексами строки и столбца) к каждому элементу и возвращает новый двумерный массив. - //! \sa PIVector::mapIndexed() + //! \~\sa PIVector::mapIndexed() template inline PIVector2D mapIndexed(std::function f) const { PIVector mappedMat; @@ -1189,7 +1241,7 @@ public: //! \~english Applies a function to each row (modifiable). //! \~russian Применяет функцию к каждой строке (с возможностью изменения). - //! \sa forEachRow() const, PIVector::forEach() + //! \~\sa forEachRow() const, PIVector::forEach() inline PIVector2D & forEachRow(std::function f) { for (size_t r = 0; r < rows_; ++r) f(row(r)); @@ -1221,7 +1273,7 @@ public: //! \~english Accumulates a value across all elements. //! \~russian Аккумулирует значение по всем элементам. - //! \sa PIVector::reduce() + //! \~\sa PIVector::reduce() template inline ST reduce(std::function f, const ST & initial = ST()) const { return mat.template reduce(f, initial); @@ -1229,7 +1281,7 @@ public: //! \~english Accumulates a value across all elements with indices. //! \~russian Аккумулирует значение по всем элементам с индексами. - //! \sa PIVector::reduceIndexed() + //! \~\sa PIVector::reduceIndexed() template inline ST reduceIndexed(std::function f, const ST & initial = ST()) const { ST ret(initial); @@ -1246,7 +1298,7 @@ public: //! \details //! \~english If the last row is removed and the array becomes empty, \a cols() is set to 0. //! \~russian Если удаляется последняя строка и массив становится пустым, \a cols() устанавливается в 0. - //! \sa removeColumn(), PIVector::remove() + //! \~\sa removeColumn(), PIVector::remove() inline PIVector2D & removeRow(size_t row) { return deleteRows(row, 1); } //! \~english Removes a column from the 2D array. @@ -1254,7 +1306,7 @@ public: //! \details //! \~english This operation is more expensive than removing a row because elements must be moved. //! \~russian Эта операция дороже, чем удаление строки, поскольку требуется перемещение элементов. - //! \sa removeRow(), PIVector::remove() + //! \~\sa removeRow(), PIVector::remove() inline PIVector2D & removeColumn(size_t col) { return deleteColumns(col, 1); } //! \~english Removes all rows that satisfy a condition. @@ -1262,7 +1314,7 @@ public: //! \details //! \~english Rows are removed from the bottom to avoid index shifting issues. //! \~russian Строки удаляются снизу вверх, чтобы избежать проблем со смещением индексов. - //! \sa removeColumnsWhere(), PIVector::removeWhere() + //! \~\sa removeColumnsWhere(), PIVector::removeWhere() inline PIVector2D & removeRowsWhere(std::function test) { ssize_t r = rows_; while (--r >= 0) { @@ -1275,7 +1327,7 @@ public: //! \~english Removes all columns that satisfy a condition. //! \~russian Удаляет все столбцы, удовлетворяющие условию. - //! \sa removeRowsWhere() + //! \~\sa removeRowsWhere() inline PIVector2D & removeColumnsWhere(std::function test) { ssize_t c = cols_; while (--c >= 0) { @@ -1289,7 +1341,7 @@ public: //! \~english Returns a new 2D array containing only the rows that pass the test. //! \~russian Возвращает новый двумерный массив, содержащий только строки, прошедшие проверку. - //! \sa filterColumns(), PIVector::filter() + //! \~\sa filterColumns(), PIVector::filter() inline PIVector2D filterRows(std::function test) const { PIVector2D result; for (size_t r = 0; r < rows_; ++r) { @@ -1303,7 +1355,7 @@ public: //! \~english Returns a new 2D array containing only the columns that pass the test. //! \~russian Возвращает новый двумерный массив, содержащий только столбцы, прошедшие проверку. - //! \sa filterRows() + //! \~\sa filterRows() inline PIVector2D filterColumns(std::function test) const { if (isEmpty()) return PIVector2D(); PIVector goodCols; @@ -1313,13 +1365,8 @@ public: } } PIVector2D result; - result._resizeRaw(rows_, goodCols.size()); - for (size_t r = 0; r < rows_; ++r) { - const size_t start_dst = r * result.cols_; - const size_t start_src = r * cols_; - for (size_t gc = 0; gc < goodCols.size(); ++gc) { - result.mat._copyRaw(result.mat.data(start_dst + gc), mat.data(start_src + goodCols[gc]), 1); - } + for (size_t gc = 0; gc < goodCols.size(); ++gc) { + result.addColumn(col(goodCols[gc])); } return result; } diff --git a/plans/doxygen_example.md b/plans/doxygen_example.md index 52581c92..4c52cdfd 100644 --- a/plans/doxygen_example.md +++ b/plans/doxygen_example.md @@ -11,3 +11,5 @@ | //! \~english | Важное примечание о сложности/поведении на английском языке | | //! \~russian | Важное примечание о сложности/поведении на русском языке | | //! \~\sa | Ссылки на связанные функции | + +NOTE: Не использовать секции \param и \return