0032402: Coding Rules - eliminate msvc warning C4668 (symbol is not defined as a...
[occt.git] / src / NCollection / NCollection_BaseVector.cxx
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 #include <NCollection_BaseVector.hxx>
17
18 #include <Standard_RangeError.hxx>
19 #include <cstdlib>
20
21 //=======================================================================
22 //function : initV
23 //purpose  : Initialisation of iterator by a vector
24 //=======================================================================
25
26 void NCollection_BaseVector::Iterator::initV (const NCollection_BaseVector& theVector, Standard_Boolean theToEnd)
27 {
28   myVector = &theVector;
29
30   if (theVector.myNBlocks == 0)
31   {
32     myCurIndex  = 0;
33     myEndIndex  = 0;
34     myICurBlock = 0;
35     myIEndBlock = 0;
36   }
37   else
38   {
39     myIEndBlock = theVector.myNBlocks - 1;
40     myEndIndex  = theVector.myData[myIEndBlock].Length;
41
42     myICurBlock = !theToEnd ? 0 : myIEndBlock;
43     myCurIndex  = !theToEnd ? 0 : myEndIndex;
44   }
45 }
46
47 //=======================================================================
48 //function : allocMemBlocks
49 //purpose  :
50 //=======================================================================
51
52 NCollection_BaseVector::MemBlock* NCollection_BaseVector
53   ::allocMemBlocks (const Standard_Integer             theCapacity,
54                     MemBlock*                          theSource,
55                     const Standard_Integer             theSourceSize)
56 {
57   MemBlock* aData = (MemBlock* )myAllocator->Allocate (theCapacity * sizeof(MemBlock));
58
59   // copy content from source array
60   Standard_Integer aCapacity = 0;
61   if (theSource != NULL)
62   {
63     memcpy (aData, theSource, theSourceSize * sizeof(MemBlock));
64     aCapacity = theSourceSize;
65     myAllocator->Free (theSource);
66   }
67
68   // Nullify newly allocated blocks
69   if (aCapacity < theCapacity)
70   {
71     memset (&aData[aCapacity], 0, (theCapacity - aCapacity) * sizeof(MemBlock));
72   }
73   return aData;
74 }
75
76 //=======================================================================
77 //function : Clear
78 //purpose  :
79 //=======================================================================
80
81 void NCollection_BaseVector::Clear()
82 {
83   if (myLength > 0)
84   {
85     for (Standard_Integer anItemIter = 0; anItemIter < myCapacity; ++anItemIter)
86     {
87       myInitBlocks (*this, myData[anItemIter], 0, 0);
88     }
89     myLength  = 0;
90     myNBlocks = 0;
91   }
92 }
93
94 //=======================================================================
95 //function : expandV
96 //purpose  : returns the pointer where the new data item is supposed to be put
97 //=======================================================================
98
99 void* NCollection_BaseVector::expandV (const Standard_Integer theIndex)
100 {
101   const Standard_Integer aNewLength = theIndex + 1;
102   if (myNBlocks > 0)
103   {
104     // Take the last array in the vector of arrays
105     MemBlock& aLastBlock = myData[myNBlocks - 1];
106     Standard_RangeError_Raise_if (theIndex < aLastBlock.FirstIndex,
107                                   "NColelction_BaseVector::expandV");
108     Standard_Integer anIndLastBlock = theIndex - aLastBlock.FirstIndex;
109     // Is there still room for 1 item in the last array?
110     if (anIndLastBlock < aLastBlock.Size)
111     {
112       myLength = aNewLength;
113       aLastBlock.Length = anIndLastBlock + 1;
114       return aLastBlock.findV (anIndLastBlock, myItemSize);
115     }
116     myLength = aLastBlock.FirstIndex + aLastBlock.Size;
117   }
118
119   // There is no room in the last array
120   // or the whole vector is not yet initialised.
121   // Initialise a new array, but before that check whether it is available within myCapacity.
122   const Standard_Integer nNewBlock = myNBlocks + 1 + (theIndex - myLength) / myIncrement;
123   if (myCapacity < nNewBlock)
124   {
125     // Reallocate the array myData 
126     do myCapacity += GetCapacity(myIncrement); while (myCapacity <= nNewBlock);
127
128     myData = allocMemBlocks (myCapacity, myData, myNBlocks);
129   }
130   if (myNBlocks > 0)
131   {
132     // Change length of old last block to myIncrement
133     MemBlock& aLastBlock = myData[myNBlocks - 1];
134     aLastBlock.Length = myIncrement;
135   }
136
137   // Initialise new blocks
138   MemBlock* aNewBlock = &myData[myNBlocks++];
139   myInitBlocks (*this, *aNewBlock, myLength, myIncrement);
140   while (myNBlocks < nNewBlock)
141   {
142     aNewBlock->Length = myIncrement;
143     myLength += myIncrement;
144     aNewBlock = &myData[myNBlocks++];
145     myInitBlocks (*this, *aNewBlock, myLength, myIncrement);
146   }
147   aNewBlock->Length = aNewLength - myLength;
148   myLength = aNewLength;
149   return aNewBlock->findV (theIndex - aNewBlock->FirstIndex, myItemSize);
150 }