0021762: Integration of new Boolean Operation algorithm to OCCT.
[occt.git] / src / BOPCol / BOPCol_Array1.hxx
diff --git a/src/BOPCol/BOPCol_Array1.hxx b/src/BOPCol/BOPCol_Array1.hxx
new file mode 100644 (file)
index 0000000..67842a9
--- /dev/null
@@ -0,0 +1,433 @@
+// Created by: Peter KURNEV
+// Copyright (c) 1999-2012 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#ifndef BOPCol_Array1_HeaderFile
+#define BOPCol_Array1_HeaderFile
+
+#include <NCollection_List.hxx>
+#include <Standard.hxx>
+#include <NCollection_BaseAllocator.hxx>
+
+/**
+* Class BOPCol_Array1 (dynamic array of objects)
+*
+*   1. The Array1 uses the allocator (in terms of NCollection_BaseAllocator)
+*      to allocate the memory.
+*   2. The memory is allocated as a list of memory blocks. The size of the first
+*      block is myStartSize. The size of the other blocks is myIncrement  
+*   3  The Array1 is  created with 0 length. 
+*   4. The Array1 must be initiated by invoke the method Init(). 
+*      Init() allocates the memory block for initial myStartSize elements. 
+*   5. The elements can be added by the method Append(theElement). the method 
+*      Append(theElement) arranges theElement in 
+*       a) previously allocated memory block (if it is possible)     
+*       b) new allocated memory block (otherwise). The size of new blocks to 
+*          allocate can be set [once only] by the method SetIncrement(theSize). 
+*   6. The contents of the element with index "i" can be queried or modified 
+*      by the methods  
+*      SetValue(i, theElement), Value(i), ChangeValue(i), operator()(i)
+*/
+
+//=======================================================================
+//class : MemBlock
+//
+//=======================================================================
+template <class Type> class BOPCol_MemBlock {
+ public:
+  // Ctor
+  BOPCol_MemBlock(const Handle(NCollection_BaseAllocator)& theAllocator) {
+    myI1=0;
+    myI2=0;
+    mySize=0;
+    myData=NULL;
+    myAllocator=theAllocator;
+    myNext=NULL;
+  }
+  // ~
+  ~BOPCol_MemBlock(){
+    Clear();
+  }
+  // Clear
+  void Clear() {
+    if (myData) {
+      //Standard_Integer i;
+      Standard_Size i;
+      //
+      for (i=0; i<mySize; ++i) {
+       myData[i].~Type();
+      }
+      myAllocator->Free((Standard_Address&)myData); 
+      //
+      myData=NULL;
+      mySize=0;
+      myNext=NULL;
+    }
+  }
+  // Allocate
+  void Allocate(const Standard_Size theSize) { 
+    //Standard_Integer i;
+    Standard_Size i;
+    //
+    Clear();
+    mySize=theSize;
+    myData=(Type*)myAllocator->Allocate(theSize*sizeof(Type));
+    for (i=0; i<mySize; ++i) {
+#ifdef BOPCol_Array1_Use_Allocator
+      new (myData+i) Type (myAllocator);
+#else
+      new (myData+i) Type;
+#endif
+    }
+  }
+  // SetRange
+  void SetRange(const Standard_Integer theI1,
+               const Standard_Integer theI2) {
+    myI1=theI1;
+    myI2=theI2;
+  }
+  // Range
+  void Range(Standard_Integer& theI1,
+            Standard_Integer& theI2) const {
+    theI1=myI1;
+    theI2=myI2;
+  }
+  // Contains
+  Standard_Boolean Contains(const Standard_Integer theIndex)const {
+    return (theIndex>=myI1 && theIndex<=myI2);
+  }
+  // SetValue
+  void SetValue(const Standard_Integer theIndex,
+               const Type& theValue) {
+    *(myData+theIndex-myI1)=theValue;
+  }
+  // Value
+  const Type& Value(const Standard_Integer theIndex)const {
+    return *(myData+theIndex-myI1);
+  }
+  // ChangeValue
+  Type& ChangeValue(const Standard_Integer theIndex) {
+    return *(myData+theIndex-myI1);
+  }
+  // SetNext
+  void SetNext(BOPCol_MemBlock<Type>* pNext) {
+    myNext=pNext;
+  }
+  // Next
+  BOPCol_MemBlock<Type>* Next() {
+    return myNext;
+  }
+  //
+ public:
+  BOPCol_MemBlock<Type>* myNext;
+ protected:
+  Standard_Integer myI1;
+  Standard_Integer myI2;
+  Standard_Size mySize;
+  Type *myData;
+  Handle(NCollection_BaseAllocator) myAllocator;
+};
+
+//=======================================================================
+//class  : BOPCol_Array1
+//
+//=======================================================================
+template <class Type> class BOPCol_Array1 {
+
+ public:
+  typedef BOPCol_MemBlock<Type>*  BOPCol_PMemBlock;
+  typedef BOPCol_MemBlock<Type>   BOPCol_XMemBlock;
+  //=========
+  // Ctor
+  BOPCol_Array1(const Handle(NCollection_BaseAllocator)& theAllocator=0L) {
+    myStartSize=32;
+    myIncrement=8;
+    myExtent=0;
+    myPBlock=NULL;
+    myPBlock1=NULL;
+    //
+    if (theAllocator.IsNull()) {
+      myAllocator = NCollection_BaseAllocator::CommonBaseAllocator();
+    }
+    else {
+      myAllocator=theAllocator;
+    }
+  }
+  // ~
+  ~BOPCol_Array1() {
+    Clear();
+  }
+  //===========
+  // Clear
+  void Clear() {
+    BOPCol_PMemBlock pBlock, pNext;
+    //
+    pBlock=myPBlock1;
+    while(pBlock) {
+      pNext=pBlock->Next();
+      //
+      //pBlock->~BOPCol_MemBlock<Type> ();
+      pBlock->~BOPCol_XMemBlock();
+      //pBlock->Clear();
+      myAllocator->Free((Standard_Address&)pBlock);
+      //
+      pBlock=pNext;
+    }
+    myPBlock1=NULL;
+    myPBlock=NULL;
+    myExtent=0;
+  }
+  // SetStartSize
+  void SetStartSize(const Standard_Size theSize) {
+    if (theSize>0) {
+      myStartSize=theSize;
+    }
+  }
+  // SetIncrement
+  void SetIncrement(const Standard_Size theSize){
+    if (theSize>0) {
+      myIncrement=theSize;
+    }
+  }
+  // Increment
+  Standard_Size Increment()const {
+    return myIncrement;
+  }
+  // Extent
+  Standard_Size Extent()const {
+    return myExtent;
+  }
+  // Size
+  Standard_Size Size()const {
+    return myExtent;
+  }
+  // Size
+  Standard_Size Length()const {
+    return myExtent;
+  }
+  // Init
+  void Init();
+  // Append(const Type& theValue)
+  Standard_Integer Append(const Type& theValue);
+  // Append()
+  Standard_Integer Append();
+  // SetValue
+  void SetValue(const Standard_Integer theIndex,
+               const Type& theValue);
+  // Value
+  const Type& operator()(const Standard_Integer theIndex)const;
+  //
+  const Type& Value(const Standard_Integer theIndex)const;
+  // ChangeValue
+  Type& operator()(const Standard_Integer theIndex);
+  //
+  Type& ChangeValue(const Standard_Integer theIndex);
+ //
+ // protected
+ protected:
+  //===========
+  //FindBlock
+  Standard_Boolean FindBlock(const Standard_Integer theIndex)const ;
+  //Copy ctor
+  BOPCol_Array1(const BOPCol_Array1&);
+  //Assign operator
+  BOPCol_Array1& operator =(const BOPCol_Array1& theOther);
+  //==========
+  // fields
+ protected:
+  Standard_Size myStartSize;
+  Standard_Size myIncrement;
+  Standard_Size myExtent;
+  Type myDfltItem;
+  BOPCol_MemBlock<Type> * myPBlock; 
+  BOPCol_MemBlock<Type> * myPBlock1; 
+  Handle(NCollection_BaseAllocator) myAllocator;
+};
+//
+//=======================================================================
+//function : Init
+//purpose  : 
+//=======================================================================
+template <class Type> 
+  void BOPCol_Array1<Type>::Init() {
+    BOPCol_PMemBlock pBlock;
+    //
+    pBlock=(BOPCol_PMemBlock)myAllocator->Allocate(sizeof(BOPCol_MemBlock<Type>));
+    new (pBlock) BOPCol_MemBlock<Type>(myAllocator);
+    //
+    pBlock->Allocate(myStartSize);
+    pBlock->SetRange(0, myStartSize-1);
+    myPBlock1=pBlock;
+    myPBlock=pBlock;
+  }
+//=======================================================================
+//function : Append
+//purpose  : 
+//=======================================================================
+template <class Type> 
+  Standard_Integer BOPCol_Array1<Type>::Append(const Type& theValue) {
+    BOPCol_PMemBlock pBlock, pNext;
+    //
+    pBlock=myPBlock1;
+    while(1) {
+      pNext=pBlock->myNext;
+      if(!pNext) {
+       myPBlock=pBlock;
+       break;
+      }
+      pBlock=pNext;
+    }
+    //
+    if (!myPBlock->Contains(myExtent)) {
+      //
+      pBlock=(BOPCol_PMemBlock)myAllocator->Allocate(sizeof(BOPCol_MemBlock<Type>));
+      new (pBlock) BOPCol_MemBlock<Type>(myAllocator);
+      //
+      pBlock->Allocate(myIncrement);
+      pBlock->SetRange(myExtent, myExtent+myIncrement-1);
+      //
+      myPBlock->myNext=pBlock;
+      //
+      myPBlock=pBlock;
+    }
+    //
+    myPBlock->SetValue(myExtent, theValue);
+    //
+    ++myExtent;
+    //
+    return myExtent;
+  }
+//=======================================================================
+//function : Append
+//purpose  : 
+//=======================================================================
+template <class Type> 
+  Standard_Integer BOPCol_Array1<Type>::Append() {
+    BOPCol_PMemBlock pBlock, pNext;
+    //
+    pBlock=myPBlock1;
+    while(1) {
+      pNext=pBlock->myNext;
+      if(!pNext) {
+       myPBlock=pBlock;
+       break;
+      }
+      pBlock=pNext;
+    }
+    //
+    if (!myPBlock->Contains(myExtent)) {
+      //
+      pBlock=(BOPCol_PMemBlock)myAllocator->Allocate(sizeof(BOPCol_MemBlock<Type>));
+      new (pBlock) BOPCol_MemBlock<Type>(myAllocator);
+      //
+      pBlock->Allocate(myIncrement);
+      pBlock->SetRange(myExtent, myExtent+myIncrement-1);
+      //
+      myPBlock->myNext=pBlock;
+      //
+      myPBlock=pBlock;
+    }
+    ++myExtent;
+    //
+    return myExtent;
+  }
+//=======================================================================
+//function : SetValue
+//purpose  : 
+//=======================================================================
+template <class Type> 
+  void BOPCol_Array1<Type>::SetValue(const Standard_Integer theIndex,
+                                    const Type& theValue) {
+    if (FindBlock(theIndex)) {
+      myPBlock->SetValue(theIndex, theValue);
+    }
+  }
+//=======================================================================
+//function : operator()
+//purpose  : 
+//=======================================================================
+template <class Type> 
+  const Type& BOPCol_Array1<Type>::operator()(const Standard_Integer theIndex)const {
+    if (FindBlock(theIndex)) {
+      return myPBlock->Value(theIndex);
+    }
+    return myDfltItem;
+  }
+//=======================================================================
+//function : Value
+//purpose  : 
+//=======================================================================
+template <class Type> 
+  const Type& BOPCol_Array1<Type>::Value(const Standard_Integer theIndex)const {
+    return operator()(theIndex);
+  }
+//=======================================================================
+//function : operator
+//purpose  : 
+//=======================================================================
+template <class Type> 
+  Type& BOPCol_Array1<Type>::operator()(const Standard_Integer theIndex) {
+    if (FindBlock(theIndex)) {
+      return myPBlock->ChangeValue(theIndex);
+    }
+    return myDfltItem;
+  }
+//=======================================================================
+//function : ChangeValue
+//purpose  : 
+//=======================================================================
+template <class Type> 
+  Type& BOPCol_Array1<Type>::ChangeValue(const Standard_Integer theIndex) {
+    return operator()(theIndex);
+  }
+//=======================================================================
+//function : FindBlock
+//purpose  : 
+//=======================================================================
+template <class Type> 
+  Standard_Boolean BOPCol_Array1<Type>::FindBlock(const Standard_Integer theIndex)const {
+    Standard_Boolean bRet;
+    //
+    bRet=myPBlock->Contains(theIndex);
+    if(bRet) {
+      return bRet;
+    }
+    //
+    Standard_Integer i1, i2;
+    BOPCol_PMemBlock pBlock, *xPBlock;
+    //
+    xPBlock=(BOPCol_PMemBlock*)&myPBlock;
+    pBlock=myPBlock1;
+    //
+    i1=0;
+    i2=myStartSize-1;
+    do {
+      if (theIndex>=i1 && theIndex<=i2) {
+       *xPBlock=pBlock;
+       return !bRet;
+      }
+      //
+      i1=i2+1;
+      i2=i1+myIncrement-1;
+      pBlock=pBlock->myNext;
+    } while(pBlock);
+    //
+    return bRet;
+  }
+
+#endif