File indexing completed on 2026-09-17 09:21:21
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef NCollection_Array2_HeaderFile
0017 #define NCollection_Array2_HeaderFile
0018
0019 #include <Standard_DimensionMismatch.hxx>
0020 #include <Standard_OutOfMemory.hxx>
0021 #include <NCollection_Allocator.hxx>
0022 #include <Standard_OutOfRange.hxx>
0023 #include <NCollection_Array1.hxx>
0024
0025 #include <NCollection_DefineAlloc.hxx>
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050 template <class TheItemType>
0051 class NCollection_Array2 : public NCollection_Array1<TheItemType>
0052 {
0053 public:
0054
0055 DEFINE_STANDARD_ALLOC;
0056 DEFINE_NCOLLECTION_ALLOC;
0057
0058 public:
0059 typedef NCollection_Allocator<TheItemType> allocator_type;
0060
0061 public:
0062
0063 using value_type = typename NCollection_Array1<TheItemType>::value_type;
0064 using size_type = typename NCollection_Array1<TheItemType>::size_type;
0065 using difference_type = typename NCollection_Array1<TheItemType>::difference_type;
0066 using pointer = typename NCollection_Array1<TheItemType>::pointer;
0067 using const_pointer = typename NCollection_Array1<TheItemType>::const_pointer;
0068 using reference = typename NCollection_Array1<TheItemType>::reference;
0069 using const_reference = typename NCollection_Array1<TheItemType>::const_reference;
0070
0071 using iterator = typename NCollection_Array1<TheItemType>::iterator;
0072 using const_iterator = typename NCollection_Array1<TheItemType>::const_iterator;
0073
0074 static int BeginPosition(int theRowLower,
0075 int ,
0076 int theColLower,
0077 int theColUpper) noexcept
0078 {
0079
0080 return theColLower + (theRowLower * (theColUpper - theColLower + 1));
0081 }
0082
0083 static int LastPosition(int theRowLower,
0084 int theRowUpper,
0085 int theColLower,
0086 int theColUpper) noexcept
0087 {
0088 return ((theRowUpper - theRowLower + 1) * (theColUpper - theColLower + 1)) + theColLower
0089 + (theRowLower * (theColUpper - theColLower + 1)) - 1;
0090 }
0091
0092 public:
0093
0094
0095
0096
0097 NCollection_Array2() noexcept
0098 : NCollection_Array1<TheItemType>(),
0099 myLowerRow(1),
0100 mySizeRow(0),
0101 myLowerCol(1),
0102 mySizeCol(0)
0103 {
0104 }
0105
0106
0107 NCollection_Array2(const int theRowLower,
0108 const int theRowUpper,
0109 const int theColLower,
0110 const int theColUpper)
0111 : NCollection_Array1<TheItemType>(
0112 BeginPosition(theRowLower, theRowUpper, theColLower, theColUpper),
0113 LastPosition(theRowLower, theRowUpper, theColLower, theColUpper)),
0114 myLowerRow(theRowLower),
0115 mySizeRow(theRowUpper - theRowLower + 1),
0116 myLowerCol(theColLower),
0117 mySizeCol(theColUpper - theColLower + 1)
0118 {
0119 }
0120
0121
0122 NCollection_Array2(const NCollection_Array2& theOther)
0123 : NCollection_Array1<TheItemType>(theOther),
0124 myLowerRow(theOther.LowerRow()),
0125 mySizeRow(theOther.NbRows()),
0126 myLowerCol(theOther.LowerCol()),
0127 mySizeCol(theOther.NbColumns())
0128 {
0129 }
0130
0131
0132 NCollection_Array2(NCollection_Array2&& theOther) noexcept
0133 : NCollection_Array1<TheItemType>(std::forward<NCollection_Array2>(theOther)),
0134 myLowerRow(theOther.LowerRow()),
0135 mySizeRow(theOther.NbRows()),
0136 myLowerCol(theOther.LowerCol()),
0137 mySizeCol(theOther.NbColumns())
0138 {
0139 theOther.myLowerRow = 1;
0140 theOther.mySizeRow = 0;
0141 theOther.myLowerCol = 1;
0142 theOther.mySizeCol = 0;
0143 }
0144
0145
0146 explicit NCollection_Array2(const TheItemType& theBegin,
0147 const int theRowLower,
0148 const int theRowUpper,
0149 const int theColLower,
0150 const int theColUpper)
0151 : NCollection_Array1<TheItemType>(
0152 theBegin,
0153 BeginPosition(theRowLower, theRowUpper, theColLower, theColUpper),
0154 LastPosition(theRowLower, theRowUpper, theColLower, theColUpper)),
0155 myLowerRow(theRowLower),
0156 mySizeRow(theRowUpper - theRowLower + 1),
0157 myLowerCol(theColLower),
0158 mySizeCol(theColUpper - theColLower + 1)
0159 {
0160 }
0161
0162
0163
0164 explicit NCollection_Array2(const size_t theNbRows, const size_t theNbCols)
0165 : NCollection_Array1<TheItemType>(theNbRows * theNbCols),
0166 myLowerRow(0),
0167 mySizeRow(theNbRows),
0168 myLowerCol(0),
0169 mySizeCol(theNbCols)
0170 {
0171 }
0172
0173
0174
0175
0176 explicit NCollection_Array2(pointer theBegin, const size_t theNbRows, const size_t theNbCols)
0177 : NCollection_Array1<TheItemType>(theBegin, theNbRows * theNbCols),
0178 myLowerRow(0),
0179 mySizeRow(theNbRows),
0180 myLowerCol(0),
0181 mySizeCol(theNbCols)
0182 {
0183 }
0184
0185
0186 size_t Size() const noexcept { return mySizeRow * mySizeCol; }
0187
0188
0189 int Length() const noexcept { return NbRows() * NbColumns(); }
0190
0191
0192 int NbRows() const noexcept { return static_cast<int>(mySizeRow); }
0193
0194
0195 int NbColumns() const noexcept { return static_cast<int>(mySizeCol); }
0196
0197
0198 int RowLength() const noexcept { return NbColumns(); }
0199
0200
0201 int ColLength() const noexcept { return NbRows(); }
0202
0203
0204 int LowerRow() const noexcept { return myLowerRow; }
0205
0206
0207 int UpperRow() const noexcept { return myLowerRow + static_cast<int>(mySizeRow) - 1; }
0208
0209
0210 int LowerCol() const noexcept { return myLowerCol; }
0211
0212
0213 int UpperCol() const noexcept { return myLowerCol + static_cast<int>(mySizeCol) - 1; }
0214
0215
0216 void UpdateLowerRow(const int theLowerRow) noexcept { myLowerRow = theLowerRow; }
0217
0218
0219 void UpdateLowerCol(const int theLowerCol) noexcept { myLowerCol = theLowerCol; }
0220
0221
0222 void UpdateUpperRow(const int theUpperRow) noexcept
0223 {
0224 myLowerRow = myLowerRow - UpperRow() + theUpperRow;
0225 }
0226
0227
0228 void UpdateUpperCol(const int theUpperCol) noexcept
0229 {
0230 myLowerCol = myLowerCol - UpperCol() + theUpperCol;
0231 }
0232
0233
0234
0235 NCollection_Array2& Assign(const NCollection_Array2& theOther)
0236 {
0237 if (&theOther == this)
0238 {
0239 return *this;
0240 }
0241 NCollection_Array1<TheItemType>::Assign(theOther);
0242 myLowerRow = theOther.myLowerRow;
0243 mySizeRow = theOther.mySizeRow;
0244 myLowerCol = theOther.myLowerCol;
0245 mySizeCol = theOther.mySizeCol;
0246 return *this;
0247 }
0248
0249
0250
0251
0252 NCollection_Array2& CopyValues(const NCollection_Array2& theOther)
0253 {
0254 if (&theOther == this)
0255 {
0256 return *this;
0257 }
0258 Standard_DimensionMismatch_Raise_if(mySizeRow != theOther.mySizeRow
0259 || mySizeCol != theOther.mySizeCol,
0260 "NCollection_Array2::CopyValues");
0261 NCollection_Array1<TheItemType>::CopyValues(theOther);
0262 return *this;
0263 }
0264
0265
0266
0267
0268 NCollection_Array2& Move(NCollection_Array2&& theOther) noexcept
0269 {
0270 if (&theOther == this)
0271 {
0272 return *this;
0273 }
0274 NCollection_Array1<TheItemType>::Move(theOther);
0275 myLowerRow = theOther.myLowerRow;
0276 mySizeRow = theOther.mySizeRow;
0277 myLowerCol = theOther.myLowerCol;
0278 mySizeCol = theOther.mySizeCol;
0279 theOther.myLowerRow = 1;
0280 theOther.mySizeRow = 0;
0281 theOther.myLowerCol = 1;
0282 theOther.mySizeCol = 0;
0283 return *this;
0284 }
0285
0286
0287
0288
0289 NCollection_Array2& Move(NCollection_Array2& theOther) noexcept
0290 {
0291 return Move(std::move(theOther));
0292 }
0293
0294
0295 NCollection_Array2& operator=(const NCollection_Array2& theOther) { return Assign(theOther); }
0296
0297
0298 NCollection_Array2& operator=(NCollection_Array2&& theOther) noexcept
0299 {
0300 return Move(std::forward<NCollection_Array2>(theOther));
0301 }
0302
0303
0304 const_reference Value(const int theRow, const int theCol) const
0305 {
0306 const size_t aPos = (theRow - myLowerRow) * mySizeCol + (theCol - myLowerCol);
0307 return NCollection_Array1<TheItemType>::at(aPos);
0308 }
0309
0310
0311 const_reference operator()(const int theRow, const int theCol) const
0312 {
0313 const size_t aPos = (theRow - myLowerRow) * mySizeCol + (theCol - myLowerCol);
0314 return NCollection_Array1<TheItemType>::at(aPos);
0315 }
0316
0317
0318 reference ChangeValue(const int theRow, const int theCol)
0319 {
0320 const size_t aPos = (theRow - myLowerRow) * mySizeCol + (theCol - myLowerCol);
0321 return NCollection_Array1<TheItemType>::at(aPos);
0322 }
0323
0324
0325 reference operator()(const int theRow, const int theCol) { return ChangeValue(theRow, theCol); }
0326
0327
0328 void SetValue(const int theRow, const int theCol, const TheItemType& theItem)
0329 {
0330 const size_t aPos = (theRow - myLowerRow) * mySizeCol + (theCol - myLowerCol);
0331 NCollection_Array1<TheItemType>::at(aPos) = theItem;
0332 }
0333
0334
0335 void SetValue(const int theRow, const int theCol, TheItemType&& theItem)
0336 {
0337 const size_t aPos = (theRow - myLowerRow) * mySizeCol + (theCol - myLowerCol);
0338 NCollection_Array1<TheItemType>::at(aPos) = std::forward<TheItemType>(theItem);
0339 }
0340
0341
0342
0343
0344 const_reference At(const size_t theRow, const size_t theCol) const
0345 {
0346 Standard_OutOfRange_Raise_if(theRow >= mySizeRow || theCol >= mySizeCol,
0347 "NCollection_Array2::At");
0348 return NCollection_Array1<TheItemType>::at(theRow * mySizeCol + theCol);
0349 }
0350
0351
0352
0353
0354 reference ChangeAt(const size_t theRow, const size_t theCol)
0355 {
0356 Standard_OutOfRange_Raise_if(theRow >= mySizeRow || theCol >= mySizeCol,
0357 "NCollection_Array2::ChangeAt");
0358 return NCollection_Array1<TheItemType>::at(theRow * mySizeCol + theCol);
0359 }
0360
0361
0362
0363
0364
0365
0366 template <typename... Args>
0367 reference EmplaceValue(const int theRow, const int theCol, Args&&... theArgs)
0368 {
0369 const size_t aPos = (theRow - myLowerRow) * mySizeCol + (theCol - myLowerCol);
0370 Standard_OutOfRange_Raise_if(aPos >= this->mySize, "NCollection_Array2::EmplaceValue");
0371 this->myPointer[aPos] = value_type(std::forward<Args>(theArgs)...);
0372 return this->myPointer[aPos];
0373 }
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384 void Resize(int theRowLower,
0385 int theRowUpper,
0386 int theColLower,
0387 int theColUpper,
0388 bool theToCopyData)
0389 {
0390 if (!theToCopyData)
0391 {
0392 resizeNoData(theRowLower, theRowUpper, theColLower, theColUpper);
0393 return;
0394 }
0395 resizeImpl<false>(theRowLower, theRowUpper, theColLower, theColUpper);
0396 }
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409 void ResizeWithTrim(int theRowLower,
0410 int theRowUpper,
0411 int theColLower,
0412 int theColUpper,
0413 bool theToCopyData)
0414 {
0415 if (!theToCopyData)
0416 {
0417 resizeNoData(theRowLower, theRowUpper, theColLower, theColUpper);
0418 return;
0419 }
0420 resizeImpl<true>(theRowLower, theRowUpper, theColLower, theColUpper);
0421 }
0422
0423
0424
0425
0426
0427
0428 void Resize(const size_t theNbRows, const size_t theNbCols, const bool theToCopyData)
0429 {
0430 Resize(myLowerRow,
0431 myLowerRow + static_cast<int>(theNbRows) - 1,
0432 myLowerCol,
0433 myLowerCol + static_cast<int>(theNbCols) - 1,
0434 theToCopyData);
0435 }
0436
0437
0438
0439
0440
0441
0442 void ResizeWithTrim(const size_t theNbRows, const size_t theNbCols, const bool theToCopyData)
0443 {
0444 ResizeWithTrim(myLowerRow,
0445 myLowerRow + static_cast<int>(theNbRows) - 1,
0446 myLowerCol,
0447 myLowerCol + static_cast<int>(theNbCols) - 1,
0448 theToCopyData);
0449 }
0450
0451 protected:
0452
0453 void resizeNoData(int theRowLower, int theRowUpper, int theColLower, int theColUpper)
0454 {
0455 Standard_RangeError_Raise_if(theRowUpper < theRowLower || theColUpper < theColLower,
0456 "NCollection_Array2::Resize");
0457 NCollection_Array1<TheItemType>::Resize(
0458 BeginPosition(theRowLower, theRowUpper, theColLower, theColUpper),
0459 LastPosition(theRowLower, theRowUpper, theColLower, theColUpper),
0460 false);
0461 mySizeRow = theRowUpper - theRowLower + 1;
0462 mySizeCol = theColUpper - theColLower + 1;
0463 myLowerRow = theRowLower;
0464 myLowerCol = theColLower;
0465 }
0466
0467
0468
0469
0470 template <bool thePreserve2D>
0471 void resizeImpl(int theRowLower, int theRowUpper, int theColLower, int theColUpper)
0472 {
0473 Standard_RangeError_Raise_if(theRowUpper < theRowLower || theColUpper < theColLower,
0474 "NCollection_Array2::Resize");
0475 const size_t aNewNbRows = theRowUpper - theRowLower + 1;
0476 const size_t aNewNbCols = theColUpper - theColLower + 1;
0477 if (mySizeRow == aNewNbRows && mySizeCol == aNewNbCols)
0478 {
0479 myLowerRow = theRowLower;
0480 myLowerCol = theColLower;
0481 NCollection_Array1<TheItemType>::UpdateLowerBound(
0482 BeginPosition(theRowLower, theRowUpper, theColLower, theColUpper));
0483 return;
0484 }
0485 if (mySizeRow == 0 || mySizeCol == 0)
0486 {
0487 resizeNoData(theRowLower, theRowUpper, theColLower, theColUpper);
0488 return;
0489 }
0490 const size_t aNbRowsToCopy = (std::min)(mySizeRow, aNewNbRows);
0491 const size_t aNbColsToCopy = (std::min)(mySizeCol, aNewNbCols);
0492 const size_t aOldStride = thePreserve2D ? mySizeCol : aNbColsToCopy;
0493
0494 NCollection_Array2<TheItemType> aTmpMovedCopy(std::move(*this));
0495 TheItemType* anOldPointer = &aTmpMovedCopy.ChangeFirst();
0496 NCollection_Array1<TheItemType>::Resize(
0497 BeginPosition(theRowLower, theRowUpper, theColLower, theColUpper),
0498 LastPosition(theRowLower, theRowUpper, theColLower, theColUpper),
0499 false);
0500 mySizeRow = aNewNbRows;
0501 mySizeCol = aNewNbCols;
0502 myLowerRow = theRowLower;
0503 myLowerCol = theColLower;
0504 for (size_t aRowIter = 0; aRowIter < aNbRowsToCopy; ++aRowIter)
0505 {
0506 for (size_t aColIter = 0; aColIter < aNbColsToCopy; ++aColIter)
0507 {
0508 NCollection_Array1<TheItemType>::at(aRowIter * aNewNbCols + aColIter) =
0509 std::move(anOldPointer[aRowIter * aOldStride + aColIter]);
0510 }
0511 }
0512 }
0513
0514 protected:
0515
0516 int myLowerRow;
0517 size_t mySizeRow;
0518 int myLowerCol;
0519 size_t mySizeCol;
0520
0521
0522 friend iterator;
0523 friend const_iterator;
0524 };
0525
0526 #endif