0031671: Coding Rules - eliminate warnings issued by clang 11
[occt.git] / src / NCollection / NCollection_BaseVector.hxx
1 // Created on: 2002-04-24
2 // Created by: Alexander GRIGORIEV
3 // Copyright (c) 2002-2013 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
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.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #ifndef NCollection_BaseVector_HeaderFile
17 #define NCollection_BaseVector_HeaderFile
18
19 #include <Standard_TypeDef.hxx>
20 #include <Standard_OutOfRange.hxx>
21 #include <NCollection_BaseAllocator.hxx>
22 #include <NCollection_DefineAlloc.hxx>
23
24 #include <stddef.h>
25
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)
29 {
30   return Max(theIncrement/8, 1);
31 }
32
33 //! Class NCollection_BaseVector - base for NCollection_Vector template
34 class NCollection_BaseVector
35 {
36 public:
37   //! Memory allocation
38   DEFINE_STANDARD_ALLOC
39   DEFINE_NCOLLECTION_ALLOC
40
41 protected:
42
43   // Auxiliary structure for memory blocks
44   struct MemBlock
45   {
46
47   public:
48
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
54     {
55       return (char* )DataPtr + size_t(theIndex) * theItemSize;
56     }
57
58   public:
59
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;
64
65   };
66
67   //! Base class for Iterator implementation
68   class Iterator
69   {
70   protected:
71     Iterator()
72     : myICurBlock (0),
73       myIEndBlock (0),
74       myCurIndex  (0),
75       myEndIndex  (0) {}
76
77     Iterator (const NCollection_BaseVector& theVector, Standard_Boolean theToEnd = Standard_False)
78     {
79       initV (theVector, theToEnd);
80     }
81
82     Standard_EXPORT void initV (const NCollection_BaseVector& theVector, Standard_Boolean theToEnd = Standard_False);
83
84     Standard_Boolean moreV() const
85     {
86       return (myICurBlock < myIEndBlock || myCurIndex < myEndIndex);
87     }
88
89     void nextV()
90     {
91       if (++myCurIndex >= myVector->myData[myICurBlock].Length
92        && myICurBlock < myIEndBlock)
93       {
94         ++myICurBlock;
95         myCurIndex = 0;
96       }
97     }
98
99     void prevV()
100     {
101       if (--myCurIndex < 0 && myICurBlock > 0)
102       {
103         --myICurBlock;
104         myCurIndex = myVector->myData[myICurBlock].Length - 1;
105       }
106     }
107
108     void offsetV (Standard_Integer theOffset)
109     {
110       const Standard_Integer anIndex = myCurIndex + myICurBlock * myVector->myIncrement + theOffset;
111       myICurBlock = anIndex / myVector->myIncrement;
112       myCurIndex = anIndex % myVector->myIncrement;
113       if (myICurBlock > myIEndBlock)
114       {
115         // make sure that iterator produced by Offset()
116         // is equal to the end() iterator
117         --myICurBlock;
118         myCurIndex += myVector->myIncrement;
119       }
120     }
121
122     Standard_Integer differV (const Iterator& theOther) const
123     {
124       return (myCurIndex - theOther.myCurIndex) + (myICurBlock - theOther.myICurBlock) * myVector->myIncrement;
125     }
126
127     const MemBlock* curBlockV() const
128     {
129       return &myVector->myData[myICurBlock];
130     }
131
132   protected:
133     const NCollection_BaseVector* myVector;    //!< the Master vector
134     Standard_Integer              myICurBlock; //!< # of the current block
135     Standard_Integer              myIEndBlock;
136     Standard_Integer              myCurIndex;  //!< Index in the current block
137     Standard_Integer              myEndIndex;
138   };
139
140 protected: //! @name Block initializer
141
142   typedef void (*initMemBlocks_t) (NCollection_BaseVector& theVector,
143                                    MemBlock&               theBlock,
144                                    const Standard_Integer  theFirst,
145                                    const Standard_Integer  theSize);
146
147   //! Allocate memory for array of memory blocks.
148   //! @param theCapacity   Number of memory blocks in array
149   //! @param theSource     Original array of memory blocks, will be automatically deallocated
150   //! @param theSourceSize Number of memory blocks in original array
151   Standard_EXPORT MemBlock* allocMemBlocks (const Standard_Integer theCapacity,
152                                             MemBlock*              theSource     = NULL,
153                                             const Standard_Integer theSourceSize = 0);
154
155 protected: //! @name protected methods
156
157   //! Empty constructor
158   NCollection_BaseVector (const Handle(NCollection_BaseAllocator)& theAllocator,
159                           initMemBlocks_t                    theInitBlocks,
160                           const size_t                       theSize,
161                           const Standard_Integer             theInc)
162   : myItemSize   (theSize),
163     myIncrement  (theInc),
164     myLength     (0),
165     myCapacity   (GetCapacity (myIncrement)),
166     myNBlocks    (0),
167     myInitBlocks (theInitBlocks)
168   {
169     myAllocator = (theAllocator.IsNull() ? NCollection_BaseAllocator::CommonBaseAllocator() : theAllocator);
170     myData = allocMemBlocks (myCapacity);
171   }
172
173   //! Copy constructor
174   NCollection_BaseVector (const Handle(NCollection_BaseAllocator)& theAllocator,
175                           initMemBlocks_t                    theInitBlocks,
176                           const NCollection_BaseVector&      theOther)
177   : myItemSize   (theOther.myItemSize),
178     myIncrement  (theOther.myIncrement),
179     myLength     (theOther.myLength),
180     myCapacity   (GetCapacity(myIncrement) + theOther.myLength / theOther.myIncrement),
181     myNBlocks    (theOther.myLength == 0 ? 0 : 1 + (theOther.myLength - 1)/theOther.myIncrement),
182     myInitBlocks (theInitBlocks)
183   {
184     myAllocator = (theAllocator.IsNull() ? NCollection_BaseAllocator::CommonBaseAllocator() : theAllocator);
185     myData = allocMemBlocks (myCapacity);
186   }
187
188   //! Destructor
189   virtual ~NCollection_BaseVector() {}
190
191   //! @return pointer to memory where to put the new item
192   Standard_EXPORT void* expandV (const Standard_Integer theIndex);
193
194   //! Locate the memory holding the desired value
195   inline void* findV (const Standard_Integer theIndex) const
196   {
197     Standard_OutOfRange_Raise_if (theIndex < 0 || theIndex >= myLength,
198                                   "NCollection_BaseVector::findV");
199     const Standard_Integer aBlock = theIndex / myIncrement;
200     return myData[aBlock].findV (theIndex - aBlock * myIncrement, myItemSize);
201   }
202
203 public: //! @name public API
204
205   //! Empty the vector of its objects
206   Standard_EXPORT void Clear();
207   // to set the size of increment dynamically
208   void SetIncrement(const Standard_Integer aIncrement) {
209     if (aIncrement > 0) {
210       if (!myIncrement) {
211         myIncrement=aIncrement;
212       }
213     }
214   }
215
216   //! Returns attached allocator
217   const Handle(NCollection_BaseAllocator)& Allocator() const
218   {
219     return myAllocator;
220   }
221
222 protected: //! @name Protected fields
223
224   Handle(NCollection_BaseAllocator) myAllocator;
225   size_t           myItemSize;
226   Standard_Integer myIncrement;
227   Standard_Integer myLength;
228   Standard_Integer myCapacity;
229   Standard_Integer myNBlocks;
230   MemBlock*        myData;
231   initMemBlocks_t  myInitBlocks;
232
233 protected:
234
235   friend class Iterator;
236 };
237
238 #endif // NCollection_BaseVector_HeaderFile