0022815: Missing delete operator for placement new
[occt.git] / src / NCollection / NCollection_Array2.hxx
1 // File:      NCollection_Array2.hxx
2 // Created:   15.04.02 17:05:16
3 // Author:    Alexander Kartomin (akm)
4 //            <a-kartomin@opencascade.com>
5 // Copyright: Open Cascade 2002
6
7 #ifndef NCollection_Array2_HeaderFile
8 #define NCollection_Array2_HeaderFile
9
10 #ifndef No_Exception
11 #include <Standard_DimensionMismatch.hxx>
12 #include <Standard_OutOfMemory.hxx>
13 #include <Standard_OutOfRange.hxx>
14 #endif
15
16 #include <NCollection_BaseCollection.hxx>
17
18 // *********************************************** Template for Array2 class
19 /**
20 * Purpose:   The class Array2 represents bi-dimensional arrays 
21 *            of fixed size known at run time. 
22 *            The ranges of indices are user defined.
23 *            
24 * Warning:   Programs clients of such class must be independant
25 *            of the range of the first element. Then, a C++ for
26 *            loop must be written like this
27 *            
28 *            for (i = A.LowerRow(); i <= A.UpperRow(); i++)
29 *              for (j = A.LowerCol(); j <= A.UpperCol(); j++)
30 */            
31 template <class TheItemType> class NCollection_Array2
32   : public NCollection_BaseCollection<TheItemType>
33 {
34  public:
35   // **************** Implementation of the Iterator interface.
36   class Iterator : public NCollection_BaseCollection<TheItemType>::Iterator
37   {
38   public:
39     //! Empty constructor - for later Init
40     Iterator (void) :
41       myCurrent (0),
42       mySize    (0),
43       myArray   (NULL) {}
44     //! Constructor with initialisation
45     Iterator  (const NCollection_Array2& theArray) :
46       myCurrent (0),
47       mySize    (theArray.Length()),
48       myArray   ((NCollection_Array2 *) &theArray) {}
49     //! Initialisation
50     void Init (const NCollection_Array2& theArray)
51     { 
52       myCurrent = 0;
53       mySize    = theArray.Length();
54       myArray   = (NCollection_Array2 *) &theArray; 
55     }
56     //! Check end
57     virtual Standard_Boolean More (void) const
58     { return (myCurrent < mySize); }
59     //! Make step
60     virtual void Next (void)
61     { myCurrent++; }
62     //! Constant value access
63     virtual const TheItemType& Value (void) const
64     { return myArray->myStart[myCurrent]; }
65     //! Variable value access
66     virtual TheItemType& ChangeValue (void) const
67     { return myArray->myStart[myCurrent]; }
68   private:
69     Standard_Integer    myCurrent;  //!< Index of the current item
70     Standard_Integer    mySize;     //!< Total amount of items
71     NCollection_Array2* myArray;    //!< Pointer to the array being iterated
72   }; // End of nested class Iterator
73
74  public:
75   // ---------- PUBLIC METHODS ------------
76
77   //! Constructor
78   NCollection_Array2(const Standard_Integer theRowLower,
79                      const Standard_Integer theRowUpper,
80                      const Standard_Integer theColLower,
81                      const Standard_Integer theColUpper) :
82     NCollection_BaseCollection<TheItemType>     (),
83     myLowerRow                                  (theRowLower),
84     myUpperRow                                  (theRowUpper),
85     myLowerCol                                  (theColLower),
86     myUpperCol                                  (theColUpper),
87     myDeletable                                 (Standard_True)
88   { Allocate(); }
89
90   //! Copy constructor 
91   NCollection_Array2 (const NCollection_Array2& theOther) :
92     NCollection_BaseCollection<TheItemType>     (),
93     myLowerRow                                  (theOther.LowerRow()),
94     myUpperRow                                  (theOther.UpperRow()),
95     myLowerCol                                  (theOther.LowerCol()),
96     myUpperCol                                  (theOther.UpperCol()),
97     myDeletable                                 (Standard_True)
98   {
99     Allocate();
100     *this = theOther;
101   }
102
103   //! C array-based constructor
104   NCollection_Array2(const TheItemType&     theBegin,
105                      const Standard_Integer theRowLower,
106                      const Standard_Integer theRowUpper,
107                      const Standard_Integer theColLower,
108                      const Standard_Integer theColUpper) :
109     NCollection_BaseCollection<TheItemType>     (),
110     myLowerRow                                  (theRowLower),
111     myUpperRow                                  (theRowUpper),
112     myLowerCol                                  (theColLower),
113     myUpperCol                                  (theColUpper),
114     myDeletable                                 (Standard_False)
115   {
116     myStart = (TheItemType *) &theBegin;
117     Allocate();
118   }
119
120   //! Initialise the values
121   void Init (const TheItemType& theValue) 
122   {
123     TheItemType *pCur, *pEnd=myStart+Size();
124     for(pCur = myStart; pCur<pEnd; pCur++)
125       *pCur = theValue;
126   }
127
128   //! Size (number of items)
129   virtual Standard_Integer Size (void) const
130   { return Length(); }
131   //! Length (number of items)
132   Standard_Integer Length (void) const
133   { return RowLength() * ColLength(); }
134
135   //! RowLength 
136   Standard_Integer RowLength (void) const
137   { return (myUpperCol-myLowerCol+1); }
138   //! ColLength 
139   Standard_Integer ColLength (void) const
140   { return (myUpperRow-myLowerRow+1); }
141
142   //! LowerRow
143   Standard_Integer LowerRow (void) const
144   { return myLowerRow; }
145   //! UpperRow
146   Standard_Integer UpperRow (void) const
147   { return myUpperRow; }
148   //! LowerCol
149   Standard_Integer LowerCol (void) const
150   { return myLowerCol; }
151   //! UpperCol
152   Standard_Integer UpperCol (void) const
153   { return myUpperCol; }
154
155   //! myDeletable flag
156   Standard_Boolean IsDeletable (void) const
157   { return myDeletable; }
158
159   //! Assign 
160   // Copies items from the other collection into the allocated
161   // storage. Raises an exception when sizes differ.
162   virtual void Assign (const NCollection_BaseCollection<TheItemType>& theOther)
163   {
164     if (&theOther == this)
165       return;
166 #if !defined No_Exception && !defined No_Standard_DimensionMismatch
167     if (Length() != theOther.Size())
168       Standard_DimensionMismatch::Raise ("NCollection_Array2::Assign");
169 #endif
170     TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& anIter2 = 
171       theOther.CreateIterator();
172     const TheItemType* pEnd = myStart+Length();
173     for (TheItemType* pItem=myStart;
174          pItem < pEnd;
175          pItem++, anIter2.Next())
176       *pItem = anIter2.Value();
177   }
178
179   //! operator= (array to array)
180   NCollection_Array2& operator= (const NCollection_Array2& theOther)
181   { 
182     if (&theOther == this)
183       return *this;
184 #if !defined No_Exception && !defined No_Standard_DimensionMismatch
185     if (Length() != theOther.Length())
186       Standard_DimensionMismatch::Raise ("NCollection_Array2::operator=");
187 #endif
188     TheItemType * pMyItem  = myStart;
189     TheItemType * pItem    = theOther.myStart;
190     const Standard_Integer iSize = Length();
191     for (Standard_Integer i=0; i < iSize; i++, pItem++, pMyItem++)
192       *pMyItem = *pItem;
193     return *this; 
194   }
195
196   //! Constant value access
197   const TheItemType& Value (const Standard_Integer theRow,
198                             const Standard_Integer theCol) const
199   {
200 #if !defined No_Exception && !defined No_Standard_OutOfRange
201     if (theRow < myLowerRow || theRow > myUpperRow ||
202         theCol < myLowerCol || theCol > myUpperCol)
203       Standard_OutOfRange::Raise ("NCollection_Array2::Value");
204 #endif
205     return myData[theRow][theCol];
206   }
207
208   //! operator() - alias to ChangeValue
209   const TheItemType& operator() (const Standard_Integer theRow,
210                                  const Standard_Integer theCol) const
211   { return Value (theRow,theCol); }
212
213   //! Variable value access
214   TheItemType& ChangeValue (const Standard_Integer theRow,
215                             const Standard_Integer theCol)
216   {
217 #if !defined No_Exception && !defined No_Standard_OutOfRange
218     if (theRow < myLowerRow || theRow > myUpperRow ||
219         theCol < myLowerCol || theCol > myUpperCol)
220       Standard_OutOfRange::Raise ("NCollection_Array2::ChangeValue");
221 #endif
222     return myData[theRow][theCol];
223   }
224
225   //! operator() - alias to ChangeValue
226   TheItemType& operator() (const Standard_Integer theRow,
227                            const Standard_Integer theCol)
228   { return ChangeValue (theRow,theCol); }
229
230   //! SetValue
231   void SetValue (const Standard_Integer theRow,
232                  const Standard_Integer theCol,
233                  const TheItemType&     theItem)
234   {
235 #if !defined No_Exception && !defined No_Standard_OutOfRange
236     if (theRow < myLowerRow || theRow > myUpperRow ||
237         theCol < myLowerCol || theCol > myUpperCol)
238       Standard_OutOfRange::Raise ("NCollection_Array2::SetValue");
239 #endif
240     myData[theRow][theCol] = theItem;
241   }
242   
243   //! Destructor - releases the memory
244   ~NCollection_Array2 (void)
245   { 
246     if (myDeletable) delete [] myStart;
247     delete [] &(myData[myLowerRow]);
248   }
249
250  private:
251   // ----------- PRIVATE METHODS -----------
252
253   //! Allocate memory for the array, set up indirection table
254   void Allocate (void)
255   {
256     const Standard_Integer iRowSize = myUpperCol - myLowerCol + 1;
257     const Standard_Integer iColSize = myUpperRow - myLowerRow + 1;
258 #if !defined No_Exception && !defined No_Standard_RangeError
259     if (iRowSize <= 0  || iColSize <= 0)
260       Standard_RangeError::Raise ("NCollection_Array2::Allocate");
261 #endif
262     if (myDeletable) {
263       // allocation of the data in the array
264       myStart = new TheItemType[iRowSize * iColSize];
265 #if !defined No_Exception && !defined No_Standard_OutOfMemory
266       if (!myStart)
267         Standard_OutOfMemory::Raise ("NCollection_Array2 : Allocation failed");
268 #endif
269     }
270     // else myStart is set to the beginning of the given array
271     TheItemType** pTable = new TheItemType* [iColSize];
272 #if !defined No_Exception && !defined No_Standard_OutOfMemory
273     if (!pTable)
274       Standard_OutOfMemory::Raise ("NCollection_Array2 : Allocation failed");
275 #endif
276
277     // Items of pTable point to the '0'th items in the rows of the array
278     TheItemType* pRow = myStart - myLowerCol;
279     for (Standard_Integer i = 0; i < iColSize; i++) 
280     {
281       pTable[i] = pRow;
282       pRow += iRowSize;
283     }
284
285     // Set myData to the '0'th row pointer of the pTable
286     myData = pTable - myLowerRow;
287   }
288
289   //! Creates Iterator for use on BaseCollection
290   virtual TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& 
291     CreateIterator(void) const
292   { return *(new (this->IterAllocator()) Iterator(*this)); }
293
294  protected:
295   // ---------- PROTECTED FIELDS -----------
296   Standard_Integer myLowerRow;
297   Standard_Integer myUpperRow;
298   Standard_Integer myLowerCol;
299   Standard_Integer myUpperCol;
300
301   TheItemType**    myData;      //!< Pointer to the row pointers table
302   TheItemType*     myStart;     //!< Pointer to the memory array
303   Standard_Boolean myDeletable; //!< Flag showing who allocated the array
304
305   // ----------- FRIEND CLASSES ------------
306  friend class Iterator;
307
308 };
309
310 #endif