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 // Disable the warning: "operator new unmatched by delete"
19 #pragma warning (push)
20 #pragma warning (disable:4291)
24 * Class NCollection_Vector (dynamic array of objects)
26 * This class is similar to NCollection_Array1 though the indices always start
27 * at 0 (in Array1 the first index must be specified)
29 * The Vector is always created with 0 length. It can be enlarged by two means:
30 * 1. Calling the method Append (val) - then "val" is added to the end of the
31 * vector (the vector length is incremented)
32 * 2. Calling the method SetValue (i, val) - if "i" is greater than or equal
33 * to the current length of the vector, the vector is enlarged to accomo-
36 * The methods Append and SetValue return a non-const reference to the copied
37 * object inside the vector. This reference is guaranteed to be valid until
38 * the vector is destroyed. It can be used to access the vector member directly
39 * or to pass its address to other data structures.
41 * The vector iterator remembers the length of the vector at the moment of the
42 * creation or initialisation of the iterator. Therefore the iteration begins
43 * at index 0 and stops at the index equal to (remembered_length-1). It is OK
44 * to enlarge the vector during the iteration.
47 template <class TheItemType> class NCollection_Vector
48 : public NCollection_BaseCollection<TheItemType>,
49 public NCollection_BaseVector
51 // **************** Implementation of the Iterator interface.
53 // ----------------------------------------------------------------------
54 //! Nested class MemBlock
55 class MemBlock : public NCollection_BaseVector::MemBlock
58 void * operator new (size_t, void * theAddress) { return theAddress; }
60 MemBlock () : NCollection_BaseVector::MemBlock(0,0) {}
62 MemBlock (const Standard_Integer theFirstInd,
63 const Standard_Integer theSize)
64 : NCollection_BaseVector::MemBlock (theFirstInd, theSize)
65 { myData = new TheItemType [theSize]; }
67 MemBlock (const MemBlock& theOther)
68 : NCollection_BaseVector::MemBlock (theOther.FirstIndex(),theOther.Size())
70 myLength = theOther.Length();
71 myData = new TheItemType [Size()];
72 for (size_t i=0; i < Length(); i++)
73 ((TheItemType *) myData)[i] = theOther.Value(i);
76 virtual void Reinit (const Standard_Integer theFirst,
79 if (myData) delete [] (TheItemType *) myData;
80 myData = (theSize > 0) ? new TheItemType [theSize] : NULL;
81 myFirstInd = theFirst;
86 virtual ~MemBlock () { if (myData) delete [] (TheItemType *) myData; }
88 const TheItemType& Value (const Standard_Integer theIndex) const
89 { return ((TheItemType *) myData) [theIndex]; }
91 TheItemType& ChangeValue (const Standard_Integer theIndex)
92 { return ((TheItemType *) myData) [theIndex]; }
94 Standard_Integer GetIndex (const TheItemType& theItem) const {
95 return GetIndexV ((void *)&theItem, sizeof(TheItemType));
97 }; // End of the nested class MemBlock
99 // ----------------------------------------------------------------------
100 // ------------------------ Nested class Iterator -----------------------
101 // ----------------------------------------------------------------------
102 class Iterator : public NCollection_BaseCollection<TheItemType>::Iterator,
103 public NCollection_BaseVector::Iterator
106 //! Empty constructor - for later Init
108 //! Constructor with initialisation
109 Iterator (const NCollection_Vector& theVector) :
110 NCollection_BaseVector::Iterator (theVector) {}
112 Iterator (const Iterator& theOther) :
113 NCollection_BaseVector::Iterator (theOther) {}
115 void Init (const NCollection_Vector& theVector) { InitV (theVector); }
117 Iterator& operator = (const Iterator& theOther) {
122 virtual Standard_Boolean More (void) const { return MoreV (); }
124 virtual void Next (void) { NextV(); }
125 //! Constant value access
126 virtual const TheItemType& Value (void) const {
127 return ((const MemBlock *) CurBlockV()) -> Value(myCurIndex); }
128 //! Variable value access
129 virtual TheItemType& ChangeValue (void) const {
130 return ((MemBlock *) CurBlockV()) -> ChangeValue(myCurIndex); }
131 //! Operator new for allocating iterators
132 void* operator new(size_t theSize,
133 const Handle(NCollection_BaseAllocator)& theAllocator)
134 { return theAllocator->Allocate(theSize); }
135 }; // End of the nested class Iterator
137 // ----------------------------------------------------------------------
138 // ------------------------ Class Vector itself -------------------------
139 // ----------------------------------------------------------------------
141 // ---------- PUBLIC METHODS ----------
144 NCollection_Vector (const Standard_Integer theIncrement = 256,
145 const Handle_NCollection_BaseAllocator& theAlloc = 0L)
146 : NCollection_BaseCollection<TheItemType>(theAlloc),
147 NCollection_BaseVector (sizeof(TheItemType), theIncrement,
148 FuncDataInit, FuncDataFree) {}
151 NCollection_Vector (const NCollection_Vector& theOther)
152 : NCollection_BaseCollection<TheItemType>(theOther.myAllocator),
153 NCollection_BaseVector (theOther, FuncDataInit, FuncDataFree)
154 { CopyData (theOther); }
157 NCollection_Vector& operator = (const NCollection_Vector& theOther) {
158 if (this != &theOther) {
159 this->myAllocator = theOther.myAllocator;
160 NCollection_BaseVector::operator = (theOther);
166 //! Total number of items in the vector
167 virtual Standard_Integer Size () const { return Length(); }
169 //! Virtual assignment (any collection to this array)
170 virtual void Assign (const NCollection_BaseCollection<TheItemType>& theOther)
172 if (this != &theOther) {
173 TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& anIter2 =
174 theOther.CreateIterator();
175 while (anIter2.More()) {
176 Append (anIter2.Value());
182 //! Assignment to the collection of the same type
183 void Assign (const NCollection_Vector& theOther)
185 if (this != &theOther) {
186 NCollection_BaseVector::operator = (theOther);
191 //! Method to create iterators for base collections
192 virtual TYPENAME NCollection_BaseCollection<TheItemType>::Iterator&
193 CreateIterator(void) const
194 { return *(new (this->IterAllocator()) Iterator(*this)); }
197 TheItemType& Append (const TheItemType& theValue) {
198 TheItemType& anAppended = * (TheItemType *) ExpandV (myLength);
199 anAppended = theValue;
203 //! Operator () - query the const value
204 const TheItemType& operator () (const Standard_Integer theIndex) const
205 { return Value (theIndex); }
206 const TheItemType& Value (const Standard_Integer theIndex) const {
207 // if (myNBlocks == 1) return ((MemBlock *) myData) -> Value(theIndex);
208 return * (const TheItemType *) Find (theIndex);
211 //! Operator () - query the value
212 TheItemType& operator () (const Standard_Integer theIndex)
213 { return ChangeValue (theIndex); }
214 TheItemType& ChangeValue (const Standard_Integer theIndex) {
215 // if (myNBlocks == 1) return ((MemBlock *) myData) -> ChangeValue(theIndex);
216 return * (TheItemType *) Find (theIndex);
219 //! SetValue () - set or append a value
220 TheItemType& SetValue (const Standard_Integer theIndex,
221 const TheItemType& theValue) {
222 #if !defined No_Exception && !defined No_Standard_OutOfRange
224 Standard_OutOfRange::Raise ("NCollection_Vector::SetValue");
226 TheItemType * const aVecValue =
227 (TheItemType *)(theIndex<myLength? Find(theIndex): ExpandV(theIndex));
228 * aVecValue = theValue;
233 // ---------- PRIVATE METHODS ----------
234 void CopyData (const NCollection_Vector& theOther) {
235 Standard_Integer i, iBlock = 0;
236 /*NCollection_Vector::*/Iterator anIter (theOther);
237 for (int aLength = 0; aLength < myLength; aLength += myIncrement) {
238 MemBlock& aBlock = (MemBlock&) myData[iBlock];
239 aBlock.Reinit (aLength, myIncrement);
240 for (i = 0; i < myIncrement; i++) {
241 if (!anIter.More()) break;
242 aBlock.ChangeValue(i) = anIter.Value();
250 static NCollection_BaseVector::MemBlock * FuncDataInit
251 (const NCollection_BaseVector& theVector,
252 const Standard_Integer aCapacity,
253 const void * aSource,
254 const Standard_Integer aSize)
256 const NCollection_Vector& aSelf =
257 static_cast<const NCollection_Vector&> (theVector);
259 (MemBlock *) aSelf.myAllocator->Allocate(aCapacity * sizeof(MemBlock));
260 Standard_Integer i = 0;
261 if (aSource != NULL) {
262 memcpy (aData, aSource, aSize * sizeof(MemBlock));
265 while (i < aCapacity)
266 new (&aData[i++]) MemBlock;
270 static void FuncDataFree (const NCollection_BaseVector& theVector,
271 NCollection_BaseVector::MemBlock * aData)
273 const NCollection_Vector& aSelf =
274 static_cast<const NCollection_Vector&> (theVector);
275 aSelf.myAllocator->Free(aData);
278 friend class Iterator;
282 #pragma warning (pop)