1 // Created on: 2002-04-23
2 // Created by: Alexander GRIGORIEV
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.
20 #ifndef NCollection_Vector_HeaderFile
21 #define NCollection_Vector_HeaderFile
23 #include <NCollection_BaseVector.hxx>
24 #include <NCollection_BaseCollection.hxx>
26 #if !defined No_Exception && !defined No_Standard_OutOfRange
27 #include <Standard_OutOfRange.hxx>
31 * Class NCollection_Vector (dynamic array of objects)
33 * This class is similar to NCollection_Array1 though the indices always start
34 * at 0 (in Array1 the first index must be specified)
36 * The Vector is always created with 0 length. It can be enlarged by two means:
37 * 1. Calling the method Append (val) - then "val" is added to the end of the
38 * vector (the vector length is incremented)
39 * 2. Calling the method SetValue (i, val) - if "i" is greater than or equal
40 * to the current length of the vector, the vector is enlarged to accomo-
43 * The methods Append and SetValue return a non-const reference to the copied
44 * object inside the vector. This reference is guaranteed to be valid until
45 * the vector is destroyed. It can be used to access the vector member directly
46 * or to pass its address to other data structures.
48 * The vector iterator remembers the length of the vector at the moment of the
49 * creation or initialisation of the iterator. Therefore the iteration begins
50 * at index 0 and stops at the index equal to (remembered_length-1). It is OK
51 * to enlarge the vector during the iteration.
54 template <class TheItemType> class NCollection_Vector
55 : public NCollection_BaseCollection<TheItemType>,
56 public NCollection_BaseVector
59 typedef TheItemType TheItemTypeD;
60 // ----------------------------------------------------------------------
61 //! Nested class MemBlock
62 class MemBlock : public NCollection_BaseVector::MemBlock
68 MemBlock (NCollection_BaseAllocator* theAlloc)
69 : NCollection_BaseVector::MemBlock(0,0,theAlloc)
72 MemBlock (const Standard_Integer theFirstInd,
73 const Standard_Integer theSize,
74 NCollection_BaseAllocator* theAlloc)
75 : NCollection_BaseVector::MemBlock (theFirstInd, theSize, theAlloc)
77 myData = myAlloc->Allocate(theSize * sizeof(TheItemType));
78 for (Standard_Integer i=0; i < theSize; i++)
79 new (&((TheItemType *) myData)[i]) TheItemType;
82 MemBlock (const MemBlock& theOther)
83 : NCollection_BaseVector::MemBlock (theOther.FirstIndex(),theOther.Size(),
86 myLength = theOther.Length();
87 myData = myAlloc->Allocate(Size() * sizeof(TheItemType));
89 for (i=0; i < Length(); i++)
90 new (&((TheItemType *) myData)[i]) TheItemType(theOther.Value(i));
91 for (; i < Size(); i++)
92 new (&((TheItemType *) myData)[i]) TheItemType;
95 virtual void Reinit (const Standard_Integer theFirst,
96 const Standard_Integer theSize)
99 for (Standard_Integer i=0; i < mySize; i++)
100 ((TheItemType *) myData)[i].~TheItemTypeD();
101 myAlloc->Free(myData);
105 myData = myAlloc->Allocate(theSize * sizeof(TheItemType));
106 for (Standard_Integer i=0; i < theSize; i++)
107 new (&((TheItemType *) myData)[i]) TheItemType;
109 myFirstInd = theFirst;
117 for (Standard_Integer i=0; i < Size(); i++)
118 ((TheItemType *) myData)[i].~TheItemTypeD();
119 myAlloc->Free(myData);
123 //! Operator () const
124 const TheItemType& Value (const Standard_Integer theIndex) const
125 { return ((TheItemType *) myData) [theIndex]; }
127 TheItemType& ChangeValue (const Standard_Integer theIndex)
128 { return ((TheItemType *) myData) [theIndex]; }
130 Standard_Integer GetIndex (const TheItemType& theItem) const {
131 return GetIndexV ((void *)&theItem, sizeof(TheItemType));
133 }; // End of the nested class MemBlock
135 // ----------------------------------------------------------------------
136 // ------------------------ Nested class Iterator -----------------------
137 // ----------------------------------------------------------------------
138 class Iterator : public NCollection_BaseCollection<TheItemType>::Iterator,
139 public NCollection_BaseVector::Iterator
142 //! Empty constructor - for later Init
144 //! Constructor with initialisation
145 Iterator (const NCollection_Vector& theVector) :
146 NCollection_BaseVector::Iterator (theVector) {}
148 Iterator (const Iterator& theOther) :
149 NCollection_BaseVector::Iterator (theOther) {}
151 void Init (const NCollection_Vector& theVector) { InitV (theVector); }
153 Iterator& operator = (const Iterator& theOther) {
158 virtual Standard_Boolean More (void) const { return MoreV (); }
160 virtual void Next (void) { NextV(); }
161 //! Constant value access
162 virtual const TheItemType& Value (void) const {
163 return ((const MemBlock *) CurBlockV()) -> Value(myCurIndex); }
164 //! Variable value access
165 virtual TheItemType& ChangeValue (void) const {
166 return ((MemBlock *) CurBlockV()) -> ChangeValue(myCurIndex); }
167 }; // End of the nested class Iterator
169 // ----------------------------------------------------------------------
170 // ------------------------ Class Vector itself -------------------------
171 // ----------------------------------------------------------------------
173 // ---------- PUBLIC METHODS ----------
176 NCollection_Vector (const Standard_Integer theIncrement = 256,
177 const Handle_NCollection_BaseAllocator& theAlloc = 0L)
178 : NCollection_BaseCollection<TheItemType>(theAlloc),
179 NCollection_BaseVector (sizeof(TheItemType), theIncrement,
180 FuncDataInit, FuncDataFree) {}
183 NCollection_Vector (const NCollection_Vector& theOther)
184 : NCollection_BaseCollection<TheItemType>(theOther.myAllocator),
185 NCollection_BaseVector (theOther, FuncDataInit, FuncDataFree)
186 { CopyData (theOther); }
189 NCollection_Vector& operator = (const NCollection_Vector& theOther) {
190 if (this != &theOther) {
191 this->myAllocator = theOther.myAllocator;
192 NCollection_BaseVector::operator = (theOther);
198 //! Total number of items in the vector
199 virtual Standard_Integer Size () const { return Length(); }
201 //! Method for consistency with other collections.
202 //! @return Lower bound (inclusive) for iteration.
203 Standard_Integer Lower() const
208 //! Method for consistency with other collections.
209 //! @return Upper bound (inclusive) for iteration.
210 Standard_Integer Upper() const
216 Standard_Boolean IsEmpty() const
218 return (Length() == 0);
221 //! Virtual assignment (any collection to this array)
222 virtual void Assign (const NCollection_BaseCollection<TheItemType>& theOther)
224 if (this != &theOther) {
225 TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& anIter2 =
226 theOther.CreateIterator();
227 while (anIter2.More()) {
228 Append (anIter2.Value());
234 //! Assignment to the collection of the same type
235 void Assign (const NCollection_Vector& theOther)
237 if (this != &theOther) {
238 NCollection_BaseVector::operator = (theOther);
243 //! Method to create iterators for base collections
244 virtual TYPENAME NCollection_BaseCollection<TheItemType>::Iterator&
245 CreateIterator(void) const
246 { return *(new (this->IterAllocator()) Iterator(*this)); }
249 TheItemType& Append (const TheItemType& theValue) {
250 TheItemType& anAppended = * (TheItemType *) ExpandV (myLength);
251 anAppended = theValue;
255 //! Operator () - query the const value
256 const TheItemType& operator () (const Standard_Integer theIndex) const
257 { return Value (theIndex); }
258 const TheItemType& Value (const Standard_Integer theIndex) const {
259 // if (myNBlocks == 1) return ((MemBlock *) myData) -> Value(theIndex);
260 return * (const TheItemType *) Find (theIndex);
263 //! @return first element
264 const TheItemType& First() const
266 return *(const TheItemType* )Find (Lower());
269 //! @return first element
270 TheItemType& ChangeFirst()
272 return *(TheItemType* )Find (Lower());
275 //! @return last element
276 const TheItemType& Last() const
278 return *(const TheItemType* )Find (Upper());
281 //! @return last element
282 TheItemType& ChangeLast()
284 return *(TheItemType* )Find (Upper());
287 //! Operator () - query the value
288 TheItemType& operator () (const Standard_Integer theIndex)
289 { return ChangeValue (theIndex); }
290 TheItemType& ChangeValue (const Standard_Integer theIndex) {
291 // if (myNBlocks == 1) return ((MemBlock *) myData) -> ChangeValue(theIndex);
292 return * (TheItemType *) Find (theIndex);
295 //! SetValue () - set or append a value
296 TheItemType& SetValue (const Standard_Integer theIndex,
297 const TheItemType& theValue) {
298 #if !defined No_Exception && !defined No_Standard_OutOfRange
300 Standard_OutOfRange::Raise ("NCollection_Vector::SetValue");
302 TheItemType * const aVecValue =
303 (TheItemType *)(theIndex<myLength? Find(theIndex): ExpandV(theIndex));
304 * aVecValue = theValue;
309 // ---------- PRIVATE METHODS ----------
310 void CopyData (const NCollection_Vector& theOther) {
311 Standard_Integer i, iBlock = 0;
312 /*NCollection_Vector::*/Iterator anIter (theOther);
313 for (int aLength = 0; aLength < myLength; aLength += myIncrement) {
314 MemBlock& aBlock = (MemBlock&) myData[iBlock];
315 aBlock.Reinit (aLength, myIncrement);
316 for (i = 0; i < myIncrement; i++) {
317 if (!anIter.More()) break;
318 aBlock.ChangeValue(i) = anIter.Value();
326 static NCollection_BaseVector::MemBlock * FuncDataInit
327 (const NCollection_BaseVector& theVector,
328 const Standard_Integer aCapacity,
329 const void * aSource,
330 const Standard_Integer aSize)
332 const NCollection_Vector& aSelf =
333 static_cast<const NCollection_Vector&> (theVector);
335 (MemBlock *) aSelf.myAllocator->Allocate(aCapacity * sizeof(MemBlock));
336 Standard_Integer i = 0;
337 if (aSource != NULL) {
338 memcpy (aData, aSource, aSize * sizeof(MemBlock));
341 while (i < aCapacity)
342 new (&aData[i++]) MemBlock(aSelf.myAllocator.operator->());
346 static void FuncDataFree (const NCollection_BaseVector& theVector,
347 NCollection_BaseVector::MemBlock * aData)
349 const NCollection_Vector& aSelf =
350 static_cast<const NCollection_Vector&> (theVector);
351 aSelf.myAllocator->Free(aData);
354 friend class Iterator;