diff --git a/libs/main/containers/pivector2d.h b/libs/main/containers/pivector2d.h index d48a8925..bd434075 100644 --- a/libs/main/containers/pivector2d.h +++ b/libs/main/containers/pivector2d.h @@ -869,16 +869,18 @@ public: //! \sa PIVector::resize() inline PIVector2D & resize(size_t rows, size_t cols, const T & f = T()) { if (rows == rows_ && cols == cols_) return *this; - PIVector2D tmp(rows, cols, f); - size_t copyRows = piMin(rows_, rows); - size_t copyCols = piMin(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 (rows_ == 0 || cols_ == 0) { + mat.resize(rows * cols, f); + rows_ = rows; + cols_ = cols; + return *this; } - swap(tmp); - return *this; + if (rows != rows_ && cols == cols_) { + mat.resize(rows * cols_, f); + rows_ = rows; + return *this; + } + return __resize(rows, cols, f, std::is_trivially_copyable()); } //! \~english Equality operator. @@ -1103,8 +1105,8 @@ public: //! \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(); - size_t actualRowCount = piMin(rowCount, rows_ - rowStart); - size_t actualColCount = piMin(colCount, cols_ - colStart); + const size_t actualRowCount = piMin(rowCount, rows_ - rowStart); + const size_t actualColCount = piMin(colCount, cols_ - colStart); PIVector2D result(actualRowCount, actualColCount); for (size_t r = 0; r < actualRowCount; ++r) { @@ -1292,16 +1294,47 @@ public: goodCols << c; } } - PIVector2D result(rows_, goodCols.size()); + 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.element(r, gc) = element(r, goodCols[gc]); + result.mat._copyRaw(result.mat.data(start_dst + gc), mat.data(start_src + goodCols[gc]), 1); } } return result; } protected: + template::value, int>::type = 0> + inline PIVector2D & __resize(size_t rows, size_t cols, const T & f, std::true_type) { + PIVector2D tmp(rows, cols, f); + const size_t copyRows = piMin(rows_, rows); + const size_t copyCols = piMin(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)); + } + swap(tmp); + return *this; + } + + template::value, int>::type = 0> + inline PIVector2D & __resize(size_t rows, size_t cols, const T & f, std::false_type) { + PIVector2D tmp(rows, cols, f); + const size_t copyRows = piMin(rows_, rows); + const size_t copyCols = piMin(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); + } + } + swap(tmp); + return *this; + } + size_t rows_, cols_; PIVector mat; };