1 // Created on: 2002-04-15
2 // Created by: Alexander Kartomin (akm)
3 // Copyright (c) 2002-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #ifndef NCollection_Array2_HeaderFile
17 #define NCollection_Array2_HeaderFile
20 #include <Standard_DimensionMismatch.hxx>
21 #include <Standard_OutOfMemory.hxx>
22 #include <Standard_OutOfRange.hxx>
25 #include <NCollection_BaseCollection.hxx>
27 // *********************************************** Template for Array2 class
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.
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
37 * for (i = A.LowerRow(); i <= A.UpperRow(); i++)
38 * for (j = A.LowerCol(); j <= A.UpperCol(); j++)
40 template <class TheItemType> class NCollection_Array2
41 : public NCollection_BaseCollection<TheItemType>
44 // **************** Implementation of the Iterator interface.
45 class Iterator : public NCollection_BaseCollection<TheItemType>::Iterator
48 //! Empty constructor - for later Init
53 //! Constructor with initialisation
54 Iterator (const NCollection_Array2& theArray) :
56 mySize (theArray.Length()),
57 myArray ((NCollection_Array2 *) &theArray) {}
59 void Init (const NCollection_Array2& theArray)
62 mySize = theArray.Length();
63 myArray = (NCollection_Array2 *) &theArray;
66 virtual Standard_Boolean More (void) const
67 { return (myCurrent < mySize); }
69 virtual void Next (void)
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]; }
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
84 // ---------- PUBLIC METHODS ------------
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)
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)
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)
125 myStart = (TheItemType *) &theBegin;
129 //! Initialise the values
130 void Init (const TheItemType& theValue)
132 TheItemType *pCur, *pEnd=myStart+Size();
133 for(pCur = myStart; pCur<pEnd; pCur++)
137 //! Size (number of items)
138 virtual Standard_Integer Size (void) const
140 //! Length (number of items)
141 Standard_Integer Length (void) const
142 { return RowLength() * ColLength(); }
145 Standard_Integer RowLength (void) const
146 { return (myUpperCol-myLowerCol+1); }
148 Standard_Integer ColLength (void) const
149 { return (myUpperRow-myLowerRow+1); }
152 Standard_Integer LowerRow (void) const
153 { return myLowerRow; }
155 Standard_Integer UpperRow (void) const
156 { return myUpperRow; }
158 Standard_Integer LowerCol (void) const
159 { return myLowerCol; }
161 Standard_Integer UpperCol (void) const
162 { return myUpperCol; }
165 Standard_Boolean IsDeletable (void) const
166 { return myDeletable; }
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)
173 if (&theOther == this)
175 #if !defined No_Exception && !defined No_Standard_DimensionMismatch
176 if (Length() != theOther.Size())
177 Standard_DimensionMismatch::Raise ("NCollection_Array2::Assign");
179 TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& anIter2 =
180 theOther.CreateIterator();
181 const TheItemType* pEnd = myStart+Length();
182 for (TheItemType* pItem=myStart;
184 pItem++, anIter2.Next())
185 *pItem = anIter2.Value();
188 //! operator= (array to array)
189 NCollection_Array2& operator= (const NCollection_Array2& theOther)
191 if (&theOther == this)
193 #if !defined No_Exception && !defined No_Standard_DimensionMismatch
194 if (Length() != theOther.Length())
195 Standard_DimensionMismatch::Raise ("NCollection_Array2::operator=");
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++)
205 //! Constant value access
206 const TheItemType& Value (const Standard_Integer theRow,
207 const Standard_Integer theCol) const
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");
214 return myData[theRow][theCol];
217 //! operator() - alias to ChangeValue
218 const TheItemType& operator() (const Standard_Integer theRow,
219 const Standard_Integer theCol) const
220 { return Value (theRow,theCol); }
222 //! Variable value access
223 TheItemType& ChangeValue (const Standard_Integer theRow,
224 const Standard_Integer theCol)
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");
231 return myData[theRow][theCol];
234 //! operator() - alias to ChangeValue
235 TheItemType& operator() (const Standard_Integer theRow,
236 const Standard_Integer theCol)
237 { return ChangeValue (theRow,theCol); }
240 void SetValue (const Standard_Integer theRow,
241 const Standard_Integer theCol,
242 const TheItemType& theItem)
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");
249 myData[theRow][theCol] = theItem;
252 //! Destructor - releases the memory
253 ~NCollection_Array2 (void)
255 if (myDeletable) delete [] myStart;
256 delete [] &(myData[myLowerRow]);
260 // ----------- PRIVATE METHODS -----------
262 //! Allocate memory for the array, set up indirection table
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");
272 // allocation of the data in the array
273 myStart = new TheItemType[iRowSize * iColSize];
274 #if !defined No_Exception && !defined No_Standard_OutOfMemory
276 Standard_OutOfMemory::Raise ("NCollection_Array2 : Allocation failed");
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
283 Standard_OutOfMemory::Raise ("NCollection_Array2 : Allocation failed");
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++)
294 // Set myData to the '0'th row pointer of the pTable
295 myData = pTable - myLowerRow;
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)); }
304 // ---------- PROTECTED FIELDS -----------
305 Standard_Integer myLowerRow;
306 Standard_Integer myUpperRow;
307 Standard_Integer myLowerCol;
308 Standard_Integer myUpperCol;
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
314 // ----------- FRIEND CLASSES ------------
315 friend class Iterator;