SALOME - SMESH
SMESH_Array2.hxx
Go to the documentation of this file.
00001 // File:      NCollection_Array2.hxx
00002 // Created:   15.04.02 17:05:16
00003 // Author:    Alexander Kartomin (akm)
00004 //            <a-kartomin@opencascade.com>
00005 // Copyright: Open Cascade 2002
00006 
00007 #ifndef SMESH_Array2_HeaderFile
00008 #define SMESH_Array2_HeaderFile
00009 
00010 #ifndef No_Exception
00011 #include <Standard_DimensionMismatch.hxx>
00012 #include <Standard_OutOfMemory.hxx>
00013 #include <Standard_OutOfRange.hxx>
00014 #endif
00015 
00016 #include <NCollection_BaseCollection.hxx>
00017 
00018 #ifdef WNT
00019 // Disable the warning "operator new unmatched by delete"
00020 #pragma warning (disable:4291)
00021 #endif
00022 
00023 // *********************************************** Template for Array2 class
00036 template <class TheItemType> class SMESH_Array2
00037   : public NCollection_BaseCollection<TheItemType>
00038 {
00039  public:
00040   // **************** Implementation of the Iterator interface.
00041   class Iterator : public NCollection_BaseCollection<TheItemType>::Iterator
00042   {
00043   public:
00045      Iterator (void) :
00046       myCurrent (0),
00047       mySize    (0),
00048        myArray   (NULL) {}
00050      Iterator  (const SMESH_Array2& theArray) :
00051       myCurrent (0),
00052       mySize    (theArray.Length()),
00053        myArray   (const_cast<SMESH_Array2<TheItemType>*>(&theArray)) {}
00055     void Init (const SMESH_Array2& theArray)
00056      {
00057       myCurrent = 0;
00058       mySize    = theArray.Length();
00059       myArray   = (SMESH_Array2 *) &theArray; 
00060     }
00062     virtual Standard_Boolean More (void) const
00063     { return (myCurrent < mySize); }
00065     virtual void Next (void)
00066     { myCurrent++; }
00068     virtual const TheItemType& Value (void) const
00069     { return myArray->myStart[myCurrent]; }
00071     virtual TheItemType& ChangeValue (void) const
00072     { return myArray->myStart[myCurrent]; }
00074     void* operator new(size_t theSize,
00075                        const Handle(NCollection_BaseAllocator)& theAllocator) 
00076     { return theAllocator->Allocate(theSize); }
00077   private:
00078     Standard_Integer    myCurrent;  
00079     Standard_Integer    mySize;     
00080     SMESH_Array2* myArray;    
00081   }; // End of nested class Iterator
00082 
00083  public:
00084   // ---------- PUBLIC METHODS ------------
00085 
00087   SMESH_Array2(const Standard_Integer theRowLower,
00088                      const Standard_Integer theRowUpper,
00089                      const Standard_Integer theColLower,
00090                      const Standard_Integer theColUpper) :
00091     NCollection_BaseCollection<TheItemType>     (),
00092     myLowerRow                                  (theRowLower),
00093     myUpperRow                                  (theRowUpper),
00094     myLowerCol                                  (theColLower),
00095     myUpperCol                                  (theColUpper),
00096     myDeletable                                 (Standard_True)
00097   { Allocate(); }
00098 
00100   SMESH_Array2 (const SMESH_Array2& theOther) :
00101     NCollection_BaseCollection<TheItemType>     (),
00102     myLowerRow                                  (theOther.LowerRow()),
00103     myUpperRow                                  (theOther.UpperRow()),
00104     myLowerCol                                  (theOther.LowerCol()),
00105     myUpperCol                                  (theOther.UpperCol()),
00106     myDeletable                                 (Standard_True)
00107   {
00108     Allocate();
00109     *this = theOther;
00110   }
00111 
00113   SMESH_Array2(const TheItemType&     theBegin,
00114                      const Standard_Integer theRowLower,
00115                      const Standard_Integer theRowUpper,
00116                      const Standard_Integer theColLower,
00117                      const Standard_Integer theColUpper) :
00118     NCollection_BaseCollection<TheItemType>     (),
00119     myLowerRow                                  (theRowLower),
00120     myUpperRow                                  (theRowUpper),
00121     myLowerCol                                  (theColLower),
00122     myUpperCol                                  (theColUpper),
00123     myDeletable                                 (Standard_False)
00124   {
00125     myStart = (TheItemType *) &theBegin;
00126     Allocate();
00127   }
00128 
00130   void Init (const TheItemType& theValue) 
00131   {
00132     TheItemType *pCur, *pEnd=myStart+Size();
00133     for(pCur = myStart; pCur<pEnd; pCur++)
00134       *pCur = theValue;
00135   }
00136 
00138   virtual Standard_Integer Size (void) const
00139   { return Length(); }
00141   Standard_Integer Length (void) const
00142   { return RowLength() * ColLength(); }
00143 
00145   Standard_Integer RowLength (void) const
00146   { return (myUpperCol-myLowerCol+1); }
00148   Standard_Integer ColLength (void) const
00149   { return (myUpperRow-myLowerRow+1); }
00150 
00152   Standard_Integer LowerRow (void) const
00153   { return myLowerRow; }
00155   Standard_Integer UpperRow (void) const
00156   { return myUpperRow; }
00158   Standard_Integer LowerCol (void) const
00159   { return myLowerCol; }
00161   Standard_Integer UpperCol (void) const
00162   { return myUpperCol; }
00163 
00165   Standard_Boolean IsDeletable (void) const
00166   { return myDeletable; }
00167 
00169   // Copies items from the other collection into the allocated
00170   // storage. Raises an exception when sizes differ.
00171   virtual void Assign (const NCollection_BaseCollection<TheItemType>& theOther)
00172   {
00173     if (&theOther == this)
00174       return;
00175 #if !defined No_Exception && !defined No_Standard_DimensionMismatch
00176     if (Length() != theOther.Size())
00177       Standard_DimensionMismatch::Raise ("SMESH_Array2::Assign");
00178 #endif
00179     TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& anIter2 = 
00180       theOther.CreateIterator();
00181     const TheItemType* pEnd = myStart+Length();
00182     for (TheItemType* pItem=myStart;
00183          pItem < pEnd;
00184          pItem++, anIter2.Next())
00185       *pItem = anIter2.Value();
00186   }
00187 
00189   SMESH_Array2& operator= (const SMESH_Array2& theOther)
00190   { 
00191     if (&theOther == this)
00192       return *this;
00193 #if !defined No_Exception && !defined No_Standard_DimensionMismatch
00194     if (Length() != theOther.Length())
00195       Standard_DimensionMismatch::Raise ("SMESH_Array2::operator=");
00196 #endif
00197     TheItemType * pMyItem  = myStart;
00198     TheItemType * pItem    = theOther.myStart;
00199     const Standard_Integer iSize = Length();
00200     for (Standard_Integer i=0; i < iSize; i++, pItem++, pMyItem++)
00201       *pMyItem = *pItem;
00202     return *this; 
00203   }
00204 
00206   const TheItemType& Value (const Standard_Integer theRow,
00207                             const Standard_Integer theCol) const
00208   {
00209 #if !defined No_Exception && !defined No_Standard_OutOfRange
00210     if (theRow < myLowerRow || theRow > myUpperRow ||
00211         theCol < myLowerCol || theCol > myUpperCol)
00212       Standard_OutOfRange::Raise ("SMESH_Array2::Value");
00213 #endif
00214     return myData[theRow][theCol];
00215   }
00216 
00218   const TheItemType& operator() (const Standard_Integer theRow,
00219                                  const Standard_Integer theCol) const
00220   { return Value (theRow,theCol); }
00221 
00223   TheItemType& ChangeValue (const Standard_Integer theRow,
00224                             const Standard_Integer theCol)
00225   {
00226 #if !defined No_Exception && !defined No_Standard_OutOfRange
00227     if (theRow < myLowerRow || theRow > myUpperRow ||
00228         theCol < myLowerCol || theCol > myUpperCol)
00229       Standard_OutOfRange::Raise ("SMESH_Array2::ChangeValue");
00230 #endif
00231     return myData[theRow][theCol];
00232   }
00233 
00235   TheItemType& operator() (const Standard_Integer theRow,
00236                            const Standard_Integer theCol)
00237   { return ChangeValue (theRow,theCol); }
00238 
00240   void SetValue (const Standard_Integer theRow,
00241                  const Standard_Integer theCol,
00242                  const TheItemType&     theItem)
00243   {
00244 #if !defined No_Exception && !defined No_Standard_OutOfRange
00245     if (theRow < myLowerRow || theRow > myUpperRow ||
00246         theCol < myLowerCol || theCol > myUpperCol)
00247       Standard_OutOfRange::Raise ("SMESH_Array2::SetValue");
00248 #endif
00249     myData[theRow][theCol] = theItem;
00250   }
00251   
00253   ~SMESH_Array2 (void)
00254   { 
00255     if (myDeletable) delete [] myStart;
00256     delete [] &(myData[myLowerRow]);
00257   }
00258 
00259  private:
00260   // ----------- PRIVATE METHODS -----------
00261 
00263   void Allocate (void)
00264   {
00265     const Standard_Integer iRowSize = myUpperCol - myLowerCol + 1;
00266     const Standard_Integer iColSize = myUpperRow - myLowerRow + 1;
00267 #if !defined No_Exception && !defined No_Standard_RangeError
00268     if (iRowSize <= 0  || iColSize <= 0)
00269       Standard_RangeError::Raise ("SMESH_Array2::Allocate");
00270 #endif
00271     if (myDeletable) {
00272       // allocation of the data in the array
00273       myStart = new TheItemType[iRowSize * iColSize];
00274 #if !defined No_Exception && !defined No_Standard_OutOfMemory
00275       if (!myStart)
00276         Standard_OutOfMemory::Raise ("SMESH_Array2 : Allocation failed");
00277 #endif
00278     }
00279     // else myStart is set to the beginning of the given array
00280     TheItemType** pTable = new TheItemType* [iColSize];
00281 #if !defined No_Exception && !defined No_Standard_OutOfMemory
00282     if (!pTable)
00283       Standard_OutOfMemory::Raise ("SMESH_Array2 : Allocation failed");
00284 #endif
00285 
00286     // Items of pTable point to the '0'th items in the rows of the array
00287     TheItemType* pRow = myStart - myLowerCol;
00288     for (Standard_Integer i = 0; i < iColSize; i++) 
00289     {
00290       pTable[i] = pRow;
00291       pRow += iRowSize;
00292     }
00293 
00294     // Set myData to the '0'th row pointer of the pTable
00295     myData = pTable - myLowerRow;
00296   }
00297 
00299   virtual TYPENAME NCollection_BaseCollection<TheItemType>::Iterator&
00300     CreateIterator(void) const
00301   { return *(new (this->IterAllocator()) Iterator(*this)); }
00302 
00303  protected:
00304   // ---------- PROTECTED FIELDS -----------
00305   Standard_Integer myLowerRow;
00306   Standard_Integer myUpperRow;
00307   Standard_Integer myLowerCol;
00308   Standard_Integer myUpperCol;
00309 
00310   TheItemType**    myData;      
00311   TheItemType*     myStart;     
00312   Standard_Boolean myDeletable; 
00313 
00314   // ----------- FRIEND CLASSES ------------
00315  friend class Iterator;
00316 
00317 };
00318 
00319 #ifdef WNT
00320 #pragma warning (default:4291)
00321 #endif
00322 
00323 #endif