b311480e |
1 | // Created on: 2002-04-24 |
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 | #include <NCollection_BaseVector.hxx> |
17 | #include <Standard_RangeError.hxx> |
f4aad56f |
18 | #include <cstdlib> |
7fd59977 |
19 | |
20 | //======================================================================= |
f4aad56f |
21 | //function : NCollection_BaseVector::Iterator::copyV |
22 | //purpose : Copy from another iterator |
7fd59977 |
23 | //======================================================================= |
24 | |
f4aad56f |
25 | void NCollection_BaseVector::Iterator::copyV (const NCollection_BaseVector::Iterator& theOth) |
7fd59977 |
26 | { |
f4aad56f |
27 | myVector = theOth.myVector; |
28 | myICurBlock = theOth.myICurBlock; |
29 | myIEndBlock = theOth.myIEndBlock; |
30 | myCurIndex = theOth.myCurIndex; |
31 | myEndIndex = theOth.myEndIndex; |
7fd59977 |
32 | } |
33 | |
34 | //======================================================================= |
f4aad56f |
35 | //function : initV |
36 | //purpose : Initialisation of iterator by a vector |
7fd59977 |
37 | //======================================================================= |
38 | |
79a35943 |
39 | void NCollection_BaseVector::Iterator::initV (const NCollection_BaseVector& theVector, Standard_Boolean theToEnd) |
7fd59977 |
40 | { |
79a35943 |
41 | myVector = &theVector; |
42 | |
f4aad56f |
43 | if (theVector.myNBlocks == 0) |
44 | { |
79a35943 |
45 | myCurIndex = 0; |
f4aad56f |
46 | myEndIndex = 0; |
79a35943 |
47 | myICurBlock = 0; |
48 | myIEndBlock = 0; |
f4aad56f |
49 | } |
50 | else |
51 | { |
52 | myIEndBlock = theVector.myNBlocks - 1; |
53 | myEndIndex = theVector.myData[myIEndBlock].Length; |
79a35943 |
54 | |
55 | myICurBlock = !theToEnd ? 0 : myIEndBlock; |
56 | myCurIndex = !theToEnd ? 0 : myEndIndex; |
23be7421 |
57 | } |
7fd59977 |
58 | } |
59 | |
60 | //======================================================================= |
f4aad56f |
61 | //function : allocMemBlocks |
62 | //purpose : |
7fd59977 |
63 | //======================================================================= |
64 | |
f4aad56f |
65 | NCollection_BaseVector::MemBlock* NCollection_BaseVector |
ddf2fe8e |
66 | ::allocMemBlocks (const Standard_Integer theCapacity, |
f4aad56f |
67 | MemBlock* theSource, |
68 | const Standard_Integer theSourceSize) |
7fd59977 |
69 | { |
ddf2fe8e |
70 | MemBlock* aData = (MemBlock* )myAllocator->Allocate (theCapacity * sizeof(MemBlock)); |
f4aad56f |
71 | |
72 | // copy content from source array |
73 | Standard_Integer aCapacity = 0; |
74 | if (theSource != NULL) |
75 | { |
76 | memcpy (aData, theSource, theSourceSize * sizeof(MemBlock)); |
77 | aCapacity = theSourceSize; |
ddf2fe8e |
78 | myAllocator->Free (theSource); |
f4aad56f |
79 | } |
7fd59977 |
80 | |
f4aad56f |
81 | // Nullify newly allocated blocks |
82 | if (aCapacity < theCapacity) |
83 | { |
84 | memset (&aData[aCapacity], 0, (theCapacity - aCapacity) * sizeof(MemBlock)); |
7fd59977 |
85 | } |
f4aad56f |
86 | return aData; |
7fd59977 |
87 | } |
88 | |
89 | //======================================================================= |
f4aad56f |
90 | //function : Clear |
91 | //purpose : |
7fd59977 |
92 | //======================================================================= |
93 | |
f4aad56f |
94 | void NCollection_BaseVector::Clear() |
7fd59977 |
95 | { |
f4aad56f |
96 | if (myLength > 0) |
97 | { |
98 | for (Standard_Integer anItemIter = 0; anItemIter < myCapacity; ++anItemIter) |
99 | { |
100 | myInitBlocks (*this, myData[anItemIter], 0, 0); |
101 | } |
102 | myLength = 0; |
103 | myNBlocks = 0; |
104 | } |
7fd59977 |
105 | } |
106 | |
107 | //======================================================================= |
f4aad56f |
108 | //function : expandV |
7fd59977 |
109 | //purpose : returns the pointer where the new data item is supposed to be put |
110 | //======================================================================= |
111 | |
ddf2fe8e |
112 | void* NCollection_BaseVector::expandV (const Standard_Integer theIndex) |
7fd59977 |
113 | { |
114 | const Standard_Integer aNewLength = theIndex + 1; |
f4aad56f |
115 | if (myNBlocks > 0) |
116 | { |
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) |
124 | { |
7fd59977 |
125 | myLength = aNewLength; |
f4aad56f |
126 | aLastBlock.Length = anIndLastBlock + 1; |
127 | return aLastBlock.findV (anIndLastBlock, myItemSize); |
7fd59977 |
128 | } |
f4aad56f |
129 | myLength = aLastBlock.FirstIndex + aLastBlock.Size; |
7fd59977 |
130 | } |
131 | |
f4aad56f |
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) |
137 | { |
7fd59977 |
138 | // Reallocate the array myData |
23be7421 |
139 | do myCapacity += GetCapacity(myIncrement); while (myCapacity <= nNewBlock); |
f4aad56f |
140 | |
ddf2fe8e |
141 | myData = allocMemBlocks (myCapacity, myData, myNBlocks); |
7fd59977 |
142 | } |
f4aad56f |
143 | if (myNBlocks > 0) |
144 | { |
7fd59977 |
145 | // Change length of old last block to myIncrement |
f4aad56f |
146 | MemBlock& aLastBlock = myData[myNBlocks - 1]; |
147 | aLastBlock.Length = myIncrement; |
7fd59977 |
148 | } |
f4aad56f |
149 | |
7fd59977 |
150 | // Initialise new blocks |
f4aad56f |
151 | MemBlock* aNewBlock = &myData[myNBlocks++]; |
152 | myInitBlocks (*this, *aNewBlock, myLength, myIncrement); |
153 | while (myNBlocks < nNewBlock) |
154 | { |
155 | aNewBlock->Length = myIncrement; |
7fd59977 |
156 | myLength += myIncrement; |
f4aad56f |
157 | aNewBlock = &myData[myNBlocks++]; |
158 | myInitBlocks (*this, *aNewBlock, myLength, myIncrement); |
7fd59977 |
159 | } |
f4aad56f |
160 | aNewBlock->Length = aNewLength - myLength; |
7fd59977 |
161 | myLength = aNewLength; |
f4aad56f |
162 | return aNewBlock->findV (theIndex - aNewBlock->FirstIndex, myItemSize); |
7fd59977 |
163 | } |