pivector2d fix add\remove rows\cols and resize
This commit is contained in:
@@ -777,66 +777,57 @@ public:
|
||||
//! \~russian Добавляет новую строку в конец массива из \a PIVector.
|
||||
inline PIVector2D<T> & addRow(const PIVector<T> & other) {
|
||||
if (cols_ == 0) cols_ = other.size();
|
||||
const size_t sz = piMin<size_t>(cols_, other.size());
|
||||
const size_t ps = mat.size();
|
||||
mat.resize(mat.size() + cols_);
|
||||
mat._copyRaw(mat.data(ps), other.data(), sz);
|
||||
mat.append(other);
|
||||
rows_++;
|
||||
mat.resize(rows_ * cols_);
|
||||
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;
|
||||
inline PIVector2D<T> & appendRows(size_t count, const T & f = T()) {
|
||||
if (count == 0) return *this;
|
||||
if (cols_ == 0) ++cols_;
|
||||
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);
|
||||
}
|
||||
inline PIVector2D<T> & appendColumns(size_t count, const T & f = T()) {
|
||||
if (count == 0) return *this;
|
||||
if (rows_ == 0) {
|
||||
mat.resize(count, f);
|
||||
rows_ = 1;
|
||||
cols_ = count;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const size_t newCols = cols_ + count;
|
||||
mat.reserve(rows_ * newCols);
|
||||
for (size_t r = rows_; r > 0; --r) {
|
||||
mat.insert(r * cols_, f, count);
|
||||
}
|
||||
|
||||
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()) {
|
||||
inline PIVector2D<T> & deleteRows(size_t row_start, size_t count) {
|
||||
if (row_start >= rows_ || count == 0) return *this;
|
||||
mat.remove(row_start * cols_, cols_ * count);
|
||||
if (isEmpty()) {
|
||||
cols_ = 0;
|
||||
rows_ = 0;
|
||||
} else {
|
||||
rows_ -= count;
|
||||
}
|
||||
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);
|
||||
inline PIVector2D<T> & deleteColumns(size_t col_start, size_t count) {
|
||||
if (col_start >= cols_ || rows_ == 0) return *this;
|
||||
count = piMin(count, cols_ - col_start);
|
||||
if (count == 0) return *this;
|
||||
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));
|
||||
}
|
||||
mat.remove(r * (cols_ - count) + col_start, count);
|
||||
}
|
||||
cols_ -= count;
|
||||
mat.resize(rows_ * cols_);
|
||||
@@ -847,32 +838,25 @@ public:
|
||||
//! \~russian Добавляет новую строку в конец массива из \a ColConst.
|
||||
inline PIVector2D<T> & addColumn(const ColConst & other) {
|
||||
if (other.size() == 0) return *this;
|
||||
if (size() == 0) {
|
||||
_resizeRaw(other.size(), 1);
|
||||
if (isEmpty()) {
|
||||
mat.reserve(other.size());
|
||||
for (size_t r = 0; r < other.size(); ++r) {
|
||||
element(r, 0) = other[r];
|
||||
mat.append(other[r]);
|
||||
}
|
||||
rows_ = mat.size();
|
||||
cols_ = 1;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const size_t oldCols = cols_;
|
||||
const size_t newCols = oldCols + 1;
|
||||
const size_t newSize = rows_ * newCols;
|
||||
|
||||
mat._resizeRaw(newSize);
|
||||
|
||||
for (size_t r = rows_ - 1; r > 0; --r) {
|
||||
T * src = mat.data(r * oldCols);
|
||||
T * dst = mat.data(r * newCols);
|
||||
memmove(dst, src, oldCols * sizeof(T));
|
||||
if (r < other.size()) {
|
||||
mat._copyRaw(&(dst[oldCols]), &(other[r]), 1);
|
||||
const size_t newCols = cols_ + 1;
|
||||
mat.reserve(rows_ * newCols);
|
||||
for (size_t r = rows_; r > 0; --r) {
|
||||
if (r - 1 < other.size()) {
|
||||
mat.insert(r * cols_, other[r - 1]);
|
||||
} else {
|
||||
const T tmp = T();
|
||||
mat._copyRaw(&(dst[oldCols]), &tmp, 1);
|
||||
mat.insert(r * cols_);
|
||||
}
|
||||
}
|
||||
mat._copyRaw(mat.data(oldCols), &(other[0]), 1);
|
||||
|
||||
cols_ = newCols;
|
||||
return *this;
|
||||
@@ -882,32 +866,22 @@ public:
|
||||
//! \~russian Добавляет новую строку в конец массива из \a PIVector.
|
||||
inline PIVector2D<T> & addColumn(const PIVector<T> & other) {
|
||||
if (other.size() == 0) return *this;
|
||||
if (size() == 0) {
|
||||
_resizeRaw(other.size(), 1);
|
||||
for (size_t r = 0; r < other.size(); ++r) {
|
||||
element(r, 0) = other[r];
|
||||
}
|
||||
if (isEmpty()) {
|
||||
mat.append(other);
|
||||
rows_ = mat.size();
|
||||
cols_ = 1;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const size_t oldCols = cols_;
|
||||
const size_t newCols = oldCols + 1;
|
||||
const size_t newSize = rows_ * newCols;
|
||||
|
||||
mat._resizeRaw(newSize);
|
||||
|
||||
for (size_t r = rows_ - 1; r > 0; --r) {
|
||||
T * src = mat.data(r * oldCols);
|
||||
T * dst = mat.data(r * newCols);
|
||||
memmove(dst, src, oldCols * sizeof(T));
|
||||
if (r < other.size()) {
|
||||
mat._copyRaw(&(dst[oldCols]), &(other[r]), 1);
|
||||
const size_t newCols = cols_ + 1;
|
||||
mat.reserve(rows_ * newCols);
|
||||
for (size_t r = rows_; r > 0; --r) {
|
||||
if (r - 1 < other.size()) {
|
||||
mat.insert(r * cols_, other[r - 1]);
|
||||
} else {
|
||||
const T tmp = T();
|
||||
mat._copyRaw(&(dst[oldCols]), &tmp, 1);
|
||||
mat.insert(r * cols_);
|
||||
}
|
||||
}
|
||||
mat._copyRaw(mat.data(oldCols), &(other[0]), 1);
|
||||
|
||||
cols_ = newCols;
|
||||
return *this;
|
||||
@@ -938,7 +912,19 @@ public:
|
||||
rows_ = rows;
|
||||
return *this;
|
||||
}
|
||||
return __resize(rows, cols, f);
|
||||
if (cols > cols_) {
|
||||
appendColumns(cols - cols_, f);
|
||||
}
|
||||
if (rows > rows_) {
|
||||
appendRows(rows - rows_, f);
|
||||
}
|
||||
if (cols < cols_) {
|
||||
deleteColumns(cols, cols_ - cols);
|
||||
}
|
||||
if (rows < rows_) {
|
||||
deleteRows(rows, rows_ - rows);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Equality operator.
|
||||
@@ -1261,9 +1247,7 @@ public:
|
||||
//! \~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) {
|
||||
return deleteRows(row, 1);
|
||||
}
|
||||
inline PIVector2D<T> & removeRow(size_t row) { return deleteRows(row, 1); }
|
||||
|
||||
//! \~english Removes a column from the 2D array.
|
||||
//! \~russian Удаляет столбец из двумерного массива.
|
||||
@@ -1271,9 +1255,7 @@ public:
|
||||
//! \~english This operation is more expensive than removing a row because elements must be moved.
|
||||
//! \~russian Эта операция дороже, чем удаление строки, поскольку требуется перемещение элементов.
|
||||
//! \sa removeRow(), PIVector::remove()
|
||||
inline PIVector2D<T> & removeColumn(size_t col) {
|
||||
return deleteColumns(col, 1);
|
||||
}
|
||||
inline PIVector2D<T> & removeColumn(size_t col) { return deleteColumns(col, 1); }
|
||||
|
||||
//! \~english Removes all rows that satisfy a condition.
|
||||
//! \~russian Удаляет все строки, удовлетворяющие условию.
|
||||
@@ -1343,22 +1325,6 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
inline PIVector2D<T> & __resize(size_t rows, size_t cols, const T & f) {
|
||||
if (cols > cols_) {
|
||||
addEmptyColumns(cols - cols_, f);
|
||||
}
|
||||
if (rows > rows_) {
|
||||
addEmptyRows(rows - rows_, f);
|
||||
}
|
||||
if (cols < cols_) {
|
||||
deleteColumns(cols, cols_ - cols);
|
||||
}
|
||||
if (rows < rows_) {
|
||||
deleteRows(rows, rows_ - rows);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
size_t rows_, cols_;
|
||||
PIVector<T> mat;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user