1 // Created on: 2002-04-24
2 // Created by: Alexander GRIGORIEV
3 // Copyright (c) 2002-2013 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #ifndef NCollection_BaseVector_HeaderFile
17 #define NCollection_BaseVector_HeaderFile
19 #include <Standard_TypeDef.hxx>
20 #include <Standard_OutOfRange.hxx>
21 #include <NCollection_BaseAllocator.hxx>
22 #include <NCollection_DefineAlloc.hxx>
26 // this value defines the number of blocks that are reserved
27 // when the capacity of vector is increased
28 inline Standard_Integer GetCapacity (const Standard_Integer theIncrement)
30 return Max(theIncrement/8, 1);
33 //! Class NCollection_BaseVector - base for NCollection_Vector template
34 class NCollection_BaseVector
39 DEFINE_NCOLLECTION_ALLOC
43 // Auxiliary structure for memory blocks
49 //! @param theIndex Item index in the block
50 //! @param theItemSize Element size in bytes
51 //! @return the address of specified item in this memory block
52 void* findV (const Standard_Integer theIndex,
53 const size_t theItemSize) const
55 return (char* )DataPtr + size_t(theIndex) * theItemSize;
60 void* DataPtr; //!< block of elements
61 Standard_Integer FirstIndex; //!< index of the first element (among all memory blocks in collection)
62 Standard_Integer Length;
63 Standard_Integer Size;
67 //! Base class for Iterator implementation
78 Iterator (const NCollection_BaseVector& theVector, Standard_Boolean theToEnd = Standard_False)
80 initV (theVector, theToEnd);
83 Standard_EXPORT void initV (const NCollection_BaseVector& theVector, Standard_Boolean theToEnd = Standard_False);
85 Standard_Boolean moreV() const
87 return (myICurBlock < myIEndBlock || myCurIndex < myEndIndex);
92 if (++myCurIndex >= myVector->myData[myICurBlock].Length
93 && myICurBlock < myIEndBlock)
102 if (--myCurIndex < 0 && myICurBlock > 0)
105 myCurIndex = myVector->myData[myICurBlock].Length - 1;
109 void offsetV (Standard_Integer theOffset)
111 const Standard_Integer anIndex = myCurIndex + myICurBlock * myVector->myIncrement + theOffset;
112 myICurBlock = anIndex / myVector->myIncrement;
113 myCurIndex = anIndex % myVector->myIncrement;
114 if (myICurBlock > myIEndBlock)
116 // make sure that iterator produced by Offset()
117 // is equal to the end() iterator
119 myCurIndex += myVector->myIncrement;
123 Standard_Integer differV (const Iterator& theOther) const
125 return (myCurIndex - theOther.myCurIndex) + (myICurBlock - theOther.myICurBlock) * myVector->myIncrement;
128 const MemBlock* curBlockV() const
130 return &myVector->myData[myICurBlock];
134 const NCollection_BaseVector* myVector; //!< the Master vector
135 Standard_Integer myICurBlock; //!< # of the current block
136 Standard_Integer myIEndBlock;
137 Standard_Integer myCurIndex; //!< Index in the current block
138 Standard_Integer myEndIndex;
141 protected: //! @name Block initializer
143 typedef void (*initMemBlocks_t) (NCollection_BaseVector& theVector,
145 const Standard_Integer theFirst,
146 const Standard_Integer theSize);
148 //! Allocate memory for array of memory blocks.
149 //! @param theCapacity Number of memory blocks in array
150 //! @param theSource Original array of memory blocks, will be automatically deallocated
151 //! @param theSourceSize Number of memory blocks in original array
152 Standard_EXPORT MemBlock* allocMemBlocks (const Standard_Integer theCapacity,
153 MemBlock* theSource = NULL,
154 const Standard_Integer theSourceSize = 0);
156 protected: //! @name protected methods
158 //! Empty constructor
159 NCollection_BaseVector (const Handle(NCollection_BaseAllocator)& theAllocator,
160 initMemBlocks_t theInitBlocks,
161 const size_t theSize,
162 const Standard_Integer theInc)
163 : myItemSize (theSize),
164 myIncrement (theInc),
166 myCapacity (GetCapacity (myIncrement)),
168 myInitBlocks (theInitBlocks)
170 myAllocator = (theAllocator.IsNull() ? NCollection_BaseAllocator::CommonBaseAllocator() : theAllocator);
171 myData = allocMemBlocks (myCapacity);
175 NCollection_BaseVector (const Handle(NCollection_BaseAllocator)& theAllocator,
176 initMemBlocks_t theInitBlocks,
177 const NCollection_BaseVector& theOther)
178 : myItemSize (theOther.myItemSize),
179 myIncrement (theOther.myIncrement),
180 myLength (theOther.myLength),
181 myCapacity (GetCapacity(myIncrement) + theOther.myLength / theOther.myIncrement),
182 myNBlocks (theOther.myLength == 0 ? 0 : 1 + (theOther.myLength - 1)/theOther.myIncrement),
183 myInitBlocks (theInitBlocks)
185 myAllocator = (theAllocator.IsNull() ? NCollection_BaseAllocator::CommonBaseAllocator() : theAllocator);
186 myData = allocMemBlocks (myCapacity);
190 virtual ~NCollection_BaseVector() {}
192 //! @return pointer to memory where to put the new item
193 Standard_EXPORT void* expandV (const Standard_Integer theIndex);
195 //! Locate the memory holding the desired value
196 inline void* findV (const Standard_Integer theIndex) const
198 Standard_OutOfRange_Raise_if (theIndex < 0 || theIndex >= myLength,
199 "NCollection_BaseVector::findV");
200 const Standard_Integer aBlock = theIndex / myIncrement;
201 return myData[aBlock].findV (theIndex - aBlock * myIncrement, myItemSize);
204 public: //! @name public API
206 //! Empty the vector of its objects
207 Standard_EXPORT void Clear();
208 // to set the size of increment dynamically
209 void SetIncrement(const Standard_Integer aIncrement) {
210 if (aIncrement > 0) {
212 myIncrement=aIncrement;
217 //! Returns attached allocator
218 const Handle(NCollection_BaseAllocator)& Allocator() const
223 protected: //! @name Protected fields
225 Handle(NCollection_BaseAllocator) myAllocator;
227 Standard_Integer myIncrement;
228 Standard_Integer myLength;
229 Standard_Integer myCapacity;
230 Standard_Integer myNBlocks;
232 initMemBlocks_t myInitBlocks;
236 friend class Iterator;
239 #endif // NCollection_BaseVector_HeaderFile