0021762: Integration of new Boolean Operation algorithm to OCCT.
[occt.git] / src / BOPCol / BOPCol_Array1.hxx
CommitLineData
4e57c75e 1// Created by: Peter KURNEV
2// Copyright (c) 1999-2012 OPEN CASCADE SAS
3//
4// The content of this file is subject to the Open CASCADE Technology Public
5// License Version 6.5 (the "License"). You may not use the content of this file
6// except in compliance with the License. Please obtain a copy of the License
7// at http://www.opencascade.org and read it completely before using this file.
8//
9// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11//
12// The Original Code and all software distributed under the License is
13// distributed on an "AS IS" basis, without warranty of any kind, and the
14// Initial Developer hereby disclaims all such warranties, including without
15// limitation, any warranties of merchantability, fitness for a particular
16// purpose or non-infringement. Please see the License for the specific terms
17// and conditions governing the rights and limitations under the License.
18
19#ifndef BOPCol_Array1_HeaderFile
20#define BOPCol_Array1_HeaderFile
21
22#include <NCollection_List.hxx>
23#include <Standard.hxx>
24#include <NCollection_BaseAllocator.hxx>
25
26/**
27* Class BOPCol_Array1 (dynamic array of objects)
28*
29* 1. The Array1 uses the allocator (in terms of NCollection_BaseAllocator)
30* to allocate the memory.
31* 2. The memory is allocated as a list of memory blocks. The size of the first
32* block is myStartSize. The size of the other blocks is myIncrement
33* 3 The Array1 is created with 0 length.
34* 4. The Array1 must be initiated by invoke the method Init().
35* Init() allocates the memory block for initial myStartSize elements.
36* 5. The elements can be added by the method Append(theElement). the method
37* Append(theElement) arranges theElement in
38* a) previously allocated memory block (if it is possible)
39* b) new allocated memory block (otherwise). The size of new blocks to
40* allocate can be set [once only] by the method SetIncrement(theSize).
41* 6. The contents of the element with index "i" can be queried or modified
42* by the methods
43* SetValue(i, theElement), Value(i), ChangeValue(i), operator()(i)
44*/
45
46//=======================================================================
47//class : MemBlock
48//
49//=======================================================================
50template <class Type> class BOPCol_MemBlock {
51
52 public:
53 // Ctor
54 BOPCol_MemBlock(const Handle(NCollection_BaseAllocator)& theAllocator) {
55 myI1=0;
56 myI2=0;
57 mySize=0;
58 myData=NULL;
59 myAllocator=theAllocator;
60 myNext=NULL;
61 }
62 // ~
63 ~BOPCol_MemBlock(){
64 Clear();
65 }
66 // Clear
67 void Clear() {
68 if (myData) {
69 //Standard_Integer i;
70 Standard_Size i;
71 //
72 for (i=0; i<mySize; ++i) {
73 myData[i].~Type();
74 }
75 myAllocator->Free((Standard_Address&)myData);
76 //
77 myData=NULL;
78 mySize=0;
79 myNext=NULL;
80 }
81 }
82 // Allocate
83 void Allocate(const Standard_Size theSize) {
84 //Standard_Integer i;
85 Standard_Size i;
86 //
87 Clear();
88 mySize=theSize;
89 myData=(Type*)myAllocator->Allocate(theSize*sizeof(Type));
90 for (i=0; i<mySize; ++i) {
91#ifdef BOPCol_Array1_Use_Allocator
92 new (myData+i) Type (myAllocator);
93#else
94 new (myData+i) Type;
95#endif
96 }
97 }
98 // SetRange
99 void SetRange(const Standard_Integer theI1,
100 const Standard_Integer theI2) {
101 myI1=theI1;
102 myI2=theI2;
103 }
104 // Range
105 void Range(Standard_Integer& theI1,
106 Standard_Integer& theI2) const {
107 theI1=myI1;
108 theI2=myI2;
109 }
110 // Contains
111 Standard_Boolean Contains(const Standard_Integer theIndex)const {
112 return (theIndex>=myI1 && theIndex<=myI2);
113 }
114 // SetValue
115 void SetValue(const Standard_Integer theIndex,
116 const Type& theValue) {
117 *(myData+theIndex-myI1)=theValue;
118 }
119 // Value
120 const Type& Value(const Standard_Integer theIndex)const {
121 return *(myData+theIndex-myI1);
122 }
123 // ChangeValue
124 Type& ChangeValue(const Standard_Integer theIndex) {
125 return *(myData+theIndex-myI1);
126 }
127 // SetNext
128 void SetNext(BOPCol_MemBlock<Type>* pNext) {
129 myNext=pNext;
130 }
131 // Next
132 BOPCol_MemBlock<Type>* Next() {
133 return myNext;
134 }
135 //
136 public:
137 BOPCol_MemBlock<Type>* myNext;
138 protected:
139 Standard_Integer myI1;
140 Standard_Integer myI2;
141 Standard_Size mySize;
142 Type *myData;
143 Handle(NCollection_BaseAllocator) myAllocator;
144};
145
146//=======================================================================
147//class : BOPCol_Array1
148//
149//=======================================================================
150template <class Type> class BOPCol_Array1 {
151
152 public:
153 typedef BOPCol_MemBlock<Type>* BOPCol_PMemBlock;
154 typedef BOPCol_MemBlock<Type> BOPCol_XMemBlock;
155 //=========
156 // Ctor
157 BOPCol_Array1(const Handle(NCollection_BaseAllocator)& theAllocator=0L) {
158 myStartSize=32;
159 myIncrement=8;
160 myExtent=0;
161 myPBlock=NULL;
162 myPBlock1=NULL;
163 //
164 if (theAllocator.IsNull()) {
165 myAllocator = NCollection_BaseAllocator::CommonBaseAllocator();
166 }
167 else {
168 myAllocator=theAllocator;
169 }
170 }
171 // ~
172 ~BOPCol_Array1() {
173 Clear();
174 }
175 //===========
176 // Clear
177 void Clear() {
178 BOPCol_PMemBlock pBlock, pNext;
179 //
180 pBlock=myPBlock1;
181 while(pBlock) {
182 pNext=pBlock->Next();
183 //
184 //pBlock->~BOPCol_MemBlock<Type> ();
185 pBlock->~BOPCol_XMemBlock();
186 //pBlock->Clear();
187 myAllocator->Free((Standard_Address&)pBlock);
188 //
189 pBlock=pNext;
190 }
191 myPBlock1=NULL;
192 myPBlock=NULL;
193 myExtent=0;
194 }
195 // SetStartSize
196 void SetStartSize(const Standard_Size theSize) {
197 if (theSize>0) {
198 myStartSize=theSize;
199 }
200 }
201 // SetIncrement
202 void SetIncrement(const Standard_Size theSize){
203 if (theSize>0) {
204 myIncrement=theSize;
205 }
206 }
207 // Increment
208 Standard_Size Increment()const {
209 return myIncrement;
210 }
211 // Extent
212 Standard_Size Extent()const {
213 return myExtent;
214 }
215 // Size
216 Standard_Size Size()const {
217 return myExtent;
218 }
219 // Size
220 Standard_Size Length()const {
221 return myExtent;
222 }
223 // Init
224 void Init();
225 // Append(const Type& theValue)
226 Standard_Integer Append(const Type& theValue);
227 // Append()
228 Standard_Integer Append();
229 // SetValue
230 void SetValue(const Standard_Integer theIndex,
231 const Type& theValue);
232 // Value
233 const Type& operator()(const Standard_Integer theIndex)const;
234 //
235 const Type& Value(const Standard_Integer theIndex)const;
236 // ChangeValue
237 Type& operator()(const Standard_Integer theIndex);
238 //
239 Type& ChangeValue(const Standard_Integer theIndex);
240 //
241 // protected
242 protected:
243 //===========
244 //FindBlock
245 Standard_Boolean FindBlock(const Standard_Integer theIndex)const ;
246 //Copy ctor
247 BOPCol_Array1(const BOPCol_Array1&);
248 //Assign operator
249 BOPCol_Array1& operator =(const BOPCol_Array1& theOther);
250 //==========
251 // fields
252 protected:
253 Standard_Size myStartSize;
254 Standard_Size myIncrement;
255 Standard_Size myExtent;
256 Type myDfltItem;
257 BOPCol_MemBlock<Type> * myPBlock;
258 BOPCol_MemBlock<Type> * myPBlock1;
259 Handle(NCollection_BaseAllocator) myAllocator;
260};
261//
262//=======================================================================
263//function : Init
264//purpose :
265//=======================================================================
266template <class Type>
267 void BOPCol_Array1<Type>::Init() {
268 BOPCol_PMemBlock pBlock;
269 //
270 pBlock=(BOPCol_PMemBlock)myAllocator->Allocate(sizeof(BOPCol_MemBlock<Type>));
271 new (pBlock) BOPCol_MemBlock<Type>(myAllocator);
272 //
273 pBlock->Allocate(myStartSize);
274 pBlock->SetRange(0, myStartSize-1);
275 myPBlock1=pBlock;
276 myPBlock=pBlock;
277 }
278//=======================================================================
279//function : Append
280//purpose :
281//=======================================================================
282template <class Type>
283 Standard_Integer BOPCol_Array1<Type>::Append(const Type& theValue) {
284 BOPCol_PMemBlock pBlock, pNext;
285 //
286 pBlock=myPBlock1;
287 while(1) {
288 pNext=pBlock->myNext;
289 if(!pNext) {
290 myPBlock=pBlock;
291 break;
292 }
293 pBlock=pNext;
294 }
295 //
296 if (!myPBlock->Contains(myExtent)) {
297 //
298 pBlock=(BOPCol_PMemBlock)myAllocator->Allocate(sizeof(BOPCol_MemBlock<Type>));
299 new (pBlock) BOPCol_MemBlock<Type>(myAllocator);
300 //
301 pBlock->Allocate(myIncrement);
302 pBlock->SetRange(myExtent, myExtent+myIncrement-1);
303 //
304 myPBlock->myNext=pBlock;
305 //
306 myPBlock=pBlock;
307 }
308 //
309 myPBlock->SetValue(myExtent, theValue);
310 //
311 ++myExtent;
312 //
313 return myExtent;
314 }
315//=======================================================================
316//function : Append
317//purpose :
318//=======================================================================
319template <class Type>
320 Standard_Integer BOPCol_Array1<Type>::Append() {
321 BOPCol_PMemBlock pBlock, pNext;
322 //
323 pBlock=myPBlock1;
324 while(1) {
325 pNext=pBlock->myNext;
326 if(!pNext) {
327 myPBlock=pBlock;
328 break;
329 }
330 pBlock=pNext;
331 }
332 //
333 if (!myPBlock->Contains(myExtent)) {
334 //
335 pBlock=(BOPCol_PMemBlock)myAllocator->Allocate(sizeof(BOPCol_MemBlock<Type>));
336 new (pBlock) BOPCol_MemBlock<Type>(myAllocator);
337 //
338 pBlock->Allocate(myIncrement);
339 pBlock->SetRange(myExtent, myExtent+myIncrement-1);
340 //
341 myPBlock->myNext=pBlock;
342 //
343 myPBlock=pBlock;
344 }
345 ++myExtent;
346 //
347 return myExtent;
348 }
349//=======================================================================
350//function : SetValue
351//purpose :
352//=======================================================================
353template <class Type>
354 void BOPCol_Array1<Type>::SetValue(const Standard_Integer theIndex,
355 const Type& theValue) {
356 if (FindBlock(theIndex)) {
357 myPBlock->SetValue(theIndex, theValue);
358 }
359 }
360//=======================================================================
361//function : operator()
362//purpose :
363//=======================================================================
364template <class Type>
365 const Type& BOPCol_Array1<Type>::operator()(const Standard_Integer theIndex)const {
366 if (FindBlock(theIndex)) {
367 return myPBlock->Value(theIndex);
368 }
369 return myDfltItem;
370 }
371//=======================================================================
372//function : Value
373//purpose :
374//=======================================================================
375template <class Type>
376 const Type& BOPCol_Array1<Type>::Value(const Standard_Integer theIndex)const {
377 return operator()(theIndex);
378 }
379//=======================================================================
380//function : operator
381//purpose :
382//=======================================================================
383template <class Type>
384 Type& BOPCol_Array1<Type>::operator()(const Standard_Integer theIndex) {
385 if (FindBlock(theIndex)) {
386 return myPBlock->ChangeValue(theIndex);
387 }
388 return myDfltItem;
389 }
390//=======================================================================
391//function : ChangeValue
392//purpose :
393//=======================================================================
394template <class Type>
395 Type& BOPCol_Array1<Type>::ChangeValue(const Standard_Integer theIndex) {
396 return operator()(theIndex);
397 }
398//=======================================================================
399//function : FindBlock
400//purpose :
401//=======================================================================
402template <class Type>
403 Standard_Boolean BOPCol_Array1<Type>::FindBlock(const Standard_Integer theIndex)const {
404 Standard_Boolean bRet;
405 //
406 bRet=myPBlock->Contains(theIndex);
407 if(bRet) {
408 return bRet;
409 }
410 //
411 Standard_Integer i1, i2;
412 BOPCol_PMemBlock pBlock, *xPBlock;
413 //
414 xPBlock=(BOPCol_PMemBlock*)&myPBlock;
415 pBlock=myPBlock1;
416 //
417 i1=0;
418 i2=myStartSize-1;
419 do {
420 if (theIndex>=i1 && theIndex<=i2) {
421 *xPBlock=pBlock;
422 return !bRet;
423 }
424 //
425 i1=i2+1;
426 i2=i1+myIncrement-1;
427 pBlock=pBlock->myNext;
428 } while(pBlock);
429 //
430 return bRet;
431 }
432
433#endif