0031671: Coding Rules - eliminate warnings issued by clang 11
[occt.git] / src / NCollection / NCollection_Vector.hxx
CommitLineData
b311480e 1// Created on: 2002-04-23
2// Created by: Alexander GRIGORIEV
f4aad56f 3// Copyright (c) 2002-2013 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
b311480e 15
7fd59977 16#ifndef NCollection_Vector_HeaderFile
17#define NCollection_Vector_HeaderFile
18
19#include <NCollection_BaseVector.hxx>
79a35943 20#include <NCollection_StlIterator.hxx>
7fd59977 21
f4aad56f 22//! Class NCollection_Vector (dynamic array of objects)
23//!
24//! This class is similar to NCollection_Array1 though the indices always start
25//! at 0 (in Array1 the first index must be specified)
26//!
27//! The Vector is always created with 0 length. It can be enlarged by two means:
28//! 1. Calling the method Append (val) - then "val" is added to the end of the
29//! vector (the vector length is incremented)
30//! 2. Calling the method SetValue (i, val) - if "i" is greater than or equal
31//! to the current length of the vector, the vector is enlarged to accomo-
32//! date this index
33//!
34//! The methods Append and SetValue return a non-const reference to the copied
35//! object inside the vector. This reference is guaranteed to be valid until
36//! the vector is destroyed. It can be used to access the vector member directly
37//! or to pass its address to other data structures.
38//!
39//! The vector iterator remembers the length of the vector at the moment of the
40//! creation or initialisation of the iterator. Therefore the iteration begins
41//! at index 0 and stops at the index equal to (remembered_length-1). It is OK
42//! to enlarge the vector during the iteration.
ddf2fe8e 43template <class TheItemType>
44class NCollection_Vector : public NCollection_BaseVector
7fd59977 45{
f4aad56f 46public:
79a35943 47 //! STL-compliant typedef for value type
48 typedef TheItemType value_type;
f4aad56f 49
79a35943 50public:
7fd59977 51
f4aad56f 52 //! Nested class Iterator
ddf2fe8e 53 class Iterator : public NCollection_BaseVector::Iterator
7fd59977 54 {
55 public:
f4aad56f 56
7fd59977 57 //! Empty constructor - for later Init
f4aad56f 58 Iterator() {}
59
7fd59977 60 //! Constructor with initialisation
79a35943 61 Iterator (const NCollection_Vector& theVector, Standard_Boolean theToEnd = Standard_False)
62 : NCollection_BaseVector::Iterator (theVector, theToEnd) {}
f4aad56f 63
7fd59977 64 //! Initialisation
f4aad56f 65 void Init (const NCollection_Vector& theVector)
66 {
67 initV (theVector);
68 }
69
7fd59977 70 //! Check end
ddf2fe8e 71 Standard_Boolean More() const
f4aad56f 72 {
73 return moreV();
74 }
75
79a35943 76 //! Increment operator.
ddf2fe8e 77 void Next()
f4aad56f 78 {
79 nextV();
80 }
81
79a35943 82 //! Decrement operator.
ddf2fe8e 83 void Previous()
79a35943 84 {
85 prevV();
86 }
87
88 //! Offset operator.
ddf2fe8e 89 void Offset (ptrdiff_t theOffset)
79a35943 90 {
ddf2fe8e 91 offsetV (static_cast<int>(theOffset));
79a35943 92 }
93
94 //! Difference operator.
ddf2fe8e 95 ptrdiff_t Differ (const Iterator& theOther) const
79a35943 96 {
97 return differV (theOther);
98 }
99
7fd59977 100 //! Constant value access
ddf2fe8e 101 const TheItemType& Value() const
f4aad56f 102 {
103 return ((const TheItemType* )curBlockV()->DataPtr)[myCurIndex];
104 }
105
7fd59977 106 //! Variable value access
ddf2fe8e 107 TheItemType& ChangeValue() const
f4aad56f 108 {
109 return ((TheItemType* )curBlockV()->DataPtr)[myCurIndex];
110 }
111
79a35943 112 //! Performs comparison of two iterators.
ddf2fe8e 113 Standard_Boolean IsEqual (const Iterator& theOther) const
79a35943 114 {
115 return myVector == theOther.myVector
116 && myCurIndex == theOther.myCurIndex
117 && myEndIndex == theOther.myEndIndex
118 && myICurBlock == theOther.myICurBlock
119 && myIEndBlock == theOther.myIEndBlock;
120 }
f4aad56f 121 };
7fd59977 122
79a35943 123 //! Shorthand for a regular iterator type.
124 typedef NCollection_StlIterator<std::random_access_iterator_tag, Iterator, TheItemType, false> iterator;
125
126 //! Shorthand for a constant iterator type.
127 typedef NCollection_StlIterator<std::random_access_iterator_tag, Iterator, TheItemType, true> const_iterator;
128
129 //! Returns an iterator pointing to the first element in the vector.
130 iterator begin() const { return Iterator (*this, false); }
131
132 //! Returns an iterator referring to the past-the-end element in the vector.
133 iterator end() const { return Iterator (*this, true); }
134
135 //! Returns a const iterator pointing to the first element in the vector.
136 const_iterator cbegin() const { return Iterator (*this, false); }
137
138 //! Returns a const iterator referring to the past-the-end element in the vector.
139 const_iterator cend() const { return Iterator (*this, true); }
140
f4aad56f 141public: //! @name public methods
7fd59977 142
143 //! Constructor
3a5a656c 144 explicit NCollection_Vector (const Standard_Integer theIncrement = 256,
145 const Handle(NCollection_BaseAllocator)& theAlloc = NULL) :
ddf2fe8e 146 NCollection_BaseVector (theAlloc, initMemBlocks, sizeof(TheItemType), theIncrement)
147 {}
7fd59977 148
149 //! Copy constructor
ddf2fe8e 150 NCollection_Vector (const NCollection_Vector& theOther) :
151 NCollection_BaseVector (theOther.myAllocator, initMemBlocks, theOther)
f4aad56f 152 {
153 copyData (theOther);
154 }
155
156 //! Destructor
6928e351 157 virtual ~NCollection_Vector()
f4aad56f 158 {
159 for (Standard_Integer anItemIter = 0; anItemIter < myCapacity; ++anItemIter)
160 {
161 initMemBlocks (*this, myData[anItemIter], 0, 0);
7fd59977 162 }
ddf2fe8e 163 this->myAllocator->Free (myData);
f4aad56f 164 }
165
166 //! Total number of items
167 Standard_Integer Length() const
168 {
169 return myLength;
7fd59977 170 }
171
172 //! Total number of items in the vector
ddf2fe8e 173 Standard_Integer Size() const
f4aad56f 174 {
175 return myLength;
176 }
7fd59977 177
a174a3c5 178 //! Method for consistency with other collections.
179 //! @return Lower bound (inclusive) for iteration.
180 Standard_Integer Lower() const
181 {
182 return 0;
183 }
184
185 //! Method for consistency with other collections.
186 //! @return Upper bound (inclusive) for iteration.
187 Standard_Integer Upper() const
188 {
f4aad56f 189 return myLength - 1;
a174a3c5 190 }
191
192 //! Empty query
193 Standard_Boolean IsEmpty() const
194 {
f4aad56f 195 return (myLength == 0);
a174a3c5 196 }
197
7fd59977 198 //! Assignment to the collection of the same type
f4aad56f 199 inline void Assign (const NCollection_Vector& theOther,
ddf2fe8e 200 const Standard_Boolean theOwnAllocator = Standard_True);
7fd59977 201
ddf2fe8e 202 //! Assignment operator
203 NCollection_Vector& operator= (const NCollection_Vector& theOther)
f4aad56f 204 {
ddf2fe8e 205 Assign (theOther, Standard_False);
206 return *this;
f4aad56f 207 }
7fd59977 208
209 //! Append
f4aad56f 210 TheItemType& Append (const TheItemType& theValue)
211 {
ddf2fe8e 212 TheItemType& anAppended = *(TheItemType* )expandV (myLength);
7fd59977 213 anAppended = theValue;
214 return anAppended;
215 }
216
1155d05a 217 //! Appends an empty value and returns the reference to it
218 TheItemType& Appended ()
219 {
220 TheItemType& anAppended = *(TheItemType* )expandV (myLength);
221 return anAppended;
222 }
223
f4aad56f 224 //! Operator() - query the const value
225 const TheItemType& operator() (const Standard_Integer theIndex) const
226 {
227 return Value (theIndex);
228 }
229
b8f7f608 230 //! Operator[] - query the const value
231 const TheItemType& operator[] (Standard_Integer theIndex) const { return Value (theIndex); }
232
f4aad56f 233 const TheItemType& Value (const Standard_Integer theIndex) const
234 {
235 return *(const TheItemType* )findV (theIndex);
7fd59977 236 }
237
a174a3c5 238 //! @return first element
239 const TheItemType& First() const
240 {
f4aad56f 241 return *(const TheItemType* )findV (Lower());
a174a3c5 242 }
243
244 //! @return first element
245 TheItemType& ChangeFirst()
246 {
f4aad56f 247 return *(TheItemType* )findV (Lower());
a174a3c5 248 }
249
250 //! @return last element
251 const TheItemType& Last() const
252 {
f4aad56f 253 return *(const TheItemType* )findV (Upper());
a174a3c5 254 }
255
256 //! @return last element
257 TheItemType& ChangeLast()
258 {
f4aad56f 259 return *(TheItemType* )findV (Upper());
a174a3c5 260 }
261
f4aad56f 262 //! Operator() - query the value
263 TheItemType& operator() (const Standard_Integer theIndex)
264 {
265 return ChangeValue (theIndex);
266 }
267
b8f7f608 268 //! Operator[] - query the value
269 TheItemType& operator[] ( Standard_Integer theIndex) { return ChangeValue (theIndex); }
270
f4aad56f 271 TheItemType& ChangeValue (const Standard_Integer theIndex)
272 {
273 return *(TheItemType* )findV (theIndex);
7fd59977 274 }
275
276 //! SetValue () - set or append a value
f4aad56f 277 TheItemType& SetValue (const Standard_Integer theIndex,
278 const TheItemType& theValue)
279 {
280 Standard_OutOfRange_Raise_if (theIndex < 0, "NCollection_Vector::SetValue");
ddf2fe8e 281 TheItemType* const aVecValue = (TheItemType* )(theIndex < myLength ? findV (theIndex) : expandV (theIndex));
f4aad56f 282 *aVecValue = theValue;
283 return *aVecValue;
7fd59977 284 }
285
f4aad56f 286private: //! @name private methods
287
288 void copyData (const NCollection_Vector& theOther)
289 {
290 Standard_Integer iBlock = 0;
7fd59977 291 /*NCollection_Vector::*/Iterator anIter (theOther);
f4aad56f 292 for (Standard_Integer aLength = 0; aLength < myLength; aLength += myIncrement)
293 {
294 MemBlock& aBlock = myData[iBlock];
295 initMemBlocks (*this, aBlock, aLength, myIncrement);
296 Standard_Integer anItemIter = 0;
297 for (; anItemIter < myIncrement; ++anItemIter)
298 {
299 if (!anIter.More())
300 {
301 break;
302 }
303
304 ((TheItemType* )aBlock.DataPtr)[anItemIter] = anIter.Value();
7fd59977 305 anIter.Next();
306 }
f4aad56f 307 aBlock.Length = anItemIter;
7fd59977 308 iBlock++;
309 }
310 }
311
f4aad56f 312 //! Method to initialize memory block content
313 static void initMemBlocks (NCollection_BaseVector& theVector,
314 NCollection_BaseVector::MemBlock& theBlock,
315 const Standard_Integer theFirst,
316 const Standard_Integer theSize)
7fd59977 317 {
f4aad56f 318 NCollection_Vector& aSelf = static_cast<NCollection_Vector&> (theVector);
319 Handle(NCollection_BaseAllocator)& anAllocator = aSelf.myAllocator;
320
321 // release current content
322 if (theBlock.DataPtr != NULL)
323 {
324 for (Standard_Integer anItemIter = 0; anItemIter < theBlock.Size; ++anItemIter)
325 {
79a35943 326 ((TheItemType* )theBlock.DataPtr)[anItemIter].~TheItemType();
f4aad56f 327 }
328 anAllocator->Free (theBlock.DataPtr);
329 theBlock.DataPtr = NULL;
7fd59977 330 }
7fd59977 331
f4aad56f 332 // allocate new content if requested
333 if (theSize > 0)
334 {
335 theBlock.DataPtr = anAllocator->Allocate (theSize * sizeof(TheItemType));
336 for (Standard_Integer anItemIter = 0; anItemIter < theSize; ++anItemIter)
337 {
338 new (&((TheItemType* )theBlock.DataPtr)[anItemIter]) TheItemType;
339 }
340 }
341 theBlock.FirstIndex = theFirst;
342 theBlock.Size = theSize;
343 theBlock.Length = 0;
7fd59977 344 }
345
346 friend class Iterator;
f4aad56f 347
7fd59977 348};
349
f4aad56f 350//! Assignment to the collection of the same type
351template <class TheItemType> inline
352void NCollection_Vector<TheItemType>::Assign (const NCollection_Vector& theOther,
353 const Standard_Boolean theOwnAllocator)
354{
355 if (this == &theOther)
356 {
357 return;
358 }
359
360 // destroy current data using current allocator
361 for (Standard_Integer anItemIter = 0; anItemIter < myCapacity; ++anItemIter)
362 {
363 initMemBlocks (*this, myData[anItemIter], 0, 0);
364 }
ddf2fe8e 365 this->myAllocator->Free (myData);
f4aad56f 366
367 // allocate memory blocks with new allocator
368 if (!theOwnAllocator)
369 {
ddf2fe8e 370 this->myAllocator = theOther.myAllocator;
f4aad56f 371 }
372 myIncrement = theOther.myIncrement;
373 myLength = theOther.myLength;
374 myNBlocks = (myLength == 0) ? 0 : (1 + (myLength - 1)/myIncrement);
375 myCapacity = GetCapacity (myIncrement) + myLength / myIncrement;
ddf2fe8e 376 myData = allocMemBlocks (myCapacity);
f4aad56f 377
378 // copy data
379 copyData (theOther);
380}
381
382#endif // NCollection_Vector_HeaderFile