OCC22540 Regression: Exception during building of patch by GeomPlate
[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
17#ifdef WNT
18// Disable the warning: "operator new unmatched by delete"
19#pragma warning (push)
20#pragma warning (disable:4291)
21#endif
22
23/**
24* Class NCollection_Vector (dynamic array of objects)
25*
26* This class is similar to NCollection_Array1 though the indices always start
27* at 0 (in Array1 the first index must be specified)
28*
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-
34* date this index
35*
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.
40*
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.
45*/
46
47template <class TheItemType> class NCollection_Vector
48 : public NCollection_BaseCollection<TheItemType>,
49 public NCollection_BaseVector
50{
7fd59977 51 public:
23be7421 52 typedef TheItemType TheItemTypeD;
7fd59977 53 // ----------------------------------------------------------------------
54 //! Nested class MemBlock
55 class MemBlock : public NCollection_BaseVector::MemBlock
56 {
57 public:
58 void * operator new (size_t, void * theAddress) { return theAddress; }
59 //! Empty constructor
23be7421
M
60 MemBlock (NCollection_BaseAllocator* theAlloc)
61 : NCollection_BaseVector::MemBlock(0,0,theAlloc)
62 {}
7fd59977 63 //! Constructor
64 MemBlock (const Standard_Integer theFirstInd,
23be7421
M
65 const Standard_Integer theSize,
66 NCollection_BaseAllocator* theAlloc)
67 : NCollection_BaseVector::MemBlock (theFirstInd, theSize, theAlloc)
68 {
69 myData = myAlloc->Allocate(theSize * sizeof(TheItemType));
70 for (size_t i=0; i < theSize; i++)
71 new (&((TheItemType *) myData)[i]) TheItemType;
72 }
7fd59977 73 //! Copy constructor
74 MemBlock (const MemBlock& theOther)
23be7421
M
75 : NCollection_BaseVector::MemBlock (theOther.FirstIndex(),theOther.Size(),
76 theOther.myAlloc)
7fd59977 77 {
78 myLength = theOther.Length();
23be7421
M
79 myData = myAlloc->Allocate(Size() * sizeof(TheItemType));
80 size_t i;
81 for (i=0; i < Length(); i++)
82 new (&((TheItemType *) myData)[i]) TheItemType(theOther.Value(i));
83 for (; i < Size(); i++)
84 new (&((TheItemType *) myData)[i]) TheItemType;
7fd59977 85 }
86 //! Reinit
87 virtual void Reinit (const Standard_Integer theFirst,
88 const size_t theSize)
89 {
23be7421
M
90 if (myData) {
91 for (size_t i=0; i < mySize; i++)
92 ((TheItemType *) myData)[i].~TheItemTypeD();
93 myAlloc->Free(myData);
94 myData = NULL;
95 }
96 if (theSize > 0) {
97 myData = myAlloc->Allocate(theSize * sizeof(TheItemType));
98 for (size_t i=0; i < theSize; i++)
99 new (&((TheItemType *) myData)[i]) TheItemType;
100 }
7fd59977 101 myFirstInd = theFirst;
102 mySize = theSize;
103 myLength = 0;
104 }
105 //! Destructor
23be7421
M
106 virtual ~MemBlock ()
107 {
108 if (myData) {
109 for (size_t i=0; i < Size(); i++)
110 ((TheItemType *) myData)[i].~TheItemTypeD();
111 myAlloc->Free(myData);
112 myData = NULL;
113 }
114 }
7fd59977 115 //! Operator () const
116 const TheItemType& Value (const Standard_Integer theIndex) const
117 { return ((TheItemType *) myData) [theIndex]; }
118 //! Operator ()
119 TheItemType& ChangeValue (const Standard_Integer theIndex)
120 { return ((TheItemType *) myData) [theIndex]; }
121 //! GetIndex
122 Standard_Integer GetIndex (const TheItemType& theItem) const {
123 return GetIndexV ((void *)&theItem, sizeof(TheItemType));
124 }
125 }; // End of the nested class MemBlock
126
127 // ----------------------------------------------------------------------
128 // ------------------------ Nested class Iterator -----------------------
129 // ----------------------------------------------------------------------
130 class Iterator : public NCollection_BaseCollection<TheItemType>::Iterator,
131 public NCollection_BaseVector::Iterator
132 {
133 public:
134 //! Empty constructor - for later Init
135 Iterator (void) {}
136 //! Constructor with initialisation
137 Iterator (const NCollection_Vector& theVector) :
138 NCollection_BaseVector::Iterator (theVector) {}
139 //! Copy constructor
140 Iterator (const Iterator& theOther) :
141 NCollection_BaseVector::Iterator (theOther) {}
142 //! Initialisation
143 void Init (const NCollection_Vector& theVector) { InitV (theVector); }
144 //! Assignment
145 Iterator& operator = (const Iterator& theOther) {
146 CopyV (theOther);
147 return * this;
148 }
149 //! Check end
150 virtual Standard_Boolean More (void) const { return MoreV (); }
151 //! Make step
152 virtual void Next (void) { NextV(); }
153 //! Constant value access
154 virtual const TheItemType& Value (void) const {
155 return ((const MemBlock *) CurBlockV()) -> Value(myCurIndex); }
156 //! Variable value access
157 virtual TheItemType& ChangeValue (void) const {
158 return ((MemBlock *) CurBlockV()) -> ChangeValue(myCurIndex); }
159 //! Operator new for allocating iterators
160 void* operator new(size_t theSize,
161 const Handle(NCollection_BaseAllocator)& theAllocator)
162 { return theAllocator->Allocate(theSize); }
163 }; // End of the nested class Iterator
164
165 // ----------------------------------------------------------------------
166 // ------------------------ Class Vector itself -------------------------
167 // ----------------------------------------------------------------------
168 public:
169 // ---------- PUBLIC METHODS ----------
170
171 //! Constructor
172 NCollection_Vector (const Standard_Integer theIncrement = 256,
173 const Handle_NCollection_BaseAllocator& theAlloc = 0L)
174 : NCollection_BaseCollection<TheItemType>(theAlloc),
175 NCollection_BaseVector (sizeof(TheItemType), theIncrement,
176 FuncDataInit, FuncDataFree) {}
177
178 //! Copy constructor
179 NCollection_Vector (const NCollection_Vector& theOther)
180 : NCollection_BaseCollection<TheItemType>(theOther.myAllocator),
181 NCollection_BaseVector (theOther, FuncDataInit, FuncDataFree)
182 { CopyData (theOther); }
183
184 //! Operator =
185 NCollection_Vector& operator = (const NCollection_Vector& theOther) {
186 if (this != &theOther) {
187 this->myAllocator = theOther.myAllocator;
188 NCollection_BaseVector::operator = (theOther);
189 CopyData (theOther);
190 }
191 return * this;
192 }
193
194 //! Total number of items in the vector
195 virtual Standard_Integer Size () const { return Length(); }
196
197 //! Virtual assignment (any collection to this array)
198 virtual void Assign (const NCollection_BaseCollection<TheItemType>& theOther)
199 {
200 if (this != &theOther) {
201 TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& anIter2 =
202 theOther.CreateIterator();
203 while (anIter2.More()) {
204 Append (anIter2.Value());
205 anIter2.Next();
206 }
207 }
208 }
209
210 //! Assignment to the collection of the same type
211 void Assign (const NCollection_Vector& theOther)
212 {
213 if (this != &theOther) {
214 NCollection_BaseVector::operator = (theOther);
215 CopyData (theOther);
216 }
217 }
218
219 //! Method to create iterators for base collections
220 virtual TYPENAME NCollection_BaseCollection<TheItemType>::Iterator&
221 CreateIterator(void) const
222 { return *(new (this->IterAllocator()) Iterator(*this)); }
223
224 //! Append
225 TheItemType& Append (const TheItemType& theValue) {
226 TheItemType& anAppended = * (TheItemType *) ExpandV (myLength);
227 anAppended = theValue;
228 return anAppended;
229 }
230
231 //! Operator () - query the const value
232 const TheItemType& operator () (const Standard_Integer theIndex) const
233 { return Value (theIndex); }
234 const TheItemType& Value (const Standard_Integer theIndex) const {
235// if (myNBlocks == 1) return ((MemBlock *) myData) -> Value(theIndex);
236 return * (const TheItemType *) Find (theIndex);
237 }
238
239 //! Operator () - query the value
240 TheItemType& operator () (const Standard_Integer theIndex)
241 { return ChangeValue (theIndex); }
242 TheItemType& ChangeValue (const Standard_Integer theIndex) {
243// if (myNBlocks == 1) return ((MemBlock *) myData) -> ChangeValue(theIndex);
244 return * (TheItemType *) Find (theIndex);
245 }
246
247 //! SetValue () - set or append a value
248 TheItemType& SetValue (const Standard_Integer theIndex,
249 const TheItemType& theValue) {
250#if !defined No_Exception && !defined No_Standard_OutOfRange
251 if (theIndex < 0)
252 Standard_OutOfRange::Raise ("NCollection_Vector::SetValue");
253#endif
254 TheItemType * const aVecValue =
255 (TheItemType *)(theIndex<myLength? Find(theIndex): ExpandV(theIndex));
256 * aVecValue = theValue;
257 return * aVecValue;
258 }
259
260 private:
261 // ---------- PRIVATE METHODS ----------
262 void CopyData (const NCollection_Vector& theOther) {
263 Standard_Integer i, iBlock = 0;
264 /*NCollection_Vector::*/Iterator anIter (theOther);
265 for (int aLength = 0; aLength < myLength; aLength += myIncrement) {
266 MemBlock& aBlock = (MemBlock&) myData[iBlock];
267 aBlock.Reinit (aLength, myIncrement);
268 for (i = 0; i < myIncrement; i++) {
269 if (!anIter.More()) break;
270 aBlock.ChangeValue(i) = anIter.Value();
271 anIter.Next();
272 }
273 aBlock.SetLength(i);
274 iBlock++;
275 }
276 }
277
278 static NCollection_BaseVector::MemBlock * FuncDataInit
279 (const NCollection_BaseVector& theVector,
280 const Standard_Integer aCapacity,
281 const void * aSource,
282 const Standard_Integer aSize)
283 {
284 const NCollection_Vector& aSelf =
285 static_cast<const NCollection_Vector&> (theVector);
286 MemBlock * aData =
287 (MemBlock *) aSelf.myAllocator->Allocate(aCapacity * sizeof(MemBlock));
288 Standard_Integer i = 0;
289 if (aSource != NULL) {
290 memcpy (aData, aSource, aSize * sizeof(MemBlock));
291 i = aSize;
292 }
293 while (i < aCapacity)
23be7421 294 new (&aData[i++]) MemBlock(aSelf.myAllocator.operator->());
7fd59977 295 return aData;
296 }
297
298 static void FuncDataFree (const NCollection_BaseVector& theVector,
299 NCollection_BaseVector::MemBlock * aData)
300 {
301 const NCollection_Vector& aSelf =
302 static_cast<const NCollection_Vector&> (theVector);
303 aSelf.myAllocator->Free(aData);
304 }
305
306 friend class Iterator;
307};
308
309#ifdef WNT
310#pragma warning (pop)
311#endif
312
313#endif