0022627: Change OCCT memory management defaults
[occt.git] / src / NCollection / NCollection_Vector.hxx
CommitLineData
7fd59977 1// File: NCollection_Vector.hxx
2// Created: 23.04.02 19:24:33
3// Author: Alexander GRIGORIEV
4// Copyright: Open Cascade 2002
5
6
7#ifndef NCollection_Vector_HeaderFile
8#define NCollection_Vector_HeaderFile
9
10#include <NCollection_BaseVector.hxx>
11#include <NCollection_BaseCollection.hxx>
12
13#if !defined No_Exception && !defined No_Standard_OutOfRange
14#include <Standard_OutOfRange.hxx>
15#endif
16
7fd59977 17/**
18* Class NCollection_Vector (dynamic array of objects)
19*
20* This class is similar to NCollection_Array1 though the indices always start
21* at 0 (in Array1 the first index must be specified)
22*
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-
28* date this index
29*
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.
34*
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.
39*/
40
41template <class TheItemType> class NCollection_Vector
42 : public NCollection_BaseCollection<TheItemType>,
43 public NCollection_BaseVector
44{
7fd59977 45 public:
23be7421 46 typedef TheItemType TheItemTypeD;
7fd59977 47 // ----------------------------------------------------------------------
48 //! Nested class MemBlock
49 class MemBlock : public NCollection_BaseVector::MemBlock
50 {
1c35b92f 51 public:
52 DEFINE_STANDARD_ALLOC
53
7fd59977 54 //! Empty constructor
23be7421
M
55 MemBlock (NCollection_BaseAllocator* theAlloc)
56 : NCollection_BaseVector::MemBlock(0,0,theAlloc)
57 {}
7fd59977 58 //! Constructor
59 MemBlock (const Standard_Integer theFirstInd,
23be7421
M
60 const Standard_Integer theSize,
61 NCollection_BaseAllocator* theAlloc)
62 : NCollection_BaseVector::MemBlock (theFirstInd, theSize, theAlloc)
63 {
64 myData = myAlloc->Allocate(theSize * sizeof(TheItemType));
0f633a22 65 for (Standard_Integer i=0; i < theSize; i++)
23be7421
M
66 new (&((TheItemType *) myData)[i]) TheItemType;
67 }
7fd59977 68 //! Copy constructor
69 MemBlock (const MemBlock& theOther)
23be7421
M
70 : NCollection_BaseVector::MemBlock (theOther.FirstIndex(),theOther.Size(),
71 theOther.myAlloc)
7fd59977 72 {
73 myLength = theOther.Length();
23be7421 74 myData = myAlloc->Allocate(Size() * sizeof(TheItemType));
0f633a22 75 Standard_Integer i;
23be7421
M
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;
7fd59977 80 }
81 //! Reinit
82 virtual void Reinit (const Standard_Integer theFirst,
0f633a22 83 const Standard_Integer theSize)
7fd59977 84 {
23be7421 85 if (myData) {
0f633a22 86 for (Standard_Integer i=0; i < mySize; i++)
23be7421
M
87 ((TheItemType *) myData)[i].~TheItemTypeD();
88 myAlloc->Free(myData);
89 myData = NULL;
90 }
91 if (theSize > 0) {
92 myData = myAlloc->Allocate(theSize * sizeof(TheItemType));
0f633a22 93 for (Standard_Integer i=0; i < theSize; i++)
23be7421
M
94 new (&((TheItemType *) myData)[i]) TheItemType;
95 }
7fd59977 96 myFirstInd = theFirst;
97 mySize = theSize;
98 myLength = 0;
99 }
100 //! Destructor
23be7421
M
101 virtual ~MemBlock ()
102 {
103 if (myData) {
0f633a22 104 for (Standard_Integer i=0; i < Size(); i++)
23be7421
M
105 ((TheItemType *) myData)[i].~TheItemTypeD();
106 myAlloc->Free(myData);
107 myData = NULL;
108 }
109 }
7fd59977 110 //! Operator () const
111 const TheItemType& Value (const Standard_Integer theIndex) const
112 { return ((TheItemType *) myData) [theIndex]; }
113 //! Operator ()
114 TheItemType& ChangeValue (const Standard_Integer theIndex)
115 { return ((TheItemType *) myData) [theIndex]; }
116 //! GetIndex
117 Standard_Integer GetIndex (const TheItemType& theItem) const {
118 return GetIndexV ((void *)&theItem, sizeof(TheItemType));
119 }
120 }; // End of the nested class MemBlock
121
122 // ----------------------------------------------------------------------
123 // ------------------------ Nested class Iterator -----------------------
124 // ----------------------------------------------------------------------
125 class Iterator : public NCollection_BaseCollection<TheItemType>::Iterator,
126 public NCollection_BaseVector::Iterator
127 {
128 public:
129 //! Empty constructor - for later Init
130 Iterator (void) {}
131 //! Constructor with initialisation
132 Iterator (const NCollection_Vector& theVector) :
133 NCollection_BaseVector::Iterator (theVector) {}
134 //! Copy constructor
135 Iterator (const Iterator& theOther) :
136 NCollection_BaseVector::Iterator (theOther) {}
137 //! Initialisation
138 void Init (const NCollection_Vector& theVector) { InitV (theVector); }
139 //! Assignment
140 Iterator& operator = (const Iterator& theOther) {
141 CopyV (theOther);
142 return * this;
143 }
144 //! Check end
145 virtual Standard_Boolean More (void) const { return MoreV (); }
146 //! Make step
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); }
7fd59977 154 }; // End of the nested class Iterator
155
156 // ----------------------------------------------------------------------
157 // ------------------------ Class Vector itself -------------------------
158 // ----------------------------------------------------------------------
159 public:
160 // ---------- PUBLIC METHODS ----------
161
162 //! Constructor
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) {}
168
169 //! Copy constructor
170 NCollection_Vector (const NCollection_Vector& theOther)
171 : NCollection_BaseCollection<TheItemType>(theOther.myAllocator),
172 NCollection_BaseVector (theOther, FuncDataInit, FuncDataFree)
173 { CopyData (theOther); }
174
175 //! Operator =
176 NCollection_Vector& operator = (const NCollection_Vector& theOther) {
177 if (this != &theOther) {
178 this->myAllocator = theOther.myAllocator;
179 NCollection_BaseVector::operator = (theOther);
180 CopyData (theOther);
181 }
182 return * this;
183 }
184
185 //! Total number of items in the vector
186 virtual Standard_Integer Size () const { return Length(); }
187
188 //! Virtual assignment (any collection to this array)
189 virtual void Assign (const NCollection_BaseCollection<TheItemType>& theOther)
190 {
191 if (this != &theOther) {
192 TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& anIter2 =
193 theOther.CreateIterator();
194 while (anIter2.More()) {
195 Append (anIter2.Value());
196 anIter2.Next();
197 }
198 }
199 }
200
201 //! Assignment to the collection of the same type
202 void Assign (const NCollection_Vector& theOther)
203 {
204 if (this != &theOther) {
205 NCollection_BaseVector::operator = (theOther);
206 CopyData (theOther);
207 }
208 }
209
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)); }
214
215 //! Append
216 TheItemType& Append (const TheItemType& theValue) {
217 TheItemType& anAppended = * (TheItemType *) ExpandV (myLength);
218 anAppended = theValue;
219 return anAppended;
220 }
221
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);
228 }
229
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);
236 }
237
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
242 if (theIndex < 0)
243 Standard_OutOfRange::Raise ("NCollection_Vector::SetValue");
244#endif
245 TheItemType * const aVecValue =
246 (TheItemType *)(theIndex<myLength? Find(theIndex): ExpandV(theIndex));
247 * aVecValue = theValue;
248 return * aVecValue;
249 }
250
251 private:
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();
262 anIter.Next();
263 }
264 aBlock.SetLength(i);
265 iBlock++;
266 }
267 }
268
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)
274 {
275 const NCollection_Vector& aSelf =
276 static_cast<const NCollection_Vector&> (theVector);
277 MemBlock * aData =
278 (MemBlock *) aSelf.myAllocator->Allocate(aCapacity * sizeof(MemBlock));
279 Standard_Integer i = 0;
280 if (aSource != NULL) {
281 memcpy (aData, aSource, aSize * sizeof(MemBlock));
282 i = aSize;
283 }
284 while (i < aCapacity)
23be7421 285 new (&aData[i++]) MemBlock(aSelf.myAllocator.operator->());
7fd59977 286 return aData;
287 }
288
289 static void FuncDataFree (const NCollection_BaseVector& theVector,
290 NCollection_BaseVector::MemBlock * aData)
291 {
292 const NCollection_Vector& aSelf =
293 static_cast<const NCollection_Vector&> (theVector);
294 aSelf.myAllocator->Free(aData);
295 }
296
297 friend class Iterator;
298};
299
7fd59977 300#endif