0022815: Missing delete operator for placement new
[occt.git] / src / NCollection / NCollection_Array2.hxx
CommitLineData
7fd59977 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
7fd59977 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*/
31template <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]; }
7fd59977 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
7fd59977 310#endif