1 // Created on: 2002-04-15
2 // Created by: Alexander Kartomin (akm)
3 // Copyright (c) 2002-2012 OPEN CASCADE SAS
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
21 #ifndef NCollection_Array2_HeaderFile
22 #define NCollection_Array2_HeaderFile
25 #include <Standard_DimensionMismatch.hxx>
26 #include <Standard_OutOfMemory.hxx>
27 #include <Standard_OutOfRange.hxx>
30 #include <NCollection_BaseCollection.hxx>
32 // *********************************************** Template for Array2 class
34 * Purpose: The class Array2 represents bi-dimensional arrays
35 * of fixed size known at run time.
36 * The ranges of indices are user defined.
38 * Warning: Programs clients of such class must be independant
39 * of the range of the first element. Then, a C++ for
40 * loop must be written like this
42 * for (i = A.LowerRow(); i <= A.UpperRow(); i++)
43 * for (j = A.LowerCol(); j <= A.UpperCol(); j++)
45 template <class TheItemType> class NCollection_Array2
46 : public NCollection_BaseCollection<TheItemType>
49 // **************** Implementation of the Iterator interface.
50 class Iterator : public NCollection_BaseCollection<TheItemType>::Iterator
53 //! Empty constructor - for later Init
58 //! Constructor with initialisation
59 Iterator (const NCollection_Array2& theArray) :
61 mySize (theArray.Length()),
62 myArray ((NCollection_Array2 *) &theArray) {}
64 void Init (const NCollection_Array2& theArray)
67 mySize = theArray.Length();
68 myArray = (NCollection_Array2 *) &theArray;
71 virtual Standard_Boolean More (void) const
72 { return (myCurrent < mySize); }
74 virtual void Next (void)
76 //! Constant value access
77 virtual const TheItemType& Value (void) const
78 { return myArray->myStart[myCurrent]; }
79 //! Variable value access
80 virtual TheItemType& ChangeValue (void) const
81 { return myArray->myStart[myCurrent]; }
83 Standard_Integer myCurrent; //!< Index of the current item
84 Standard_Integer mySize; //!< Total amount of items
85 NCollection_Array2* myArray; //!< Pointer to the array being iterated
86 }; // End of nested class Iterator
89 // ---------- PUBLIC METHODS ------------
92 NCollection_Array2(const Standard_Integer theRowLower,
93 const Standard_Integer theRowUpper,
94 const Standard_Integer theColLower,
95 const Standard_Integer theColUpper) :
96 NCollection_BaseCollection<TheItemType> (),
97 myLowerRow (theRowLower),
98 myUpperRow (theRowUpper),
99 myLowerCol (theColLower),
100 myUpperCol (theColUpper),
101 myDeletable (Standard_True)
105 NCollection_Array2 (const NCollection_Array2& theOther) :
106 NCollection_BaseCollection<TheItemType> (),
107 myLowerRow (theOther.LowerRow()),
108 myUpperRow (theOther.UpperRow()),
109 myLowerCol (theOther.LowerCol()),
110 myUpperCol (theOther.UpperCol()),
111 myDeletable (Standard_True)
117 //! C array-based constructor
118 NCollection_Array2(const TheItemType& theBegin,
119 const Standard_Integer theRowLower,
120 const Standard_Integer theRowUpper,
121 const Standard_Integer theColLower,
122 const Standard_Integer theColUpper) :
123 NCollection_BaseCollection<TheItemType> (),
124 myLowerRow (theRowLower),
125 myUpperRow (theRowUpper),
126 myLowerCol (theColLower),
127 myUpperCol (theColUpper),
128 myDeletable (Standard_False)
130 myStart = (TheItemType *) &theBegin;
134 //! Initialise the values
135 void Init (const TheItemType& theValue)
137 TheItemType *pCur, *pEnd=myStart+Size();
138 for(pCur = myStart; pCur<pEnd; pCur++)
142 //! Size (number of items)
143 virtual Standard_Integer Size (void) const
145 //! Length (number of items)
146 Standard_Integer Length (void) const
147 { return RowLength() * ColLength(); }
150 Standard_Integer RowLength (void) const
151 { return (myUpperCol-myLowerCol+1); }
153 Standard_Integer ColLength (void) const
154 { return (myUpperRow-myLowerRow+1); }
157 Standard_Integer LowerRow (void) const
158 { return myLowerRow; }
160 Standard_Integer UpperRow (void) const
161 { return myUpperRow; }
163 Standard_Integer LowerCol (void) const
164 { return myLowerCol; }
166 Standard_Integer UpperCol (void) const
167 { return myUpperCol; }
170 Standard_Boolean IsDeletable (void) const
171 { return myDeletable; }
174 // Copies items from the other collection into the allocated
175 // storage. Raises an exception when sizes differ.
176 virtual void Assign (const NCollection_BaseCollection<TheItemType>& theOther)
178 if (&theOther == this)
180 #if !defined No_Exception && !defined No_Standard_DimensionMismatch
181 if (Length() != theOther.Size())
182 Standard_DimensionMismatch::Raise ("NCollection_Array2::Assign");
184 TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& anIter2 =
185 theOther.CreateIterator();
186 const TheItemType* pEnd = myStart+Length();
187 for (TheItemType* pItem=myStart;
189 pItem++, anIter2.Next())
190 *pItem = anIter2.Value();
193 //! operator= (array to array)
194 NCollection_Array2& operator= (const NCollection_Array2& theOther)
196 if (&theOther == this)
198 #if !defined No_Exception && !defined No_Standard_DimensionMismatch
199 if (Length() != theOther.Length())
200 Standard_DimensionMismatch::Raise ("NCollection_Array2::operator=");
202 TheItemType * pMyItem = myStart;
203 TheItemType * pItem = theOther.myStart;
204 const Standard_Integer iSize = Length();
205 for (Standard_Integer i=0; i < iSize; i++, pItem++, pMyItem++)
210 //! Constant value access
211 const TheItemType& Value (const Standard_Integer theRow,
212 const Standard_Integer theCol) const
214 #if !defined No_Exception && !defined No_Standard_OutOfRange
215 if (theRow < myLowerRow || theRow > myUpperRow ||
216 theCol < myLowerCol || theCol > myUpperCol)
217 Standard_OutOfRange::Raise ("NCollection_Array2::Value");
219 return myData[theRow][theCol];
222 //! operator() - alias to ChangeValue
223 const TheItemType& operator() (const Standard_Integer theRow,
224 const Standard_Integer theCol) const
225 { return Value (theRow,theCol); }
227 //! Variable value access
228 TheItemType& ChangeValue (const Standard_Integer theRow,
229 const Standard_Integer theCol)
231 #if !defined No_Exception && !defined No_Standard_OutOfRange
232 if (theRow < myLowerRow || theRow > myUpperRow ||
233 theCol < myLowerCol || theCol > myUpperCol)
234 Standard_OutOfRange::Raise ("NCollection_Array2::ChangeValue");
236 return myData[theRow][theCol];
239 //! operator() - alias to ChangeValue
240 TheItemType& operator() (const Standard_Integer theRow,
241 const Standard_Integer theCol)
242 { return ChangeValue (theRow,theCol); }
245 void SetValue (const Standard_Integer theRow,
246 const Standard_Integer theCol,
247 const TheItemType& theItem)
249 #if !defined No_Exception && !defined No_Standard_OutOfRange
250 if (theRow < myLowerRow || theRow > myUpperRow ||
251 theCol < myLowerCol || theCol > myUpperCol)
252 Standard_OutOfRange::Raise ("NCollection_Array2::SetValue");
254 myData[theRow][theCol] = theItem;
257 //! Destructor - releases the memory
258 ~NCollection_Array2 (void)
260 if (myDeletable) delete [] myStart;
261 delete [] &(myData[myLowerRow]);
265 // ----------- PRIVATE METHODS -----------
267 //! Allocate memory for the array, set up indirection table
270 const Standard_Integer iRowSize = myUpperCol - myLowerCol + 1;
271 const Standard_Integer iColSize = myUpperRow - myLowerRow + 1;
272 #if !defined No_Exception && !defined No_Standard_RangeError
273 if (iRowSize <= 0 || iColSize <= 0)
274 Standard_RangeError::Raise ("NCollection_Array2::Allocate");
277 // allocation of the data in the array
278 myStart = new TheItemType[iRowSize * iColSize];
279 #if !defined No_Exception && !defined No_Standard_OutOfMemory
281 Standard_OutOfMemory::Raise ("NCollection_Array2 : Allocation failed");
284 // else myStart is set to the beginning of the given array
285 TheItemType** pTable = new TheItemType* [iColSize];
286 #if !defined No_Exception && !defined No_Standard_OutOfMemory
288 Standard_OutOfMemory::Raise ("NCollection_Array2 : Allocation failed");
291 // Items of pTable point to the '0'th items in the rows of the array
292 TheItemType* pRow = myStart - myLowerCol;
293 for (Standard_Integer i = 0; i < iColSize; i++)
299 // Set myData to the '0'th row pointer of the pTable
300 myData = pTable - myLowerRow;
303 //! Creates Iterator for use on BaseCollection
304 virtual TYPENAME NCollection_BaseCollection<TheItemType>::Iterator&
305 CreateIterator(void) const
306 { return *(new (this->IterAllocator()) Iterator(*this)); }
309 // ---------- PROTECTED FIELDS -----------
310 Standard_Integer myLowerRow;
311 Standard_Integer myUpperRow;
312 Standard_Integer myLowerCol;
313 Standard_Integer myUpperCol;
315 TheItemType** myData; //!< Pointer to the row pointers table
316 TheItemType* myStart; //!< Pointer to the memory array
317 Standard_Boolean myDeletable; //!< Flag showing who allocated the array
319 // ----------- FRIEND CLASSES ------------
320 friend class Iterator;