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_Array1_HeaderFile
17 #define NCollection_Array1_HeaderFile
20 #include <Standard_DimensionMismatch.hxx>
21 #include <Standard_OutOfMemory.hxx>
22 #include <Standard_OutOfRange.hxx>
25 #include <NCollection_DefineAlloc.hxx>
26 #include <NCollection_StlIterator.hxx>
28 // *********************************************** Template for Array1 class
31 * Purpose: The class Array1 represents unidimensional arrays
32 * of fixed size known at run time.
33 * The range of the index is user defined.
34 * An array1 can be constructed with a "C array".
35 * This functionality is useful to call methods expecting
36 * an Array1. It allows to carry the bounds inside the arrays.
38 * Examples: Item tab[100]; // An example with a C array
39 * Array1OfItem ttab (tab[0],1,100);
41 * Array1OfItem tttab (ttab(10),10,20); // a slice of ttab
43 * If you want to reindex an array from 1 to Length do :
45 * Array1 tab1(tab(tab.Lower()),1,tab.Length());
47 * Warning: Programs client of such a class must be independant
48 * of the range of the first element. Then, a C++ for
49 * loop must be written like this
51 * for (i = A.Lower(); i <= A.Upper(); i++)
53 * Changes: In comparison to TCollection the flag isAllocated was
54 * renamed into myDeletable (alike in the Array2). For naming
55 * compatibility the method IsAllocated remained in class along
58 template <class TheItemType>
59 class NCollection_Array1
62 //! STL-compliant typedef for value type
63 typedef TheItemType value_type;
66 //! Implementation of the Iterator interface.
71 //! Empty constructor - for later Init
79 //! Constructor with initialization
80 Iterator (const NCollection_Array1& theArray, Standard_Boolean theToEnd = Standard_False) :
81 myPtrEnd (const_cast<TheItemType*> (&theArray.Last() + 1))
83 myPtrCur = theToEnd ? myPtrEnd : const_cast<TheItemType*> (&theArray.First());
87 void Init (const NCollection_Array1& theArray)
89 myPtrCur = const_cast<TheItemType*> (&theArray.First());
90 myPtrEnd = const_cast<TheItemType*> (&theArray.Last() + 1);
94 Iterator& operator= (const Iterator& theOther)
96 myPtrCur = theOther.myPtrCur;
97 myPtrEnd = theOther.myPtrEnd;
102 Standard_Boolean More (void) const
103 { return myPtrCur < myPtrEnd; }
105 //! Increment operator
109 //! Decrement operator
114 void Offset (ptrdiff_t theOffset)
115 { myPtrCur += theOffset; }
117 //! Difference operator.
118 ptrdiff_t Differ (const Iterator& theOther) const
119 { return myPtrCur - theOther.myPtrCur; }
121 //! Constant value access
122 const TheItemType& Value (void) const
123 { return *myPtrCur; }
125 //! Variable value access
126 TheItemType& ChangeValue (void) const
127 { return *myPtrCur; }
129 //! Performs comparison of two iterators
130 Standard_Boolean IsEqual (const Iterator& theOther) const
131 { return myPtrCur == theOther.myPtrCur; }
134 TheItemType* myPtrCur; //!< Pointer to the current element in the array
135 TheItemType* myPtrEnd; //!< Pointer to the past-the-end element in the array
136 }; // End of the nested class Iterator
138 //! Shorthand for a regular iterator type.
139 typedef NCollection_StlIterator<std::random_access_iterator_tag, Iterator, TheItemType, false> iterator;
141 //! Shorthand for a constant iterator type.
142 typedef NCollection_StlIterator<std::random_access_iterator_tag, Iterator, TheItemType, true> const_iterator;
144 //! Returns an iterator pointing to the first element in the array.
145 iterator begin() const { return Iterator (*this, false); }
147 //! Returns an iterator referring to the past-the-end element in the array.
148 iterator end() const { return Iterator (*this, true); }
150 //! Returns a const iterator pointing to the first element in the array.
151 const_iterator cbegin() const { return Iterator (*this, false); }
153 //! Returns a const iterator referring to the past-the-end element in the array.
154 const_iterator cend() const { return Iterator (*this, true); }
157 // ---------- PUBLIC METHODS ------------
160 NCollection_Array1(const Standard_Integer theLower,
161 const Standard_Integer theUpper) :
162 myLowerBound (theLower),
163 myUpperBound (theUpper),
164 myDeletable (Standard_True)
166 #if !defined No_Exception && !defined No_Standard_RangeError
167 if (theUpper < theLower)
168 Standard_RangeError::Raise ("NCollection_Array1::Create");
170 TheItemType* pBegin = new TheItemType[Length()];
171 #if !defined No_Exception && !defined No_Standard_OutOfMemory
173 Standard_OutOfMemory::Raise ("NCollection_Array1 : Allocation failed");
176 myData = pBegin - theLower;
180 NCollection_Array1 (const NCollection_Array1& theOther) :
181 myLowerBound (theOther.Lower()),
182 myUpperBound (theOther.Upper()),
183 myDeletable (Standard_True)
185 TheItemType* pBegin = new TheItemType[Length()];
186 #if !defined No_Exception && !defined No_Standard_OutOfMemory
188 Standard_OutOfMemory::Raise ("NCollection_Array1 : Allocation failed");
190 myData = pBegin - myLowerBound;
195 //! C array-based constructor
196 NCollection_Array1 (const TheItemType& theBegin,
197 const Standard_Integer theLower,
198 const Standard_Integer theUpper) :
199 myLowerBound (theLower),
200 myUpperBound (theUpper),
201 myDeletable (Standard_False)
203 #if !defined No_Exception && !defined No_Standard_RangeError
204 if (theUpper < theLower)
205 Standard_RangeError::Raise ("NCollection_Array1::Array1");
207 myData = (TheItemType *) &theBegin - theLower;
210 //! Initialise the items with theValue
211 void Init (const TheItemType& theValue)
213 TheItemType *pCur = &myData[myLowerBound], *pEnd=&myData[myUpperBound];
214 for(; pCur <= pEnd; pCur++)
215 *pCur = (TheItemType&) theValue;
219 Standard_Integer Size (void) const
221 //! Length query (the same)
222 Standard_Integer Length (void) const
223 { return (myUpperBound-myLowerBound+1); }
226 Standard_Integer Lower (void) const
227 { return myLowerBound; }
229 Standard_Integer Upper (void) const
230 { return myUpperBound; }
233 Standard_Boolean IsDeletable (void) const
234 { return myDeletable; }
236 //! IsAllocated flag - for naming compatibility
237 Standard_Boolean IsAllocated (void) const
238 { return myDeletable; }
241 NCollection_Array1& Assign (const NCollection_Array1& theOther)
243 if (&theOther == this)
245 #if !defined No_Exception && !defined No_Standard_DimensionMismatch
246 if (Length() != theOther.Length())
247 Standard_DimensionMismatch::Raise ("NCollection_Array1::operator=");
249 TheItemType * pMyItem = &myData[myLowerBound];
250 TheItemType * const pEndItem = &(theOther.myData)[theOther.myUpperBound];
251 TheItemType * pItem = &(theOther.myData)[theOther.myLowerBound];
252 while (pItem <= pEndItem) * pMyItem ++ = * pItem ++;
256 //! Assignment operator
257 NCollection_Array1& operator= (const NCollection_Array1& theOther)
259 return Assign (theOther);
262 //! @return first element
263 const TheItemType& First() const
265 return myData[myLowerBound];
268 //! @return first element
269 TheItemType& ChangeFirst()
271 return myData[myLowerBound];
274 //! @return last element
275 const TheItemType& Last() const
277 return myData[myUpperBound];
280 //! @return last element
281 TheItemType& ChangeLast()
283 return myData[myUpperBound];
286 //! Constant value access
287 const TheItemType& Value (const Standard_Integer theIndex) const
289 #if !defined No_Exception && !defined No_Standard_OutOfRange
290 if (theIndex < myLowerBound || theIndex > myUpperBound)
291 Standard_OutOfRange::Raise ("NCollection_Array1::Value");
293 return myData[theIndex];
296 //! operator() - alias to Value
297 const TheItemType& operator() (const Standard_Integer theIndex) const
298 { return Value (theIndex); }
300 //! Variable value access
301 TheItemType& ChangeValue (const Standard_Integer theIndex)
303 #if !defined No_Exception && !defined No_Standard_OutOfRange
304 if (theIndex < myLowerBound || theIndex > myUpperBound)
305 Standard_OutOfRange::Raise ("NCollection_Array1::ChangeValue");
307 return myData[theIndex];
310 //! operator() - alias to ChangeValue
311 TheItemType& operator() (const Standard_Integer theIndex)
312 { return ChangeValue (theIndex); }
315 void SetValue (const Standard_Integer theIndex,
316 const TheItemType& theItem)
318 #if !defined No_Exception && !defined No_Standard_OutOfRange
319 if (theIndex < myLowerBound || theIndex > myUpperBound)
320 Standard_OutOfRange::Raise ("NCollection_Array1::SetValue");
322 myData[theIndex] = theItem;
325 //! Destructor - releases the memory
326 ~NCollection_Array1 (void)
327 { if (myDeletable) delete [] &(myData[myLowerBound]); }
330 // ---------- PROTECTED FIELDS -----------
331 Standard_Integer myLowerBound;
332 Standard_Integer myUpperBound;
333 Standard_Boolean myDeletable; //!< Flag showing who allocated the array
334 TheItemType* myData; //!< Pointer to '0'th array item