0024512: clang++ compiler complains about extra semicolon
[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//
973c2be1 7// This library is free software; you can redistribute it and / or modify it
8// under the terms of the GNU Lesser General Public version 2.1 as published
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{
43 public:
44 // **************** Implementation of the Iterator interface.
45 class Iterator : public NCollection_BaseCollection<TheItemType>::Iterator
46 {
47 public:
48 //! Empty constructor - for later Init
49 Iterator (void) :
50 myCurrent (0),
51 mySize (0),
52 myArray (NULL) {}
53 //! Constructor with initialisation
54 Iterator (const NCollection_Array2& theArray) :
55 myCurrent (0),
56 mySize (theArray.Length()),
57 myArray ((NCollection_Array2 *) &theArray) {}
58 //! Initialisation
59 void Init (const NCollection_Array2& theArray)
60 {
61 myCurrent = 0;
62 mySize = theArray.Length();
63 myArray = (NCollection_Array2 *) &theArray;
64 }
65 //! Check end
66 virtual Standard_Boolean More (void) const
67 { return (myCurrent < mySize); }
68 //! Make step
69 virtual void Next (void)
70 { myCurrent++; }
71 //! Constant value access
72 virtual const TheItemType& Value (void) const
73 { return myArray->myStart[myCurrent]; }
74 //! Variable value access
75 virtual TheItemType& ChangeValue (void) const
76 { return myArray->myStart[myCurrent]; }
7fd59977 77 private:
78 Standard_Integer myCurrent; //!< Index of the current item
79 Standard_Integer mySize; //!< Total amount of items
80 NCollection_Array2* myArray; //!< Pointer to the array being iterated
81 }; // End of nested class Iterator
82
83 public:
84 // ---------- PUBLIC METHODS ------------
85
86 //! Constructor
87 NCollection_Array2(const Standard_Integer theRowLower,
88 const Standard_Integer theRowUpper,
89 const Standard_Integer theColLower,
90 const Standard_Integer theColUpper) :
91 NCollection_BaseCollection<TheItemType> (),
92 myLowerRow (theRowLower),
93 myUpperRow (theRowUpper),
94 myLowerCol (theColLower),
95 myUpperCol (theColUpper),
96 myDeletable (Standard_True)
97 { Allocate(); }
98
99 //! Copy constructor
100 NCollection_Array2 (const NCollection_Array2& theOther) :
101 NCollection_BaseCollection<TheItemType> (),
102 myLowerRow (theOther.LowerRow()),
103 myUpperRow (theOther.UpperRow()),
104 myLowerCol (theOther.LowerCol()),
105 myUpperCol (theOther.UpperCol()),
106 myDeletable (Standard_True)
107 {
108 Allocate();
109 *this = theOther;
110 }
111
112 //! C array-based constructor
113 NCollection_Array2(const TheItemType& theBegin,
114 const Standard_Integer theRowLower,
115 const Standard_Integer theRowUpper,
116 const Standard_Integer theColLower,
117 const Standard_Integer theColUpper) :
118 NCollection_BaseCollection<TheItemType> (),
119 myLowerRow (theRowLower),
120 myUpperRow (theRowUpper),
121 myLowerCol (theColLower),
122 myUpperCol (theColUpper),
123 myDeletable (Standard_False)
124 {
125 myStart = (TheItemType *) &theBegin;
126 Allocate();
127 }
128
129 //! Initialise the values
130 void Init (const TheItemType& theValue)
131 {
132 TheItemType *pCur, *pEnd=myStart+Size();
133 for(pCur = myStart; pCur<pEnd; pCur++)
134 *pCur = theValue;
135 }
136
137 //! Size (number of items)
138 virtual Standard_Integer Size (void) const
139 { return Length(); }
140 //! Length (number of items)
141 Standard_Integer Length (void) const
142 { return RowLength() * ColLength(); }
143
144 //! RowLength
145 Standard_Integer RowLength (void) const
146 { return (myUpperCol-myLowerCol+1); }
147 //! ColLength
148 Standard_Integer ColLength (void) const
149 { return (myUpperRow-myLowerRow+1); }
150
151 //! LowerRow
152 Standard_Integer LowerRow (void) const
153 { return myLowerRow; }
154 //! UpperRow
155 Standard_Integer UpperRow (void) const
156 { return myUpperRow; }
157 //! LowerCol
158 Standard_Integer LowerCol (void) const
159 { return myLowerCol; }
160 //! UpperCol
161 Standard_Integer UpperCol (void) const
162 { return myUpperCol; }
163
164 //! myDeletable flag
165 Standard_Boolean IsDeletable (void) const
166 { return myDeletable; }
167
168 //! Assign
169 // Copies items from the other collection into the allocated
170 // storage. Raises an exception when sizes differ.
171 virtual void Assign (const NCollection_BaseCollection<TheItemType>& theOther)
172 {
173 if (&theOther == this)
174 return;
175#if !defined No_Exception && !defined No_Standard_DimensionMismatch
176 if (Length() != theOther.Size())
177 Standard_DimensionMismatch::Raise ("NCollection_Array2::Assign");
178#endif
179 TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& anIter2 =
180 theOther.CreateIterator();
181 const TheItemType* pEnd = myStart+Length();
182 for (TheItemType* pItem=myStart;
183 pItem < pEnd;
184 pItem++, anIter2.Next())
185 *pItem = anIter2.Value();
186 }
187
188 //! operator= (array to array)
189 NCollection_Array2& operator= (const NCollection_Array2& theOther)
190 {
191 if (&theOther == this)
192 return *this;
193#if !defined No_Exception && !defined No_Standard_DimensionMismatch
194 if (Length() != theOther.Length())
195 Standard_DimensionMismatch::Raise ("NCollection_Array2::operator=");
196#endif
197 TheItemType * pMyItem = myStart;
198 TheItemType * pItem = theOther.myStart;
199 const Standard_Integer iSize = Length();
200 for (Standard_Integer i=0; i < iSize; i++, pItem++, pMyItem++)
201 *pMyItem = *pItem;
202 return *this;
203 }
204
205 //! Constant value access
206 const TheItemType& Value (const Standard_Integer theRow,
207 const Standard_Integer theCol) const
208 {
209#if !defined No_Exception && !defined No_Standard_OutOfRange
210 if (theRow < myLowerRow || theRow > myUpperRow ||
211 theCol < myLowerCol || theCol > myUpperCol)
212 Standard_OutOfRange::Raise ("NCollection_Array2::Value");
213#endif
214 return myData[theRow][theCol];
215 }
216
217 //! operator() - alias to ChangeValue
218 const TheItemType& operator() (const Standard_Integer theRow,
219 const Standard_Integer theCol) const
220 { return Value (theRow,theCol); }
221
222 //! Variable value access
223 TheItemType& ChangeValue (const Standard_Integer theRow,
224 const Standard_Integer theCol)
225 {
226#if !defined No_Exception && !defined No_Standard_OutOfRange
227 if (theRow < myLowerRow || theRow > myUpperRow ||
228 theCol < myLowerCol || theCol > myUpperCol)
229 Standard_OutOfRange::Raise ("NCollection_Array2::ChangeValue");
230#endif
231 return myData[theRow][theCol];
232 }
233
234 //! operator() - alias to ChangeValue
235 TheItemType& operator() (const Standard_Integer theRow,
236 const Standard_Integer theCol)
237 { return ChangeValue (theRow,theCol); }
238
239 //! SetValue
240 void SetValue (const Standard_Integer theRow,
241 const Standard_Integer theCol,
242 const TheItemType& theItem)
243 {
244#if !defined No_Exception && !defined No_Standard_OutOfRange
245 if (theRow < myLowerRow || theRow > myUpperRow ||
246 theCol < myLowerCol || theCol > myUpperCol)
247 Standard_OutOfRange::Raise ("NCollection_Array2::SetValue");
248#endif
249 myData[theRow][theCol] = theItem;
250 }
251
252 //! Destructor - releases the memory
253 ~NCollection_Array2 (void)
254 {
255 if (myDeletable) delete [] myStart;
256 delete [] &(myData[myLowerRow]);
257 }
258
259 private:
260 // ----------- PRIVATE METHODS -----------
261
262 //! Allocate memory for the array, set up indirection table
263 void Allocate (void)
264 {
265 const Standard_Integer iRowSize = myUpperCol - myLowerCol + 1;
266 const Standard_Integer iColSize = myUpperRow - myLowerRow + 1;
267#if !defined No_Exception && !defined No_Standard_RangeError
268 if (iRowSize <= 0 || iColSize <= 0)
269 Standard_RangeError::Raise ("NCollection_Array2::Allocate");
270#endif
271 if (myDeletable) {
272 // allocation of the data in the array
273 myStart = new TheItemType[iRowSize * iColSize];
274#if !defined No_Exception && !defined No_Standard_OutOfMemory
275 if (!myStart)
276 Standard_OutOfMemory::Raise ("NCollection_Array2 : Allocation failed");
277#endif
278 }
279 // else myStart is set to the beginning of the given array
280 TheItemType** pTable = new TheItemType* [iColSize];
281#if !defined No_Exception && !defined No_Standard_OutOfMemory
282 if (!pTable)
283 Standard_OutOfMemory::Raise ("NCollection_Array2 : Allocation failed");
284#endif
285
286 // Items of pTable point to the '0'th items in the rows of the array
287 TheItemType* pRow = myStart - myLowerCol;
288 for (Standard_Integer i = 0; i < iColSize; i++)
289 {
290 pTable[i] = pRow;
291 pRow += iRowSize;
292 }
293
294 // Set myData to the '0'th row pointer of the pTable
295 myData = pTable - myLowerRow;
296 }
297
298 //! Creates Iterator for use on BaseCollection
299 virtual TYPENAME NCollection_BaseCollection<TheItemType>::Iterator&
300 CreateIterator(void) const
301 { return *(new (this->IterAllocator()) Iterator(*this)); }
302
303 protected:
304 // ---------- PROTECTED FIELDS -----------
305 Standard_Integer myLowerRow;
306 Standard_Integer myUpperRow;
307 Standard_Integer myLowerCol;
308 Standard_Integer myUpperCol;
309
310 TheItemType** myData; //!< Pointer to the row pointers table
311 TheItemType* myStart; //!< Pointer to the memory array
312 Standard_Boolean myDeletable; //!< Flag showing who allocated the array
313
314 // ----------- FRIEND CLASSES ------------
315 friend class Iterator;
316
317};
318
7fd59977 319#endif