1 // File: NCollection_Array1.hxx
2 // Created: 15.04.02 17:05:16
3 // Author: Alexander Kartomin (akm)
4 // <a-kartomin@opencascade.com>
5 // Copyright: Open Cascade 2002
7 #ifndef NCollection_Array1_HeaderFile
8 #define NCollection_Array1_HeaderFile
11 #include <Standard_DimensionMismatch.hxx>
12 #include <Standard_OutOfMemory.hxx>
13 #include <Standard_OutOfRange.hxx>
16 #include <NCollection_BaseCollection.hxx>
18 // *********************************************** Template for Array1 class
21 * Purpose: The class Array1 represents unidimensional arrays
22 * of fixed size known at run time.
23 * The range of the index is user defined.
24 * An array1 can be constructed with a "C array".
25 * This functionality is useful to call methods expecting
26 * an Array1. It allows to carry the bounds inside the arrays.
28 * Examples: Item tab[100]; // An example with a C array
29 * Array1OfItem ttab (tab[0],1,100);
31 * Array1OfItem tttab (ttab(10),10,20); // a slice of ttab
33 * If you want to reindex an array from 1 to Length do :
35 * Array1 tab1(tab(tab.Lower()),1,tab.Length());
37 * Warning: Programs client of such a class must be independant
38 * of the range of the first element. Then, a C++ for
39 * loop must be written like this
41 * for (i = A.Lower(); i <= A.Upper(); i++)
43 * Changes: In comparison to TCollection the flag isAllocated was
44 * renamed into myDeletable (alike in the Array2). For naming
45 * compatibility the method IsAllocated remained in class along
48 template <class TheItemType> class NCollection_Array1
49 : public NCollection_BaseCollection<TheItemType>
53 //! Implementation of the Iterator interface.
54 class Iterator : public NCollection_BaseCollection<TheItemType>::Iterator
57 //! Empty constructor - for later Init
61 //! Constructor with initialisation
62 Iterator (const NCollection_Array1& theArray) :
63 myCurrent (theArray.Lower()),
64 myArray ((NCollection_Array1 *) &theArray) {}
66 void Init (const NCollection_Array1& theArray)
68 myCurrent = theArray.Lower();
69 myArray = (NCollection_Array1 *) &theArray;
72 virtual Standard_Boolean More (void) const
73 { return (myCurrent<=myArray->Upper()); }
75 virtual void Next (void)
77 //! Constant value access
78 virtual const TheItemType& Value (void) const
79 { return myArray->Value(myCurrent); }
80 //! Variable value access
81 virtual TheItemType& ChangeValue (void) const
82 { return myArray->ChangeValue(myCurrent); }
84 Standard_Integer myCurrent; //!< Index of the current item
85 NCollection_Array1* myArray; //!< Pointer to the array being iterated
86 }; // End of the nested class Iterator
89 // ---------- PUBLIC METHODS ------------
92 NCollection_Array1(const Standard_Integer theLower,
93 const Standard_Integer theUpper) :
94 NCollection_BaseCollection<TheItemType> (),
95 myLowerBound (theLower),
96 myUpperBound (theUpper),
97 myDeletable (Standard_True)
99 #if !defined No_Exception && !defined No_Standard_RangeError
100 if (theUpper < theLower)
101 Standard_RangeError::Raise ("NCollection_Array1::Create");
103 TheItemType* pBegin = new TheItemType[Length()];
104 #if !defined No_Exception && !defined No_Standard_OutOfMemory
106 Standard_OutOfMemory::Raise ("NCollection_Array1 : Allocation failed");
109 myData = pBegin - theLower;
113 NCollection_Array1 (const NCollection_Array1& theOther) :
114 NCollection_BaseCollection<TheItemType> (),
115 myLowerBound (theOther.Lower()),
116 myUpperBound (theOther.Upper()),
117 myDeletable (Standard_True)
119 TheItemType* pBegin = new TheItemType[Length()];
120 #if !defined No_Exception && !defined No_Standard_OutOfMemory
122 Standard_OutOfMemory::Raise ("NCollection_Array1 : Allocation failed");
124 myData = pBegin - myLowerBound;
129 //! C array-based constructor
130 NCollection_Array1 (const TheItemType& theBegin,
131 const Standard_Integer theLower,
132 const Standard_Integer theUpper) :
133 NCollection_BaseCollection<TheItemType> (),
134 myLowerBound (theLower),
135 myUpperBound (theUpper),
136 myDeletable (Standard_False)
138 #if !defined No_Exception && !defined No_Standard_RangeError
139 if (theUpper < theLower)
140 Standard_RangeError::Raise ("NCollection_Array1::Array1");
142 myData = (TheItemType *) &theBegin - theLower;
145 //! Initialise the items with theValue
146 void Init (const TheItemType& theValue)
148 TheItemType *pCur = &myData[myLowerBound], *pEnd=&myData[myUpperBound];
149 for(; pCur <= pEnd; pCur++)
150 *pCur = (TheItemType&) theValue;
154 virtual Standard_Integer Size (void) const
156 //! Length query (the same)
157 Standard_Integer Length (void) const
158 { return (myUpperBound-myLowerBound+1); }
161 Standard_Integer Lower (void) const
162 { return myLowerBound; }
164 Standard_Integer Upper (void) const
165 { return myUpperBound; }
168 Standard_Boolean IsDeletable (void) const
169 { return myDeletable; }
171 //! IsAllocated flag - for naming compatibility
172 Standard_Boolean IsAllocated (void) const
173 { return myDeletable; }
175 //! Assign (any collection to this array)
176 // Copies items from the other collection into the allocated
177 // storage. Raises an exception when sizes differ.
178 virtual void Assign (const NCollection_BaseCollection<TheItemType>& theOther)
180 if (&theOther == this)
182 #if !defined No_Exception && !defined No_Standard_DimensionMismatch
183 if (Length() != theOther.Size())
184 Standard_DimensionMismatch::Raise ("NCollection_Array1::Assign");
186 TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& anIter2 =
187 theOther.CreateIterator();
188 TheItemType * const pEndItem = &myData[myUpperBound];
189 for (TheItemType * pItem = &myData[myLowerBound];
190 pItem <= pEndItem; anIter2.Next())
191 * pItem ++ = anIter2.Value();
194 //! operator= (array to array)
195 NCollection_Array1& operator= (const NCollection_Array1& theOther)
197 if (&theOther == this)
199 #if !defined No_Exception && !defined No_Standard_DimensionMismatch
200 if (Length() != theOther.Length())
201 Standard_DimensionMismatch::Raise ("NCollection_Array1::operator=");
203 TheItemType * pMyItem = &myData[myLowerBound];
204 TheItemType * const pEndItem = &(theOther.myData)[theOther.myUpperBound];
205 TheItemType * pItem = &(theOther.myData)[theOther.myLowerBound];
206 while (pItem <= pEndItem) * pMyItem ++ = * pItem ++;
210 //! Constant value access
211 const TheItemType& Value (const Standard_Integer theIndex) const
213 #if !defined No_Exception && !defined No_Standard_OutOfRange
214 if (theIndex < myLowerBound || theIndex > myUpperBound)
215 Standard_OutOfRange::Raise ("NCollection_Array1::Value");
217 return myData[theIndex];
220 //! operator() - alias to Value
221 const TheItemType& operator() (const Standard_Integer theIndex) const
222 { return Value (theIndex); }
224 //! Variable value access
225 TheItemType& ChangeValue (const Standard_Integer theIndex)
227 #if !defined No_Exception && !defined No_Standard_OutOfRange
228 if (theIndex < myLowerBound || theIndex > myUpperBound)
229 Standard_OutOfRange::Raise ("NCollection_Array1::ChangeValue");
231 return myData[theIndex];
234 //! operator() - alias to ChangeValue
235 TheItemType& operator() (const Standard_Integer theIndex)
236 { return ChangeValue (theIndex); }
239 void SetValue (const Standard_Integer theIndex,
240 const TheItemType& theItem)
242 #if !defined No_Exception && !defined No_Standard_OutOfRange
243 if (theIndex < myLowerBound || theIndex > myUpperBound)
244 Standard_OutOfRange::Raise ("NCollection_Array1::SetValue");
246 myData[theIndex] = theItem;
249 //! Destructor - releases the memory
250 ~NCollection_Array1 (void)
251 { if (myDeletable) delete [] &(myData[myLowerBound]); }
254 // ----------- PRIVATE METHODS -----------
256 // ******** Creates Iterator for use on BaseCollection
258 TYPENAME NCollection_BaseCollection<TheItemType>::Iterator&
259 CreateIterator(void) const
260 { return *(new (this->IterAllocator()) Iterator(*this)); }
263 // ---------- PROTECTED FIELDS -----------
264 Standard_Integer myLowerBound;
265 Standard_Integer myUpperBound;
266 Standard_Boolean myDeletable; //!< Flag showing who allocated the array
267 TheItemType* myData; //!< Pointer to '0'th array item