* Purpose: The class Array2 represents bi-dimensional arrays
* of fixed size known at run time.
* The ranges of indices are user defined.
-*
-* Warning: Programs clients of such class must be independant
+*
+* Class allocates one 1D array storing full data (all Rows and Columns)
+* and extra 1D array storing pointers to each Row.
+*
+* Warning: Programs clients of such class must be independent
* of the range of the first element. Then, a C++ for
* loop must be written like this
*
public:
// ---------- PUBLIC METHODS ------------
+ //! Empty constructor; should be used with caution.
+ //! @sa methods Resize() and Move().
+ NCollection_Array2()
+ : myLowerRow (1),
+ myUpperRow (0),
+ myLowerCol (1),
+ myUpperCol (0),
+ myData (NULL),
+ myStart (NULL),
+ myDeletable(false)
+ {
+ //
+ }
+
//! Constructor
NCollection_Array2(const Standard_Integer theRowLower,
const Standard_Integer theRowUpper,
*this = theOther;
}
+#ifndef OCCT_NO_RVALUE_REFERENCE
+ //! Move constructor
+ NCollection_Array2 (NCollection_Array2&& theOther)
+ : myLowerRow (theOther.myLowerRow),
+ myUpperRow (theOther.myUpperRow),
+ myLowerCol (theOther.myLowerRow),
+ myUpperCol (theOther.myUpperCol),
+ myData (theOther.myData),
+ myStart (theOther.myStart),
+ myDeletable(theOther.myDeletable)
+ {
+ theOther.myStart = NULL;
+ theOther.myData = NULL;
+ theOther.myDeletable = false;
+ }
+#endif
+
//! C array-based constructor
NCollection_Array2(const TheItemType& theBegin,
const Standard_Integer theRowLower,
{ return Length(); }
//! Length (number of items)
Standard_Integer Length (void) const
- { return RowLength() * ColLength(); }
+ { return NbRows() * NbColumns(); }
+
+ //! Returns number of rows
+ Standard_Integer NbRows() const { return myUpperRow - myLowerRow + 1; }
+
+ //! Returns number of columns
+ Standard_Integer NbColumns() const { return myUpperCol - myLowerCol + 1; }
//! Returns length of the row, i.e. number of columns
- Standard_Integer RowLength (void) const
- { return (myUpperCol-myLowerCol+1); }
+ Standard_Integer RowLength() const { return NbColumns(); }
//! Returns length of the column, i.e. number of rows
- Standard_Integer ColLength (void) const
- { return (myUpperRow-myLowerRow+1); }
+ Standard_Integer ColLength() const { return NbRows(); }
//! LowerRow
Standard_Integer LowerRow (void) const
return *this;
}
+ //! Move assignment.
+ //! This array will borrow all the data from theOther.
+ //! The moved object will be left unitialized and should not be used anymore.
+ NCollection_Array2& Move (NCollection_Array2& theOther)
+ {
+ if (&theOther == this)
+ {
+ return *this;
+ }
+
+ if (myDeletable)
+ {
+ delete[] myStart;
+ }
+ if (myData != NULL)
+ {
+ delete[] &(myData[myLowerRow]);
+ }
+
+ myLowerRow = theOther.myLowerRow;
+ myUpperRow = theOther.myUpperRow;
+ myLowerCol = theOther.myLowerRow;
+ myUpperCol = theOther.myUpperCol;
+ myData = theOther.myData;
+ myStart = theOther.myStart;
+ myDeletable = theOther.myDeletable;
+
+ theOther.myStart = NULL;
+ theOther.myData = NULL;
+ theOther.myDeletable = Standard_False;
+ return *this;
+ }
+
//! Assignment operator
NCollection_Array2& operator= (const NCollection_Array2& theOther)
{
return Assign (theOther);
}
+#ifndef OCCT_NO_RVALUE_REFERENCE
+ //! Move assignment operator; @sa Move()
+ NCollection_Array2& operator= (NCollection_Array2&& theOther)
+ {
+ return Move (theOther);
+ }
+#endif
+
//! Constant value access
const TheItemType& Value (const Standard_Integer theRow,
const Standard_Integer theCol) const
theCol < myLowerCol || theCol > myUpperCol, "NCollection_Array2::SetValue");
myData[theRow][theCol] = theItem;
}
-
+
+ //! Resizes the array to specified bounds.
+ //! No re-allocation will be done if length of array does not change,
+ //! but existing values will not be discarded if theToCopyData set to FALSE.
+ //! @param theRowLower new lower Row of array
+ //! @param theRowUpper new upper Row of array
+ //! @param theColLower new lower Column of array
+ //! @param theColUpper new upper Column of array
+ //! @param theToCopyData flag to copy existing data into new array
+ void Resize (Standard_Integer theRowLower,
+ Standard_Integer theRowUpper,
+ Standard_Integer theColLower,
+ Standard_Integer theColUpper,
+ Standard_Boolean theToCopyData)
+ {
+ Standard_RangeError_Raise_if (theRowUpper < theRowLower
+ || theColUpper < theColLower, "NCollection_Array2::Resize");
+ const Standard_Integer anOldNbRows = NbRows();
+ const Standard_Integer anOldNbCols = NbColumns();
+ const Standard_Integer aLowerRowOld = myLowerRow;
+ const Standard_Integer aLowerColOld = myLowerCol;
+ const Standard_Integer aNewNbRows = theRowUpper - theRowLower + 1;
+ const Standard_Integer aNewNbCols = theColUpper - theColLower + 1;
+
+ TheItemType* aStartOld = myStart;
+ TheItemType** aTableOld = myData != NULL ? myData + aLowerRowOld : NULL;
+ myLowerRow = theRowLower;
+ myUpperRow = theRowUpper;
+ myLowerCol = theColLower;
+ myUpperCol = theColUpper;
+ if (aNewNbRows == anOldNbRows
+ && aNewNbCols == anOldNbCols)
+ {
+ if (myLowerCol != aLowerColOld)
+ {
+ fillIndexTable (aTableOld);
+ }
+ myData = aTableOld - myLowerRow;
+ return;
+ }
+
+ if (myDeletable
+ && !theToCopyData)
+ {
+ delete[] aStartOld;
+ }
+ delete[] aTableOld;
+
+ Allocate();
+ if (!theToCopyData)
+ {
+ myDeletable = Standard_True;
+ return;
+ }
+
+ const Standard_Integer aNbRowsToCopy = Min (anOldNbRows, aNewNbRows);
+ const Standard_Integer aNbColsToCopy = Min (anOldNbCols, aNewNbCols);
+ for (Standard_Integer aRowIter = 0; aRowIter < aNbRowsToCopy; ++aRowIter)
+ {
+ for (Standard_Integer aColIter = 0; aColIter < aNbColsToCopy; ++aColIter)
+ {
+ myStart[size_t(aRowIter) * size_t(aNewNbCols) + size_t(aColIter)] = aStartOld[size_t(aRowIter) * size_t(anOldNbCols) + size_t(aColIter)];
+ }
+ }
+
+ if (myDeletable)
+ {
+ delete[] aStartOld;
+ }
+ myDeletable = Standard_True;
+ }
+
//! Destructor - releases the memory
~NCollection_Array2 (void)
{
if (myDeletable) delete [] myStart;
- delete [] &(myData[myLowerRow]);
+ if (myData != NULL)
+ {
+ delete[] &(myData[myLowerRow]);
+ }
}
private:
//! Allocate memory for the array, set up indirection table
void Allocate (void)
{
- const Standard_Integer iRowSize = myUpperCol - myLowerCol + 1;
- const Standard_Integer iColSize = myUpperRow - myLowerRow + 1;
- Standard_RangeError_Raise_if (iRowSize <= 0 || iColSize <= 0, "NCollection_Array2::Allocate");
- if (myDeletable) {
+ const Standard_Integer aNbRows = NbRows();
+ const Standard_Integer aNbCols = NbColumns();
+ Standard_RangeError_Raise_if (aNbRows <= 0 || aNbCols <= 0, "NCollection_Array2::Allocate");
+ if (myDeletable)
+ {
// allocation of the data in the array
- myStart = new TheItemType[iRowSize * iColSize];
+ myStart = new TheItemType[size_t(aNbRows) * size_t(aNbCols)];
Standard_OutOfMemory_Raise_if (!myStart, "NCollection_Array2 : Allocation failed");
}
// else myStart is set to the beginning of the given array
- TheItemType** pTable = new TheItemType* [iColSize];
+
+ TheItemType** pTable = new TheItemType* [aNbRows];
Standard_OutOfMemory_Raise_if (!pTable, "NCollection_Array2 : Allocation failed");
+ fillIndexTable (pTable);
+ }
- // Items of pTable point to the '0'th items in the rows of the array
- TheItemType* pRow = myStart - myLowerCol;
- for (Standard_Integer i = 0; i < iColSize; i++)
+ //! Fill index table for accessing array elements.
+ void fillIndexTable (TheItemType** theTable)
+ {
+ // Items of table point to the 0th items in the rows of the array
+ TheItemType* aRow = myStart - myLowerCol;
+ const Standard_Integer aNbRows = NbRows();
+ const Standard_Size aNbCols = NbColumns();
+ for (Standard_Integer aRowIter = 0; aRowIter < aNbRows; ++aRowIter)
{
- pTable[i] = pRow;
- pRow += iRowSize;
+ theTable[aRowIter] = aRow;
+ aRow += aNbCols;
}
- // Set myData to the '0'th row pointer of the pTable
- myData = pTable - myLowerRow;
+ // Set myData to the 0th row pointer of the table
+ myData = theTable - myLowerRow;
}
protected: