Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:04:17

0001 // Created on: 2002-04-15
0002 // Created by: Alexander Kartomin (akm)
0003 // Copyright (c) 2002-2014 OPEN CASCADE SAS
0004 //
0005 // This file is part of Open CASCADE Technology software library.
0006 //
0007 // This library is free software; you can redistribute it and/or modify it under
0008 // the terms of the GNU Lesser General Public License version 2.1 as published
0009 // by the Free Software Foundation, with special exception defined in the file
0010 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0011 // distribution for complete text of the license and disclaimer of any warranty.
0012 //
0013 // Alternatively, this file may be used under the terms of Open CASCADE
0014 // commercial license or contractual agreement.
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 // *********************************************** Template for Array2 class
0028 /**
0029 * Purpose:   The class Array2 represents bi-dimensional arrays
0030 *            of fixed size known at run time.
0031 *            The ranges of indices are user defined.
0032 *
0033 *            Class allocates one 1D array storing full data (all Rows and Columns)
0034 *            and extra 1D array storing pointers to each Row.
0035 *
0036 * Warning:   Programs clients of such class must be independent
0037 *            of the range of the first element. Then, a C++ for
0038 *            loop must be written like this
0039 *
0040 *            for (i = A.LowerRow(); i <= A.UpperRow(); i++)
0041 *              for (j = A.LowerCol(); j <= A.UpperCol(); j++)
0042 */
0043 template <class TheItemType>
0044 class NCollection_Array2 : public NCollection_Array1<TheItemType>
0045 {
0046 public:
0047   //! Memory allocation
0048   DEFINE_STANDARD_ALLOC;
0049   DEFINE_NCOLLECTION_ALLOC;
0050 public:
0051   typedef NCollection_Allocator<TheItemType> allocator_type;
0052 public:
0053 
0054   // Define various type aliases for convenience
0055   using value_type = typename NCollection_Array1<TheItemType>::value_type;
0056   using size_type = typename NCollection_Array1<TheItemType>::size_type;
0057   using difference_type = typename NCollection_Array1<TheItemType>::difference_type;
0058   using pointer = typename NCollection_Array1<TheItemType>::pointer;
0059   using const_pointer = typename NCollection_Array1<TheItemType>::const_pointer;
0060   using reference = typename NCollection_Array1<TheItemType>::reference;
0061   using const_reference = typename NCollection_Array1<TheItemType>::const_reference;
0062 
0063   using iterator = typename NCollection_Array1<TheItemType>::iterator;
0064   using const_iterator = typename NCollection_Array1<TheItemType>::const_iterator;
0065 
0066   static int BeginPosition(Standard_Integer theRowLower,
0067                            Standard_Integer /*theRowUpper*/,
0068                            Standard_Integer theColLower,
0069                            Standard_Integer theColUpper)
0070   {
0071     // Calculate the offset for the beginning position
0072     return theColLower + (theRowLower * (theColUpper - theColLower + 1));
0073   }
0074 
0075   static int LastPosition(Standard_Integer theRowLower,
0076                           Standard_Integer theRowUpper,
0077                           Standard_Integer theColLower,
0078                           Standard_Integer theColUpper)
0079   {
0080     return ((theRowUpper - theRowLower + 1) * (theColUpper - theColLower + 1)) + theColLower + (theRowLower * (theColUpper - theColLower + 1)) - 1;
0081   }
0082 
0083 public:
0084   // ---------- PUBLIC METHODS ------------
0085 
0086   //! Empty constructor; should be used with caution.
0087   //! @sa methods Resize() and Move().
0088   NCollection_Array2() :
0089     NCollection_Array1<TheItemType>(),
0090     myLowerRow(1),
0091     mySizeRow(0),
0092     myLowerCol(1),
0093     mySizeCol(0)
0094   {}
0095 
0096   //! Constructor
0097   NCollection_Array2(const Standard_Integer theRowLower,
0098                      const Standard_Integer theRowUpper,
0099                      const Standard_Integer theColLower,
0100                      const Standard_Integer theColUpper) :
0101     NCollection_Array1<TheItemType>(BeginPosition(theRowLower, theRowUpper, theColLower, theColUpper),
0102                                     LastPosition(theRowLower, theRowUpper, theColLower, theColUpper)),
0103     myLowerRow(theRowLower),
0104     mySizeRow(theRowUpper - theRowLower + 1),
0105     myLowerCol(theColLower),
0106     mySizeCol(theColUpper - theColLower + 1)
0107   {}
0108 
0109   //! Constructor
0110   explicit NCollection_Array2(const allocator_type& theAlloc,
0111                               const Standard_Integer theRowLower,
0112                               const Standard_Integer theRowUpper,
0113                               const Standard_Integer theColLower,
0114                               const Standard_Integer theColUpper) :
0115     NCollection_Array1<TheItemType>(theAlloc,
0116                                     BeginPosition(theRowLower, theRowUpper, theColLower, theColUpper),
0117                                     LastPosition(theRowLower, theRowUpper, theColLower, theColUpper)),
0118     myLowerRow(theRowLower),
0119     mySizeRow(theRowUpper - theRowLower + 1),
0120     myLowerCol(theColLower),
0121     mySizeCol(theColUpper - theColLower + 1)
0122   {}
0123 
0124   //! Copy constructor 
0125   NCollection_Array2(const NCollection_Array2& theOther) :
0126     NCollection_Array1<TheItemType>(theOther),
0127     myLowerRow(theOther.LowerRow()),
0128     mySizeRow(theOther.NbRows()),
0129     myLowerCol(theOther.LowerCol()),
0130     mySizeCol(theOther.NbColumns())
0131   {}
0132 
0133   //! Move constructor
0134   NCollection_Array2(NCollection_Array2&& theOther) noexcept:
0135     NCollection_Array1<TheItemType>(std::forward<NCollection_Array2>(theOther)),
0136     myLowerRow(theOther.LowerRow()),
0137     mySizeRow(theOther.NbRows()),
0138     myLowerCol(theOther.LowerCol()),
0139     mySizeCol(theOther.NbColumns())
0140   {}
0141 
0142   //! C array-based constructor
0143   explicit NCollection_Array2(const TheItemType& theBegin,
0144                               const Standard_Integer theRowLower,
0145                               const Standard_Integer theRowUpper,
0146                               const Standard_Integer theColLower,
0147                               const Standard_Integer theColUpper) :
0148     NCollection_Array1<TheItemType>(theBegin,
0149                                     BeginPosition(theRowLower, theRowUpper, theColLower, theColUpper),
0150                                     LastPosition(theRowLower, theRowUpper, theColLower, theColUpper)),
0151     myLowerRow(theRowLower),
0152     mySizeRow(theRowUpper - theRowLower + 1),
0153     myLowerCol(theColLower),
0154     mySizeCol(theColUpper - theColLower + 1)
0155   {}
0156 
0157   //! Size (number of items)
0158   Standard_Integer Size() const
0159   {
0160     return Length();
0161   }
0162   //! Length (number of items)
0163   Standard_Integer Length() const
0164   {
0165     return NbRows() * NbColumns();
0166   }
0167 
0168   //! Returns number of rows
0169   Standard_Integer NbRows() const
0170   {
0171     return static_cast<int>(mySizeRow);
0172   }
0173 
0174   //! Returns number of columns
0175   Standard_Integer NbColumns() const
0176   {
0177     return static_cast<int>(mySizeCol);
0178   }
0179 
0180   //! Returns length of the row, i.e. number of columns
0181   Standard_Integer RowLength() const
0182   {
0183     return NbColumns();
0184   }
0185 
0186   //! Returns length of the column, i.e. number of rows
0187   Standard_Integer ColLength() const
0188   {
0189     return NbRows();
0190   }
0191 
0192   //! LowerRow
0193   Standard_Integer LowerRow() const
0194   {
0195     return myLowerRow;
0196   }
0197   //! UpperRow
0198   Standard_Integer UpperRow() const
0199   {
0200     return myLowerRow + static_cast<int>(mySizeRow) - 1;
0201   }
0202   //! LowerCol
0203   Standard_Integer LowerCol() const
0204   {
0205     return myLowerCol;
0206   }
0207   //! UpperCol
0208   Standard_Integer UpperCol() const
0209   {
0210     return myLowerCol + static_cast<int>(mySizeCol) - 1;
0211   }
0212 
0213   //! Assignment
0214   NCollection_Array2& Assign(const NCollection_Array2& theOther)
0215   {
0216     if (&theOther == this)
0217     {
0218       return *this;
0219     }
0220     NCollection_Array1<TheItemType>::Assign(theOther);
0221     return *this;
0222   }
0223 
0224 
0225   //! Move assignment.
0226   //! This array will borrow all the data from theOther.
0227   //! The moved object will be left uninitialized and should not be used anymore.
0228   NCollection_Array2& Move(NCollection_Array2&& theOther)
0229   {
0230     if (&theOther == this)
0231     {
0232       return *this;
0233     }
0234     NCollection_Array1<TheItemType>::Move(theOther);
0235     myLowerRow = theOther.myLowerRow;
0236     mySizeRow = theOther.mySizeRow;
0237     myLowerCol = theOther.myLowerCol;
0238     mySizeCol = theOther.mySizeCol;
0239     return *this;
0240   }
0241 
0242   //! Move assignment.
0243   //! This array will borrow all the data from theOther.
0244   //! The moved object will be left uninitialized and should not be used anymore.
0245   NCollection_Array2& Move(NCollection_Array2& theOther)
0246   {
0247     return Move(std::move(theOther));
0248   }
0249 
0250   //! Assignment operator
0251   NCollection_Array2& operator= (const NCollection_Array2& theOther)
0252   {
0253     return Assign(theOther);
0254   }
0255 
0256   //! Move assignment operator; @sa Move()
0257   NCollection_Array2& operator= (NCollection_Array2&& theOther)
0258   {
0259     return Move(std::forward<NCollection_Array2>(theOther));
0260   }
0261 
0262   //! Constant value access
0263   const_reference Value(const Standard_Integer theRow,
0264                         const Standard_Integer theCol) const
0265   {
0266     const size_t aPos = (theRow - myLowerRow) * mySizeCol + (theCol - myLowerCol);
0267     return NCollection_Array1<TheItemType>::at(aPos);
0268   }
0269 
0270   //! operator() - alias to ChangeValue
0271   const_reference operator() (const Standard_Integer theRow,
0272                               const Standard_Integer theCol) const
0273   {
0274     const size_t aPos = (theRow - myLowerRow) * mySizeCol + (theCol - myLowerCol);
0275     return NCollection_Array1<TheItemType>::at(aPos);
0276   }
0277 
0278   //! Variable value access
0279   reference ChangeValue(const Standard_Integer theRow,
0280                         const Standard_Integer theCol)
0281   {
0282     const size_t aPos = (theRow - myLowerRow) * mySizeCol + (theCol - myLowerCol);
0283     return NCollection_Array1<TheItemType>::at(aPos);
0284   }
0285 
0286   //! operator() - alias to ChangeValue
0287   reference operator() (const Standard_Integer theRow,
0288                         const Standard_Integer theCol)
0289   {
0290     return ChangeValue(theRow, theCol);
0291   }
0292 
0293   //! SetValue
0294   void SetValue(const Standard_Integer theRow,
0295                 const Standard_Integer theCol,
0296                 const TheItemType& theItem)
0297   {
0298     const size_t aPos = (theRow - myLowerRow) * mySizeCol + (theCol - myLowerCol);
0299     NCollection_Array1<TheItemType>::at(aPos) = theItem;
0300   }
0301 
0302   //! SetValue
0303   void SetValue(const Standard_Integer theRow,
0304                 const Standard_Integer theCol,
0305                 TheItemType&& theItem)
0306   {
0307     const size_t aPos = (theRow - myLowerRow) * mySizeCol + (theCol - myLowerCol);
0308     NCollection_Array1<TheItemType>::at(aPos) = std::forward<TheItemType>(theItem);
0309   }
0310 
0311   //! Resizes the array to specified bounds.
0312   //! No re-allocation will be done if length of array does not change,
0313   //! but existing values will not be discarded if theToCopyData set to FALSE.
0314   //! @param theRowLower new lower Row of array
0315   //! @param theRowUpper new upper Row of array
0316   //! @param theColLower new lower Column of array
0317   //! @param theColUpper new upper Column of array
0318   //! @param theToCopyData flag to copy existing data into new array
0319   void Resize(Standard_Integer theRowLower,
0320               Standard_Integer theRowUpper,
0321               Standard_Integer theColLower,
0322               Standard_Integer theColUpper,
0323               Standard_Boolean theToCopyData)
0324   {
0325     Standard_RangeError_Raise_if(theRowUpper < theRowLower ||
0326                                  theColUpper < theColLower, "NCollection_Array2::Resize");
0327     myLowerRow = theRowLower;
0328     myLowerCol = theColLower;
0329     if (!theToCopyData)
0330     {
0331       NCollection_Array1<TheItemType>::Resize(BeginPosition(theRowLower, theRowUpper, theColLower, theColUpper),
0332                                               LastPosition(theRowLower, theRowUpper, theColLower, theColUpper),
0333                                               false);
0334       mySizeRow = theRowUpper - theRowLower + 1;
0335       mySizeCol = theColUpper - theColLower + 1;
0336       return;
0337     }
0338     NCollection_Array1<TheItemType> aTmpMovedCopy(std::move(*this));
0339     TheItemType* anOldPointer = &aTmpMovedCopy.ChangeFirst();
0340     NCollection_Array1<TheItemType>::Resize(BeginPosition(theRowLower, theRowUpper, theColLower, theColUpper),
0341                                             LastPosition(theRowLower, theRowUpper, theColLower, theColUpper),
0342                                             false);
0343     const size_t aNewNbRows = theRowUpper - theRowLower + 1;
0344     const size_t aNewNbCols = theColUpper - theColLower + 1;
0345     const size_t aNbRowsToCopy = std::min<size_t>(mySizeRow, aNewNbRows);
0346     const size_t aNbColsToCopy = std::min<size_t>(mySizeCol, aNewNbCols);
0347     mySizeRow = aNewNbRows;
0348     mySizeCol = aNewNbCols;
0349     size_t aOldInter = 0;
0350     for (size_t aRowIter = 0; aRowIter < aNbRowsToCopy; ++aRowIter)
0351     {
0352       for (size_t aColIter = 0; aColIter < aNbColsToCopy; ++aColIter)
0353       {
0354         NCollection_Array1<TheItemType>::at(aRowIter * aNewNbCols + aColIter) = std::move(anOldPointer[aOldInter++]);
0355       }
0356     }
0357   }
0358 
0359 protected:
0360   // ---------- PROTECTED FIELDS -----------
0361   Standard_Integer myLowerRow;
0362   size_t mySizeRow;
0363   Standard_Integer myLowerCol;
0364   size_t mySizeCol;
0365 
0366   // ----------- FRIEND CLASSES ------------
0367   friend iterator;
0368   friend const_iterator;
0369 
0370 };
0371 
0372 #endif