1 // File: NCollection_Vector.hxx
2 // Created: 23.04.02 19:24:33
3 // Author: Alexander GRIGORIEV
4 // Copyright: Open Cascade 2002
7 #ifndef NCollection_Vector_HeaderFile
8 #define NCollection_Vector_HeaderFile
10 #include <NCollection_BaseVector.hxx>
11 #include <NCollection_BaseCollection.hxx>
13 #if !defined No_Exception && !defined No_Standard_OutOfRange
14 #include <Standard_OutOfRange.hxx>
18 * Class NCollection_Vector (dynamic array of objects)
20 * This class is similar to NCollection_Array1 though the indices always start
21 * at 0 (in Array1 the first index must be specified)
23 * The Vector is always created with 0 length. It can be enlarged by two means:
24 * 1. Calling the method Append (val) - then "val" is added to the end of the
25 * vector (the vector length is incremented)
26 * 2. Calling the method SetValue (i, val) - if "i" is greater than or equal
27 * to the current length of the vector, the vector is enlarged to accomo-
30 * The methods Append and SetValue return a non-const reference to the copied
31 * object inside the vector. This reference is guaranteed to be valid until
32 * the vector is destroyed. It can be used to access the vector member directly
33 * or to pass its address to other data structures.
35 * The vector iterator remembers the length of the vector at the moment of the
36 * creation or initialisation of the iterator. Therefore the iteration begins
37 * at index 0 and stops at the index equal to (remembered_length-1). It is OK
38 * to enlarge the vector during the iteration.
41 template <class TheItemType> class NCollection_Vector
42 : public NCollection_BaseCollection<TheItemType>,
43 public NCollection_BaseVector
46 typedef TheItemType TheItemTypeD;
47 // ----------------------------------------------------------------------
48 //! Nested class MemBlock
49 class MemBlock : public NCollection_BaseVector::MemBlock
55 MemBlock (NCollection_BaseAllocator* theAlloc)
56 : NCollection_BaseVector::MemBlock(0,0,theAlloc)
59 MemBlock (const Standard_Integer theFirstInd,
60 const Standard_Integer theSize,
61 NCollection_BaseAllocator* theAlloc)
62 : NCollection_BaseVector::MemBlock (theFirstInd, theSize, theAlloc)
64 myData = myAlloc->Allocate(theSize * sizeof(TheItemType));
65 for (Standard_Integer i=0; i < theSize; i++)
66 new (&((TheItemType *) myData)[i]) TheItemType;
69 MemBlock (const MemBlock& theOther)
70 : NCollection_BaseVector::MemBlock (theOther.FirstIndex(),theOther.Size(),
73 myLength = theOther.Length();
74 myData = myAlloc->Allocate(Size() * sizeof(TheItemType));
76 for (i=0; i < Length(); i++)
77 new (&((TheItemType *) myData)[i]) TheItemType(theOther.Value(i));
78 for (; i < Size(); i++)
79 new (&((TheItemType *) myData)[i]) TheItemType;
82 virtual void Reinit (const Standard_Integer theFirst,
83 const Standard_Integer theSize)
86 for (Standard_Integer i=0; i < mySize; i++)
87 ((TheItemType *) myData)[i].~TheItemTypeD();
88 myAlloc->Free(myData);
92 myData = myAlloc->Allocate(theSize * sizeof(TheItemType));
93 for (Standard_Integer i=0; i < theSize; i++)
94 new (&((TheItemType *) myData)[i]) TheItemType;
96 myFirstInd = theFirst;
104 for (Standard_Integer i=0; i < Size(); i++)
105 ((TheItemType *) myData)[i].~TheItemTypeD();
106 myAlloc->Free(myData);
110 //! Operator () const
111 const TheItemType& Value (const Standard_Integer theIndex) const
112 { return ((TheItemType *) myData) [theIndex]; }
114 TheItemType& ChangeValue (const Standard_Integer theIndex)
115 { return ((TheItemType *) myData) [theIndex]; }
117 Standard_Integer GetIndex (const TheItemType& theItem) const {
118 return GetIndexV ((void *)&theItem, sizeof(TheItemType));
120 }; // End of the nested class MemBlock
122 // ----------------------------------------------------------------------
123 // ------------------------ Nested class Iterator -----------------------
124 // ----------------------------------------------------------------------
125 class Iterator : public NCollection_BaseCollection<TheItemType>::Iterator,
126 public NCollection_BaseVector::Iterator
129 //! Empty constructor - for later Init
131 //! Constructor with initialisation
132 Iterator (const NCollection_Vector& theVector) :
133 NCollection_BaseVector::Iterator (theVector) {}
135 Iterator (const Iterator& theOther) :
136 NCollection_BaseVector::Iterator (theOther) {}
138 void Init (const NCollection_Vector& theVector) { InitV (theVector); }
140 Iterator& operator = (const Iterator& theOther) {
145 virtual Standard_Boolean More (void) const { return MoreV (); }
147 virtual void Next (void) { NextV(); }
148 //! Constant value access
149 virtual const TheItemType& Value (void) const {
150 return ((const MemBlock *) CurBlockV()) -> Value(myCurIndex); }
151 //! Variable value access
152 virtual TheItemType& ChangeValue (void) const {
153 return ((MemBlock *) CurBlockV()) -> ChangeValue(myCurIndex); }
154 }; // End of the nested class Iterator
156 // ----------------------------------------------------------------------
157 // ------------------------ Class Vector itself -------------------------
158 // ----------------------------------------------------------------------
160 // ---------- PUBLIC METHODS ----------
163 NCollection_Vector (const Standard_Integer theIncrement = 256,
164 const Handle_NCollection_BaseAllocator& theAlloc = 0L)
165 : NCollection_BaseCollection<TheItemType>(theAlloc),
166 NCollection_BaseVector (sizeof(TheItemType), theIncrement,
167 FuncDataInit, FuncDataFree) {}
170 NCollection_Vector (const NCollection_Vector& theOther)
171 : NCollection_BaseCollection<TheItemType>(theOther.myAllocator),
172 NCollection_BaseVector (theOther, FuncDataInit, FuncDataFree)
173 { CopyData (theOther); }
176 NCollection_Vector& operator = (const NCollection_Vector& theOther) {
177 if (this != &theOther) {
178 this->myAllocator = theOther.myAllocator;
179 NCollection_BaseVector::operator = (theOther);
185 //! Total number of items in the vector
186 virtual Standard_Integer Size () const { return Length(); }
188 //! Virtual assignment (any collection to this array)
189 virtual void Assign (const NCollection_BaseCollection<TheItemType>& theOther)
191 if (this != &theOther) {
192 TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& anIter2 =
193 theOther.CreateIterator();
194 while (anIter2.More()) {
195 Append (anIter2.Value());
201 //! Assignment to the collection of the same type
202 void Assign (const NCollection_Vector& theOther)
204 if (this != &theOther) {
205 NCollection_BaseVector::operator = (theOther);
210 //! Method to create iterators for base collections
211 virtual TYPENAME NCollection_BaseCollection<TheItemType>::Iterator&
212 CreateIterator(void) const
213 { return *(new (this->IterAllocator()) Iterator(*this)); }
216 TheItemType& Append (const TheItemType& theValue) {
217 TheItemType& anAppended = * (TheItemType *) ExpandV (myLength);
218 anAppended = theValue;
222 //! Operator () - query the const value
223 const TheItemType& operator () (const Standard_Integer theIndex) const
224 { return Value (theIndex); }
225 const TheItemType& Value (const Standard_Integer theIndex) const {
226 // if (myNBlocks == 1) return ((MemBlock *) myData) -> Value(theIndex);
227 return * (const TheItemType *) Find (theIndex);
230 //! Operator () - query the value
231 TheItemType& operator () (const Standard_Integer theIndex)
232 { return ChangeValue (theIndex); }
233 TheItemType& ChangeValue (const Standard_Integer theIndex) {
234 // if (myNBlocks == 1) return ((MemBlock *) myData) -> ChangeValue(theIndex);
235 return * (TheItemType *) Find (theIndex);
238 //! SetValue () - set or append a value
239 TheItemType& SetValue (const Standard_Integer theIndex,
240 const TheItemType& theValue) {
241 #if !defined No_Exception && !defined No_Standard_OutOfRange
243 Standard_OutOfRange::Raise ("NCollection_Vector::SetValue");
245 TheItemType * const aVecValue =
246 (TheItemType *)(theIndex<myLength? Find(theIndex): ExpandV(theIndex));
247 * aVecValue = theValue;
252 // ---------- PRIVATE METHODS ----------
253 void CopyData (const NCollection_Vector& theOther) {
254 Standard_Integer i, iBlock = 0;
255 /*NCollection_Vector::*/Iterator anIter (theOther);
256 for (int aLength = 0; aLength < myLength; aLength += myIncrement) {
257 MemBlock& aBlock = (MemBlock&) myData[iBlock];
258 aBlock.Reinit (aLength, myIncrement);
259 for (i = 0; i < myIncrement; i++) {
260 if (!anIter.More()) break;
261 aBlock.ChangeValue(i) = anIter.Value();
269 static NCollection_BaseVector::MemBlock * FuncDataInit
270 (const NCollection_BaseVector& theVector,
271 const Standard_Integer aCapacity,
272 const void * aSource,
273 const Standard_Integer aSize)
275 const NCollection_Vector& aSelf =
276 static_cast<const NCollection_Vector&> (theVector);
278 (MemBlock *) aSelf.myAllocator->Allocate(aCapacity * sizeof(MemBlock));
279 Standard_Integer i = 0;
280 if (aSource != NULL) {
281 memcpy (aData, aSource, aSize * sizeof(MemBlock));
284 while (i < aCapacity)
285 new (&aData[i++]) MemBlock(aSelf.myAllocator.operator->());
289 static void FuncDataFree (const NCollection_BaseVector& theVector,
290 NCollection_BaseVector::MemBlock * aData)
292 const NCollection_Vector& aSelf =
293 static_cast<const NCollection_Vector&> (theVector);
294 aSelf.myAllocator->Free(aData);
297 friend class Iterator;