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.
22 #ifndef NCollection_Vector_HeaderFile
23 #define NCollection_Vector_HeaderFile
25 #include <NCollection_BaseVector.hxx>
26 #include <NCollection_BaseCollection.hxx>
28 #if !defined No_Exception && !defined No_Standard_OutOfRange
29 #include <Standard_OutOfRange.hxx>
33 * Class NCollection_Vector (dynamic array of objects)
35 * This class is similar to NCollection_Array1 though the indices always start
36 * at 0 (in Array1 the first index must be specified)
38 * The Vector is always created with 0 length. It can be enlarged by two means:
39 * 1. Calling the method Append (val) - then "val" is added to the end of the
40 * vector (the vector length is incremented)
41 * 2. Calling the method SetValue (i, val) - if "i" is greater than or equal
42 * to the current length of the vector, the vector is enlarged to accomo-
45 * The methods Append and SetValue return a non-const reference to the copied
46 * object inside the vector. This reference is guaranteed to be valid until
47 * the vector is destroyed. It can be used to access the vector member directly
48 * or to pass its address to other data structures.
50 * The vector iterator remembers the length of the vector at the moment of the
51 * creation or initialisation of the iterator. Therefore the iteration begins
52 * at index 0 and stops at the index equal to (remembered_length-1). It is OK
53 * to enlarge the vector during the iteration.
56 template <class TheItemType> class NCollection_Vector
57 : public NCollection_BaseCollection<TheItemType>,
58 public NCollection_BaseVector
61 typedef TheItemType TheItemTypeD;
62 // ----------------------------------------------------------------------
63 //! Nested class MemBlock
64 class MemBlock : public NCollection_BaseVector::MemBlock
70 MemBlock (NCollection_BaseAllocator* theAlloc)
71 : NCollection_BaseVector::MemBlock(0,0,theAlloc)
74 MemBlock (const Standard_Integer theFirstInd,
75 const Standard_Integer theSize,
76 NCollection_BaseAllocator* theAlloc)
77 : NCollection_BaseVector::MemBlock (theFirstInd, theSize, theAlloc)
79 myData = myAlloc->Allocate(theSize * sizeof(TheItemType));
80 for (Standard_Integer i=0; i < theSize; i++)
81 new (&((TheItemType *) myData)[i]) TheItemType;
84 MemBlock (const MemBlock& theOther)
85 : NCollection_BaseVector::MemBlock (theOther.FirstIndex(),theOther.Size(),
88 myLength = theOther.Length();
89 myData = myAlloc->Allocate(Size() * sizeof(TheItemType));
91 for (i=0; i < Length(); i++)
92 new (&((TheItemType *) myData)[i]) TheItemType(theOther.Value(i));
93 for (; i < Size(); i++)
94 new (&((TheItemType *) myData)[i]) TheItemType;
97 virtual void Reinit (const Standard_Integer theFirst,
98 const Standard_Integer theSize)
101 for (Standard_Integer i=0; i < mySize; i++)
102 ((TheItemType *) myData)[i].~TheItemTypeD();
103 myAlloc->Free(myData);
107 myData = myAlloc->Allocate(theSize * sizeof(TheItemType));
108 for (Standard_Integer i=0; i < theSize; i++)
109 new (&((TheItemType *) myData)[i]) TheItemType;
111 myFirstInd = theFirst;
119 for (Standard_Integer i=0; i < Size(); i++)
120 ((TheItemType *) myData)[i].~TheItemTypeD();
121 myAlloc->Free(myData);
125 //! Operator () const
126 const TheItemType& Value (const Standard_Integer theIndex) const
127 { return ((TheItemType *) myData) [theIndex]; }
129 TheItemType& ChangeValue (const Standard_Integer theIndex)
130 { return ((TheItemType *) myData) [theIndex]; }
132 Standard_Integer GetIndex (const TheItemType& theItem) const {
133 return GetIndexV ((void *)&theItem, sizeof(TheItemType));
135 }; // End of the nested class MemBlock
137 // ----------------------------------------------------------------------
138 // ------------------------ Nested class Iterator -----------------------
139 // ----------------------------------------------------------------------
140 class Iterator : public NCollection_BaseCollection<TheItemType>::Iterator,
141 public NCollection_BaseVector::Iterator
144 //! Empty constructor - for later Init
146 //! Constructor with initialisation
147 Iterator (const NCollection_Vector& theVector) :
148 NCollection_BaseVector::Iterator (theVector) {}
150 Iterator (const Iterator& theOther) :
151 NCollection_BaseVector::Iterator (theOther) {}
153 void Init (const NCollection_Vector& theVector) { InitV (theVector); }
155 Iterator& operator = (const Iterator& theOther) {
160 virtual Standard_Boolean More (void) const { return MoreV (); }
162 virtual void Next (void) { NextV(); }
163 //! Constant value access
164 virtual const TheItemType& Value (void) const {
165 return ((const MemBlock *) CurBlockV()) -> Value(myCurIndex); }
166 //! Variable value access
167 virtual TheItemType& ChangeValue (void) const {
168 return ((MemBlock *) CurBlockV()) -> ChangeValue(myCurIndex); }
169 }; // End of the nested class Iterator
171 // ----------------------------------------------------------------------
172 // ------------------------ Class Vector itself -------------------------
173 // ----------------------------------------------------------------------
175 // ---------- PUBLIC METHODS ----------
178 NCollection_Vector (const Standard_Integer theIncrement = 256,
179 const Handle_NCollection_BaseAllocator& theAlloc = 0L)
180 : NCollection_BaseCollection<TheItemType>(theAlloc),
181 NCollection_BaseVector (sizeof(TheItemType), theIncrement,
182 FuncDataInit, FuncDataFree) {}
185 NCollection_Vector (const NCollection_Vector& theOther)
186 : NCollection_BaseCollection<TheItemType>(theOther.myAllocator),
187 NCollection_BaseVector (theOther, FuncDataInit, FuncDataFree)
188 { CopyData (theOther); }
191 NCollection_Vector& operator = (const NCollection_Vector& theOther) {
192 if (this != &theOther) {
193 this->myAllocator = theOther.myAllocator;
194 NCollection_BaseVector::operator = (theOther);
200 //! Total number of items in the vector
201 virtual Standard_Integer Size () const { return Length(); }
203 //! Virtual assignment (any collection to this array)
204 virtual void Assign (const NCollection_BaseCollection<TheItemType>& theOther)
206 if (this != &theOther) {
207 TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& anIter2 =
208 theOther.CreateIterator();
209 while (anIter2.More()) {
210 Append (anIter2.Value());
216 //! Assignment to the collection of the same type
217 void Assign (const NCollection_Vector& theOther)
219 if (this != &theOther) {
220 NCollection_BaseVector::operator = (theOther);
225 //! Method to create iterators for base collections
226 virtual TYPENAME NCollection_BaseCollection<TheItemType>::Iterator&
227 CreateIterator(void) const
228 { return *(new (this->IterAllocator()) Iterator(*this)); }
231 TheItemType& Append (const TheItemType& theValue) {
232 TheItemType& anAppended = * (TheItemType *) ExpandV (myLength);
233 anAppended = theValue;
237 //! Operator () - query the const value
238 const TheItemType& operator () (const Standard_Integer theIndex) const
239 { return Value (theIndex); }
240 const TheItemType& Value (const Standard_Integer theIndex) const {
241 // if (myNBlocks == 1) return ((MemBlock *) myData) -> Value(theIndex);
242 return * (const TheItemType *) Find (theIndex);
245 //! Operator () - query the value
246 TheItemType& operator () (const Standard_Integer theIndex)
247 { return ChangeValue (theIndex); }
248 TheItemType& ChangeValue (const Standard_Integer theIndex) {
249 // if (myNBlocks == 1) return ((MemBlock *) myData) -> ChangeValue(theIndex);
250 return * (TheItemType *) Find (theIndex);
253 //! SetValue () - set or append a value
254 TheItemType& SetValue (const Standard_Integer theIndex,
255 const TheItemType& theValue) {
256 #if !defined No_Exception && !defined No_Standard_OutOfRange
258 Standard_OutOfRange::Raise ("NCollection_Vector::SetValue");
260 TheItemType * const aVecValue =
261 (TheItemType *)(theIndex<myLength? Find(theIndex): ExpandV(theIndex));
262 * aVecValue = theValue;
267 // ---------- PRIVATE METHODS ----------
268 void CopyData (const NCollection_Vector& theOther) {
269 Standard_Integer i, iBlock = 0;
270 /*NCollection_Vector::*/Iterator anIter (theOther);
271 for (int aLength = 0; aLength < myLength; aLength += myIncrement) {
272 MemBlock& aBlock = (MemBlock&) myData[iBlock];
273 aBlock.Reinit (aLength, myIncrement);
274 for (i = 0; i < myIncrement; i++) {
275 if (!anIter.More()) break;
276 aBlock.ChangeValue(i) = anIter.Value();
284 static NCollection_BaseVector::MemBlock * FuncDataInit
285 (const NCollection_BaseVector& theVector,
286 const Standard_Integer aCapacity,
287 const void * aSource,
288 const Standard_Integer aSize)
290 const NCollection_Vector& aSelf =
291 static_cast<const NCollection_Vector&> (theVector);
293 (MemBlock *) aSelf.myAllocator->Allocate(aCapacity * sizeof(MemBlock));
294 Standard_Integer i = 0;
295 if (aSource != NULL) {
296 memcpy (aData, aSource, aSize * sizeof(MemBlock));
299 while (i < aCapacity)
300 new (&aData[i++]) MemBlock(aSelf.myAllocator.operator->());
304 static void FuncDataFree (const NCollection_BaseVector& theVector,
305 NCollection_BaseVector::MemBlock * aData)
307 const NCollection_Vector& aSelf =
308 static_cast<const NCollection_Vector&> (theVector);
309 aSelf.myAllocator->Free(aData);
312 friend class Iterator;