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 #include <NCollection_BaseVector.hxx>
17 #include <Standard_RangeError.hxx>
20 //=======================================================================
21 //function : NCollection_BaseVector::Iterator::copyV
22 //purpose : Copy from another iterator
23 //=======================================================================
25 void NCollection_BaseVector::Iterator::copyV (const NCollection_BaseVector::Iterator& theOth)
27 myVector = theOth.myVector;
28 myICurBlock = theOth.myICurBlock;
29 myIEndBlock = theOth.myIEndBlock;
30 myCurIndex = theOth.myCurIndex;
31 myEndIndex = theOth.myEndIndex;
34 //=======================================================================
36 //purpose : Initialisation of iterator by a vector
37 //=======================================================================
39 void NCollection_BaseVector::Iterator::initV (const NCollection_BaseVector& theVector, Standard_Boolean theToEnd)
41 myVector = &theVector;
43 if (theVector.myNBlocks == 0)
52 myIEndBlock = theVector.myNBlocks - 1;
53 myEndIndex = theVector.myData[myIEndBlock].Length;
55 myICurBlock = !theToEnd ? 0 : myIEndBlock;
56 myCurIndex = !theToEnd ? 0 : myEndIndex;
60 //=======================================================================
61 //function : allocMemBlocks
63 //=======================================================================
65 NCollection_BaseVector::MemBlock* NCollection_BaseVector
66 ::allocMemBlocks (const Standard_Integer theCapacity,
68 const Standard_Integer theSourceSize)
70 MemBlock* aData = (MemBlock* )myAllocator->Allocate (theCapacity * sizeof(MemBlock));
72 // copy content from source array
73 Standard_Integer aCapacity = 0;
74 if (theSource != NULL)
76 memcpy (aData, theSource, theSourceSize * sizeof(MemBlock));
77 aCapacity = theSourceSize;
78 myAllocator->Free (theSource);
81 // Nullify newly allocated blocks
82 if (aCapacity < theCapacity)
84 memset (&aData[aCapacity], 0, (theCapacity - aCapacity) * sizeof(MemBlock));
89 //=======================================================================
92 //=======================================================================
94 void NCollection_BaseVector::Clear()
98 for (Standard_Integer anItemIter = 0; anItemIter < myCapacity; ++anItemIter)
100 myInitBlocks (*this, myData[anItemIter], 0, 0);
107 //=======================================================================
109 //purpose : returns the pointer where the new data item is supposed to be put
110 //=======================================================================
112 void* NCollection_BaseVector::expandV (const Standard_Integer theIndex)
114 const Standard_Integer aNewLength = theIndex + 1;
117 // Take the last array in the vector of arrays
118 MemBlock& aLastBlock = myData[myNBlocks - 1];
119 Standard_RangeError_Raise_if (theIndex < aLastBlock.FirstIndex,
120 "NColelction_BaseVector::expandV");
121 Standard_Integer anIndLastBlock = theIndex - aLastBlock.FirstIndex;
122 // Is there still room for 1 item in the last array?
123 if (anIndLastBlock < aLastBlock.Size)
125 myLength = aNewLength;
126 aLastBlock.Length = anIndLastBlock + 1;
127 return aLastBlock.findV (anIndLastBlock, myItemSize);
129 myLength = aLastBlock.FirstIndex + aLastBlock.Size;
132 // There is no room in the last array
133 // or the whole vector is not yet initialised.
134 // Initialise a new array, but before that check whether it is available within myCapacity.
135 const Standard_Integer nNewBlock = myNBlocks + 1 + (theIndex - myLength) / myIncrement;
136 if (myCapacity < nNewBlock)
138 // Reallocate the array myData
139 do myCapacity += GetCapacity(myIncrement); while (myCapacity <= nNewBlock);
141 myData = allocMemBlocks (myCapacity, myData, myNBlocks);
145 // Change length of old last block to myIncrement
146 MemBlock& aLastBlock = myData[myNBlocks - 1];
147 aLastBlock.Length = myIncrement;
150 // Initialise new blocks
151 MemBlock* aNewBlock = &myData[myNBlocks++];
152 myInitBlocks (*this, *aNewBlock, myLength, myIncrement);
153 while (myNBlocks < nNewBlock)
155 aNewBlock->Length = myIncrement;
156 myLength += myIncrement;
157 aNewBlock = &myData[myNBlocks++];
158 myInitBlocks (*this, *aNewBlock, myLength, myIncrement);
160 aNewBlock->Length = aNewLength - myLength;
161 myLength = aNewLength;
162 return aNewBlock->findV (theIndex - aNewBlock->FirstIndex, myItemSize);