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