PIVector2D - add funcs, optimize, tests, fixes, doxygen #194
@@ -785,6 +785,64 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
// TODO: fix - memove existing elements
|
||||
inline PIVector2D<T> & addEmptyRows(size_t count, const T & f = T()) {
|
||||
if (count == 0 || cols_ == 0) return *this;
|
||||
mat.resize(mat.size() + count * cols_, f);
|
||||
rows_ += count;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// TODO: fix - memove existing elements
|
||||
inline PIVector2D<T> & addEmptyColumns(size_t count, const T & f = T()) {
|
||||
if (count == 0 || rows_ == 0) return *this;
|
||||
const size_t newCols = cols_ + count;
|
||||
const size_t newSize = rows_ * newCols;
|
||||
mat.resize(newSize);
|
||||
for (size_t r = rows_ - 1; r < rows_; --r) {
|
||||
for (size_t c = newCols - 1; c >= cols_; --c) {
|
||||
element(r, c) = f;
|
||||
}
|
||||
for (size_t c = cols_; c > 0; --c) {
|
||||
element(r, c - 1 + count) = element(r, c - 1);
|
||||
}
|
||||
}
|
||||
cols_ = newCols;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline PIVector2D<T> & deleteRows(size_t row, size_t count) {
|
||||
if (row >= rows_) return *this;
|
||||
mat.remove(row * cols_, cols_ * count);
|
||||
rows_ -= count;
|
||||
if (mat.isEmpty()) {
|
||||
cols_ = 0;
|
||||
rows_ = 0;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline PIVector2D<T> & deleteColumns(size_t col, size_t count) {
|
||||
if (col >= cols_ || rows_ == 0 || count == 0) return *this;
|
||||
count = piMin(count, cols_ - col);
|
||||
for (size_t r = 0; r < rows_; ++r) {
|
||||
T * dst = mat.data(r * (cols_ - count));
|
||||
T * src = mat.data(r * cols_);
|
||||
if (col > 0) {
|
||||
memmove(dst, src, col * sizeof(T));
|
||||
dst += col;
|
||||
src += col;
|
||||
}
|
||||
size_t remaining = (cols_ - count) - col;
|
||||
if (remaining > 0) {
|
||||
memmove(dst, src + 1, remaining * sizeof(T));
|
||||
}
|
||||
}
|
||||
cols_ -= count;
|
||||
mat.resize(rows_ * cols_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~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) {
|
||||
@@ -880,7 +938,7 @@ public:
|
||||
rows_ = rows;
|
||||
return *this;
|
||||
}
|
||||
return __resize(rows, cols, f, std::is_trivially_copyable<T>());
|
||||
return __resize(rows, cols, f);
|
||||
}
|
||||
|
||||
//! \~english Equality operator.
|
||||
@@ -1200,17 +1258,11 @@ public:
|
||||
//! \~english Removes a row from the 2D array.
|
||||
//! \~russian Удаляет строку из двумерного массива.
|
||||
//! \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.
|
||||
//! \~russian Элементы указанной строки уничтожаются, а все последующие строки сдвигаются вверх.
|
||||
//! Если удаляется последняя строка и массив становится пустым, \a cols() устанавливается в 0.
|
||||
//! \~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()
|
||||
inline PIVector2D<T> & removeRow(size_t row) {
|
||||
if (row >= rows_) return *this;
|
||||
mat.remove(row * cols_, cols_);
|
||||
rows_--;
|
||||
if (rows_ == 0) cols_ = 0;
|
||||
return *this;
|
||||
return deleteRows(row, 1);
|
||||
}
|
||||
|
||||
//! \~english Removes a column from the 2D array.
|
||||
@@ -1220,23 +1272,7 @@ public:
|
||||
//! \~russian Эта операция дороже, чем удаление строки, поскольку требуется перемещение элементов.
|
||||
//! \sa removeRow(), PIVector::remove()
|
||||
inline PIVector2D<T> & removeColumn(size_t col) {
|
||||
if (col >= cols_ || rows_ == 0) return *this;
|
||||
for (size_t r = 0; r < rows_; ++r) {
|
||||
T * dst = mat.data(r * (cols_ - 1));
|
||||
T * src = mat.data(r * cols_);
|
||||
if (col > 0) {
|
||||
memmove(dst, src, col * sizeof(T));
|
||||
dst += col;
|
||||
src += col;
|
||||
}
|
||||
size_t remaining = (cols_ - 1) - col;
|
||||
if (remaining > 0) {
|
||||
memmove(dst, src + 1, remaining * sizeof(T));
|
||||
}
|
||||
}
|
||||
cols_--;
|
||||
mat.resize(rows_ * cols_);
|
||||
return *this;
|
||||
return deleteColumns(col, 1);
|
||||
}
|
||||
|
||||
//! \~english Removes all rows that satisfy a condition.
|
||||
@@ -1307,31 +1343,19 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline PIVector2D<T> & __resize(size_t rows, size_t cols, const T & f, std::true_type) {
|
||||
PIVector2D<T> tmp(rows, cols, f);
|
||||
const size_t copyRows = piMin<size_t>(rows_, rows);
|
||||
const size_t copyCols = piMin<size_t>(cols_, cols);
|
||||
for (size_t r = 0; r < copyRows; ++r) {
|
||||
T * dst = tmp.mat.data() + r * cols;
|
||||
T * src = mat.data() + r * cols_;
|
||||
memmove(dst, src, copyCols * sizeof(T));
|
||||
inline PIVector2D<T> & __resize(size_t rows, size_t cols, const T & f) {
|
||||
if (cols > cols_) {
|
||||
addEmptyColumns(cols - cols_, f);
|
||||
}
|
||||
swap(tmp);
|
||||
return *this;
|
||||
if (rows > rows_) {
|
||||
addEmptyRows(rows - rows_, f);
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<!std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline PIVector2D<T> & __resize(size_t rows, size_t cols, const T & f, std::false_type) {
|
||||
PIVector2D<T> tmp(rows, cols, f);
|
||||
const size_t copyRows = piMin<size_t>(rows_, rows);
|
||||
const size_t copyCols = piMin<size_t>(cols_, cols);
|
||||
for (size_t r = 0; r < copyRows; ++r) {
|
||||
for (size_t c = 0; c < copyCols; ++c) {
|
||||
tmp.element(r, c) = element(r, c);
|
||||
if (cols < cols_) {
|
||||
deleteColumns(cols, cols_ - cols);
|
||||
}
|
||||
if (rows < rows_) {
|
||||
deleteRows(rows, rows_ - rows);
|
||||
}
|
||||
swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user