1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

Integration of OCCT 6.5.0 from SVN

This commit is contained in:
bugmaster
2011-03-16 07:30:28 +00:00
committed by bugmaster
parent 4903637061
commit 7fd59977df
16375 changed files with 3882564 additions and 0 deletions

76
src/NCollection/FILES Executable file
View File

@@ -0,0 +1,76 @@
NCollection_TypeDef.hxx
NCollection_BaseAllocator.hxx
NCollection_BaseAllocator.cxx
NCollection_IncAllocator.hxx
NCollection_IncAllocator.cxx
NCollection_HeapAllocator.hxx
NCollection_HeapAllocator.cxx
NCollection_ListNode.hxx
NCollection_BaseList.hxx
NCollection_BaseList.cxx
NCollection_BaseSequence.hxx
NCollection_BaseSequence.cxx
NCollection_BaseMap.hxx
NCollection_BaseMap.cxx
NCollection_BaseCollection.hxx
NCollection_TListNode.hxx
NCollection_TListIterator.hxx
NCollection_Sequence.hxx
NCollection_HSequence.hxx
NCollection_Array1.hxx
NCollection_HArray1.hxx
NCollection_Array2.hxx
NCollection_HArray2.hxx
NCollection_Queue.hxx
NCollection_Stack.hxx
NCollection_List.hxx
NCollection_SList.hxx
NCollection_Set.hxx
NCollection_HSet.hxx
NCollection_Map.hxx
NCollection_DataMap.hxx
NCollection_DoubleMap.hxx
NCollection_IndexedMap.hxx
NCollection_IndexedDataMap.hxx
NCollection_DefineBaseCollection.hxx
NCollection_DefineTListIterator.hxx
NCollection_DefineTListNode.hxx
NCollection_DefineArray1.hxx
NCollection_DefineHArray1.hxx
NCollection_DefineArray2.hxx
NCollection_DefineHArray2.hxx
NCollection_DefineList.hxx
NCollection_DefineMap.hxx
NCollection_DefineDataMap.hxx
NCollection_DefineDoubleMap.hxx
NCollection_DefineIndexedMap.hxx
NCollection_DefineIndexedDataMap.hxx
NCollection_DefineQueue.hxx
NCollection_DefineSList.hxx
NCollection_DefineSequence.hxx
NCollection_DefineHSequence.hxx
NCollection_DefineSet.hxx
NCollection_DefineHSet.hxx
NCollection_DefineStack.hxx
NCollection_BaseVector.hxx
NCollection_BaseVector.cxx
NCollection_Vector.hxx
NCollection_DefineVector.hxx
NCollection_StdBase.hxx
templates2macros.sh
NCollection.mdl.gz
NCollection_EBTree.hxx
NCollection_UBTree.hxx
NCollection_UBTreeFiller.hxx
NCollection_SparseArray.hxx
NCollection_SparseArrayBase.hxx
NCollection_SparseArrayBase.cxx
NCollection_CellFilter.hxx
NCollection_Handle.hxx
NCollection_Handle.cxx

Binary file not shown.

View File

@@ -0,0 +1,284 @@
// File: NCollection_Array1.hxx
// Created: 15.04.02 17:05:16
// Author: Alexander Kartomin (akm)
// <a-kartomin@opencascade.com>
// Copyright: Open Cascade 2002
#ifndef NCollection_Array1_HeaderFile
#define NCollection_Array1_HeaderFile
#ifndef No_Exception
#include <Standard_DimensionMismatch.hxx>
#include <Standard_OutOfMemory.hxx>
#include <Standard_OutOfRange.hxx>
#endif
#include <NCollection_BaseCollection.hxx>
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (push)
#pragma warning (disable:4291)
#endif
// *********************************************** Template for Array1 class
/**
* Purpose: The class Array1 represents unidimensional arrays
* of fixed size known at run time.
* The range of the index is user defined.
* An array1 can be constructed with a "C array".
* This functionality is useful to call methods expecting
* an Array1. It allows to carry the bounds inside the arrays.
*
* Examples: Item tab[100]; // An example with a C array
* Array1OfItem ttab (tab[0],1,100);
*
* Array1OfItem tttab (ttab(10),10,20); // a slice of ttab
*
* If you want to reindex an array from 1 to Length do :
*
* Array1 tab1(tab(tab.Lower()),1,tab.Length());
*
* Warning: Programs client of such a class must be independant
* of the range of the first element. Then, a C++ for
* loop must be written like this
*
* for (i = A.Lower(); i <= A.Upper(); i++)
*
* Changes: In comparison to TCollection the flag isAllocated was
* renamed into myDeletable (alike in the Array2). For naming
* compatibility the method IsAllocated remained in class along
* with IsDeletable.
*/
template <class TheItemType> class NCollection_Array1
: public NCollection_BaseCollection<TheItemType>
{
public:
//! Implementation of the Iterator interface.
class Iterator : public NCollection_BaseCollection<TheItemType>::Iterator
{
public:
//! Empty constructor - for later Init
Iterator (void) :
myCurrent (0),
myArray (NULL) {}
//! Constructor with initialisation
Iterator (const NCollection_Array1& theArray) :
myCurrent (theArray.Lower()),
myArray ((NCollection_Array1 *) &theArray) {}
//! Initialisation
void Init (const NCollection_Array1& theArray)
{
myCurrent = theArray.Lower();
myArray = (NCollection_Array1 *) &theArray;
}
//! Check end
virtual Standard_Boolean More (void) const
{ return (myCurrent<=myArray->Upper()); }
//! Make step
virtual void Next (void)
{ myCurrent++; }
//! Constant value access
virtual const TheItemType& Value (void) const
{ return myArray->Value(myCurrent); }
//! Variable value access
virtual TheItemType& ChangeValue (void) const
{ return myArray->ChangeValue(myCurrent); }
//! Operator new for allocating iterators
void* operator new(size_t theSize,
const Handle(NCollection_BaseAllocator)& theAllocator)
{ return theAllocator->Allocate(theSize); }
private:
Standard_Integer myCurrent; //!< Index of the current item
NCollection_Array1* myArray; //!< Pointer to the array being iterated
}; // End of the nested class Iterator
public:
// ---------- PUBLIC METHODS ------------
//! Constructor
NCollection_Array1(const Standard_Integer theLower,
const Standard_Integer theUpper) :
NCollection_BaseCollection<TheItemType> (),
myLowerBound (theLower),
myUpperBound (theUpper),
myDeletable (Standard_True)
{
#if !defined No_Exception && !defined No_Standard_RangeError
if (theUpper < theLower)
Standard_RangeError::Raise ("NCollection_Array1::Create");
#endif
TheItemType* pBegin = new TheItemType[Length()];
#if !defined No_Exception && !defined No_Standard_OutOfMemory
if (!pBegin)
Standard_OutOfMemory::Raise ("NCollection_Array1 : Allocation failed");
#endif
myData = pBegin - theLower;
}
//! Copy constructor
NCollection_Array1 (const NCollection_Array1& theOther) :
NCollection_BaseCollection<TheItemType> (),
myLowerBound (theOther.Lower()),
myUpperBound (theOther.Upper()),
myDeletable (Standard_True)
{
TheItemType* pBegin = new TheItemType[Length()];
#if !defined No_Exception && !defined No_Standard_OutOfMemory
if (!pBegin)
Standard_OutOfMemory::Raise ("NCollection_Array1 : Allocation failed");
#endif
myData = pBegin - myLowerBound;
*this = theOther;
}
//! C array-based constructor
NCollection_Array1 (const TheItemType& theBegin,
const Standard_Integer theLower,
const Standard_Integer theUpper) :
NCollection_BaseCollection<TheItemType> (),
myLowerBound (theLower),
myUpperBound (theUpper),
myDeletable (Standard_False)
{
#if !defined No_Exception && !defined No_Standard_RangeError
if (theUpper < theLower)
Standard_RangeError::Raise ("NCollection_Array1::Array1");
#endif
myData = (TheItemType *) &theBegin - theLower;
}
//! Initialise the items with theValue
void Init (const TheItemType& theValue)
{
TheItemType *pCur = &myData[myLowerBound], *pEnd=&myData[myUpperBound];
for(; pCur <= pEnd; pCur++)
*pCur = (TheItemType&) theValue;
}
//! Size query
virtual Standard_Integer Size (void) const
{ return Length(); }
//! Length query (the same)
Standard_Integer Length (void) const
{ return (myUpperBound-myLowerBound+1); }
//! Lower bound
Standard_Integer Lower (void) const
{ return myLowerBound; }
//! Upper bound
Standard_Integer Upper (void) const
{ return myUpperBound; }
//! myDeletable flag
Standard_Boolean IsDeletable (void) const
{ return myDeletable; }
//! IsAllocated flag - for naming compatibility
Standard_Boolean IsAllocated (void) const
{ return myDeletable; }
//! Assign (any collection to this array)
// Copies items from the other collection into the allocated
// storage. Raises an exception when sizes differ.
virtual void Assign (const NCollection_BaseCollection<TheItemType>& theOther)
{
if (&theOther == this)
return;
#if !defined No_Exception && !defined No_Standard_DimensionMismatch
if (Length() != theOther.Size())
Standard_DimensionMismatch::Raise ("NCollection_Array1::Assign");
#endif
TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& anIter2 =
theOther.CreateIterator();
TheItemType * const pEndItem = &myData[myUpperBound];
for (TheItemType * pItem = &myData[myLowerBound];
pItem <= pEndItem; anIter2.Next())
* pItem ++ = anIter2.Value();
}
//! operator= (array to array)
NCollection_Array1& operator= (const NCollection_Array1& theOther)
{
if (&theOther == this)
return *this;
#if !defined No_Exception && !defined No_Standard_DimensionMismatch
if (Length() != theOther.Length())
Standard_DimensionMismatch::Raise ("NCollection_Array1::operator=");
#endif
TheItemType * pMyItem = &myData[myLowerBound];
TheItemType * const pEndItem = &(theOther.myData)[theOther.myUpperBound];
TheItemType * pItem = &(theOther.myData)[theOther.myLowerBound];
while (pItem <= pEndItem) * pMyItem ++ = * pItem ++;
return *this;
}
//! Constant value access
const TheItemType& Value (const Standard_Integer theIndex) const
{
#if !defined No_Exception && !defined No_Standard_OutOfRange
if (theIndex < myLowerBound || theIndex > myUpperBound)
Standard_OutOfRange::Raise ("NCollection_Array1::Value");
#endif
return myData[theIndex];
}
//! operator() - alias to Value
const TheItemType& operator() (const Standard_Integer theIndex) const
{ return Value (theIndex); }
//! Variable value access
TheItemType& ChangeValue (const Standard_Integer theIndex)
{
#if !defined No_Exception && !defined No_Standard_OutOfRange
if (theIndex < myLowerBound || theIndex > myUpperBound)
Standard_OutOfRange::Raise ("NCollection_Array1::ChangeValue");
#endif
return myData[theIndex];
}
//! operator() - alias to ChangeValue
TheItemType& operator() (const Standard_Integer theIndex)
{ return ChangeValue (theIndex); }
//! Set value
void SetValue (const Standard_Integer theIndex,
const TheItemType& theItem)
{
#if !defined No_Exception && !defined No_Standard_OutOfRange
if (theIndex < myLowerBound || theIndex > myUpperBound)
Standard_OutOfRange::Raise ("NCollection_Array1::SetValue");
#endif
myData[theIndex] = theItem;
}
//! Destructor - releases the memory
~NCollection_Array1 (void)
{ if (myDeletable) delete [] &(myData[myLowerBound]); }
private:
// ----------- PRIVATE METHODS -----------
// ******** Creates Iterator for use on BaseCollection
virtual
TYPENAME NCollection_BaseCollection<TheItemType>::Iterator&
CreateIterator(void) const
{ return *(new (this->IterAllocator()) Iterator(*this)); }
protected:
// ---------- PROTECTED FIELDS -----------
Standard_Integer myLowerBound;
Standard_Integer myUpperBound;
Standard_Boolean myDeletable; //!< Flag showing who allocated the array
TheItemType* myData; //!< Pointer to '0'th array item
};
#ifdef WNT
#pragma warning (pop)
#endif
#endif

View File

@@ -0,0 +1,323 @@
// File: NCollection_Array2.hxx
// Created: 15.04.02 17:05:16
// Author: Alexander Kartomin (akm)
// <a-kartomin@opencascade.com>
// Copyright: Open Cascade 2002
#ifndef NCollection_Array2_HeaderFile
#define NCollection_Array2_HeaderFile
#ifndef No_Exception
#include <Standard_DimensionMismatch.hxx>
#include <Standard_OutOfMemory.hxx>
#include <Standard_OutOfRange.hxx>
#endif
#include <NCollection_BaseCollection.hxx>
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (disable:4291)
#endif
// *********************************************** Template for Array2 class
/**
* Purpose: The class Array2 represents bi-dimensional arrays
* of fixed size known at run time.
* The ranges of indices are user defined.
*
* Warning: Programs clients of such class must be independant
* of the range of the first element. Then, a C++ for
* loop must be written like this
*
* for (i = A.LowerRow(); i <= A.UpperRow(); i++)
* for (j = A.LowerCol(); j <= A.UpperCol(); j++)
*/
template <class TheItemType> class NCollection_Array2
: public NCollection_BaseCollection<TheItemType>
{
public:
// **************** Implementation of the Iterator interface.
class Iterator : public NCollection_BaseCollection<TheItemType>::Iterator
{
public:
//! Empty constructor - for later Init
Iterator (void) :
myCurrent (0),
mySize (0),
myArray (NULL) {}
//! Constructor with initialisation
Iterator (const NCollection_Array2& theArray) :
myCurrent (0),
mySize (theArray.Length()),
myArray ((NCollection_Array2 *) &theArray) {}
//! Initialisation
void Init (const NCollection_Array2& theArray)
{
myCurrent = 0;
mySize = theArray.Length();
myArray = (NCollection_Array2 *) &theArray;
}
//! Check end
virtual Standard_Boolean More (void) const
{ return (myCurrent < mySize); }
//! Make step
virtual void Next (void)
{ myCurrent++; }
//! Constant value access
virtual const TheItemType& Value (void) const
{ return myArray->myStart[myCurrent]; }
//! Variable value access
virtual TheItemType& ChangeValue (void) const
{ return myArray->myStart[myCurrent]; }
//! Operator new for allocating iterators
void* operator new(size_t theSize,
const Handle(NCollection_BaseAllocator)& theAllocator)
{ return theAllocator->Allocate(theSize); }
private:
Standard_Integer myCurrent; //!< Index of the current item
Standard_Integer mySize; //!< Total amount of items
NCollection_Array2* myArray; //!< Pointer to the array being iterated
}; // End of nested class Iterator
public:
// ---------- PUBLIC METHODS ------------
//! Constructor
NCollection_Array2(const Standard_Integer theRowLower,
const Standard_Integer theRowUpper,
const Standard_Integer theColLower,
const Standard_Integer theColUpper) :
NCollection_BaseCollection<TheItemType> (),
myLowerRow (theRowLower),
myUpperRow (theRowUpper),
myLowerCol (theColLower),
myUpperCol (theColUpper),
myDeletable (Standard_True)
{ Allocate(); }
//! Copy constructor
NCollection_Array2 (const NCollection_Array2& theOther) :
NCollection_BaseCollection<TheItemType> (),
myLowerRow (theOther.LowerRow()),
myUpperRow (theOther.UpperRow()),
myLowerCol (theOther.LowerCol()),
myUpperCol (theOther.UpperCol()),
myDeletable (Standard_True)
{
Allocate();
*this = theOther;
}
//! C array-based constructor
NCollection_Array2(const TheItemType& theBegin,
const Standard_Integer theRowLower,
const Standard_Integer theRowUpper,
const Standard_Integer theColLower,
const Standard_Integer theColUpper) :
NCollection_BaseCollection<TheItemType> (),
myLowerRow (theRowLower),
myUpperRow (theRowUpper),
myLowerCol (theColLower),
myUpperCol (theColUpper),
myDeletable (Standard_False)
{
myStart = (TheItemType *) &theBegin;
Allocate();
}
//! Initialise the values
void Init (const TheItemType& theValue)
{
TheItemType *pCur, *pEnd=myStart+Size();
for(pCur = myStart; pCur<pEnd; pCur++)
*pCur = theValue;
}
//! Size (number of items)
virtual Standard_Integer Size (void) const
{ return Length(); }
//! Length (number of items)
Standard_Integer Length (void) const
{ return RowLength() * ColLength(); }
//! RowLength
Standard_Integer RowLength (void) const
{ return (myUpperCol-myLowerCol+1); }
//! ColLength
Standard_Integer ColLength (void) const
{ return (myUpperRow-myLowerRow+1); }
//! LowerRow
Standard_Integer LowerRow (void) const
{ return myLowerRow; }
//! UpperRow
Standard_Integer UpperRow (void) const
{ return myUpperRow; }
//! LowerCol
Standard_Integer LowerCol (void) const
{ return myLowerCol; }
//! UpperCol
Standard_Integer UpperCol (void) const
{ return myUpperCol; }
//! myDeletable flag
Standard_Boolean IsDeletable (void) const
{ return myDeletable; }
//! Assign
// Copies items from the other collection into the allocated
// storage. Raises an exception when sizes differ.
virtual void Assign (const NCollection_BaseCollection<TheItemType>& theOther)
{
if (&theOther == this)
return;
#if !defined No_Exception && !defined No_Standard_DimensionMismatch
if (Length() != theOther.Size())
Standard_DimensionMismatch::Raise ("NCollection_Array2::Assign");
#endif
TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& anIter2 =
theOther.CreateIterator();
const TheItemType* pEnd = myStart+Length();
for (TheItemType* pItem=myStart;
pItem < pEnd;
pItem++, anIter2.Next())
*pItem = anIter2.Value();
}
//! operator= (array to array)
NCollection_Array2& operator= (const NCollection_Array2& theOther)
{
if (&theOther == this)
return *this;
#if !defined No_Exception && !defined No_Standard_DimensionMismatch
if (Length() != theOther.Length())
Standard_DimensionMismatch::Raise ("NCollection_Array2::operator=");
#endif
TheItemType * pMyItem = myStart;
TheItemType * pItem = theOther.myStart;
const Standard_Integer iSize = Length();
for (Standard_Integer i=0; i < iSize; i++, pItem++, pMyItem++)
*pMyItem = *pItem;
return *this;
}
//! Constant value access
const TheItemType& Value (const Standard_Integer theRow,
const Standard_Integer theCol) const
{
#if !defined No_Exception && !defined No_Standard_OutOfRange
if (theRow < myLowerRow || theRow > myUpperRow ||
theCol < myLowerCol || theCol > myUpperCol)
Standard_OutOfRange::Raise ("NCollection_Array2::Value");
#endif
return myData[theRow][theCol];
}
//! operator() - alias to ChangeValue
const TheItemType& operator() (const Standard_Integer theRow,
const Standard_Integer theCol) const
{ return Value (theRow,theCol); }
//! Variable value access
TheItemType& ChangeValue (const Standard_Integer theRow,
const Standard_Integer theCol)
{
#if !defined No_Exception && !defined No_Standard_OutOfRange
if (theRow < myLowerRow || theRow > myUpperRow ||
theCol < myLowerCol || theCol > myUpperCol)
Standard_OutOfRange::Raise ("NCollection_Array2::ChangeValue");
#endif
return myData[theRow][theCol];
}
//! operator() - alias to ChangeValue
TheItemType& operator() (const Standard_Integer theRow,
const Standard_Integer theCol)
{ return ChangeValue (theRow,theCol); }
//! SetValue
void SetValue (const Standard_Integer theRow,
const Standard_Integer theCol,
const TheItemType& theItem)
{
#if !defined No_Exception && !defined No_Standard_OutOfRange
if (theRow < myLowerRow || theRow > myUpperRow ||
theCol < myLowerCol || theCol > myUpperCol)
Standard_OutOfRange::Raise ("NCollection_Array2::SetValue");
#endif
myData[theRow][theCol] = theItem;
}
//! Destructor - releases the memory
~NCollection_Array2 (void)
{
if (myDeletable) delete [] myStart;
delete [] &(myData[myLowerRow]);
}
private:
// ----------- PRIVATE METHODS -----------
//! Allocate memory for the array, set up indirection table
void Allocate (void)
{
const Standard_Integer iRowSize = myUpperCol - myLowerCol + 1;
const Standard_Integer iColSize = myUpperRow - myLowerRow + 1;
#if !defined No_Exception && !defined No_Standard_RangeError
if (iRowSize <= 0 || iColSize <= 0)
Standard_RangeError::Raise ("NCollection_Array2::Allocate");
#endif
if (myDeletable) {
// allocation of the data in the array
myStart = new TheItemType[iRowSize * iColSize];
#if !defined No_Exception && !defined No_Standard_OutOfMemory
if (!myStart)
Standard_OutOfMemory::Raise ("NCollection_Array2 : Allocation failed");
#endif
}
// else myStart is set to the beginning of the given array
TheItemType** pTable = new TheItemType* [iColSize];
#if !defined No_Exception && !defined No_Standard_OutOfMemory
if (!pTable)
Standard_OutOfMemory::Raise ("NCollection_Array2 : Allocation failed");
#endif
// Items of pTable point to the '0'th items in the rows of the array
TheItemType* pRow = myStart - myLowerCol;
for (Standard_Integer i = 0; i < iColSize; i++)
{
pTable[i] = pRow;
pRow += iRowSize;
}
// Set myData to the '0'th row pointer of the pTable
myData = pTable - myLowerRow;
}
//! Creates Iterator for use on BaseCollection
virtual TYPENAME NCollection_BaseCollection<TheItemType>::Iterator&
CreateIterator(void) const
{ return *(new (this->IterAllocator()) Iterator(*this)); }
protected:
// ---------- PROTECTED FIELDS -----------
Standard_Integer myLowerRow;
Standard_Integer myUpperRow;
Standard_Integer myLowerCol;
Standard_Integer myUpperCol;
TheItemType** myData; //!< Pointer to the row pointers table
TheItemType* myStart; //!< Pointer to the memory array
Standard_Boolean myDeletable; //!< Flag showing who allocated the array
// ----------- FRIEND CLASSES ------------
friend class Iterator;
};
#ifdef WNT
#pragma warning (default:4291)
#endif
#endif

View File

@@ -0,0 +1,133 @@
// File: NCollection_BaseAllocator.cxx
// Created: Fri Apr 12 12:53:28 2002
// Author: Alexander KARTOMIN (akm)
// <a-kartomin@opencascade.com>
// Purpose: Implementation of the BaseAllocator class
#include <NCollection_BaseAllocator.hxx>
#include <NCollection_DataMap.hxx>
#include <NCollection_List.hxx>
#include <Standard_Mutex.hxx>
IMPLEMENT_STANDARD_HANDLE(NCollection_BaseAllocator,MMgt_TShared)
IMPLEMENT_STANDARD_RTTIEXT(NCollection_BaseAllocator,MMgt_TShared)
//=======================================================================
//function : Allocate
//purpose : Standard allocation
//=======================================================================
void* NCollection_BaseAllocator::Allocate(const size_t size)
{
return Standard::Allocate(size);
}
//=======================================================================
//function : Free
//purpose : Standard deallocation
//=======================================================================
void NCollection_BaseAllocator::Free(void *anAddress)
{
if (anAddress) Standard::Free((Standard_Address&)anAddress);
}
//=======================================================================
//function : CommonBaseAllocator
//purpose : Creates the only one BaseAllocator
//=======================================================================
const Handle(NCollection_BaseAllocator)&
NCollection_BaseAllocator::CommonBaseAllocator(void)
{
static Handle(NCollection_BaseAllocator) pAllocator =
new NCollection_BaseAllocator;
return pAllocator;
}
// global variable to ensure that allocator will be created during loading the library
static Handle(NCollection_BaseAllocator) theAllocInit =
NCollection_BaseAllocator::CommonBaseAllocator();
//=======================================================================
//function : StandardCallBack
//purpose : Callback function to register alloc/free calls
//=======================================================================
struct StorageInfo
{
Standard_Size roundSize;
int nbAlloc;
int nbFree;
StorageInfo()
: roundSize(0), nbAlloc(0), nbFree(0) {}
StorageInfo(Standard_Size theSize)
: roundSize(theSize), nbAlloc(0), nbFree(0) {}
};
static NCollection_DataMap<Standard_Size, StorageInfo> StorageMap;
void NCollection_BaseAllocator::StandardCallBack
(const Standard_Boolean theIsAlloc,
const Standard_Address /*theStorage*/,
const Standard_Size theRoundSize,
const Standard_Size /*theSize*/)
{
static int aLock = 0;
if (aLock)
return;
aLock = 1;
if (!StorageMap.IsBound(theRoundSize))
{
StorageInfo aEmpty(theRoundSize);
StorageMap.Bind(theRoundSize, aEmpty);
}
StorageInfo& aInfo = StorageMap(theRoundSize);
if (theIsAlloc)
aInfo.nbAlloc++;
else
aInfo.nbFree++;
aLock = 0;
}
//=======================================================================
//function : PrintMemUsageStatistics
//purpose : Prints memory usage statistics cumulated by StandardCallBack
//=======================================================================
void NCollection_BaseAllocator::PrintMemUsageStatistics()
{
// sort by roundsize
NCollection_List<StorageInfo> aColl;
NCollection_List<StorageInfo>::Iterator itLst;
NCollection_DataMap<Standard_Size, StorageInfo>::Iterator itMap(StorageMap);
for (; itMap.More(); itMap.Next())
{
for (itLst.Init(aColl); itLst.More(); itLst.Next())
if (itMap.Value().roundSize < itLst.Value().roundSize)
break;
if (itLst.More())
aColl.InsertBefore(itMap.Value(), itLst);
else
aColl.Append(itMap.Value());
}
Standard_Size aTotAlloc = 0;
Standard_Size aTotLeft = 0;
// print
printf("%12s %12s %12s %12s %12s\n",
"BlockSize", "NbAllocated", "NbLeft", "Allocated", "Left");
for (itLst.Init(aColl); itLst.More(); itLst.Next())
{
const StorageInfo& aInfo = itLst.Value();
Standard_Integer nbLeft = aInfo.nbAlloc - aInfo.nbFree;
Standard_Size aSizeAlloc = aInfo.nbAlloc * aInfo.roundSize;
Standard_Size aSizeLeft = nbLeft * aInfo.roundSize;
printf("%12d %12d %12d %12d %12d\n", aInfo.roundSize,
aInfo.nbAlloc, nbLeft, aSizeAlloc, aSizeLeft);
aTotAlloc += aSizeAlloc;
aTotLeft += aSizeLeft;
}
printf("%12s %12s %12s %12d %12d\n", "Total:", "", "",
aTotAlloc, aTotLeft);
fflush(stdout);
}

View File

@@ -0,0 +1,78 @@
// File: NCollection_BaseAllocator.hxx
// Created: Fri Apr 12 09:22:55 2002
// Author: Alexander KARTOMIN (akm)
// <a-kartomin@opencascade.com>
//
// Purpose: Basic class for memory allocation wizards.
// Defines the interface for devising different allocators
// firstly to be used by collections of NCollection, though it
// it is not deferred. It allocates/frees the memory through
// Standard procedures, thus it is unnecessary (and sometimes
// injurious) to have more than one such allocator. To avoid
// creation of multiple objects the constructors were maid
// inaccessible. To create the BaseAllocator use the method
// CommonBaseAllocator.
// Note that this object is managed by Handle.
//
#ifndef NCollection_BaseAllocator_HeaderFile
#define NCollection_BaseAllocator_HeaderFile
#include <MMgt_TShared.hxx>
#include <Standard_DefineHandle.hxx>
#include <NCollection_TypeDef.hxx>
class Handle(NCollection_BaseAllocator);
/**
* Purpose: Basic class for memory allocation wizards.
* Defines the interface for devising different allocators
* firstly to be used by collections of NCollection, though it
* it is not deferred. It allocates/frees the memory through
* Standard procedures, thus it is unnecessary (and sometimes
* injurious) to have more than one such allocator. To avoid
* creation of multiple objects the constructors were maid
* inaccessible. To create the BaseAllocator use the method
* CommonBaseAllocator.
* Note that this object is managed by Handle.
*/
class NCollection_BaseAllocator : public MMgt_TShared
{
public:
// ---------- PUBLIC METHODS ------------
Standard_EXPORT virtual void* Allocate (const size_t size);
Standard_EXPORT virtual void Free (void * anAddress);
//! CommonBaseAllocator
//! This method is designed to have the only one BaseAllocator (to avoid
//! useless copying of collections). However one can use operator new to
//! create more BaseAllocators, but it is injurious.
Standard_EXPORT static const Handle(NCollection_BaseAllocator)&
CommonBaseAllocator(void);
//! Callback function to register alloc/free calls
Standard_EXPORT static void StandardCallBack
(const Standard_Boolean theIsAlloc,
const Standard_Address theStorage,
const Standard_Size theRoundSize,
const Standard_Size theSize);
//! Prints memory usage statistics cumulated by StandardCallBack
Standard_EXPORT static void PrintMemUsageStatistics();
protected:
//! Constructor - prohibited
NCollection_BaseAllocator(void) {};
private:
//! Copy constructor - prohibited
NCollection_BaseAllocator(const NCollection_BaseAllocator&);
public:
// ---------- CasCade RunTime Type Information
DEFINE_STANDARD_RTTI(NCollection_BaseAllocator)
};
DEFINE_STANDARD_HANDLE(NCollection_BaseAllocator,MMgt_TShared)
#endif

View File

@@ -0,0 +1,105 @@
// File: NCollection_BaseCollection.hxx
// Created: Tue Apr 9 18:53:36 2002
// Author: Alexander KARTOMIN (akm)
// <a-kartomin@opencascade.com>
#ifndef NCollection_BaseCollection_HeaderFile
#define NCollection_BaseCollection_HeaderFile
#include <NCollection_IncAllocator.hxx>
/**
* Purpose: NCollection_BaseCollection is the base abstract class for
* all collection templates of this package.
* The set of collections is similar to that of TCollection.
* Also the methods of classes have mostly the same names for
* easy switch from TCollection <-> NCollection containers.
*
* NCollection is a nocdlpack, thus it is compiled without WOK.
* BaseCollection allows assigning the collections of different
* kinds (the items type being the same) with a few obvious
* exclusions - one can not assign any collection to the map
* having double data (two keys or a key plus value). Only the
* maps of the very same type may be assigned through operator=
* Said maps are: DoubleMap,
* DataMap,
* IndexedDataMap
*
* For the users needing control over the memory usage the
* allocators were added (see NCollection_BaseAllocator header)
* Others may forget it - BaseAllocator is used by default and
* then memory is managed through Standard::Allocate/::Free.
*/
template<class TheItemType> class NCollection_BaseCollection
{
public:
// **************** The interface for iterating over collections
class Iterator
{
public:
//! Query if the end of collection is reached by iterator
virtual Standard_Boolean More(void) const=0;
//! Make a step along the collection
virtual void Next(void)=0;
//! Value inquiry
virtual const TheItemType& Value(void) const=0;
//! Value change access
virtual TheItemType& ChangeValue(void) const=0;
protected:
//! Empty constructor
Iterator (void) {}
//! Virtual destructor is necessary for classes with virtual methods
virtual ~Iterator (void) {}
protected:
//! operator= is prohibited
const Iterator& operator= (const Iterator&);
//! Copy constructor **
Iterator (const Iterator&) {}
}; // End of nested class Iterator
public:
// ---------- PUBLIC METHODS ------------
//! Common for all collections constructor takes care of theAllocator
NCollection_BaseCollection
(const Handle(NCollection_BaseAllocator)& theAllocator=0L)
{
if (theAllocator.IsNull())
myAllocator = NCollection_BaseAllocator::CommonBaseAllocator();
else
myAllocator = theAllocator;
}
//! Number of items
virtual Standard_Integer Size(void) const = 0;
//! Virtual assignment
virtual void Assign
(const NCollection_BaseCollection& theOther)=0;
//! Method to create iterators for base collections
virtual Iterator& CreateIterator(void) const=0;
//! Destructor - must be implemented to release the memory
virtual ~NCollection_BaseCollection (void) {}
protected:
// --------- PROTECTED METHOD -----------
const Handle(NCollection_BaseAllocator)& IterAllocator(void) const
{
if (myIterAllocator.IsNull())
(Handle_NCollection_BaseAllocator&) myIterAllocator =
new NCollection_IncAllocator(64);
return myIterAllocator;
}
protected:
// --------- PROTECTED FIELDS -----------
Handle(NCollection_BaseAllocator) myAllocator;
private:
// ---------- PRIVATE FIELDS ------------
Handle(NCollection_BaseAllocator) myIterAllocator;
};
#endif

View File

@@ -0,0 +1,263 @@
// File: NCollection_BaseList.cxx
// Created: Tue Apr 23 09:16:44 2002
// Author: Alexander KARTOMIN (akm)
// <a-kartomin@opencascade.com>
// Purpose: Implementation of the BaseList class
#include <NCollection_BaseList.hxx>
//=======================================================================
//function : PClear
//purpose : Deletes all nodes from the list
//=======================================================================
void NCollection_BaseList::PClear
(NCollection_DelListNode fDel,
Handle(NCollection_BaseAllocator)& theAllocator)
{
NCollection_ListNode* pCur = myFirst;
NCollection_ListNode* pNext = NULL;
while(pCur)
{
pNext = pCur->Next();
fDel (pCur,theAllocator);
pCur = pNext;
}
myLength = 0;
myFirst = myLast = NULL;
}
//=======================================================================
//function : PAppend
//purpose : Appends one item at the end
//=======================================================================
void NCollection_BaseList::PAppend (NCollection_ListNode* theNode)
{
if (myLength)
myLast->Next() = theNode;
else
myFirst = theNode;
theNode->Next() = NULL;
myLast = theNode;
myLength++;
}
//=======================================================================
//function : PAppend
//purpose : Appends another list at the end
//=======================================================================
void NCollection_BaseList::PAppend (NCollection_BaseList& theOther)
{
if (this == &theOther || theOther.IsEmpty())
return;
if (IsEmpty())
myFirst = theOther.myFirst;
else
myLast->Next() = theOther.myFirst;
myLast = theOther.myLast;
theOther.myFirst = theOther.myLast = NULL;
myLength += theOther.myLength;
theOther.myLength = 0;
}
//=======================================================================
//function : PPrepend
//purpose : Prepends one item at the beginning
//=======================================================================
void NCollection_BaseList::PPrepend (NCollection_ListNode* theNode)
{
theNode->Next() = myFirst;
myFirst = theNode;
if (myLast==NULL)
myLast = myFirst;
myLength++;
}
//=======================================================================
//function : PPrepend
//purpose :
//=======================================================================
void NCollection_BaseList::PPrepend (NCollection_BaseList& theOther)
{
if (this == &theOther || theOther.IsEmpty())
return;
theOther.myLast->Next() = myFirst;
myFirst = theOther.myFirst;
theOther.myFirst = theOther.myLast = NULL;
myLength += theOther.myLength;
theOther.myLength = 0;
}
//=======================================================================
//function : PRemoveFirst
//purpose :
//=======================================================================
void NCollection_BaseList::PRemoveFirst
(NCollection_DelListNode fDel,
Handle(NCollection_BaseAllocator)& theAllocator)
{
Standard_NoSuchObject_Raise_if(IsEmpty(),
"NCollection_BaseList::PRemoveFirst");
NCollection_ListNode* pItem = myFirst;
myFirst = pItem->Next();
fDel (pItem, theAllocator);
myLength--;
if (myLength == 0)
myLast = NULL;
}
//=======================================================================
//function : PRemove
//purpose :
//=======================================================================
void NCollection_BaseList::PRemove
(Iterator& theIter,
NCollection_DelListNode fDel,
Handle(NCollection_BaseAllocator)& theAllocator)
{
Standard_NoSuchObject_Raise_if(!theIter.More(),
"NCollection_BaseList::PRemove");
if (theIter.myPrevious == NULL)
{
PRemoveFirst (fDel,theAllocator);
theIter.myCurrent = myFirst;
}
else
{
NCollection_ListNode* pNode = (theIter.myCurrent)->Next();
(theIter.myPrevious)->Next() = pNode;
fDel (theIter.myCurrent,theAllocator);
theIter.myCurrent = pNode;
if (pNode == NULL)
myLast = theIter.myPrevious;
myLength--;
}
}
//=======================================================================
//function : PInsertBefore
//purpose :
//=======================================================================
void NCollection_BaseList::PInsertBefore (NCollection_ListNode* theNode,
Iterator& theIter)
{
Standard_NoSuchObject_Raise_if(!theIter.More(),
"NCollection_BaseList::PInsertBefore");
if (theIter.myPrevious == NULL)
{
PPrepend(theNode);
theIter.myPrevious = myFirst;
}
else
{
(theIter.myPrevious)->Next() = theNode;
theNode->Next() = theIter.myCurrent;
theIter.myPrevious = theNode;
myLength++;
}
}
//=======================================================================
//function : PInsertBefore
//purpose :
//=======================================================================
void NCollection_BaseList::PInsertBefore (NCollection_BaseList& theOther,
Iterator& theIter)
{
Standard_NoSuchObject_Raise_if(!theIter.More(),
"NCollection_BaseList::PInsertBefore");
if (theIter.myPrevious == NULL)
{
theIter.myPrevious = theOther.myLast;
PPrepend(theOther);
}
else if (!theOther.IsEmpty())
{
myLength += theOther.myLength;
(theIter.myPrevious)->Next() = theOther.myFirst;
(theOther.myLast)->Next() = theIter.myCurrent;
theIter.myPrevious = theOther.myLast;
theOther.myLast = theOther.myFirst = NULL;
theOther.myLength = 0;
}
}
//=======================================================================
//function : PInsertAfter
//purpose :
//=======================================================================
void NCollection_BaseList::PInsertAfter (NCollection_ListNode* theNode,
Iterator& theIter)
{
Standard_NoSuchObject_Raise_if(!theIter.More(),
"NCollection_BaseList::PInsertAfter");
if (theIter.myCurrent == myLast)
{
PAppend(theNode);
}
else
{
theNode->Next() = (theIter.myCurrent)->Next();
(theIter.myCurrent)->Next() = theNode;
myLength++;
}
}
//=======================================================================
//function : PInsertAfter
//purpose :
//=======================================================================
void NCollection_BaseList::PInsertAfter(NCollection_BaseList& theOther,
Iterator& theIter)
{
Standard_NoSuchObject_Raise_if(!theIter.More(),
"NCollection_BaseList::PInsertAfter");
if (theIter.myCurrent == myLast)
{
PAppend(theOther);
}
else if (!theOther.IsEmpty())
{
myLength += theOther.myLength;
(theOther.myLast)->Next() = (theIter.myCurrent)->Next();
(theIter.myCurrent)->Next() = theOther.myFirst;
theOther.myLast = theOther.myFirst = NULL;
theOther.myLength = 0;
}
}
//=======================================================================
//function : PReverse
//purpose : reverse the list
//=======================================================================
void NCollection_BaseList::PReverse ()
{
if (myLength > 1) {
NCollection_ListNode * aHead = myFirst->Next();
NCollection_ListNode * aNeck = myFirst;
aNeck->Next() = NULL;
while (aHead) {
NCollection_ListNode * aTmp = aHead->Next();
aHead->Next() = aNeck;
aNeck = aHead;
aHead = aTmp;
}
myLast = myFirst;
myFirst = aNeck;
}
}

View File

@@ -0,0 +1,196 @@
// File: NCollection_BaseList.hxx
// Created: 17.04.02 10:12:48
// Author: Alexander Kartomin (akm)
// <a-kartomin@opencascade.com>
// Copyright: Open Cascade 2002
//
// Purpose: This is a base class for the List, Set, Queue and Stack
// collections. It offers operations on abstract lists (of the
// objects of class NCollection_ListNode).
// Apart from this class being brand new (in TCollection said
// collections were independent, only using the same class for
// node representation), here is an important new feature -
// the list length is continuously updated, so the method
// Extent is quite quick.
//
#ifndef NCollection_BaseList_HeaderFile
#define NCollection_BaseList_HeaderFile
#include <Standard_NoSuchObject.hxx>
#include <NCollection_ListNode.hxx>
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (disable:4291)
#endif
typedef void (* NCollection_DelListNode)
(NCollection_ListNode*, Handle(NCollection_BaseAllocator)& theAl);
// ********************************************************** BaseList class
class NCollection_BaseList
{
public:
class Iterator
{
public:
// ******** Empty constructor
Iterator (void) :
myCurrent (NULL),
myPrevious(NULL) {}
// ******** Constructor with initialisation
Iterator (const NCollection_BaseList& theList) :
myCurrent (theList.myFirst),
myPrevious(NULL) {}
// ******** Initialisation
void Init (const NCollection_BaseList& theList)
{
myCurrent = theList.myFirst;
myPrevious = NULL;
}
// ******** More
Standard_Boolean More (void) const
{ return (myCurrent!=NULL); }
// ******** Assignment operator
Iterator& operator= (const Iterator& theIt)
{
if (&theIt != this)
{
myCurrent = theIt.myCurrent;
myPrevious = theIt.myPrevious;
}
return * this;
}
//skt----------------------------------------------------
// ******** Comparison operator
Standard_Boolean operator== (const Iterator& theIt)
{
return myCurrent == theIt.myCurrent;
}
//-------------------------------------------------------
protected:
void Init (const NCollection_BaseList& theList,
NCollection_ListNode * const thePrev)
{
myCurrent = thePrev ? thePrev -> Next() :
(NCollection_ListNode *)theList.PLast();
myPrevious = thePrev;
}
public:
NCollection_ListNode * myCurrent; // Pointer to the current node
NCollection_ListNode * myPrevious;// Pointer to the previous one
friend class NCollection_BaseList;
}; // End of nested class Iterator
public:
// ---------- PUBLIC METHODS ------------
// ******** Extent
// Purpose: Returns the number of nodes in the list
Standard_Integer Extent (void) const
{ return myLength; }
// ******** IsEmpty
// Purpose: Query if the list is empty
Standard_Boolean IsEmpty (void) const
{ return (myFirst == NULL); }
protected:
// --------- PROTECTED METHODS ----------
// ******** Constructor
// Purpose: Initializes an empty list
NCollection_BaseList(void) :
myFirst(NULL),
myLast(NULL),
myLength(0) {}
// ******** PClear
// Purpose: deletes all nodes
Standard_EXPORT void PClear (NCollection_DelListNode fDel,
Handle(NCollection_BaseAllocator)& theAllocator);
// ******** PFirst
// Purpose: Returns pointer to the first node
const NCollection_ListNode* PFirst (void) const
{ return myFirst; }
// ******** PLast
// Purpose: Returns pointer to the last node
const NCollection_ListNode* PLast (void) const
{ return myLast; }
// ******** PAppend
// Purpose: Appends theNode at the end
Standard_EXPORT void PAppend (NCollection_ListNode* theNode);
// ******** PAppend
// Purpose: Appends theNode at the end, returns iterator to the previous
void PAppend (NCollection_ListNode* theNode,
Iterator& theIt)
{
NCollection_ListNode * aPrev = myLast;
PAppend (theNode);
theIt.Init (* this, aPrev);
}
// ******** PAppend
// Purpose: Appends theOther list at the end (clearing it)
Standard_EXPORT void PAppend (NCollection_BaseList& theOther);
// ******** PPrepend
// Purpose: Prepends theNode at the beginning
Standard_EXPORT void PPrepend (NCollection_ListNode* theNode);
// ******** PPrepend
// Purpose: Prepends theOther list at the beginning (clearing it)
Standard_EXPORT void PPrepend (NCollection_BaseList& theOther);
// ******** PRemoveFirst
// Purpose: Removes first node
Standard_EXPORT void PRemoveFirst
(NCollection_DelListNode fDel,
Handle(NCollection_BaseAllocator)& theAllocator);
// ******** PRemove
// Purpose: Removes the node pointed by theIter[ator]
Standard_EXPORT void PRemove
(Iterator& theIter,
NCollection_DelListNode fDel,
Handle(NCollection_BaseAllocator)& theAllocator);
// ******** PInsertBefore
// Purpose: Inserts theNode before one pointed by theIter[ator]
Standard_EXPORT void PInsertBefore (NCollection_ListNode* theNode,
Iterator& theIter);
// ******** PInsertBefore
// Purpose: Inserts theOther list before the node pointed by theIter[ator]
Standard_EXPORT void PInsertBefore (NCollection_BaseList& theOther,
Iterator& theIter);
// ******** PInsertAfter
// Purpose: Inserts theNode after one pointed by theIter[ator]
Standard_EXPORT void PInsertAfter (NCollection_ListNode* theNode,
Iterator& theIter);
// ******** PInsertAfter
// Purpose: Inserts theOther list after the node pointed by theIter[ator]
Standard_EXPORT void PInsertAfter (NCollection_BaseList& theOther,
Iterator& theIter);
// ******** PReverse
// Purpose: Reverse the list
Standard_EXPORT void PReverse ();
protected:
// ------------ PRIVATE FIELDS ------------
NCollection_ListNode * myFirst; // Pointer to the head
NCollection_ListNode * myLast; // Pointer to the tail
Standard_Integer myLength; // Actual length
// ------------ FRIEND CLASSES ------------
friend class Iterator;
};
#endif

View File

@@ -0,0 +1,174 @@
// File: NCollection_BaseMap.hxx
// Created: Thu Apr 18 15:02:53 2002
// Author: Alexander KARTOMIN (akm)
// <akm@matrox.nnov.matra-dtv.fr>
// Purpose: Implementation of the BaseMap class
#include <NCollection_BaseMap.hxx>
#include <TCollection.hxx>
//=======================================================================
//function : BeginResize
//purpose :
//=======================================================================
Standard_Boolean NCollection_BaseMap::BeginResize
(const Standard_Integer NbBuckets,
Standard_Integer& N,
NCollection_ListNode**& data1,
NCollection_ListNode**& data2,
Handle(NCollection_BaseAllocator)& theAllocator) const
{
if (mySaturated) return Standard_False;
N = NextPrimeForMap(NbBuckets);
if (N <= myNbBuckets) {
if (!myData1)
N = myNbBuckets;
else
return Standard_False;
}
data1 = (NCollection_ListNode **)
theAllocator->Allocate((N+1)*sizeof(NCollection_ListNode *));
memset(data1, 0, (N+1)*sizeof(NCollection_ListNode *));
if (isDouble)
{
data2 = (NCollection_ListNode **)
theAllocator->Allocate((N+1)*sizeof(NCollection_ListNode *));
memset(data2, 0, (N+1)*sizeof(NCollection_ListNode *));
}
else
data2 = NULL;
return Standard_True;
}
//=======================================================================
//function : EndResize
//purpose :
//=======================================================================
void NCollection_BaseMap::EndResize
(const Standard_Integer NbBuckets,
const Standard_Integer N,
NCollection_ListNode** data1,
NCollection_ListNode** data2,
Handle(NCollection_BaseAllocator)& theAllocator)
{
if (myData1)
theAllocator->Free(myData1);
if (myData2)
theAllocator->Free(myData2);
myNbBuckets = N;
mySaturated = (myNbBuckets <= NbBuckets);
myData1 = data1;
myData2 = data2;
}
//=======================================================================
//function : Destroy
//purpose :
//=======================================================================
void NCollection_BaseMap::Destroy
(NCollection_DelMapNode fDel,
Handle(NCollection_BaseAllocator)& theAllocator,
const Standard_Boolean doReleaseMemory)
{
if (!IsEmpty())
{
Standard_Integer i;
NCollection_ListNode** data = (NCollection_ListNode**) myData1;
NCollection_ListNode *p,*q;
for (i = 0; i <= NbBuckets(); i++)
{
if (data[i])
{
p = data[i];
while (p)
{
q = (NCollection_ListNode*)p->Next();
fDel (p, theAllocator);
p = q;
}
data[i] = NULL;
}
}
}
mySize = 0;
if (doReleaseMemory)
{
mySaturated = Standard_False;
if (myData1)
theAllocator->Free(myData1);
if (isDouble && myData2)
theAllocator->Free(myData2);
myData1 = myData2 = NULL;
}
}
//=======================================================================
//function : Statistics
//purpose :
//=======================================================================
void NCollection_BaseMap::Statistics(Standard_OStream& S) const
{
S <<"\nMap Statistics\n---------------\n\n";
S <<"This Map has "<<myNbBuckets<<" Buckets and "<<mySize<<" Keys\n\n";
if (mySaturated) S<<"The maximum number of Buckets is reached\n";
if (mySize == 0) return;
// compute statistics on 1
Standard_Integer * sizes = new Standard_Integer [mySize+1];
Standard_Integer i,l,nb;
NCollection_ListNode* p;
NCollection_ListNode** data;
S << "\nStatistics for the first Key\n";
for (i = 0; i <= mySize; i++) sizes[i] = 0;
data = (NCollection_ListNode **) myData1;
nb = 0;
for (i = 0; i <= myNbBuckets; i++)
{
l = 0;
p = data[i];
if (p) nb++;
while (p)
{
l++;
p = p->Next();
}
sizes[l]++;
}
// display results
l = 0;
for (i = 0; i<= mySize; i++)
{
if (sizes[i] > 0)
{
l += sizes[i] * i;
S << setw(5) << sizes[i] <<" buckets of size "<<i<<"\n";
}
}
Standard_Real mean = ((Standard_Real) l) / ((Standard_Real) nb);
S<<"\n\nMean of length : "<<mean<<"\n";
delete [] sizes;
}
//=======================================================================
//function : NextPrimeForMap
//purpose :
//=======================================================================
Standard_Integer NCollection_BaseMap::NextPrimeForMap
(const Standard_Integer N) const
{
return TCollection::NextPrimeForMap ( N );
}

View File

@@ -0,0 +1,209 @@
// File: NCollection_BaseMap.hxx
// Created: Thu Apr 18 15:02:53 2002
// Author: Alexander KARTOMIN (akm)
// <akm@matrox.nnov.matra-dtv.fr>
#ifndef NCollection_BaseMap_HeaderFile
#define NCollection_BaseMap_HeaderFile
#include <Standard_Boolean.hxx>
#include <Standard_Integer.hxx>
#include <Standard_OStream.hxx>
#include <Standard.hxx>
#include <Standard_Macro.hxx>
#include <NCollection_BaseAllocator.hxx>
#include <NCollection_ListNode.hxx>
//#ifdef WNT
//// Disable the warning "operator new unmatched by delete"
//#pragma warning (disable:4291)
//#endif
typedef void (* NCollection_DelMapNode)
(NCollection_ListNode*, Handle(NCollection_BaseAllocator)& theAl);
/**
* Purpose: This is a base class for all Maps:
* Map
* DataMap
* DoubleMap
* IndexedMap
* IndexedDataMap
* Provides utilitites for managing the buckets.
*/
class NCollection_BaseMap
{
public:
// **************************************** Class Iterator ****************
class Iterator
{
protected:
//! Empty constructor
Iterator (void) :
myNbBuckets (0),
myBuckets (NULL),
myBucket (0),
myNode (NULL) {}
//! Constructor
Iterator (const NCollection_BaseMap& theMap) :
myNbBuckets (theMap.myNbBuckets),
myBuckets (theMap.myData1),
myBucket (-1),
myNode (NULL)
{
if (!myBuckets)
myNbBuckets = -1;
else
do {
myBucket++;
if (myBucket > myNbBuckets)
return;
myNode = myBuckets[myBucket];
} while (!myNode);
}
public:
//! Initialize
void Initialize (const NCollection_BaseMap& theMap)
{
myNbBuckets = theMap.myNbBuckets;
myBuckets = theMap.myData1;
myBucket = -1;
myNode = NULL;
if (!myBuckets)
myNbBuckets = -1;
PNext();
}
//! Reset
void Reset (void)
{
myBucket = -1;
myNode = NULL;
PNext();
}
protected:
//! PMore
Standard_Boolean PMore (void) const
{ return (myNode != NULL); }
//! PNext
void PNext (void)
{
if (!myBuckets)
return;
if (myNode)
{
myNode = myNode->Next();
if (myNode)
return;
}
while (!myNode)
{
myBucket++;
if (myBucket > myNbBuckets)
return;
myNode = myBuckets[myBucket];
}
}
protected:
// ---------- PRIVATE FIELDS ------------
Standard_Integer myNbBuckets; //!< Total buckets in the map
NCollection_ListNode **myBuckets; //!< Location in memory
Standard_Integer myBucket; //!< Current bucket
NCollection_ListNode * myNode; //!< Current node
};
public:
// ---------- PUBLIC METHODS ------------
//! NbBuckets
Standard_Integer NbBuckets() const
{ return myNbBuckets; }
//! Extent
Standard_Integer Extent() const
{ return mySize; }
//! IsEmpty
Standard_Boolean IsEmpty() const
{ return mySize == 0; }
//! Statistics
Standard_EXPORT void Statistics(Standard_OStream& S) const;
protected:
// -------- PROTECTED METHODS -----------
//! Constructor
NCollection_BaseMap (const Standard_Integer NbBuckets,
const Standard_Boolean single) :
myData1(NULL),
myData2(NULL),
isDouble(!single),
mySaturated(Standard_False),
myNbBuckets(NbBuckets),
mySize(0) {}
//! BeginResize
Standard_EXPORT Standard_Boolean BeginResize
(const Standard_Integer NbBuckets,
Standard_Integer& NewBuckets,
NCollection_ListNode**& data1,
NCollection_ListNode**& data2,
Handle(NCollection_BaseAllocator)& theAllocator) const;
//! EndResize
Standard_EXPORT void EndResize
(const Standard_Integer NbBuckets,
const Standard_Integer NewBuckets,
NCollection_ListNode** data1,
NCollection_ListNode** data2,
Handle(NCollection_BaseAllocator)& theAllocator);
//! Resizable
Standard_Boolean Resizable() const
{ return IsEmpty() || (!mySaturated && (mySize > myNbBuckets)); }
//! Increment
void Increment()
{ mySize++; }
//! Decrement
void Decrement()
{ mySize--; }
//! Destroy
Standard_EXPORT void Destroy(NCollection_DelMapNode fDel,
Handle(NCollection_BaseAllocator)& theAllocator,
const Standard_Boolean doReleaseMemory
= Standard_True);
//! NextPrimeForMap
Standard_EXPORT Standard_Integer NextPrimeForMap
(const Standard_Integer N) const;
protected:
// --------- PROTECTED FIELDS -----------
NCollection_ListNode ** myData1;
NCollection_ListNode ** myData2;
private:
// ---------- PRIVATE FIELDS ------------
Standard_Boolean isDouble;
Standard_Boolean mySaturated;
Standard_Integer myNbBuckets;
Standard_Integer mySize;
// ---------- FRIEND CLASSES ------------
friend class Iterator;
};
#endif

View File

@@ -0,0 +1,445 @@
// File: NCollection_BaseSequence.cxx
// Created: 29.03.02 10:01:05
// Author: Alexander GRIGORIEV
// Copyright: Open Cascade 2002
// Purpose: Implementation of the BaseSequence class
#include <NCollection_BaseSequence.hxx>
#include <Standard_NoSuchObject.hxx>
#include <Standard_OutOfRange.hxx>
#include <Standard_DomainError.hxx>
//=======================================================================
//function : ClearSeq
//purpose : removes all items from the current sequence
//=======================================================================
void NCollection_BaseSequence::ClearSeq
(NCollection_DelSeqNode fDel, Handle(NCollection_BaseAllocator)& theAl)
{
const NCollection_SeqNode * p = myFirstItem;
NCollection_SeqNode * q;
while (p) {
q = (NCollection_SeqNode *) p;
p = p->Next();
fDel (q, theAl);
}
Nullify();
}
//=======================================================================
//function : PAppend
//purpose : append an item to sequence
//=======================================================================
void NCollection_BaseSequence::PAppend (NCollection_SeqNode * theItem)
{
if (mySize == 0) {
myFirstItem = myLastItem = myCurrentItem = theItem;
myCurrentIndex = mySize = 1;
} else {
((NCollection_SeqNode *) myLastItem)->SetNext(theItem);
theItem->SetPrevious(myLastItem);
theItem->SetNext(NULL);
myLastItem = theItem;
++ mySize;
}
}
//=======================================================================
//function : PAppend
//purpose : push a sequence at the end of the sequence
//=======================================================================
void NCollection_BaseSequence::PAppend(NCollection_BaseSequence& Other)
{
if (mySize == 0) {
mySize = Other.mySize;
myFirstItem = Other.myFirstItem;
myLastItem = Other.myLastItem;
myCurrentItem = myFirstItem;
myCurrentIndex = 1;
} else {
mySize += Other.mySize;
((NCollection_SeqNode *) myLastItem)->SetNext(Other.myFirstItem);
if (Other.myFirstItem) {
((NCollection_SeqNode *) Other.myFirstItem)->SetPrevious(myLastItem);
myLastItem = Other.myLastItem;
}
}
Other.Nullify();
}
//=======================================================================
//function : PPrepend
//purpose : prepend an item to sequence
//=======================================================================
void NCollection_BaseSequence::PPrepend (NCollection_SeqNode * theItem)
{
if (mySize == 0) {
myFirstItem = myLastItem = myCurrentItem = theItem;
myCurrentIndex = mySize = 1;
} else {
((NCollection_SeqNode *) myFirstItem)->SetPrevious (theItem);
((NCollection_SeqNode *) theItem)->SetNext (myFirstItem);
theItem->SetPrevious(NULL);
theItem->SetNext(myFirstItem);
myFirstItem = theItem;
++ mySize;
++ myCurrentIndex;
}
}
//=======================================================================
//function : PPrepend
//purpose : push a sequence in the beginning of the sequence
//=======================================================================
void NCollection_BaseSequence::PPrepend (NCollection_BaseSequence& Other)
{
if (mySize == 0) {
mySize = Other.mySize;
myFirstItem = Other.myFirstItem;
myLastItem = Other.myLastItem;
myCurrentIndex = 1;
myCurrentItem = myFirstItem;
} else {
mySize += Other.mySize;
if (Other.myLastItem)
((NCollection_SeqNode *) Other.myLastItem)->SetNext (myFirstItem);
((NCollection_SeqNode *) myFirstItem)->SetPrevious(Other.myLastItem);
myFirstItem = Other.myFirstItem;
myCurrentIndex += Other.mySize;
}
Other.Nullify();
}
//=======================================================================
//function : PReverse
//purpose : reverse the order of a given sequence
//=======================================================================
void NCollection_BaseSequence::PReverse()
{
const NCollection_SeqNode * p = myFirstItem;
const NCollection_SeqNode * tmp;
while (p) {
tmp = p->Next();
((NCollection_SeqNode *) p)->SetNext (p->Previous());
((NCollection_SeqNode *) p)->SetPrevious (tmp);
p = tmp;
}
tmp = myFirstItem;
myFirstItem = myLastItem;
myLastItem = tmp;
if (mySize != 0) myCurrentIndex = mySize + 1 - myCurrentIndex;
}
//=======================================================================
//function : PInsertAfter
//purpose :
//=======================================================================
void NCollection_BaseSequence::PInsertAfter
(NCollection_BaseSequence::Iterator& thePosition,
NCollection_SeqNode * theItem)
{
NCollection_SeqNode * aPos = thePosition.myCurrent;
if (aPos == NULL)
PPrepend (theItem);
else {
theItem->SetNext (aPos->Next());
theItem->SetPrevious (aPos);
if (aPos->Next() == NULL) myLastItem = theItem;
else ((NCollection_SeqNode *) aPos->Next())->SetPrevious(theItem);
aPos->SetNext(theItem);
++ mySize;
myCurrentItem = myFirstItem;
myCurrentIndex = 1;
}
}
//=======================================================================
//function : PInsertAfter
//purpose :
//=======================================================================
void NCollection_BaseSequence::PInsertAfter(const Standard_Integer theIndex,
NCollection_SeqNode * theItem)
{
if (theIndex == 0)
PPrepend (theItem);
else {
const NCollection_SeqNode * p = Find (theIndex);
theItem->SetNext(p->Next());
theItem->SetPrevious(p);
if (theIndex == mySize) myLastItem = theItem;
else ((NCollection_SeqNode *) p->Next())->SetPrevious(theItem);
((NCollection_SeqNode *) p)->SetNext(theItem);
++ mySize;
if (theIndex < myCurrentIndex)
++ myCurrentIndex;
}
}
//=======================================================================
//function : PInsertAfter
//purpose : insert a sequence after a given index in the sequence
//=======================================================================
void NCollection_BaseSequence::PInsertAfter (const Standard_Integer theIndex,
NCollection_BaseSequence& Other)
{
if (theIndex < 0 || theIndex > mySize)
Standard_OutOfRange::Raise();
if (Other.mySize != 0)
if (theIndex == 0)
PPrepend (Other);
else {
const NCollection_SeqNode * p = Find (theIndex);
((NCollection_SeqNode *) Other.myFirstItem)->SetPrevious (p);
((NCollection_SeqNode *) Other.myLastItem)->SetNext (p->Next());
if (theIndex == mySize)
myLastItem = Other.myLastItem;
else
((NCollection_SeqNode *) p->Next())->SetPrevious (Other.myLastItem);
((NCollection_SeqNode *) p)->SetNext (Other.myFirstItem);
mySize += Other.mySize;
if (theIndex < myCurrentIndex)
myCurrentIndex += Other.mySize;
Other.Nullify();
}
}
//=======================================================================
//function : PExchange
//purpose : exchange two elements in the sequence
//=======================================================================
void NCollection_BaseSequence::PExchange (const Standard_Integer I,
const Standard_Integer J)
{
Standard_OutOfRange_Raise_if (I <= 0 || J <= 0 || I > mySize || J > mySize,
"" );
// Assume I < J
if (J < I)
PExchange(J,I);
else if (I < J) {
const NCollection_SeqNode * pi = Find(I);
const NCollection_SeqNode * pj = Find(J);
// update the node before I
if (pi->Previous())
((NCollection_SeqNode *) pi->Previous())->SetNext (pj);
else
myFirstItem = pj;
// update the node after J
if (pj->Next())
((NCollection_SeqNode *) pj->Next())->SetPrevious(pi);
else
myLastItem = pi;
if (pi->Next() == pj) { // I and J are consecutives, update them
((NCollection_SeqNode *) pj)->SetPrevious (pi->Previous());
((NCollection_SeqNode *) pi)->SetPrevious (pj);
((NCollection_SeqNode *) pi)->SetNext (pj->Next());
((NCollection_SeqNode *) pj)->SetNext (pi);
}
else { // I and J are not consecutive
// update the node after I
((NCollection_SeqNode *) pi->Next())->SetPrevious (pj);
// update the node before J
((NCollection_SeqNode *) pj->Previous())->SetNext (pi);
// update nodes I and J
const NCollection_SeqNode* tmp = pi->Next();
((NCollection_SeqNode *) pi)->SetNext (pj->Next());
((NCollection_SeqNode *) pj)->SetNext (tmp);
tmp = pi->Previous();
((NCollection_SeqNode *) pi)->SetPrevious (pj->Previous());
((NCollection_SeqNode *) pj)->SetPrevious (tmp);
}
if (myCurrentIndex == I) myCurrentItem = pj;
else if (myCurrentIndex == J) myCurrentItem = pi;
}
}
//=======================================================================
//function : PSplit
//purpose :
//=======================================================================
void NCollection_BaseSequence::PSplit (const Standard_Integer theIndex,
NCollection_BaseSequence& Sub)
{
Standard_OutOfRange_Raise_if (theIndex <= 0 || theIndex > mySize,"" );
Standard_DomainError_Raise_if (this == &Sub, "No Split on myself!!");
const NCollection_SeqNode * p = Find (theIndex);
Sub.myLastItem = myLastItem;
Sub.mySize = mySize - theIndex + 1;
myLastItem = p->Previous();
if (myLastItem) {
((NCollection_SeqNode *) myLastItem)->SetNext(NULL);
mySize = theIndex - 1;
if (myCurrentIndex >= theIndex) {
myCurrentIndex = 1;
myCurrentItem = myFirstItem;
}
} else {
myFirstItem = myCurrentItem = NULL;
mySize = myCurrentIndex = 0;
}
Sub.myFirstItem = Sub.myCurrentItem = p;
((NCollection_SeqNode *) p)->SetPrevious (NULL);
Sub.myCurrentIndex = 1;
}
//=======================================================================
//function : Remove
//purpose :
//=======================================================================
void NCollection_BaseSequence::RemoveSeq
(NCollection_BaseSequence::Iterator& thePosition,
NCollection_DelSeqNode fDel,
Handle(NCollection_BaseAllocator)& theAl)
{
NCollection_SeqNode * aPos = thePosition.myCurrent;
if (aPos == NULL)
return;
thePosition.myCurrent = (NCollection_SeqNode *) aPos -> Next();
if (aPos->Previous())
((NCollection_SeqNode *) aPos->Previous())->SetNext (aPos->Next());
else
myFirstItem = aPos->Next();
if (aPos->Next())
((NCollection_SeqNode *) aPos->Next())->SetPrevious (aPos->Previous());
else
myLastItem = aPos->Previous();
-- mySize;
myCurrentItem = myLastItem;
myCurrentIndex = mySize;
fDel (aPos, theAl);
}
//=======================================================================
//function : Remove
//purpose :
//=======================================================================
void NCollection_BaseSequence::RemoveSeq
(const Standard_Integer theIndex,
NCollection_DelSeqNode fDel,
Handle(NCollection_BaseAllocator)& theAl)
{
Standard_OutOfRange_Raise_if (theIndex <= 0 || theIndex > mySize, "");
const NCollection_SeqNode * p = Find (theIndex);
if (p->Previous())
((NCollection_SeqNode *) p->Previous())->SetNext (p->Next());
else
myFirstItem = p->Next();
if (p->Next())
((NCollection_SeqNode *) p->Next())->SetPrevious (p->Previous());
else
myLastItem = p->Previous();
-- mySize;
if (myCurrentIndex > theIndex) -- myCurrentIndex;
else if (myCurrentIndex == theIndex) {
if (p->Next())
myCurrentItem = p->Next();
else {
myCurrentItem = myLastItem;
myCurrentIndex = mySize;
}
}
fDel ((NCollection_SeqNode *) p, theAl);
}
//=======================================================================
//function : Remove
//purpose : remove a set of items
//=======================================================================
void NCollection_BaseSequence::RemoveSeq
(const Standard_Integer From,
const Standard_Integer To,
NCollection_DelSeqNode fDel,
Handle(NCollection_BaseAllocator)& theAl)
{
Standard_OutOfRange_Raise_if (From <= 0 || To > mySize || From > To, "");
const NCollection_SeqNode * pfrom = Find(From);
const NCollection_SeqNode * pto = Find(To);
if (pfrom->Previous())
((NCollection_SeqNode *) pfrom->Previous())->SetNext (pto->Next());
else
myFirstItem = pto->Next();
if (pto->Next())
((NCollection_SeqNode *) pto->Next())->SetPrevious (pfrom->Previous());
else
myLastItem = pfrom->Previous();
mySize -= To - From + 1;
if (myCurrentIndex > To)
myCurrentIndex -= To - From + 1;
else if (myCurrentIndex >= From) {
if (pto->Next()) {
myCurrentItem = pto->Next();
myCurrentIndex = From; // AGV fix 24.05.01
} else {
myCurrentItem = myLastItem;
myCurrentIndex = mySize;
}
}
for (Standard_Integer i = From; i <= To; i++) {
NCollection_SeqNode * tmp = (NCollection_SeqNode *)pfrom;
pfrom = pfrom->Next();
fDel (tmp, theAl);
}
}
//=======================================================================
//function : Find
//purpose :
//=======================================================================
const NCollection_SeqNode * NCollection_BaseSequence::Find
(const Standard_Integer theIndex) const
{
Standard_Integer i;
const NCollection_SeqNode * p;
if (theIndex <= myCurrentIndex) {
if (theIndex < myCurrentIndex / 2) {
p = myFirstItem;
for (i = 1; i < theIndex; i++) p = p->Next();
} else {
p = myCurrentItem;
for (i = myCurrentIndex; i > theIndex; i--) p = p->Previous();
}
} else {
if (theIndex < (myCurrentIndex + mySize) / 2) {
p = myCurrentItem;
for (i = myCurrentIndex; i < theIndex; i++) p = p->Next();
} else {
p = myLastItem;
for (i = mySize; i > theIndex; i--) p = p->Previous();
}
}
return p;
}

View File

@@ -0,0 +1,150 @@
// File: NCollection_BaseSequence.hxx
// Created: Wed Apr 10 12:19:14 2002
// Author: Alexander KARTOMIN (akm)
// <a-kartomin@opencascade.com>
#ifndef NCollection_BaseSequence_HeaderFile
#define NCollection_BaseSequence_HeaderFile
#include <Standard.hxx>
#include <NCollection_BaseAllocator.hxx>
// **************************************** Class SeqNode ********************
class NCollection_SeqNode
{
public:
// Methods PUBLIC
//
NCollection_SeqNode (void)
: myNext (NULL), myPrevious (NULL) {}
const NCollection_SeqNode * Next () const { return myNext; }
const NCollection_SeqNode * Previous () const { return myPrevious; }
void SetNext (const NCollection_SeqNode * theNext)
{ myNext = theNext; }
void SetPrevious (const NCollection_SeqNode * thePrev)
{ myPrevious = thePrev; }
//~NCollection_SeqNode() {
// if (myNext) myNext -> myPrevious = myPrevious;
// if (myPrevious) myPrevious -> myNext = myNext;
//}
private:
// Fields PRIVATE
//
const NCollection_SeqNode * myNext;
const NCollection_SeqNode * myPrevious;
};
typedef void (* NCollection_DelSeqNode)
(NCollection_SeqNode*, Handle(NCollection_BaseAllocator)& theAl);
/**
* Purpose: This is a base class for the Sequence. It deals with
* an indexed bidirectional list of NCollection_SeqNode's.
*/
class NCollection_BaseSequence
{
public:
class Iterator
{
public:
//! Empty constructor
Iterator (void) : myCurrent (NULL) {}
//! Constructor with initialisation
Iterator (const NCollection_BaseSequence& theSeq,
const Standard_Boolean isStart)
: myCurrent(isStart ? (NCollection_SeqNode *)theSeq.myFirstItem
: (NCollection_SeqNode *)theSeq.myLastItem) {}
//! Initialisation
void Init (const NCollection_BaseSequence& theSeq,
const Standard_Boolean isStart
= Standard_True)
{ myCurrent = isStart ? (NCollection_SeqNode *)theSeq.myFirstItem
: (NCollection_SeqNode *)theSeq.myLastItem; }
//! Assignment
Iterator& operator = (const Iterator& theOther)
{ myCurrent = theOther.myCurrent; return *this; }
//! Previous
void Previous ()
{ if (myCurrent)
myCurrent = (NCollection_SeqNode *)myCurrent -> Previous(); }
protected:
NCollection_SeqNode * myCurrent; //!< Pointer to the current node
friend class NCollection_BaseSequence;
};
public:
// Methods PUBLIC
//
Standard_Boolean IsEmpty () const {return (mySize == 0);}
Standard_Integer Length () const {return mySize;}
protected:
// Methods PROTECTED
//
inline NCollection_BaseSequence ();
Standard_EXPORT void ClearSeq (NCollection_DelSeqNode fDel,
Handle(NCollection_BaseAllocator)& theAl);
Standard_EXPORT void PAppend (NCollection_SeqNode *);
Standard_EXPORT void PAppend (NCollection_BaseSequence& S);
Standard_EXPORT void PPrepend (NCollection_SeqNode *);
Standard_EXPORT void PPrepend (NCollection_BaseSequence& S);
Standard_EXPORT void PInsertAfter(Iterator& thePosition,
NCollection_SeqNode *);
Standard_EXPORT void PInsertAfter(const Standard_Integer Index,
NCollection_SeqNode *);
Standard_EXPORT void PInsertAfter(const Standard_Integer Index,
NCollection_BaseSequence& S);
Standard_EXPORT void PSplit (const Standard_Integer Index,
NCollection_BaseSequence& Sub);
Standard_EXPORT void RemoveSeq (Iterator& thePosition,
NCollection_DelSeqNode fDel,
Handle(NCollection_BaseAllocator)& theAl);
Standard_EXPORT void RemoveSeq (const Standard_Integer Index,
NCollection_DelSeqNode fDel,
Handle(NCollection_BaseAllocator)& theAl);
Standard_EXPORT void RemoveSeq (const Standard_Integer From,
const Standard_Integer To,
NCollection_DelSeqNode fDel,
Handle(NCollection_BaseAllocator)& theAl);
Standard_EXPORT void PReverse ();
Standard_EXPORT void PExchange (const Standard_Integer I,
const Standard_Integer J) ;
Standard_EXPORT const NCollection_SeqNode *
Find (const Standard_Integer) const;
protected:
// Fields PROTECTED
//
const NCollection_SeqNode * myFirstItem;
const NCollection_SeqNode * myLastItem;
const NCollection_SeqNode * myCurrentItem;
Standard_Integer myCurrentIndex;
Standard_Integer mySize;
private:
// Methods PRIVATE
//
Standard_EXPORT NCollection_BaseSequence
(const NCollection_BaseSequence& Other);
inline void Nullify ();
friend class Iterator;
};
inline NCollection_BaseSequence::NCollection_BaseSequence ()
: myFirstItem (NULL),
myLastItem (NULL),
myCurrentItem (NULL),
myCurrentIndex (0),
mySize (0) {}
inline void NCollection_BaseSequence::Nullify ()
{
myFirstItem = myLastItem = myCurrentItem = NULL;
myCurrentIndex = mySize = 0;
}
#endif

View File

@@ -0,0 +1,200 @@
// File: NCollection_BaseVector.cxx
// Created: 24.04.02 10:07:15
// Author: Alexander GRIGORIEV
// Copyright: Open Cascade 2002
#include <NCollection_BaseVector.hxx>
#include <Standard_RangeError.hxx>
#ifdef DEB
#include <Standard_OutOfRange.hxx>
#endif
#include <stdlib.h>
//=======================================================================
//function : GetIndexV
//purpose :
//=======================================================================
Standard_Integer NCollection_BaseVector::MemBlock::GetIndexV
(void * theItem, const size_t theItemSize) const
{
const ptrdiff_t anOffset = (char *) theItem - (char *) myData;
const Standard_Integer anIndex = anOffset / theItemSize;
#ifdef DEB
if (anOffset < 0 || anOffset != Standard_Integer (anIndex * theItemSize)
|| anIndex > Standard_Integer (myLength))
Standard_OutOfRange::Raise ("NCollection_BaseVector: "
"Wrong object passed to GetIndex");
#endif
return anIndex + myFirstInd;
}
//=======================================================================
//function : ~NCollection_BaseVector
//purpose : Destructor
//=======================================================================
NCollection_BaseVector::~NCollection_BaseVector()
{
for (Standard_Integer i = 0; i < myCapacity; i++)
myData[i].Reinit (0, 0);
myDataFree (* this, myData);
}
//=======================================================================
//function : Clear
//purpose :
//=======================================================================
void NCollection_BaseVector::Clear()
{
for (Standard_Integer i = 0; i < myCapacity; i++)
myData[i].Reinit (0, 0);
myLength = 0;
myNBlocks = 0;
}
//=======================================================================
//function : NCollection_BaseVector::Iterator::CopyV
//purpose : Copy from another iterator
//=======================================================================
void NCollection_BaseVector::Iterator::CopyV
(const NCollection_BaseVector::Iterator& theOth)
{
myVector = theOth.myVector;
myICurBlock = theOth.myICurBlock;
myIEndBlock = theOth.myIEndBlock;
myCurIndex = theOth.myCurIndex;
myEndIndex = theOth.myEndIndex;
}
//=======================================================================
//function : InitV
//purpose : Initialisation of iterator by a vector
//=======================================================================
void NCollection_BaseVector::Iterator::InitV
(const NCollection_BaseVector& theVector)
{
myVector = &theVector;
myICurBlock = 0;
myCurIndex = 0;
if (theVector.myNBlocks == 0) {
myIEndBlock = 0;
myEndIndex = 0;
} else {
myIEndBlock = theVector.myNBlocks - 1;
myEndIndex = theVector.myData[myIEndBlock].Length();
}
}
//=======================================================================
//function : operator =
//purpose : assignment
//=======================================================================
NCollection_BaseVector& NCollection_BaseVector::operator =
(const NCollection_BaseVector& theOther)
{
// if (this != &theOther) {
myIncrement = theOther.myIncrement;
myLength = theOther.Length();
myNBlocks = (myLength == 0) ? 0 : (1 + (myLength - 1)/myIncrement);
for (Standard_Integer i = 0; i < myCapacity; i++)
myData[i].Reinit (0, 0);
myDataFree (* this, myData);
myCapacity = myIncrement + myLength / myIncrement;
myData = myDataInit (* this, myCapacity, NULL, 0);
// }
return * this;
}
//=======================================================================
//function : ExpandV
//purpose : returns the pointer where the new data item is supposed to be put
//=======================================================================
void * NCollection_BaseVector::ExpandV (const Standard_Integer theIndex)
{
const Standard_Integer aNewLength = theIndex + 1;
if (myNBlocks) {
// Take the last array in the vector of arrays
MemBlock& aLastBlock = myData [myNBlocks - 1];
Standard_RangeError_Raise_if (theIndex < aLastBlock.FirstIndex(),
"NColelction_BaseVector::ExpandV");
const unsigned int anIndLastBlock = theIndex - aLastBlock.FirstIndex();
// Is there still room for 1 item in the last array?
if (anIndLastBlock < aLastBlock.Size()) {
myLength = aNewLength;
aLastBlock.SetLength (anIndLastBlock + 1);
return aLastBlock.Find (anIndLastBlock, myItemSize);
}
myLength = aLastBlock.FirstIndex() + aLastBlock.Size();
}
// There is no room in the last array or the whole vector
// is not yet initialised. Initialise a new array, but before that
// check whether it is available within myCapacity
const Standard_Integer nNewBlock =
myNBlocks + 1 + (theIndex - myLength) / myIncrement;
if (myCapacity < nNewBlock) {
// Reallocate the array myData
do myCapacity += myIncrement; while (myCapacity <= nNewBlock);
MemBlock * aNewData = myDataInit (* this, myCapacity, myData, myNBlocks);
myDataFree (* this, myData);
myData = aNewData;
}
if (myNBlocks > 0) {
// Change length of old last block to myIncrement
MemBlock * aLastBlock = (MemBlock *) &myData[myNBlocks-1];
aLastBlock -> SetLength (myIncrement);
}
// Initialise new blocks
MemBlock * aNewBlock = (MemBlock *) &myData[myNBlocks++];
aNewBlock -> Reinit (myLength, myIncrement);
while (myNBlocks < nNewBlock) {
aNewBlock -> SetLength (myIncrement);
myLength += myIncrement;
aNewBlock = (MemBlock *) &myData[myNBlocks++];
aNewBlock -> Reinit (myLength, myIncrement);
}
aNewBlock -> SetLength (aNewLength - myLength);
myLength = aNewLength;
return aNewBlock -> Find (theIndex - aNewBlock -> FirstIndex(), myItemSize);
}
//=======================================================================
//function : Find
//purpose : locate the memory holding the desired value
//remark : This is only useful when the blocks can have holes (i.e., deletion
// is enabled at any location)
// : Currently this method is replaced by a direct one (inline)
//=======================================================================
#ifdef THIS_IS_NOW_DISABLED
void * NCollection_BaseVector::Find (const Standard_Integer theIndex) const
{
#ifdef DEB
if (theIndex < 0 || theIndex >= myLength) Standard_OutOfRange::Raise (NULL);
#endif
// Binary search for the last memory block whose 'FirstIndex'
// is not greater than 'theIndex'
const MemBlock * ptrArrays = myData;
Standard_Integer aLow = 0;
Standard_Integer anUp = myNBlocks-1;
if (theIndex >= ptrArrays[anUp].FirstIndex()) aLow = anUp;
else while (1) {
Standard_Integer aMid = (aLow + anUp)/2;
if (aMid == aLow) break;
if (ptrArrays[aMid].FirstIndex() > theIndex)
anUp = aMid;
else
aLow = aMid;
}
// Find the item at the proper offset in the found MemBlock-type block
const Standard_Integer anOffset = theIndex - ptrArrays[aLow].FirstIndex();
return ptrArrays[aLow].Find (anOffset, myItemSize);
}
#endif

View File

@@ -0,0 +1,179 @@
// File: NCollection_BaseVector.hxx
// Created: 24.04.02 09:41:39
// Author: Alexander GRIGORIEV
// Copyright: Open Cascade 2002
#ifndef NCollection_BaseVector_HeaderFile
#define NCollection_BaseVector_HeaderFile
#include <Standard_TypeDef.hxx>
#include <stddef.h>
#if !defined No_Exception && !defined No_Standard_OutOfRange
#include <Standard_OutOfRange.hxx>
#endif
#ifdef WNT
#pragma warning(push, 1)
#pragma warning(disable:4355)
#endif
/**
* Class NCollection_BaseVector - base for generic vector
*/
class NCollection_BaseVector
{
public:
// ------------ Class MemBlock ------------
class MemBlock {
protected:
MemBlock ()
: myFirstInd(0), myLength(0), mySize(0), myData(0L) {}
MemBlock (const Standard_Integer theFirstInd,
const Standard_Integer theLength)
: myFirstInd(theFirstInd), myLength(0), mySize(theLength), myData(0L) {}
virtual ~MemBlock () {}
virtual void Reinit (const Standard_Integer,
const size_t) {}
Standard_Integer FirstIndex () const { return myFirstInd; }
size_t Size () const { return mySize; }
public:
void SetLength (const size_t theLen)
{ myLength = theLen; }
size_t Length () const { return myLength; }
void * Find (const Standard_Integer theInd,
const size_t theSize) const
{ return ((char *) myData)+theInd*theSize;}
Standard_EXPORT Standard_Integer
GetIndexV (void * theItem, const size_t theSz) const;
protected:
Standard_Integer myFirstInd;
size_t myLength;
size_t mySize;
void * myData;
friend class NCollection_BaseVector;
};
class Iterator {
protected:
Iterator () :
myICurBlock (0), myIEndBlock (0), myCurIndex (0), myEndIndex (0) {}
Iterator (const NCollection_BaseVector& theVector) { InitV (theVector); }
Iterator (const Iterator& theVector) { CopyV (theVector); }
Standard_EXPORT void InitV (const NCollection_BaseVector& theVector);
Standard_EXPORT void CopyV (const Iterator&);
Standard_Boolean MoreV () const
{ return (myICurBlock < myIEndBlock || myCurIndex < myEndIndex); }
void NextV ()
{ if (++myCurIndex >= myVector -> myData[myICurBlock].Length() &&
myICurBlock < myIEndBlock)
{ ++myICurBlock; myCurIndex = 0; } }
const MemBlock * CurBlockV () const
{ return &myVector -> myData[myICurBlock]; }
const NCollection_BaseVector * myVector; // the Master vector
size_t myICurBlock; // # of the current block
size_t myIEndBlock;
size_t myCurIndex; // Index in the current block
size_t myEndIndex;
};
protected:
// ------------ Block initializer ---------
typedef MemBlock * (* FuncPtrDataInit) (const NCollection_BaseVector&,
const Standard_Integer aCapacity,
const void * aSource,
const Standard_Integer aSize);
typedef void (* FuncPtrDataFree) (const NCollection_BaseVector&,
MemBlock *);
friend class Iterator;
// ---------- PROTECTED METHODS ----------
//! Empty constructor
NCollection_BaseVector (const size_t theSize,
const Standard_Integer theInc,
FuncPtrDataInit theDataInit,
FuncPtrDataFree theDataFree)
: myItemSize (theSize),
myIncrement (theInc),
myLength (0),
myCapacity (theInc),
myNBlocks (0),
myData (theDataInit (* this, myCapacity, NULL, 0)),
myDataInit (theDataInit),
myDataFree (theDataFree)
{
// myData = (MemBlock *) new char [myCapacity * sizeof(MemBlock)];
// for (Standard_Integer i = 0; i < myCapacity; i++)
// new (&myData[i]) MemBlock;
}
//! Copy constructor
NCollection_BaseVector (const NCollection_BaseVector& theOther,
FuncPtrDataInit theDataInit,
FuncPtrDataFree theDataFree)
: myItemSize (theOther.myItemSize),
myIncrement (theOther.myIncrement),
myLength (theOther.Length()),
myCapacity (theOther.myIncrement+theOther.Length()/theOther.myIncrement),
myNBlocks (1 + (theOther.Length() - 1)/theOther.myIncrement),
myData (theDataInit (* this, myCapacity, NULL, 0)),
myDataInit (theDataInit),
myDataFree (theDataFree) {}
//! Destructor
Standard_EXPORT ~NCollection_BaseVector ();
//! Operator =
Standard_EXPORT NCollection_BaseVector& operator =
(const NCollection_BaseVector&);
//! ExpandV: returns pointer to memory where to put the new item
Standard_EXPORT void * ExpandV (const Standard_Integer theIndex);
//! Find: locate the memory holding the desired value
inline void * Find (const Standard_Integer theIndex) const;
public:
//! Total number of items
Standard_Integer Length () const { return myLength; }
//! Empty the vector of its objects
Standard_EXPORT void Clear ();
protected:
// ---------- PRIVATE FIELDS ----------
size_t myItemSize;
Standard_Integer myIncrement;
Standard_Integer myLength;
Standard_Integer myCapacity;
Standard_Integer myNBlocks;
MemBlock * myData;
FuncPtrDataInit myDataInit;
FuncPtrDataFree myDataFree;
};
//=======================================================================
//function : Find
//purpose : locate the memory holding the desired value
//=======================================================================
inline void * NCollection_BaseVector::Find
(const Standard_Integer theIndex) const
{
#if !defined No_Exception && !defined No_Standard_OutOfRange
if (theIndex < 0 || theIndex >= myLength)
Standard_OutOfRange::Raise ("NCollection_BaseVector::Find");
#endif
const Standard_Integer aBlock = theIndex / myIncrement;
return myData[aBlock].Find (theIndex - aBlock * myIncrement, myItemSize);
}
#ifdef WNT
#pragma warning(pop)
#endif
#endif

View File

@@ -0,0 +1,502 @@
// File: NCollection_CellFilter.hxx
// Created: Sat May 26 06:05:25 2007
// Author: Andrey BETENEV
// Copyright: Open CASCADE SAS 2007
#ifndef NCollection_CellFilter_HeaderFile
#define NCollection_CellFilter_HeaderFile
#include <Standard_Real.hxx>
#include <NCollection_List.hxx>
#include <NCollection_Map.hxx>
#include <NCollection_DataMap.hxx>
#include <NCollection_BaseAllocator.hxx>
// work-around for obsolete SUN WorkShop 5.3 compiler
// which does not recognize typename keyword
#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530) && ! defined(typename)
#define typename
#endif
//! Auxiliary enumeration serving as responce from method Inspect
enum NCollection_CellFilter_Action
{
CellFilter_Keep = 0, //!< Target is needed and should be kept
CellFilter_Purge = 1 //!< Target is not needed and can be removed from the current cell
};
/**
* A data structure for sorting geometric objects (called targets) in
* n-dimensional space into cells, with associated algorithm for fast checking
* of coincidence (overlapping, intersection, etc.) with other objects
* (called here bullets).
*
* Description
*
* The algorithm is based on hash map, thus it has linear time of initialization
* (O(N) where N is number of cells covered by added targets) and constant-time
* search for one bullet (more precisely, O(M) where M is number of cells covered
* by the bullet).
*
* The idea behind the algorithm is to separate each co-ordinate of the space
* into equal-size cells. Note that this works well when cell size is
* approximately equal to the characteristic size of the involved objects
* (targets and bullets; including tolerance eventually used for coincidence
* check).
*
* Usage
*
* The target objects to be searched are added to the tool by methods Add();
* each target is classified as belonging to some cell(s). The data on cells
* (list of targets found in each one) are stored in the hash map with key being
* cumulative index of the cell by all co-ordinates.
* Thus the time needed to find targets in some cell is O(1) * O(number of
* targets in the cell).
*
* As soon as all the targets are added, the algorithm is ready to check for
* coincidence.
* To find the targets coincident with any given bullet, it checks all the
* candidate targets in the cell(s) covered by the bullet object
* (methods Inspect()).
*
* The methods Add() and Inspect() have two flavours each: one accepts
* single point identifying one cell, another accept two points specifying
* the range of cells. It should be noted that normally at least one of these
* methods is called as for range of cells: either due to objects having non-
* zero size, or in order to account for the tolerance when objects are points.
*
* The set of targets can be modified during the process: new targets can be
* added by Add(), existing targets can be removed by Remove().
*
* Implementation
*
* The algorithm is implemented as template class, thus it is capable to
* work with objects of any type. The only argument of the template should be
* the specific class providing all necessary features required by the
* algorithm:
*
* - typedef "Target" defining type of target objects.
* This type must have copy constructor
*
* - typedef "Point" defining type of geometrical points used
*
* - enum Dimension whose value must be dimension of the point
*
* - method Coord() returning value of the i-th coordinate of the point:
*
* static Standard_Real Coord (int i, const Point& thePnt);
*
* Note that index i is from 0 to Dimension-1.
*
* - method IsEqual() used by Remove() to identify objects to be removed:
*
* Standard_Boolean IsEqual (const Target& theT1, const Target& theT2);
*
* - method Inspect() performing necessary actions on the candidate target
* object (usially comparison with the currently checked bullet object):
*
* NCollection_CellFilter_Action Inspect (const Target& theObject);
*
* The returned value can be used to command CellFilter
* to remove the inspected item from the current cell; this allows
* to exclude the items that has been processed and are not needed any
* more in further search (for better performance).
*
* Note that method Inspect() can be const and/or virtual.
*/
template <class Inspector>
class NCollection_CellFilter
{
public:
typedef typename Inspector::Target Target;
typedef typename Inspector::Point Point;
public:
//! Constructor; initialized by cell size.
//!
//! Note: the cell size must be ensured to be greater than
//! maximal co-ordinate of the involved points divided by INT_MAX,
//! in order to avoid integer overflow of cell index.
//!
//! By default cell size is 0, which is invalid; thus if default
//! constructor is used, the tool must be initialized later with
//! appropriate cell size by call to Reset()
NCollection_CellFilter (Standard_Real theCellSize=0,
const Handle(NCollection_IncAllocator)& theAlloc=0)
{
Reset (theCellSize, theAlloc);
}
//! Constructor; initialized by cell sizes along each dimension.
//! Note: the cell size in each dimension must be ensured to be greater than
//! maximal co-ordinate of the involved points by this dimension divided by INT_MAX,
//! in order to avoid integer overflow of cell index.
NCollection_CellFilter (Standard_Real theCellSize[],
const Handle(NCollection_IncAllocator)& theAlloc=0)
{
Reset (theCellSize, theAlloc);
}
//! Clear the data structures, set new cell size and allocator
void Reset (Standard_Real theCellSize,
const Handle(NCollection_IncAllocator)& theAlloc=0)
{
for (int i=0; i < Inspector::Dimension; i++)
myCellSize[i] = theCellSize;
resetAllocator ( theAlloc );
}
//! Clear the data structures and set new cell sizes and allocator
void Reset (Standard_Real theCellSize[],
const Handle(NCollection_IncAllocator)& theAlloc=0)
{
for (int i=0; i < Inspector::Dimension; i++)
myCellSize[i] = theCellSize[i];
resetAllocator ( theAlloc );
}
//! Adds a target object for further search at a point (into only one cell)
void Add (const Target& theTarget, const Point &thePnt)
{
Cell aCell (thePnt, myCellSize);
add (aCell, theTarget);
}
//! Adds a target object for further search in the range of cells
//! defined by two points (the first point must have all co-ordinates equal or
//! less than the same co-ordinate of the second point)
void Add (const Target& theTarget,
const Point &thePntMin, const Point &thePntMax)
{
// get cells range by minimal and maximal co-ordinates
Cell aCellMin (thePntMin, myCellSize);
Cell aCellMax (thePntMax, myCellSize);
Cell aCell = aCellMin;
// add object recursively into all cells in range
iterateAdd (Inspector::Dimension-1, aCell, aCellMin, aCellMax, theTarget);
}
//! Find a target object at a point and remove it from the structures.
//! For usage of this method "operator ==" should be defined for Target.
void Remove (const Target& theTarget, const Point &thePnt)
{
Cell aCell (thePnt, myCellSize);
remove (aCell, theTarget);
}
//! Find a target object in the range of cells defined by two points and
//! remove it from the structures
//! (the first point must have all co-ordinates equal or
//! less than the same co-ordinate of the second point).
//! For usage of this method "operator ==" should be defined for Target.
void Remove (const Target& theTarget,
const Point &thePntMin, const Point &thePntMax)
{
// get cells range by minimal and maximal co-ordinates
Cell aCellMin (thePntMin, myCellSize);
Cell aCellMax (thePntMax, myCellSize);
Cell aCell = aCellMin;
// remove object recursively from all cells in range
iterateRemove (Inspector::Dimension-1, aCell, aCellMin, aCellMax, theTarget);
}
//! Inspect all targets in the cell corresponding to the given point
void Inspect (const Point& thePnt, Inspector &theInspector)
{
Cell aCell (thePnt, myCellSize);
inspect (aCell, theInspector);
}
//! Inspect all targets in the cells range limited by two given points
//! (the first point must have all co-ordinates equal or
//! less than the same co-ordinate of the second point)
void Inspect (const Point& thePntMin, const Point& thePntMax,
Inspector &theInspector)
{
// get cells range by minimal and maximal co-ordinates
Cell aCellMin (thePntMin, myCellSize);
Cell aCellMax (thePntMax, myCellSize);
Cell aCell = aCellMin;
// inspect object recursively into all cells in range
iterateInspect (Inspector::Dimension-1, aCell,
aCellMin, aCellMax, theInspector);
}
#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)
public: // work-around against obsolete SUN WorkShop 5.3 compiler
#else
protected:
#endif
/**
* Auxiliary class for storing points belonging to the cell as the list
*/
struct ListNode {
Target Object;
ListNode *Next;
};
/**
* Auxilary structure representing a cell in the space.
* Cells are stored in the map, each cell contains list of objects
* that belong to that cell.
*/
struct Cell
{
public:
//! Empty constructor -- required only for NCollection_Map,
//! therefore does not initialize index (avoid cycle)
Cell () : Objects(0) {}
//! Constructor; computes cell indices
Cell (const Point& thePnt, const Standard_Real theCellSize[])
: Objects(0)
{
for (int i=0; i < Inspector::Dimension; i++)
{
Standard_Real val = (Standard_Real)(Inspector::Coord(i, thePnt) / theCellSize[i]);
//If the value of index is greater than
//INT_MAX it is decreased correspondingly for the value of INT_MAX. If the value
//of index is less than INT_MIN it is increased correspondingly for the absolute
//value of INT_MIN.
index[i] = long((val > INT_MAX - 1) ? fmod(val, (Standard_Real) INT_MAX)
: (val < INT_MIN + 1) ? fmod(val, (Standard_Real) INT_MIN)
: val);
}
}
//! Copy constructor: ensure that list is not deleted twice
Cell (const Cell& theOther) { (*this) = theOther; }
//! Assignment operator: ensure that list is not deleted twice
void operator = (const Cell& theOther)
{
for (int i=0; i < Inspector::Dimension; i++)
index[i] = theOther.index[i];
Objects = theOther.Objects;
((Cell&)theOther).Objects = 0;
}
//! Destructor; calls destructors for targets contained in the list
~Cell ()
{
for ( ListNode* aNode = Objects; aNode; aNode = aNode->Next )
aNode->Object.~Target();
// note that list nodes need not to be freed, since IncAllocator is used
Objects = 0;
}
//! Compare cell with other one
Standard_Boolean IsEqual (const Cell& theOther) const
{
for (int i=0; i < Inspector::Dimension; i++)
if ( index[i] != theOther.index[i] ) return Standard_False;
return Standard_True;
}
//! Compute hash code
Standard_Integer HashCode (const Standard_Integer theUpper) const
{
// number of bits per each dimension in the hash code
const Standard_Size aShiftBits = (BITS(long)-1) / Inspector::Dimension;
long aCode=0;
for (int i=0; i < Inspector::Dimension; i++)
aCode = ( aCode << aShiftBits ) ^ index[i];
return (unsigned)aCode % theUpper;
}
public:
long index[Inspector::Dimension];
ListNode *Objects;
};
// definition of global functions is needed for map
friend Standard_Integer HashCode (const Cell &aCell, const Standard_Integer theUpper)
{ return aCell.HashCode(theUpper); }
friend Standard_Boolean IsEqual (const Cell &aCell1, const Cell &aCell2)
{ return aCell1.IsEqual(aCell2); }
protected:
//! Reset allocator to the new one
void resetAllocator (const Handle(NCollection_IncAllocator)& theAlloc)
{
if ( theAlloc.IsNull() )
myAllocator = new NCollection_IncAllocator;
else
myAllocator = theAlloc;
myCells.Clear ( myAllocator );
}
//! Add a new target object into the specified cell
void add (const Cell& theCell, const Target& theTarget)
{
// add a new cell or get reference to existing one
Cell& aMapCell = (Cell&)myCells.Added (theCell);
// create a new list node and add it to the beginning of the list
ListNode* aNode = (ListNode*)myAllocator->Allocate(sizeof(ListNode));
new (&aNode->Object) Target (theTarget);
aNode->Next = aMapCell.Objects;
aMapCell.Objects = aNode;
}
//! Internal addition function, performing iteration for adjacent cells
//! by one dimension; called recursively to cover all dimensions
void iterateAdd (int idim, Cell &theCell,
const Cell& theCellMin, const Cell& theCellMax,
const Target& theTarget)
{
int start = theCellMin.index[idim];
int end = theCellMax.index[idim];
for (int i=start; i <= end; i++) {
theCell.index[idim] = i;
if ( idim ) // recurse
iterateAdd (idim-1, theCell, theCellMin, theCellMax, theTarget);
else // add to this cell
add (theCell, theTarget);
}
}
//! Remove the target object from the specified cell
void remove (const Cell& theCell, const Target& theTarget)
{
// check if any objects are recorded in that cell
if ( ! myCells.Contains (theCell) )
return;
// iterate by objects in the cell and check each
Cell& aMapCell = (Cell&)myCells.Added (theCell);
ListNode* aNode = aMapCell.Objects;
ListNode* aPrev = NULL;
while (aNode)
{
ListNode* aNext = aNode->Next;
if (Inspector::IsEqual (aNode->Object, theTarget))
{
aNode->Object.~Target();
(aPrev ? aPrev->Next : aMapCell.Objects) = aNext;
// note that aNode itself need not to be freed, since IncAllocator is used
}
else
aPrev = aNode;
aNode = aNext;
}
}
//! Internal removal function, performing iteration for adjacent cells
//! by one dimension; called recursively to cover all dimensions
void iterateRemove (int idim, Cell &theCell,
const Cell& theCellMin, const Cell& theCellMax,
const Target& theTarget)
{
int start = theCellMin.index[idim];
int end = theCellMax.index[idim];
for (int i=start; i <= end; i++) {
theCell.index[idim] = i;
if ( idim ) // recurse
iterateRemove (idim-1, theCell, theCellMin, theCellMax, theTarget);
else // remove from this cell
remove (theCell, theTarget);
}
}
//! Inspect the target objects in the specified cell.
void inspect (const Cell& theCell, Inspector& theInspector)
{
// check if any objects are recorded in that cell
if ( ! myCells.Contains (theCell) )
return;
// iterate by objects in the cell and check each
Cell& aMapCell = (Cell&)myCells.Added (theCell);
ListNode* aNode = aMapCell.Objects;
ListNode* aPrev = NULL;
while(aNode) {
ListNode* aNext = aNode->Next;
NCollection_CellFilter_Action anAction =
theInspector.Inspect (aNode->Object);
// delete items requested to be purged
if ( anAction == CellFilter_Purge ) {
aNode->Object.~Target();
(aPrev ? aPrev->Next : aMapCell.Objects) = aNext;
// note that aNode itself need not to be freed, since IncAllocator is used
}
else
aPrev = aNode;
aNode = aNext;
}
}
//! Inspect the target objects in the specified range of the cells
void iterateInspect (int idim, Cell &theCell,
const Cell& theCellMin, const Cell& theCellMax,
Inspector& theInspector)
{
int start = theCellMin.index[idim];
int end = theCellMax.index[idim];
for (int i=start; i <= end; i++) {
theCell.index[idim] = i;
if ( idim ) // recurse
iterateInspect (idim-1, theCell, theCellMin, theCellMax, theInspector);
else // inspect this cell
inspect (theCell, theInspector);
}
}
protected:
Handle(NCollection_BaseAllocator) myAllocator;
NCollection_Map<Cell> myCells;
Standard_Real myCellSize [Inspector::Dimension];
};
/**
* Base class defining part of the Inspector interface
* for CellFilter algorithm, working with gp_XYZ points in 3d space
*/
class gp_XYZ;
struct NCollection_CellFilter_InspectorXYZ
{
//! Points dimension
enum { Dimension = 3 };
//! Points type
typedef gp_XYZ Point;
//! Access to co-ordinate
static Standard_Real Coord (int i, const Point &thePnt) { return thePnt.Coord(i+1); }
//! Auxiliary method to shift point by each coordinate on given value;
//! useful for preparing a points range for Inspect with tolerance
Point Shift (const Point& thePnt, Standard_Real theTol) const
{ return Point (thePnt.X() + theTol, thePnt.Y() + theTol, thePnt.Z() + theTol); }
};
/**
* Base class defining part of the Inspector interface
* for CellFilter algorithm, working with gp_XY points in 2d space
*/
class gp_XY;
struct NCollection_CellFilter_InspectorXY
{
//! Points dimension
enum { Dimension = 2 };
//! Points type
typedef gp_XY Point;
//! Access to co-ordinate
static Standard_Real Coord (int i, const Point &thePnt) { return thePnt.Coord(i+1); }
//! Auxiliary method to shift point by each coordinate on given value;
//! useful for preparing a points range for Inspect with tolerance
Point Shift (const Point& thePnt, Standard_Real theTol) const
{ return Point (thePnt.X() + theTol, thePnt.Y() + theTol); }
};
#endif

View File

@@ -0,0 +1,343 @@
// File: NCollection_DataMap.hxx
// Created: Thu Apr 24 15:02:53 2002
// Author: Alexander KARTOMIN (akm)
// <akm@opencascade.com>
#ifndef NCollection_DataMap_HeaderFile
#define NCollection_DataMap_HeaderFile
#include <NCollection_BaseCollection.hxx>
#include <NCollection_BaseMap.hxx>
#include <NCollection_TListNode.hxx>
#include <Standard_TypeMismatch.hxx>
#include <Standard_NoSuchObject.hxx>
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (push)
#pragma warning (disable:4291)
#endif
/**
* Purpose: The DataMap is a Map to store keys with associated
* Items. See Map from NCollection for a discussion
* about the number of buckets.
*
* The DataMap can be seen as an extended array where
* the Keys are the indices. For this reason the
* operator () is defined on DataMap to fetch an Item
* from a Key. So the following syntax can be used :
*
* anItem = aMap(aKey);
* aMap(aKey) = anItem;
*
* This analogy has its limit. aMap(aKey) = anItem
* can be done only if aKey was previously bound to
* an item in the map.
*/
template <class TheKeyType, class TheItemType> class NCollection_DataMap
: public NCollection_BaseCollection<TheItemType>,
public NCollection_BaseMap
{
// **************** Adaptation of the TListNode to the DATAmap
public:
class DataMapNode : public NCollection_TListNode<TheItemType>
{
public:
//! Constructor with 'Next'
DataMapNode (const TheKeyType& theKey,
const TheItemType& theItem,
NCollection_ListNode* theNext) :
NCollection_TListNode<TheItemType> (theItem, theNext)
{ myKey = theKey; }
//! Key
const TheKeyType& Key (void) const
{ return myKey; }
//! Static deleter to be passed to BaseList
static void delNode (NCollection_ListNode * theNode,
Handle(NCollection_BaseAllocator)& theAl)
{
((DataMapNode *) theNode)->~DataMapNode();
theAl->Free(theNode);
}
private:
TheKeyType myKey;
};
public:
// **************** Implementation of the Iterator interface.
class Iterator
: public NCollection_BaseCollection<TheItemType>::Iterator,
public NCollection_BaseMap::Iterator
{
public:
//! Empty constructor
Iterator (void) :
NCollection_BaseMap::Iterator() {}
//! Constructor
Iterator (const NCollection_DataMap& theMap) :
NCollection_BaseMap::Iterator(theMap) {}
//! Query if the end of collection is reached by iterator
virtual Standard_Boolean More(void) const
{ return PMore(); }
//! Make a step along the collection
virtual void Next(void)
{ PNext(); }
//! Value inquiry
virtual const TheItemType& Value(void) const
{
#if !defined No_Exception && !defined No_Standard_NoSuchObject
if (!More())
Standard_NoSuchObject::Raise("NCollection_DataMap::Iterator::Value");
#endif
return ((DataMapNode *) myNode)->Value();
}
//! Value change access
virtual TheItemType& ChangeValue(void) const
{
#if !defined No_Exception && !defined No_Standard_NoSuchObject
if (!More())
Standard_NoSuchObject::Raise("NCollection_DataMap::Iterator::ChangeValue");
#endif
return ((DataMapNode *) myNode)->ChangeValue();
}
//! Key
const TheKeyType& Key (void) const
{
#if !defined No_Exception && !defined No_Standard_NoSuchObject
if (!More())
Standard_NoSuchObject::Raise("NCollection_DataMap::Iterator::Key");
#endif
return ((DataMapNode *) myNode)->Key();
}
//! Operator new for allocating iterators
void* operator new(size_t theSize,
const Handle(NCollection_BaseAllocator)& theAllocator)
{ return theAllocator->Allocate(theSize); }
};
public:
// ---------- PUBLIC METHODS ------------
//! Constructor
NCollection_DataMap (const Standard_Integer NbBuckets=1,
const Handle(NCollection_BaseAllocator)& theAllocator = 0L)
: NCollection_BaseCollection<TheItemType>(theAllocator),
NCollection_BaseMap (NbBuckets, Standard_True) {}
//! Copy constructor
NCollection_DataMap (const NCollection_DataMap& theOther)
: NCollection_BaseCollection<TheItemType>(theOther.myAllocator),
NCollection_BaseMap (theOther.NbBuckets(), Standard_True)
{ *this = theOther; }
//! Assign another collection
virtual void Assign(const NCollection_BaseCollection<TheItemType>& theOther)
{
if (this == &theOther)
return;
Standard_TypeMismatch::Raise ("NCollection_DataMap::Assign impossible");
}
//! = another map
NCollection_DataMap& operator= (const NCollection_DataMap& theOther)
{
if (this == &theOther)
return *this;
Clear(theOther.myAllocator);
ReSize (theOther.Extent()-1);
Iterator anIter(theOther);
for (; anIter.More(); anIter.Next())
Bind (anIter.Key(), anIter.Value());
return *this;
}
//! ReSize
void ReSize (const Standard_Integer N)
{
DataMapNode** newdata = NULL;
DataMapNode** dummy = NULL;
Standard_Integer newBuck;
if (BeginResize (N, newBuck,
(NCollection_ListNode**&)newdata,
(NCollection_ListNode**&)dummy,
this->myAllocator))
{
if (myData1)
{
DataMapNode** olddata = (DataMapNode**) myData1;
DataMapNode *p, *q;
Standard_Integer i,k;
for (i = 0; i <= NbBuckets(); i++)
{
if (olddata[i])
{
p = olddata[i];
while (p)
{
k = HashCode(p->Key(),newBuck);
q = (DataMapNode*) p->Next();
p->Next() = newdata[k];
newdata[k] = p;
p = q;
}
}
}
}
EndResize(N,newBuck,
(NCollection_ListNode**&)newdata,
(NCollection_ListNode**&)dummy,
this->myAllocator);
}
}
//! Bind
Standard_Boolean Bind (const TheKeyType& theKey, const TheItemType& theItem)
{
if (Resizable())
ReSize(Extent());
DataMapNode** data = (DataMapNode**)myData1;
Standard_Integer k = HashCode (theKey, NbBuckets());
DataMapNode* p = data[k];
while (p)
{
if (IsEqual(p->Key(), theKey))
{
p->ChangeValue() = theItem;
return Standard_False;
}
p = (DataMapNode *) p->Next();
}
data[k] = new (this->myAllocator) DataMapNode (theKey, theItem, data[k]);
Increment();
return Standard_True;
}
//! IsBound
Standard_Boolean IsBound(const TheKeyType& K) const
{
if (IsEmpty())
return Standard_False;
DataMapNode** data = (DataMapNode**) myData1;
DataMapNode* p = data[HashCode(K,NbBuckets())];
while (p)
{
if (IsEqual(p->Key(),K))
return Standard_True;
p = (DataMapNode *) p->Next();
}
return Standard_False;
}
//! UnBind
Standard_Boolean UnBind(const TheKeyType& K)
{
if (IsEmpty())
return Standard_False;
DataMapNode** data = (DataMapNode**) myData1;
Standard_Integer k = HashCode(K,NbBuckets());
DataMapNode* p = data[k];
DataMapNode* q = NULL;
while (p)
{
if (IsEqual(p->Key(),K))
{
Decrement();
if (q)
q->Next() = p->Next();
else
data[k] = (DataMapNode*) p->Next();
p->~DataMapNode();
this->myAllocator->Free(p);
return Standard_True;
}
q = p;
p = (DataMapNode*) p->Next();
}
return Standard_False;
}
//! Find
const TheItemType& Find(const TheKeyType& theKey) const
{
#if !defined No_Exception && !defined No_Standard_NoSuchObject
if (IsEmpty())
Standard_NoSuchObject::Raise ("NCollection_DataMap::Find");
#endif
DataMapNode* p = (DataMapNode*) myData1[HashCode(theKey,NbBuckets())];
while (p)
{
if (IsEqual(p->Key(),theKey))
return p->Value();
p = (DataMapNode*) p->Next();
}
Standard_NoSuchObject::Raise("NCollection_DataMap::Find");
return p->Value(); // This for compiler
}
//! operator ()
const TheItemType& operator() (const TheKeyType& theKey) const
{ return Find(theKey); }
//! ChangeFind
TheItemType& ChangeFind (const TheKeyType& theKey)
{
#if !defined No_Exception && !defined No_Standard_NoSuchObject
if (IsEmpty())
Standard_NoSuchObject::Raise ("NCollection_DataMap::Find");
#endif
DataMapNode* p = (DataMapNode*) myData1[HashCode(theKey,NbBuckets())];
while (p)
{
if (IsEqual(p->Key(),theKey))
return p->ChangeValue();
p = (DataMapNode*) p->Next();
}
Standard_NoSuchObject::Raise("NCollection_DataMap::Find");
return p->ChangeValue(); // This for compiler
}
//! operator ()
TheItemType& operator() (const TheKeyType& theKey)
{ return ChangeFind(theKey); }
//! Clear data. If doReleaseMemory is false then the table of
//! buckets is not released and will be reused.
void Clear(const Standard_Boolean doReleaseMemory = Standard_True)
{ Destroy (DataMapNode::delNode, this->myAllocator, doReleaseMemory); }
//! Clear data and reset allocator
void Clear (const Handle(NCollection_BaseAllocator)& theAllocator)
{
Clear();
this->myAllocator = ( ! theAllocator.IsNull() ? theAllocator :
NCollection_BaseAllocator::CommonBaseAllocator() );
}
//! Destructor
~NCollection_DataMap (void)
{ Clear(); }
//! Size
virtual Standard_Integer Size(void) const
{ return Extent(); }
private:
// ----------- PRIVATE METHODS -----------
//! Creates Iterator for use on BaseCollection
virtual TYPENAME NCollection_BaseCollection<TheItemType>::Iterator&
CreateIterator(void) const
{ return *(new (this->IterAllocator()) Iterator(*this)); }
};
#ifdef WNT
#pragma warning (pop)
#endif
#endif

View File

@@ -0,0 +1,52 @@
// File: NCollection_DefineArray1.hxx
// Created: 15.04.02 17:05:16
// Author: Alexander Kartomin (akm)
// <a-kartomin@opencascade.com>
// Automatically created from NCollection_Array1.hxx by GAWK
// Copyright: Open Cascade 2002
//
// Purpose: The class Array2 represents unidimensional arrays
// of fixed size known at run time.
// The range of the index is user defined.
// An array1 can be constructed with a "C array".
// This functionality is useful to call methods expecting
// an Array1. It allows to carry the bounds inside the arrays.
//
// Examples: Item tab[100]; // An example with a C array
// Array1OfItem ttab (tab[0],1,100);
//
// Array1OfItem tttab (ttab(10),10,20); // a slice of ttab
//
// If you want to reindex an array from 1 to Length do :
//
// Array1 tab1(tab(tab.Lower()),1,tab.Length());
//
// Warning: Programs client of such a class must be independant
// of the range of the first element. Then, a C++ for
// loop must be written like this
//
// for (i = A.Lower(); i <= A.Upper(); i++)
//
// Changes: In comparison to TCollection the flag isAllocated was
// renamed into myDeletable (alike in the Array2). For naming
// compatibility the method IsAllocated remained in class along
// with IsDeletable.
//
#ifndef NCollection_DefineArray1_HeaderFile
#define NCollection_DefineArray1_HeaderFile
#include <NCollection_DefineBaseCollection.hxx>
#include <NCollection_Array1.hxx>
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (disable:4291)
#endif
// *********************************************** Template for Array1 class
#define DEFINE_ARRAY1(_ClassName_, _BaseCollection_, TheItemType) \
typedef NCollection_Array1<TheItemType > _ClassName_;
#endif

View File

@@ -0,0 +1,36 @@
// File: NCollection_DefineArray2.hxx
// Created: 15.04.02 17:05:16
// Author: Alexander Kartomin (akm)
// <a-kartomin@opencascade.com>
// Automatically created from NCollection_Array2.hxx by GAWK
// Copyright: Open Cascade 2002
//
// Purpose: The class Array2 represents bi-dimensional arrays
// of fixed size known at run time.
// The ranges of indices are user defined.
//
// Warning: Programs clients of such class must be independant
// of the range of the first element. Then, a C++ for
// loop must be written like this
//
// for (i = A.LowerRow(); i <= A.UpperRow(); i++)
// for (j = A.LowerCol(); j <= A.UpperCol(); j++)
//
#ifndef NCollection_DefineArray2_HeaderFile
#define NCollection_DefineArray2_HeaderFile
#include <NCollection_DefineBaseCollection.hxx>
#include <NCollection_Array2.hxx>
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (disable:4291)
#endif
// *********************************************** Template for Array2 class
#define DEFINE_ARRAY2(_ClassName_, _BaseCollection_, TheItemType) \
typedef NCollection_Array2<TheItemType > _ClassName_;
#endif

View File

@@ -0,0 +1,38 @@
// File: NCollection_DefineBaseCollection.hxx
// Created: Tue Apr 9 18:53:36 2002
// Author: Alexander KARTOMIN (akm)
// <a-kartomin@opencascade.com>
//
// Purpose: NCollection_BaseCollection is the base abstract class for
// all collection templates of this package.
// The set of collections is similar to that of TCollection.
// Also the methods of classes have mostly the same names for
// easy switch from TCollection <-> NCollection containers.
//
// NCollection is a nocdlpack, thus it is compiled without WOK.
// BaseCollection allows assigning the collections of different
// kinds (the items type being the same) with a few obvious
// exclusions - one can not assign any collection to the map
// having double data (two keys or a key plus value). Only the
// maps of the very same type may be assigned through operator=
// Said maps are: DoubleMap,
// DataMap,
// IndexedDataMap
//
// For the users needing control over the memory usage the
// allocators were added (see NCollection_BaseAllocator header)
// Others may forget it - BaseAllocator is used by default and
// then memory is managed through Standard::Allocate/::Free.
//
#ifndef NCollection_DefineBaseCollection_HeaderFile
#define NCollection_DefineBaseCollection_HeaderFile
#include <NCollection_BaseCollection.hxx>
// *************************************** Template for BaseCollection class
#define DEFINE_BASECOLLECTION(_ClassName_, TheItemType) \
typedef NCollection_BaseCollection<TheItemType > _ClassName_;
#endif

View File

@@ -0,0 +1,39 @@
// File: NCollection_DefineDataMap.hxx
// Created: Thu Apr 24 15:02:53 2002
// Author: Alexander KARTOMIN (akm)
// <akm@opencascade.com>
//
// Purpose: The DataMap is a Map to store keys with associated
// Items. See Map from NCollection for a discussion
// about the number of buckets.
//
// The DataMap can be seen as an extended array where
// the Keys are the indices. For this reason the
// operator () is defined on DataMap to fetch an Item
// from a Key. So the following syntax can be used :
//
// anItem = aMap(aKey);
// aMap(aKey) = anItem;
//
// This analogy has its limit. aMap(aKey) = anItem
// can be done only if aKey was previously bound to
// an item in the map.
//
#ifndef NCollection_DefineDataMap_HeaderFile
#define NCollection_DefineDataMap_HeaderFile
#include <NCollection_DefineBaseCollection.hxx>
#include <NCollection_DataMap.hxx>
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (disable:4291)
#endif
// *********************************************** Class DataMap *************
#define DEFINE_DATAMAP(_ClassName_, _BaseCollection_, TheKeyType, TheItemType) \
typedef NCollection_DataMap<TheKeyType, TheItemType > _ClassName_;
#endif

View File

@@ -0,0 +1,29 @@
// File: NCollection_DefineDoubleMap.hxx
// Created: Thu Apr 24 15:02:53 2002
// Author: Alexander KARTOMIN (akm)
// <akm@opencascade.com>
//
// Purpose: The DoubleMap is used to bind pairs (Key1,Key2)
// and retrieve them in linear time.
//
// See Map from NCollection for a discussion about the number
// of buckets
//
#ifndef NCollection_DefineDoubleMap_HeaderFile
#define NCollection_DefineDoubleMap_HeaderFile
#include <NCollection_DefineBaseCollection.hxx>
#include <NCollection_DoubleMap.hxx>
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (disable:4291)
#endif
// *********************************************** Class DoubleMap ************
#define DEFINE_DOUBLEMAP(_ClassName_, _BaseCollection_, TheKey1Type, TheKey2Type) \
typedef NCollection_DoubleMap <TheKey1Type, TheKey2Type > _ClassName_;
#endif

View File

@@ -0,0 +1,51 @@
// File: NCollection_DefineHArray1.hxx
// Created: Mon Apr 29 11:36:31 2002
// Author: Alexander KARTOMIN (akm)
// <a-kartomin@opencascade.com>
// Automatically created from NCollection_HArray1.hxx by GAWK
// Copyright: Open Cascade 2002
#ifndef NCollection_DefineHArray1_HeaderFile
#define NCollection_DefineHArray1_HeaderFile
#include <Standard_DefineHandle.hxx>
#include <NCollection_DefineArray1.hxx>
#include <MMgt_TShared.hxx>
// Declaration of Array1 class managed by Handle
#define DEFINE_HARRAY1(HClassName, _Array1Type_) \
\
class HClassName : public _Array1Type_, \
public MMgt_TShared { \
public: \
inline HClassName (const Standard_Integer theLower, \
const Standard_Integer theUpper); \
inline HClassName (const _Array1Type_&); \
inline const _Array1Type_& Array1 () const; \
inline _Array1Type_& ChangeArray1 (); \
DEFINE_STANDARD_RTTI (HClassName) \
}; \
\
DEFINE_STANDARD_HANDLE (HClassName, MMgt_TShared) \
\
inline HClassName::HClassName (const Standard_Integer theLower, \
const Standard_Integer theUpper) : \
_Array1Type_ (theLower,theUpper), \
MMgt_TShared() {} \
\
inline HClassName::HClassName (const _Array1Type_& theOther) : \
_Array1Type_(theOther), \
MMgt_TShared() {} \
\
inline const _Array1Type_& HClassName::Array1 () const \
{ return * (const _Array1Type_ *) this; } \
\
inline _Array1Type_& HClassName::ChangeArray1 () \
{ return * (_Array1Type_ *) this; } \
#define IMPLEMENT_HARRAY1(HClassName) \
IMPLEMENT_STANDARD_HANDLE (HClassName, MMgt_TShared) \
IMPLEMENT_STANDARD_RTTIEXT (HClassName, MMgt_TShared)
#endif

View File

@@ -0,0 +1,55 @@
// File: NCollection_DefineHArray2.hxx
// Created: Mon Apr 29 11:36:31 2002
// Author: Alexander KARTOMIN (akm)
// <a-kartomin@opencascade.com>
// Automatically created from NCollection_HArray2.hxx by GAWK
// Copyright: Open Cascade 2002
#ifndef NCollection_DefineHArray2_HeaderFile
#define NCollection_DefineHArray2_HeaderFile
#include <Standard_DefineHandle.hxx>
#include <NCollection_DefineArray2.hxx>
#include <MMgt_TShared.hxx>
// Declaration of Array2 class managed by Handle
#define DEFINE_HARRAY2(HClassName, _Array2Type_) \
\
class HClassName : public _Array2Type_, \
public MMgt_TShared { \
public: \
inline HClassName (const Standard_Integer theRowLower, \
const Standard_Integer theRowUpper, \
const Standard_Integer theColLower, \
const Standard_Integer theColUpper);\
inline HClassName (const _Array2Type_&); \
inline const _Array2Type_& Array2 () const; \
inline _Array2Type_& ChangeArray2(); \
DEFINE_STANDARD_RTTI (HClassName) \
}; \
\
DEFINE_STANDARD_HANDLE (HClassName, MMgt_TShared) \
\
inline HClassName::HClassName (const Standard_Integer theRowLow, \
const Standard_Integer theRowUpp, \
const Standard_Integer theColLow, \
const Standard_Integer theColUpp) : \
_Array2Type_ (theRowLow, theRowUpp, theColLow, theColUpp), \
MMgt_TShared() {} \
\
inline HClassName::HClassName (const _Array2Type_& theOther) : \
_Array2Type_(theOther), \
MMgt_TShared() {} \
\
inline const _Array2Type_& HClassName::Array2 () const \
{ return * (const _Array2Type_ *) this; } \
\
inline _Array2Type_& HClassName::ChangeArray2 () \
{ return * (_Array2Type_ *) this; } \
#define IMPLEMENT_HARRAY2(HClassName) \
IMPLEMENT_STANDARD_HANDLE (HClassName, MMgt_TShared) \
IMPLEMENT_STANDARD_RTTIEXT (HClassName, MMgt_TShared)
#endif

View File

@@ -0,0 +1,48 @@
// File: NCollection_DefineHSequence.hxx
// Created: 29.01.01 12:58:53
// Author: Alexander GRIGORIEV
// Automatically created from NCollection_HSequence.hxx by GAWK
// Copyright: Open Cascade 2002
#ifndef NCollection_DefineHSequence_HeaderFile
#define NCollection_DefineHSequence_HeaderFile
#include <Standard_DefineHandle.hxx>
#include <NCollection_DefineSequence.hxx>
#include <MMgt_TShared.hxx>
// Declaration of Sequence class managed by Handle
#define DEFINE_HSEQUENCE(HClassName, _SequenceType_) \
\
class HClassName : public _SequenceType_, \
public MMgt_TShared { \
public: \
inline HClassName (); \
inline HClassName (const _SequenceType_&); \
inline const _SequenceType_& Sequence () const; \
inline _SequenceType_& ChangeSequence (); \
DEFINE_STANDARD_RTTI (HClassName) \
}; \
\
DEFINE_STANDARD_HANDLE (HClassName, MMgt_TShared) \
\
inline HClassName::HClassName () : \
_SequenceType_(), \
MMgt_TShared() {} \
\
inline HClassName::HClassName (const _SequenceType_& anOther) : \
_SequenceType_(anOther), \
MMgt_TShared() {} \
\
inline const _SequenceType_& HClassName::Sequence () const \
{ return * (const _SequenceType_ *) this; } \
\
inline _SequenceType_& HClassName::ChangeSequence () \
{ return * (_SequenceType_ *) this; } \
#define IMPLEMENT_HSEQUENCE(HClassName) \
IMPLEMENT_STANDARD_HANDLE (HClassName, MMgt_TShared) \
IMPLEMENT_STANDARD_RTTIEXT (HClassName, MMgt_TShared)
#endif

View File

@@ -0,0 +1,47 @@
// File: NCollection_DefineHSet.hxx
// Created: Mon Apr 29 12:34:55 2002
// Author: Alexander KARTOMIN (akm)
// <a-kartomin@opencascade.com>
#ifndef NCollection_DefineHSet_HeaderFile
#define NCollection_DefineHSet_HeaderFile
#include <Standard_DefineHandle.hxx>
#include <NCollection_DefineSet.hxx>
#include <MMgt_TShared.hxx>
// Declaration of Set class managed by Handle
#define DEFINE_HSET(HClassName, _SetType_) \
\
class HClassName : public _SetType_, \
public MMgt_TShared { \
public: \
inline HClassName (); \
inline HClassName (const _SetType_& anOther); \
inline const _SetType_& Set () const; \
inline _SetType_& ChangeSet (); \
DEFINE_STANDARD_RTTI (HClassName) \
}; \
\
DEFINE_STANDARD_HANDLE (HClassName, MMgt_TShared) \
\
inline HClassName::HClassName () : \
_SetType_(), \
MMgt_TShared() {} \
\
inline HClassName::HClassName (const _SetType_& anOther) : \
_SetType_(anOther), \
MMgt_TShared() {} \
\
inline const _SetType_& HClassName::Set () const \
{ return * (const _SetType_ *) this; } \
\
inline _SetType_& HClassName::ChangeSet () \
{ return * (_SetType_ *) this; } \
#define IMPLEMENT_HSET(HClassName) \
IMPLEMENT_STANDARD_HANDLE (HClassName, MMgt_TShared) \
IMPLEMENT_STANDARD_RTTIEXT (HClassName, MMgt_TShared)
#endif

View File

@@ -0,0 +1,40 @@
// File: NCollection_DefineIndexedDataMap.hxx
// Created: Thu Apr 24 15:02:53 2002
// Author: Alexander KARTOMIN (akm)
// <akm@opencascade.com>
//
// Purpose: An indexed map is used to store keys and to bind
// an index to them. Each new key stored in the map
// gets an index. Index are incremented as keys are
// stored in the map. A key can be found by the index
// and an index by the key. No key but the last can
// be removed so the indices are in the range 1..
// Extent. An Item is stored with each key.
//
// This class is similar to IndexedMap from
// NCollection with the Item as a new feature. Note
// the important difference on the operator (). In
// the IndexedMap this operator returns the Key. In
// the IndexedDataMap this operator returns the Item.
//
// See the class Map from NCollection for a
// discussion about the number of buckets.
//
#ifndef NCollection_DefineIndexedDataMap_HeaderFile
#define NCollection_DefineIndexedDataMap_HeaderFile
#include <NCollection_DefineBaseCollection.hxx>
#include <NCollection_IndexedDataMap.hxx>
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (disable:4291)
#endif
// *********************************************** Class IndexedDataMap ******
#define DEFINE_INDEXEDDATAMAP(_ClassName_, _BaseCollection_, TheKeyType, TheItemType) \
typedef NCollection_IndexedDataMap <TheKeyType, TheItemType > _ClassName_;
#endif

View File

@@ -0,0 +1,32 @@
// File: NCollection_DefineIndexedMap.hxx
// Created: Thu Apr 24 15:02:53 2002
// Author: Alexander KARTOMIN (akm)
// <akm@opencascade.com>
//
// Purpose: An indexed map is used to store keys and to bind
// an index to them. Each new key stored in the map
// gets an index. Index are incremented as keys are
// stored in the map. A key can be found by the index
// and an index by the key. No key but the last can
// be removed so the indices are in the range 1..Extent.
// See the class Map from NCollection for a
// discussion about the number of buckets.
//
#ifndef NCollection_DefineIndexedMap_HeaderFile
#define NCollection_DefineIndexedMap_HeaderFile
#include <NCollection_DefineBaseCollection.hxx>
#include <NCollection_IndexedMap.hxx>
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (disable:4291)
#endif
// *********************************************** Class IndexedMap ***********
#define DEFINE_INDEXEDMAP(_ClassName_, _BaseCollection_, TheKeyType) \
typedef NCollection_IndexedMap <TheKeyType > _ClassName_;
#endif

View File

@@ -0,0 +1,29 @@
// File: NCollection_DefineList.hxx
// Created: 17.04.02 10:12:48
// Author: Alexander Kartomin (akm)
// <a-kartomin@opencascade.com>
// Automatically created from NCollection_List.hxx by GAWK
// Copyright: Open Cascade 2002
//
// Purpose: Simple list to link items together keeping the first
// and the last one.
// Inherits BaseList, adding the data item to each node.
//
#ifndef NCollection_DefineList_HeaderFile
#define NCollection_DefineList_HeaderFile
#include <NCollection_List.hxx>
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (disable:4291)
#endif
// **************************************** Template for List class ********
#define DEFINE_LIST(_ClassName_, _BaseCollection_, TheItemType) \
typedef NCollection_List <TheItemType > _ClassName_;
#endif

View File

@@ -0,0 +1,49 @@
// File: NCollection_DefineMap.hxx
// Created: Thu Apr 23 15:02:53 2002
// Author: Alexander KARTOMIN (akm)
// <a-kartomin@opencascade.com>
//
// Purpose: Single hashed Map. This Map is used to store and
// retrieve keys in linear time.
//
// The ::Iterator class can be used to explore the
// content of the map. It is not wise to iterate and
// modify a map in parallel.
//
// To compute the hashcode of the key the function
// ::HashCode must be defined in the global namespace
//
// To compare two keys the function ::IsEqual must be
// defined in the global namespace.
//
// The performance of a Map is conditionned by its
// number of buckets that should be kept greater to
// the number of keys. This map has an automatic
// management of the number of buckets. It is resized
// when the number of Keys becomes greater than the
// number of buckets.
//
// If you have a fair idea of the number of objects
// you can save on automatic resizing by giving a
// number of buckets at creation or using the ReSize
// method. This should be consider only for crucial
// optimisation issues.
//
#ifndef NCollection_DefineMap_HeaderFile
#define NCollection_DefineMap_HeaderFile
#include <NCollection_DefineBaseCollection.hxx>
#include <NCollection_Map.hxx>
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (disable:4291)
#endif
// *********************************************** Class Map *****************
#define DEFINE_MAP(_ClassName_, _BaseCollection_, TheKeyType) \
typedef NCollection_Map <TheKeyType > _ClassName_;
#endif

View File

@@ -0,0 +1,31 @@
// File: NCollection_DefineQueue.hxx
// Created: 17.04.02 10:12:48
// Author: Alexander Kartomin (akm)
// <a-kartomin@opencascade.com>
// Automatically created from NCollection_Queue.hxx by GAWK
// Copyright: Open Cascade 2002
//
// Purpose: A queue is a structure where Items are added at
// the end and removed from the front. The first
// entered Item will be the first removed. This is
// called a FIFO (First In First Out).
// Inherits BaseList, adds the data item to each node.
//
#ifndef NCollection_DefineQueue_HeaderFile
#define NCollection_DefineQueue_HeaderFile
#include <NCollection_Queue.hxx>
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (disable:4291)
#endif
// **************************************** Template for Queue class ********
#define DEFINE_QUEUE(_ClassName_, _BaseCollection_, TheItemType) \
typedef NCollection_Queue<TheItemType > _ClassName_;
#endif

View File

@@ -0,0 +1,56 @@
// File: NCollection_DefineSList.hxx
// Created: 17.04.02 10:12:48
// Author: Alexander Kartomin (akm)
// Automatically created from NCollection_SList.hxx by GAWK
// Copyright: Open Cascade 2002
//
// Purpose: An SList is a LISP like list of Items.
// An SList is :
// . Empty.
// . Or it has a Value and a Tail which is an other SList.
//
// The Tail of an empty list is an empty list.
// SList are shared. It means that they can be
// modified through other lists.
// SList may be used as Iterators. They have Next,
// More, and value methods. To iterate on the content
// of the list S just do.
//
// SList Iterator;
// for (Iterator = S; Iterator.More(); Iterator.Next())
// X = Iterator.Value();
//
// Memory usage is automatically managed for SLists
// (using reference counts).
//
// Example:
// If S1 and S2 are SLists :
// if S1.Value() is X.
//
// And the following is done :
// S2 = S1;
// S2.SetValue(Y);
//
// S1.Value() becomes also Y. So SList must be used
// with care. Mainly the SetValue() method is
// dangerous.
//
#ifndef NCollection_DefineSList_HeaderFile
#define NCollection_DefineSList_HeaderFile
#include <NCollection_DefineBaseCollection.hxx>
#include <NCollection_SList.hxx>
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (disable:4291)
#endif
// **************************************** Template for SList class ********
#define DEFINE_SLIST(_ClassName_, _BaseCollection_, TheItemType) \
typedef NCollection_SList<TheItemType > _ClassName_;
#endif

View File

@@ -0,0 +1,28 @@
// File: NCollection_DefineSequence.hxx
// Created: 28.03.02 20:41:43
// Author: Alexander GRIGORIEV
// Automatically created from NCollection_Sequence.hxx by GAWK
// Copyright: Open Cascade 2002
//
// Purpose: Definition of a sequence of elements indexed by
// an Integer in range of 1..n
//
#ifndef NCollection_DefineSequence_HeaderFile
#define NCollection_DefineSequence_HeaderFile
#include <NCollection_DefineBaseCollection.hxx>
#include <NCollection_Sequence.hxx>
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (disable:4291)
#endif
// **************************************** Template for Sequence class ********
#define DEFINE_SEQUENCE(_ClassName_, _BaseCollection_, TheItemType) \
typedef NCollection_Sequence<TheItemType > _ClassName_;
#endif

View File

@@ -0,0 +1,31 @@
// File: NCollection_DefineSet.hxx
// Created: 17.04.02 10:12:48
// Author: Alexander Kartomin (akm)
// <a-kartomin@opencascade.com>
// Automatically created from NCollection_Set.hxx by GAWK
// Copyright: Open Cascade 2002
//
// Purpose: A set is an unordered collection of items without
// duplications. To test for duplications the operators == and !=
// are used on the items.
// Inherits BaseList, adding the data item to each node.
//
#ifndef NCollection_DefineSet_HeaderFile
#define NCollection_DefineSet_HeaderFile
#include <NCollection_DefineBaseCollection.hxx>
#include <NCollection_Set.hxx>
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (disable:4291)
#endif
// **************************************** Template for Set class ********
#define DEFINE_SET(_ClassName_, _BaseCollection_, TheItemType) \
typedef NCollection_Set<TheItemType > _ClassName_;
#endif

View File

@@ -0,0 +1,32 @@
// File: NCollection_DefineStack.hxx
// Created: 17.04.02 10:12:48
// <a-kartomin@opencascade.com>
// Author: Alexander Kartomin (akm)
// Automatically created from NCollection_Stack.hxx by GAWK
// Copyright: Open Cascade 2002
//
// Purpose: A stack is a structure where item can be added and
// removed from the top. Like a stack of plates in a
// kitchen. The last entered item will be be the
// first removed. This is called a LIFO (last In First Out).
// Inherits BaseList, adding the data item to each node.
//
#ifndef NCollection_DefineStack_HeaderFile
#define NCollection_DefineStack_HeaderFile
#include <NCollection_DefineBaseCollection.hxx>
#include <NCollection_Stack.hxx>
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (disable:4291)
#endif
// **************************************** Template for Stack class ********
#define DEFINE_STACK(_ClassName_, _BaseCollection_, TheItemType) \
typedef NCollection_Stack<TheItemType > _ClassName_;
#endif

View File

@@ -0,0 +1,26 @@
// File: NCollection_DefineTListIterator.hxx
// Created: Tue Apr 23 17:33:02 2002
// Author: Alexander KARTOMIN
// <a-kartomin@opencascade.com>
//
// Purpose: This Iterator class iterates on BaseList of TListNode and is
// instantiated in List/Set/Queue/Stack
// Remark: TListIterator is internal class
//
#ifndef NCollection_DefineTListIterator_HeaderFile
#define NCollection_DefineTListIterator_HeaderFile
#include <NCollection_DefineBaseCollection.hxx>
#include <NCollection_TListIterator.hxx>
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (disable:4291)
#endif
// ********************************** Implementation of the Iterator interface
#define DEFINE_TLISTITERATOR(_ClassName_, _BaseCollection_, TheItemType) \
typedef NCollection_TListIterator<TheItemType > _ClassName_;
#endif

View File

@@ -0,0 +1,24 @@
// File: NCollection_DefineTListNode.hxx
// Created: Tue Apr 23 17:30:38 2002
// Author: Alexander KARTOMIN (akm)
// <akm@opencascade.com>
//
// Purpose: Abstract list node class. Used by BaseList
// Remark: Internal class
//
#ifndef NCollection_DefineTListNode_HeaderFile
#define NCollection_DefineTListNode_HeaderFile
#include <NCollection_TListNode.hxx>
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (disable:4291)
#endif
// ******************************* Class defining list node - for internal use
#define DEFINE_TLISTNODE(_ClassName_, _BaseCollection_, TheItemType) \
typedef NCollection_TListNode<TheItemType > _ClassName_;
#endif

View File

@@ -0,0 +1,44 @@
// File: NCollection_DefineVector.hxx
// Created: 23.04.02 19:24:33
// Author: Alexander GRIGORIEV
// Automatically created from NCollection_Vector.hxx by GAWK
// Copyright: Open Cascade 2002
#ifndef NCollection_DefineVector_HeaderFile
#define NCollection_DefineVector_HeaderFile
#include <NCollection_DefineBaseCollection.hxx>
#include <NCollection_Vector.hxx>
#ifdef WNT
// Disable the warning: "operator new unmatched by delete"
#pragma warning (disable:4291)
#endif
// Class NCollection_Vector (dynamic array of objects)
//
// This class is similar to NCollection_Array1 though the indices always start
// at 0 (in Array1 the first index must be specified)
//
// The Vector is always created with 0 length. It can be enlarged by two means:
// 1. Calling the method Append (val) - then "val" is added to the end of the
// vector (the vector length is incremented)
// 2. Calling the method SetValue (i, val) - if "i" is greater than or equal
// to the current length of the vector, the vector is enlarged to accomo-
// date this index
//
// The methods Append and SetValue return a non-const reference to the copied
// object inside the vector. This reference is guaranteed to be valid until
// the vector is destroyed. It can be used to access the vector member directly
// or to pass its address to other data structures.
//
// The vector iterator remembers the length of the vector at the moment of the
// creation or initialisation of the iterator. Therefore the iteration begins
// at index 0 and stops at the index equal to (remembered_length-1). It is OK
// to enlarge the vector during the iteration.
#define DEFINE_VECTOR(_ClassName_, _BaseCollection_, TheItemType) \
typedef NCollection_Vector<TheItemType > _ClassName_;
#endif

View File

@@ -0,0 +1,477 @@
// File: NCollection_DoubleMap.hxx
// Created: Thu Apr 24 15:02:53 2002
// Author: Alexander KARTOMIN (akm)
// <akm@opencascade.com>
#ifndef NCollection_DoubleMap_HeaderFile
#define NCollection_DoubleMap_HeaderFile
#include <NCollection_TypeDef.hxx>
#include <NCollection_BaseCollection.hxx>
#include <NCollection_BaseMap.hxx>
#include <NCollection_TListNode.hxx>
#include <Standard_TypeMismatch.hxx>
#include <Standard_MultiplyDefined.hxx>
#include <Standard_ImmutableObject.hxx>
#include <Standard_NoSuchObject.hxx>
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (push)
#pragma warning (disable:4291)
#endif
/**
* Purpose: The DoubleMap is used to bind pairs (Key1,Key2)
* and retrieve them in linear time.
*
* See Map from NCollection for a discussion about the number
* of buckets
*/
template <class TheKey1Type, class TheKey2Type> class NCollection_DoubleMap
: public NCollection_BaseCollection<TheKey2Type>,
public NCollection_BaseMap
{
// **************** Adaptation of the TListNode to the DOUBLEmap
public:
class DoubleMapNode : public NCollection_TListNode<TheKey2Type>
{
public:
//! Constructor with 'Next'
DoubleMapNode (const TheKey1Type& theKey1,
const TheKey2Type& theKey2,
NCollection_ListNode* theNext1,
NCollection_ListNode* theNext2) :
NCollection_TListNode<TheKey2Type> (theKey2, theNext1)
{
myKey1 = theKey1;
myNext2 = (DoubleMapNode *) theNext2;
}
//! Key1
const TheKey1Type& Key1 (void)
{ return myKey1; }
//! Key2
const TheKey2Type& Key2 (void)
{ return this->myValue; }
//! Next2
DoubleMapNode*& Next2 (void)
{ return myNext2; }
//! Static deleter to be passed to BaseList
static void delNode (NCollection_ListNode * theNode,
Handle(NCollection_BaseAllocator)& theAl)
{
((DoubleMapNode *) theNode)->~DoubleMapNode();
theAl->Free(theNode);
}
private:
TheKey1Type myKey1;
DoubleMapNode *myNext2;
};
public:
// **************** Implementation of the Iterator interface.
class Iterator
: public NCollection_BaseCollection<TheKey2Type>::Iterator,
public NCollection_BaseMap::Iterator
{
public:
//! Empty constructor
Iterator (void) :
NCollection_BaseMap::Iterator() {}
//! Constructor
Iterator (const NCollection_DoubleMap& theMap) :
NCollection_BaseMap::Iterator(theMap) {}
//! Query if the end of collection is reached by iterator
virtual Standard_Boolean More(void) const
{ return PMore(); }
//! Make a step along the collection
virtual void Next(void)
{ PNext(); }
//! Key1 inquiry
const TheKey1Type& Key1(void) const
{
#if !defined No_Exception && !defined No_Standard_NoSuchObject
if (!More())
Standard_NoSuchObject::Raise ("NCollection_DoubleMap::Iterator::Key1");
#endif
return ((DoubleMapNode *) myNode)->Key1();
}
//! Key2 inquiry
const TheKey2Type& Key2(void) const
{
#if !defined No_Exception && !defined No_Standard_NoSuchObject
if (!More())
Standard_NoSuchObject::Raise ("NCollection_DoubleMap::Iterator::Key2");
#endif
return ((DoubleMapNode *) myNode)->Key2();
}
//! Value access
virtual const TheKey2Type& Value(void) const
{
#if !defined No_Exception && !defined No_Standard_NoSuchObject
if (!More())
Standard_NoSuchObject::Raise ("NCollection_DoubleMap::Iterator::Value");
#endif
return ((DoubleMapNode *) myNode)->Value();
}
//! Value change access - denied
virtual TheKey2Type& ChangeValue(void) const
{
Standard_ImmutableObject::Raise("NCollection_DoubleMap::Iterator::ChangeValue");
return * (TheKey2Type *) NULL; // For compiler
}
//! Operator new for allocating iterators
void* operator new(size_t theSize,
const Handle(NCollection_BaseAllocator)& theAllocator)
{ return theAllocator->Allocate(theSize); }
};
public:
// ---------- PUBLIC METHODS ------------
//! Constructor
NCollection_DoubleMap (const Standard_Integer NbBuckets=1,
const Handle(NCollection_BaseAllocator)& theAllocator = 0L)
: NCollection_BaseCollection<TheKey2Type>(theAllocator),
NCollection_BaseMap (NbBuckets, Standard_False) {}
//! Copy constructor
NCollection_DoubleMap (const NCollection_DoubleMap& theOther)
: NCollection_BaseCollection<TheKey2Type>(theOther.myAllocator),
NCollection_BaseMap (theOther.NbBuckets(), Standard_False)
{ *this = theOther; }
//! Assign another collection
virtual void Assign(const NCollection_BaseCollection<TheKey2Type>& theOther)
{
if (this == &theOther)
return;
Standard_TypeMismatch::Raise ("NCollection_DoubleMap::Assign impossible");
}
//! = another map
NCollection_DoubleMap& operator=(const NCollection_DoubleMap& theOther)
{
if (this == &theOther)
return *this;
Clear(theOther.myAllocator);
ReSize (theOther.Extent()-1);
Iterator anIter(theOther);
for (; anIter.More(); anIter.Next())
{
TheKey1Type aKey1 = anIter.Key1();
TheKey2Type aKey2 = anIter.Key2();
Standard_Integer iK1 = HashCode (aKey1, NbBuckets());
Standard_Integer iK2 = HashCode (aKey2, NbBuckets());
DoubleMapNode * pNode = new (this->myAllocator) DoubleMapNode (aKey1, aKey2,
myData1[iK1],
myData2[iK2]);
myData1[iK1] = pNode;
myData2[iK2] = pNode;
Increment();
}
return *this;
}
//! ReSize
void ReSize (const Standard_Integer N)
{
DoubleMapNode** ppNewData1 = NULL;
DoubleMapNode** ppNewData2 = NULL;
Standard_Integer newBuck;
if (BeginResize (N, newBuck,
(NCollection_ListNode**&)ppNewData1,
(NCollection_ListNode**&)ppNewData2,
this->myAllocator))
{
if (myData1)
{
DoubleMapNode *p, *q;
Standard_Integer i, iK1, iK2;
for (i = 0; i <= NbBuckets(); i++)
{
if (myData1[i])
{
p = (DoubleMapNode *) myData1[i];
while (p)
{
iK1 = HashCode (p->Key1(), newBuck);
iK2 = HashCode (p->Key2(), newBuck);
q = (DoubleMapNode*) p->Next();
p->Next() = ppNewData1[iK1];
p->Next2() = ppNewData2[iK2];
ppNewData1[iK1] = p;
ppNewData2[iK2] = p;
p = q;
}
}
}
}
EndResize(N,newBuck,
(NCollection_ListNode**&)ppNewData1,
(NCollection_ListNode**&)ppNewData2,
this->myAllocator);
}
}
//! Bind
void Bind (const TheKey1Type& theKey1, const TheKey2Type& theKey2)
{
if (Resizable())
ReSize(Extent());
Standard_Integer iK1 = HashCode (theKey1, NbBuckets());
Standard_Integer iK2 = HashCode (theKey2, NbBuckets());
DoubleMapNode * pNode;
pNode = (DoubleMapNode *) myData1[iK1];
while (pNode)
{
if (IsEqual (pNode->Key1(), theKey1))
Standard_MultiplyDefined::Raise("NCollection_DoubleMap:Bind");
pNode = (DoubleMapNode *) pNode->Next();
}
pNode = (DoubleMapNode *) myData2[iK2];
while (pNode)
{
if (IsEqual (pNode->Key2(), theKey2))
Standard_MultiplyDefined::Raise("NCollection_DoubleMap:Bind");
pNode = (DoubleMapNode *) pNode->Next();
}
pNode = new (this->myAllocator) DoubleMapNode (theKey1, theKey2,
myData1[iK1], myData2[iK2]);
myData1[iK1] = pNode;
myData2[iK2] = pNode;
Increment();
}
//!* AreBound
Standard_Boolean AreBound (const TheKey1Type& theKey1,
const TheKey2Type& theKey2) const
{
if (IsEmpty())
return Standard_False;
Standard_Integer iK1 = HashCode (theKey1, NbBuckets());
Standard_Integer iK2 = HashCode (theKey2, NbBuckets());
DoubleMapNode * pNode1, * pNode2;
pNode1 = (DoubleMapNode *) myData1[iK1];
while (pNode1)
{
if (IsEqual(pNode1->Key1(), theKey1))
break;
pNode1 = (DoubleMapNode *) pNode1->Next();
}
if (pNode1 == NULL)
return Standard_False;
pNode2 = (DoubleMapNode *) myData2[iK2];
while (pNode2)
{
if (IsEqual(pNode2->Key2(), theKey2))
break;
pNode2 = (DoubleMapNode *) pNode2->Next();
}
if (pNode2 == NULL)
return Standard_False;
return (pNode1 == pNode2);
}
//! IsBound1
Standard_Boolean IsBound1 (const TheKey1Type& theKey1) const
{
if (IsEmpty())
return Standard_False;
Standard_Integer iK1 = HashCode (theKey1, NbBuckets());
DoubleMapNode * pNode1;
pNode1 = (DoubleMapNode *) myData1[iK1];
while (pNode1)
{
if (IsEqual(pNode1->Key1(), theKey1))
return Standard_True;
pNode1 = (DoubleMapNode *) pNode1->Next();
}
return Standard_False;
}
//! IsBound2
Standard_Boolean IsBound2 (const TheKey2Type& theKey2) const
{
if (IsEmpty())
return Standard_False;
Standard_Integer iK2 = HashCode (theKey2, NbBuckets());
DoubleMapNode * pNode2;
pNode2 = (DoubleMapNode *) myData2[iK2];
while (pNode2)
{
if (IsEqual(pNode2->Key2(), theKey2))
return Standard_True;
pNode2 = (DoubleMapNode *) pNode2->Next2();
}
return Standard_False;
}
//! UnBind1
Standard_Boolean UnBind1 (const TheKey1Type& theKey1)
{
if (IsEmpty())
return Standard_False;
Standard_Integer iK1 = HashCode (theKey1, NbBuckets());
DoubleMapNode * p1, * p2, * q1, *q2;
q1 = q2 = NULL;
p1 = (DoubleMapNode *) myData1[iK1];
while (p1)
{
if (IsEqual (p1->Key1(), theKey1))
{
// remove from the data1
if (q1)
q1->Next() = p1->Next();
else
myData1[iK1] = (DoubleMapNode*) p1->Next();
Standard_Integer iK2 = HashCode (p1->Key2(), NbBuckets());
p2 = (DoubleMapNode *) myData2[iK2];
while (p2)
{
if (p2 == p1)
{
// remove from the data2
if (q2)
q2->Next2() = p2->Next2();
else
myData2[iK2] = (DoubleMapNode*) p2->Next2();
break;
}
q2 = p2;
p2 = (DoubleMapNode*) p2->Next2();
}
p1->~DoubleMapNode();
this->myAllocator->Free(p1);
Decrement();
return Standard_True;
}
q1 = p1;
p1 = (DoubleMapNode*) p1->Next();
}
return Standard_False;
}
//! UnBind2
Standard_Boolean UnBind2 (const TheKey2Type& theKey2)
{
if (IsEmpty())
return Standard_False;
Standard_Integer iK2 = HashCode (theKey2, NbBuckets());
DoubleMapNode * p1, * p2, * q1, *q2;
q1 = q2 = NULL;
p2 = (DoubleMapNode *) myData2[iK2];
while (p2)
{
if (IsEqual (p2->Key2(), theKey2))
{
// remove from the data2
if (q2)
q2->Next() = p2->Next();
else
myData2[iK2] = (DoubleMapNode*) p2->Next2();
Standard_Integer iK1 = HashCode (p2->Key1(), NbBuckets());
p1 = (DoubleMapNode *) myData1[iK1];
while (p1)
{
if (p1 == p2)
{
// remove from the data1
if (q1)
q1->Next() = p1->Next();
else
myData1[iK1] = (DoubleMapNode*) p1->Next();
break;
}
q1 = p1;
p1 = (DoubleMapNode*) p1->Next();
}
p2->~DoubleMapNode();
this->myAllocator->Free(p2);
Decrement();
return Standard_True;
}
q2 = p2;
p2 = (DoubleMapNode*) p2->Next2();
}
return Standard_False;
}
//! Find1
const TheKey2Type& Find1(const TheKey1Type& theKey1) const
{
#if !defined No_Exception && !defined No_Standard_NoSuchObject
if (IsEmpty())
Standard_NoSuchObject::Raise ("NCollection_DoubleMap::Find1");
#endif
DoubleMapNode * pNode1 =
(DoubleMapNode *) myData1[HashCode(theKey1,NbBuckets())];
while (pNode1)
{
if (IsEqual (pNode1->Key1(), theKey1))
return pNode1->Key2();
pNode1 = (DoubleMapNode*) pNode1->Next();
}
Standard_NoSuchObject::Raise("NCollection_DoubleMap::Find1");
return pNode1->Key2(); // This for compiler
}
//! Find2
const TheKey1Type& Find2(const TheKey2Type& theKey2) const
{
#if !defined No_Exception && !defined No_Standard_NoSuchObject
if (IsEmpty())
Standard_NoSuchObject::Raise ("NCollection_DoubleMap::Find2");
#endif
DoubleMapNode * pNode2 =
(DoubleMapNode *) myData2[HashCode(theKey2,NbBuckets())];
while (pNode2)
{
if (IsEqual (pNode2->Key2(), theKey2))
return pNode2->Key1();
pNode2 = (DoubleMapNode*) pNode2->Next2();
}
Standard_NoSuchObject::Raise("NCollection_DoubleMap::Find2");
return pNode2->Key1(); // This for compiler
}
//! Clear data. If doReleaseMemory is false then the table of
//! buckets is not released and will be reused.
void Clear(const Standard_Boolean doReleaseMemory = Standard_True)
{ Destroy (DoubleMapNode::delNode, this->myAllocator, doReleaseMemory); }
//! Clear data and reset allocator
void Clear (const Handle(NCollection_BaseAllocator)& theAllocator)
{
Clear();
this->myAllocator = ( ! theAllocator.IsNull() ? theAllocator :
NCollection_BaseAllocator::CommonBaseAllocator() );
}
//! Destructor
~NCollection_DoubleMap (void)
{ Clear(); }
//! Size
virtual Standard_Integer Size(void) const
{ return Extent(); }
private:
// ----------- PRIVATE METHODS -----------
//! Creates Iterator for use on BaseCollection
virtual TYPENAME NCollection_BaseCollection<TheKey2Type>::Iterator&
CreateIterator(void) const
{ return *(new (this->IterAllocator()) Iterator(*this)); }
};
#ifdef WNT
#pragma warning (pop)
#endif
#endif

View File

@@ -0,0 +1,210 @@
// File: NCollection_EBTree.hxx
// Created: 30.07.02 09:51:33
// Author: Michael SAZONOV
// Copyright: Open CASCADE 2002
#ifndef NCollection_EBTree_HeaderFile
#define NCollection_EBTree_HeaderFile
#include <NCollection_UBTree.hxx>
#include <Standard_DefineHandle.hxx>
#include <MMgt_TShared.hxx>
#include <NCollection_List.hxx>
#include <TColStd_SequenceOfInteger.hxx>
#include <NCollection_DataMap.hxx>
/**
* The algorithm of unbalanced binary tree of overlapped bounding boxes with
* the possibility of deleting objects from the tree.
*
* In addition to the requirements to the object type defined in the parent
* class this class requires that the object can be hashed and compared to
* another object (functions HashCode and IsEqual are defined for it), since
* the class NCollection_DataMap is used where the object plays the role of
* the key.
*/
template <class TheObjType, class TheBndType> class NCollection_EBTree
: public NCollection_UBTree <TheObjType, TheBndType>
{
public:
typedef NCollection_UBTree <TheObjType, TheBndType> UBTree;
typedef TYPENAME UBTree::TreeNode TreeNode;
// ---------- PUBLIC METHODS ----------
/**
* Constructor.
*/
NCollection_EBTree (const Handle(NCollection_BaseAllocator)& theAllocator=0L)
: UBTree (theAllocator) {}
/**
* Extends the functionality of the parent method by maintaining
* the map myObjNodeMap. Redefined virtual method
* @return
* False if the tree already contains theObj.
*/
Standard_EXPORT Standard_Boolean Add (const TheObjType& theObj,
const TheBndType& theBnd);
/**
* Removes the given object and updates the tree.
* @return
* False if the tree does not contain theObj
*/
Standard_EXPORT Standard_Boolean Remove (const TheObjType& theObj);
/**
* @return
* True if the tree contains the object.
*/
Standard_Boolean Contains (const TheObjType& theObj) const
{ return myObjNodeMap.IsBound (theObj); }
/**
* @return
* The leaf node containing the object.
*/
const TreeNode& FindNode (const TheObjType& theObj) const
{ return *myObjNodeMap.Find (theObj); }
/**
* Clears the contents of the tree. Redefined virtual method
*/
void Clear (const Handle(NCollection_BaseAllocator)& aNewAlloc = 0L)
{ myObjNodeMap.Clear(); UBTree::Clear(aNewAlloc); }
private:
// ---------- PRIVATE METHODS ----------
/// Copy constructor (prohibited).
NCollection_EBTree (const NCollection_EBTree&);
/// Assignment operator (prohibited).
NCollection_EBTree& operator = (const NCollection_EBTree&);
// ---------- PRIVATE FIELDS ----------
NCollection_DataMap <TheObjType, TreeNode*>
myObjNodeMap; ///< map of object to node pointer
};
// ================== METHODS TEMPLATES =====================
//=======================================================================
//function : Add
//purpose : Updates the tree with a new object and its bounding box.
// Returns false if the tree already contains theObj.
//=======================================================================
template <class TheObjType, class TheBndType>
Standard_Boolean NCollection_EBTree<TheObjType,TheBndType>::Add
(const TheObjType& theObj,
const TheBndType& theBnd)
{
Standard_Boolean result = Standard_False;
if (!Contains (theObj)) {
// Add object in the tree using parent method
UBTree::Add (theObj, theBnd);
// Update the map
TreeNode& aNewNode = ChangeLastNode();
myObjNodeMap.Bind (theObj, &aNewNode);
// If the new node is not the root (has a parent) check the neighbour node
if (!aNewNode.IsRoot()) {
TreeNode& aNeiNode = aNewNode.ChangeParent().ChangeChild(0);
if (aNeiNode.IsLeaf()) {
myObjNodeMap.UnBind (aNeiNode.Object());
myObjNodeMap.Bind (aNeiNode.Object(), &aNeiNode);
}
}
result = Standard_True;
}
return result;
}
//=======================================================================
//function : Remove
//purpose : Removes the given object and updates the tree.
// Returns false if the tree does not contain theObj.
//=======================================================================
template <class TheObjType, class TheBndType>
Standard_Boolean NCollection_EBTree<TheObjType,TheBndType>::Remove
(const TheObjType& theObj)
{
Standard_Boolean result = Standard_False;
if (Contains (theObj)) {
TreeNode* pNode = myObjNodeMap (theObj);
if (pNode->IsRoot()) {
// it is the root, so clear all the tree
Clear();
}
else {
// it is a child of some parent,
// so kill the child that contains theObj
// and update bounding boxes of all ancestors
myObjNodeMap.UnBind (theObj);
TreeNode* pParent = &pNode->ChangeParent();
pParent->Kill ((pNode == &pParent->Child(0) ? 0 : 1),
this->Allocator());
if (pParent->IsLeaf()) {
// the parent node became a leaf, so update the map
myObjNodeMap.UnBind (pParent->Object());
myObjNodeMap.Bind (pParent->Object(), pParent);
}
while (!pParent->IsRoot()) {
pParent = &pParent->ChangeParent();
pParent->ChangeBnd() = pParent->Child(0).Bnd();
pParent->ChangeBnd().Add (pParent->Child(1).Bnd());
}
}
result = Standard_True;
}
return result;
}
// ======================================================================
// Declaration of handled version of NCollection_EBTree.
// In the macros below the arguments are:
// _HEBTREE - the desired name of handled class
// _OBJTYPE - the name of the object type
// _BNDTYPE - the name of the bounding box type
// _HUBTREE - the name of parent class
// (defined using macro DEFINE_HUBTREE)
#define DEFINE_HEBTREE(_HEBTREE, _OBJTYPE, _BNDTYPE, _HUBTREE) \
class _HEBTREE : public _HUBTREE \
{ \
public: \
typedef NCollection_UBTree <_OBJTYPE, _BNDTYPE> UBTree; \
typedef NCollection_EBTree <_OBJTYPE, _BNDTYPE> EBTree; \
\
_HEBTREE () : _HUBTREE(new EBTree) {} \
/* Empty constructor */ \
\
/* Access to the methods of EBTree */ \
\
Standard_Boolean Remove (const _OBJTYPE& theObj) \
{ return ChangeETree().Remove (theObj); } \
\
Standard_Boolean Contains (const _OBJTYPE& theObj) const \
{ return ETree().Contains (theObj); } \
\
const UBTree::TreeNode& FindNode (const _OBJTYPE& theObj) const \
{ return ETree().FindNode (theObj); } \
\
/* Access to the extended tree algorithm */ \
\
const EBTree& ETree () const { return (const EBTree&) Tree(); } \
EBTree& ChangeETree () { return (EBTree&) ChangeTree(); } \
\
DEFINE_STANDARD_RTTI (_HEBTREE) \
/* Type management */ \
}; \
DEFINE_STANDARD_HANDLE (_HEBTREE, _HUBTREE)
#define IMPLEMENT_HEBTREE(_HEBTREE, _HUBTREE) \
IMPLEMENT_STANDARD_HANDLE (_HEBTREE, _HUBTREE) \
IMPLEMENT_STANDARD_RTTIEXT(_HEBTREE, _HUBTREE)
#endif

View File

@@ -0,0 +1,18 @@
// File: NCollection_HArray1.hxx
// Created: Mon Apr 29 11:36:31 2002
// Author: Alexander KARTOMIN (akm)
// <a-kartomin@opencascade.com>
// Copyright: Open Cascade 2002
#ifndef NCollection_HArray1_HeaderFile
#define NCollection_HArray1_HeaderFile
#include <NCollection_Array1.hxx>
#include <NCollection_DefineHArray1.hxx>
// Declaration of Array1 class managed by Handle
#define NCOLLECTION_HARRAY1(HClassName,Type) \
DEFINE_HARRAY1(HClassName,NCollection_Array1<Type >)
#endif

View File

@@ -0,0 +1,18 @@
// File: NCollection_HArray2.hxx
// Created: Mon Apr 29 11:36:31 2002
// Author: Alexander KARTOMIN (akm)
// <a-kartomin@opencascade.com>
// Copyright: Open Cascade 2002
#ifndef NCollection_HArray2_HeaderFile
#define NCollection_HArray2_HeaderFile
#include <NCollection_Array2.hxx>
#include <NCollection_DefineHArray2.hxx>
// Declaration of Array2 class managed by Handle
#define NCOLLECTION_HARRAY2(HClassName,Type) \
DEFINE_HARRAY2(HClassName,NCollection_Array2<Type >)
#endif

View File

@@ -0,0 +1,17 @@
// File: NCollection_HSequence.hxx
// Created: 29.01.01 12:58:53
// Author: Alexander GRIGORIEV
// Copyright: Open Cascade 2002
#ifndef NCollection_HSequence_HeaderFile
#define NCollection_HSequence_HeaderFile
#include <NCollection_DefineHSequence.hxx>
#include <NCollection_Sequence.hxx>
// Declaration of Sequence class managed by Handle
#define NCOLLECTION_HSEQUENCE(HClassName,Type) \
DEFINE_HSEQUENCE(HClassName,NCollection_Sequence<Type >)
#endif

View File

@@ -0,0 +1,17 @@
// File: NCollection_HSet.hxx
// Created: Mon Apr 29 12:34:55 2002
// Author: Alexander KARTOMIN (akm)
// <a-kartomin@opencascade.com>
#ifndef NCollection_HSet_HeaderFile
#define NCollection_HSet_HeaderFile
#include <NCollection_DefineHSet.hxx>
#include <NCollection_Set.hxx>
// Declaration of Set class managed by Handle
#define NCOLLECTION_HSET(HClassName,Type) \
DEFINE_HSET(HClassName,NCollection_Set<Type >)
#endif

View File

@@ -0,0 +1,24 @@
// File: NCollection_Handle.cxx
// Created: Fri Jan 30 15:15:17 2009
// Author: Andrey BETENEV (abv)
// Copyright: Open CASCADE 2009
#include <NCollection_Handle.hxx>
// NOTE: OCCT type information functions are defined explicitly
// instead of using macros from Standard_DefineHandle.hxx,
// since class NCollection_Handle is template and this is not supported
static Handle(Standard_Type) aTypeNCollection_Handle =
STANDARD_TYPE(NCollection_Handle);
const Handle(Standard_Type)& STANDARD_TYPE(NCollection_Handle)
{
static Handle(Standard_Transient) _Ancestors[] =
{ STANDARD_TYPE(Standard_Transient), NULL, };
static Handle(Standard_Type) _aType =
new Standard_Type("NCollection_Handle",
sizeof(NCollection_Handle<Standard_Transient>),
1, (Standard_Address)_Ancestors, (Standard_Address)NULL);
return _aType;
}

View File

@@ -0,0 +1,97 @@
// File: NCollection_Handle.hxx
// Created: Fri Jan 30 15:15:17 2009
// Author: Andrey BETENEV (abv)
// Copyright: Open CASCADE 2009
#ifndef NCollection_Handle_HeaderFile
#define NCollection_Handle_HeaderFile
#include <MMgt_TShared.hxx>
//! Standard type function allowing to check that contained object is Handle
Standard_EXPORT const Handle(Standard_Type)& STANDARD_TYPE(NCollection_Handle);
//! Purpose: This template class is used to define Handle adaptor
//! for allocated dynamically objects of arbitrary type.
//!
//! The advantage is that this handle will automatically destroy
//! the object when last referred Handle is destroyed (i.e. it is a
//! typical smart pointer), and that it can be handled as
//! Handle(Standard_Transient) in OCCT components.
//!
//! Use it as follows:
//!
//! NCollection_Handle<T> aPtr = new T (...);
//!
//! aPtr->Method(...);
//!
//! Handle(Standard_Transient) aBase = aPtr;
//! if ( aBase->IsKind(STANDARD_TYPE(NCollection_Handle)) )
//! {
//! NCollection_Handle<T> aPtr2 = NCollection_Handle<T>::DownCast (aBase);
//! if ( ! aPtr2.IsNull() )
//! aPtr2->Method2();
//! }
template <class T>
class NCollection_Handle : public Handle_Standard_Transient
{
private:
//! Internal adaptor class wrapping actual type
//! and enhancing it by reference counter inherited from
//! Standard_Transient
class Ptr : public Standard_Transient
{
public:
//! Constructor: stores pointer to the object
Ptr (T* theObj) { myPtr = theObj; }
//! Destructor deletes the object
~Ptr () { if ( myPtr ) delete myPtr; myPtr = 0; }
//! Implementation of DynamicType() method
const Handle(Standard_Type)& DynamicType() const
{ return STANDARD_TYPE(NCollection_Handle); }
public:
T* myPtr; //!< Pointer to the object
};
//! Constructor of handle from pointer on newly allocated object.
//! Note that additional argument is used to avoid ambiguity with
//! public constructor from pointer when Handle is intilialized by 0.
NCollection_Handle (Ptr* thePtr, int)
: Handle_Standard_Transient (thePtr) {}
public:
//! Default constructor; creates null handle
NCollection_Handle () {}
//! Constructor of handle from pointer on newly allocated object
NCollection_Handle (T* theObject)
: Handle_Standard_Transient (theObject ? new Ptr (theObject) : 0) {}
//! Cast handle to contained type
T* operator -> () { return ((Ptr*)ControlAccess())->myPtr; }
//! Cast handle to contained type
const T* operator -> () const { return ((Ptr*)ControlAccess())->myPtr; }
//! Cast handle to contained type
T& operator * () { return *((Ptr*)ControlAccess())->myPtr; }
//! Cast handle to contained type
const T& operator * () const { return *((Ptr*)ControlAccess())->myPtr; }
//! Downcast arbitrary Handle to the argument type if contained
//! object is Handle for this type; returns null otherwise
static NCollection_Handle<T> DownCast (const Handle(Standard_Transient)& theOther)
{
return NCollection_Handle<T> (theOther.IsNull() ? 0 : dynamic_cast<Ptr*> (theOther.operator->()), 0);
}
};
#endif

View File

@@ -0,0 +1,59 @@
// File: NCollection_HeapAllocator.cxx
// Created: 30.12.09 00:38
// Author: Alexander GRIGORIEV
// Copyright: Open Cascade 2009
#include <NCollection_HeapAllocator.hxx>
#include <Standard_OutOfMemory.hxx>
#include <Standard_Mutex.hxx>
IMPLEMENT_STANDARD_HANDLE (NCollection_HeapAllocator, NCollection_BaseAllocator)
IMPLEMENT_STANDARD_RTTIEXT(NCollection_HeapAllocator, NCollection_BaseAllocator)
//=======================================================================
//function : Allocate
//purpose :
//=======================================================================
void * NCollection_HeapAllocator::Allocate (const Standard_Size theSize)
{
// the size is rounded up to word size.
const Standard_Size aRoundSize = (theSize + 3) & ~0x3;
void * pResult = malloc(aRoundSize);
if (!pResult) {
char buf[128];
sprintf (buf, "Failed to allocate %d bytes in global dynamic heap",theSize);
Standard_OutOfMemory::Raise(&buf[0]);
}
return pResult;
}
//=======================================================================
//function : Free
//purpose :
//=======================================================================
void NCollection_HeapAllocator::Free (void * anAddress)
{
if (anAddress) free(anAddress);
}
//=======================================================================
//function : GlobalHeapAllocator
//purpose :
//=======================================================================
const Handle_NCollection_HeapAllocator&
NCollection_HeapAllocator::GlobalHeapAllocator()
{
static Handle(NCollection_HeapAllocator) pAllocator;
if (pAllocator.IsNull()) {
static Standard_Mutex theMutex;
Standard_Mutex::Sentry aSentry (theMutex);
if (pAllocator.IsNull()) {
pAllocator = new NCollection_HeapAllocator;
}
}
return pAllocator;
}

View File

@@ -0,0 +1,44 @@
// File: NCollection_HeapAllocator.hxx
// Created: 30.12.09 00:33
// Author: Alexander GRIGORIEV
// Copyright: Open Cascade 2009
#ifndef NCollection_HeapAllocator_HeaderFile
#define NCollection_HeapAllocator_HeaderFile
#include <NCollection_BaseAllocator.hxx>
class Handle_NCollection_HeapAllocator;
/**
* Allocator that uses the global dynamic heap (malloc / free).
*/
class NCollection_HeapAllocator : public NCollection_BaseAllocator
{
public:
// ---------- PUBLIC METHODS ----------
Standard_EXPORT virtual void* Allocate (const Standard_Size theSize);
Standard_EXPORT virtual void Free (void * anAddress);
Standard_EXPORT static const Handle_NCollection_HeapAllocator&
GlobalHeapAllocator();
protected:
//! Constructor - prohibited
NCollection_HeapAllocator(void) {};
private:
//! Copy constructor - prohibited
NCollection_HeapAllocator(const NCollection_HeapAllocator&);
public:
// Declaration of CASCADE RTTI
DEFINE_STANDARD_RTTI (NCollection_HeapAllocator)
};
// Definition of HANDLE object using Standard_DefineHandle.hxx
DEFINE_STANDARD_HANDLE (NCollection_HeapAllocator, NCollection_BaseAllocator)
#endif

View File

@@ -0,0 +1,245 @@
// File: NCollection_IncAllocator.cxx
// Created: 12.04.02 21:16:26
// Author: Alexander GRIGORIEV
// Copyright: Open Cascade 2002
#include <NCollection_IncAllocator.hxx>
#include <Standard_OutOfMemory.hxx>
#include <stdio.h>
IMPLEMENT_STANDARD_HANDLE (NCollection_IncAllocator,NCollection_BaseAllocator)
IMPLEMENT_STANDARD_RTTIEXT (NCollection_IncAllocator,NCollection_BaseAllocator)
#define IMEM_SIZE(_size) ((((_size) - 1)/sizeof(aligned_t)) + 1)
#define IMEM_FREE(p_bl) ((unsigned int)(p_bl->p_end_block - p_bl->p_free_space))
#define IMEM_ALIGN(_addr) (sizeof(aligned_t)* IMEM_SIZE((unsigned long)(_addr)))
#define MaxLookup 16
//=======================================================================
//function : NCollection_IncAllocator()
//purpose : Constructor
//=======================================================================
NCollection_IncAllocator::NCollection_IncAllocator (const size_t theBlockSize)
{
#ifdef ALLOC_TRACK_USAGE
printf ("\n..NCollection_IncAllocator: Created (%x)\n",this);
#endif
const size_t aSize = IMEM_SIZE(sizeof(IBlock)) +
IMEM_SIZE((theBlockSize > 2*sizeof(IBlock)) ? theBlockSize : 24600);
IBlock * const aBlock = (IBlock *) malloc (aSize * sizeof(aligned_t));
myFirstBlock = aBlock;
mySize = aSize;
if (aBlock == NULL)
Standard_OutOfMemory::Raise("NCollection_IncAllocator: out of memory");
aBlock -> p_free_space = (aligned_t *) IMEM_ALIGN (&aBlock[1]);
aBlock -> p_end_block = ((aligned_t *) aBlock) + aSize;
aBlock -> p_next = NULL;
}
//=======================================================================
//function : ~NCollection_IncAllocator
//purpose : Destructor
//=======================================================================
NCollection_IncAllocator::~NCollection_IncAllocator ()
{
Clean();
free (myFirstBlock);
}
//=======================================================================
//function : Allocate
//purpose : allocate a memory
//remark : returns NULL if allocation fails
//=======================================================================
void * NCollection_IncAllocator::Allocate (const size_t aSize)
{
aligned_t * aResult = NULL;
const size_t cSize = aSize ? IMEM_SIZE(aSize) : 0;
if (cSize > mySize) {
/* If the requested size exceeds normal allocation size, allocate
a separate block and place it as the head of the list */
aResult = (aligned_t *) allocateNewBlock (cSize+1);
if (aResult)
myFirstBlock -> p_free_space = myFirstBlock -> p_end_block;
} else
if (cSize <= IMEM_FREE(myFirstBlock)) {
/* If the requested size fits into the free space in the 1st block */
aResult = myFirstBlock -> allocateInBlock (cSize);
} else {
/* Search for a block in the list with enough free space */
int aMaxLookup = MaxLookup; /* limit the number of blocks to query */
IBlock * aCurrentBlock = myFirstBlock -> p_next;
while (aCurrentBlock && aMaxLookup--) {
if (cSize <= IMEM_FREE(aCurrentBlock)) {
aResult = aCurrentBlock -> allocateInBlock (cSize);
break;
}
aCurrentBlock = aCurrentBlock -> p_next;
}
if (aResult == NULL) {
/* There is no available block with enough free space. Create a new
one and place it in the head of the list */
aResult = (aligned_t *) allocateNewBlock (mySize);
if (aResult)
myFirstBlock -> p_free_space = aResult + cSize;
}
}
return aResult;
}
//=======================================================================
//function : Reallocate
//purpose :
//=======================================================================
void * NCollection_IncAllocator::Reallocate (void * theAddress,
const size_t oldSize,
const size_t newSize)
{
// Check that the dummy parameters are OK
if (theAddress == NULL || oldSize == 0)
return Allocate (newSize);
const size_t cOldSize = IMEM_SIZE(oldSize);
const size_t cNewSize = newSize ? IMEM_SIZE(newSize) : 0;
aligned_t * anAddress = (aligned_t *) theAddress;
// We check only the LAST allocation to do the real extension/contraction
if (anAddress + cOldSize == myFirstBlock -> p_free_space) {
myFirstBlock -> p_free_space = anAddress;
// If the new size fits into the memory block => OK
// This also includes any case of contraction
if (cNewSize <= IMEM_FREE(myFirstBlock)) {
myFirstBlock -> p_free_space += cNewSize;
return anAddress;
}
}
// In case of contraction of non-terminating allocation, do nothing
else if (cOldSize >= cNewSize)
return anAddress;
// Extension of non-terminated allocation if there is enough room in the
// current memory block
if (cNewSize <= IMEM_FREE(myFirstBlock)) {
aligned_t * aResult = myFirstBlock -> allocateInBlock (cNewSize);
if (aResult)
for (unsigned i = 0; i < cOldSize; i++)
aResult[i] = anAddress[i];
return aResult;
}
// This is either of the cases:
// - extension of non-terminating allocation, or
// - extension of terminating allocation when the new size is too big
// In both cases create a new memory block, allocate memory and copy there
// the reallocated memory.
aligned_t * aResult = (aligned_t *) allocateNewBlock (mySize);
if (aResult) {
myFirstBlock -> p_free_space = aResult + cNewSize;
for (unsigned i = 0; i < cOldSize; i++)
aResult[i] = anAddress[i];
}
return aResult;
}
//=======================================================================
//function : Free
//purpose :
//=======================================================================
void NCollection_IncAllocator::Free (void *)
{}
//=======================================================================
//function : Clean
//purpose :
//=======================================================================
void NCollection_IncAllocator::Clean ()
{
#ifdef ALLOC_TRACK_USAGE
printf ("\n..NCollection_IncAllocator: Memory size to clean:%8.1f kB (%x)\n",
double(GetMemSize())/1024, this);
#endif
IBlock * aBlock = myFirstBlock;
if (aBlock) {
aBlock -> p_free_space = (aligned_t *) &aBlock[1];
aBlock = aBlock -> p_next;
while (aBlock) {
IBlock * aNext = aBlock -> p_next;
free (aBlock);
aBlock = aNext;
}
myFirstBlock -> p_next = NULL;
}
}
//=======================================================================
//function : Reset
//purpose :
//=======================================================================
void NCollection_IncAllocator::Reset (const Standard_Boolean doReleaseMem)
{
if (doReleaseMem)
Clean();
else {
Standard_Integer aBlockCount(0);
IBlock * aBlock = myFirstBlock;
while (aBlock)
if (aBlockCount++ < MaxLookup) {
aBlock -> p_free_space = (aligned_t *) &aBlock[1];
if (aBlockCount < MaxLookup)
aBlock = aBlock -> p_next;
else {
IBlock * aNext = aBlock -> p_next;
aBlock -> p_next = NULL;
aBlock = aNext;
}
} else {
IBlock * aNext = aBlock -> p_next;
free (aBlock);
aBlock = aNext;
}
}
}
//=======================================================================
//function : GetMemSize
//purpose : diagnostic utility
//=======================================================================
size_t NCollection_IncAllocator::GetMemSize () const
{
size_t aResult = 0;
IBlock * aBlock = myFirstBlock;
while (aBlock) {
aResult += (aBlock -> p_end_block - (aligned_t *) aBlock);
aBlock = aBlock -> p_next;
}
return aResult * sizeof (aligned_t);
}
//=======================================================================
//function : allocateNewBlock
//purpose :
//=======================================================================
void * NCollection_IncAllocator::allocateNewBlock (const size_t cSize)
{
aligned_t * aResult = 0L;
const size_t aSz = cSize + IMEM_SIZE(sizeof(IBlock));
IBlock * aBlock = (IBlock *) malloc (aSz * sizeof(aligned_t));
if (aBlock) {
aBlock -> p_end_block = ((aligned_t *)aBlock) + aSz;
aBlock -> p_next = myFirstBlock;
myFirstBlock = aBlock;
aResult = (aligned_t *) IMEM_ALIGN(&aBlock[1]);
}
else
Standard_OutOfMemory::Raise("NCollection_IncAllocator: out of memory");
return aResult;
}

View File

@@ -0,0 +1,109 @@
// File: NCollection_IncAllocator.hxx
// Created: 12.04.02 19:45:14
// Author: Alexander GRIGORIEV
// Copyright: Open Cascade 2002
#ifndef NCollection_IncAllocator_HeaderFile
#define NCollection_IncAllocator_HeaderFile
#include <NCollection_BaseAllocator.hxx>
/**
* Class NCollection_IncAllocator - incremental memory allocator. This class
* allocates memory on request returning the pointer to an allocated
* block. This memory is never returned to the system until the allocator is
* destroyed.
*
* By comparison with the standard new() and malloc() calls, this method is
* faster and consumes very small additional memory to maintain the heap.
*
* All pointers returned by Allocate() are aligned to the size of the data
* type "aligned_t". To modify the size of memory blocks requested from the
* OS, use the parameter of the constructor (measured in bytes); if this
* parameter is smaller than 25 bytes on 32bit or 49 bytes on 64bit, the
* block size will be the default 24 kbytes
*/
class NCollection_IncAllocator : public NCollection_BaseAllocator
{
public:
// The type defining the alignement of allocated objects
typedef void * aligned_t;
// ---------- PUBLIC METHODS ----------
//! Constructor
Standard_EXPORT NCollection_IncAllocator (const size_t theBlockSize = 24600);
//! Allocate memory with given size. Returns NULL on failure
Standard_EXPORT virtual void* Allocate (const size_t size);
//! Free a previously allocated memory. Does nothing
Standard_EXPORT virtual void Free (void *anAddress);
//! Diagnostic method, returns the number of bytes totally allocated
Standard_EXPORT size_t GetMemSize () const;
//! Destructor (calls Clean() internally)
Standard_EXPORT ~NCollection_IncAllocator ();
//! Reallocation: it is always allowed but is only efficient with the
//! last allocated item
Standard_EXPORT void * Reallocate (void * anAddress,
const size_t oldSize,
const size_t newSize);
//! Re-initialize the allocator so that the next Allocate call should
//! start allocating in the very begining as though the allocator is just
//! constructed. Warning: make sure that all previously allocated data are
//! no more used in your code!
//! @param doReleaseMem
//! True - release all previously allocated memory, False - preserve it
//! for future allocations.
Standard_EXPORT void Reset (const Standard_Boolean
doReleaseMem=Standard_True);
protected:
struct IBlock;
//! Flush all previously allocated data. All pointers returned by
//! Allocate() become invalid -- be very careful with this
Standard_EXPORT void Clean ();
//! Allocate a new block and return a pointer to it
//! ** only for internal usage **
void * allocateNewBlock (const size_t cSize);
private:
// Prohibited methods
NCollection_IncAllocator (const NCollection_IncAllocator&);
NCollection_IncAllocator& operator = (const NCollection_IncAllocator&);
protected:
// ----- PROTECTED CLASS IBlock -------
struct IBlock {
aligned_t * allocateInBlock (const size_t cSize)
{
aligned_t * aResult = p_free_space;
p_free_space += cSize;
return aResult;
}
aligned_t * p_free_space;
aligned_t * p_end_block;
struct IBlock * p_next;
};
protected:
// --------- PROTECTED FIELDS ---------
IBlock * myFirstBlock;
size_t mySize;
public:
// Declaration of CASCADE RTTI
DEFINE_STANDARD_RTTI (NCollection_IncAllocator)
};
// Definition of HANDLE object using Standard_DefineHandle.hxx
DEFINE_STANDARD_HANDLE (NCollection_IncAllocator, NCollection_BaseAllocator)
#endif

View File

@@ -0,0 +1,505 @@
// File: NCollection_IndexedDataMap.hxx
// Created: Thu Apr 24 15:02:53 2002
// Author: Alexander KARTOMIN (akm)
// <akm@opencascade.com>
#ifndef NCollection_IndexedDataMap_HeaderFile
#define NCollection_IndexedDataMap_HeaderFile
#include <NCollection_BaseCollection.hxx>
#include <NCollection_BaseMap.hxx>
#include <NCollection_TListNode.hxx>
#include <Standard_TypeMismatch.hxx>
#include <Standard_NoSuchObject.hxx>
#if !defined No_Exception && !defined No_Standard_OutOfRange
#include <Standard_OutOfRange.hxx>
#endif
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (push)
#pragma warning (disable:4291)
#endif
/**
* Purpose: An indexed map is used to store keys and to bind
* an index to them. Each new key stored in the map
* gets an index. Index are incremented as keys are
* stored in the map. A key can be found by the index
* and an index by the key. No key but the last can
* be removed so the indices are in the range 1..
* Extent. An Item is stored with each key.
*
* This class is similar to IndexedMap from
* NCollection with the Item as a new feature. Note
* the important difference on the operator (). In
* the IndexedMap this operator returns the Key. In
* the IndexedDataMap this operator returns the Item.
*
* See the class Map from NCollection for a
* discussion about the number of buckets.
*/
template <class TheKeyType, class TheItemType> class NCollection_IndexedDataMap
: public NCollection_BaseCollection<TheItemType>,
public NCollection_BaseMap
{
//! Adaptation of the TListNode to the INDEXEDDatamap
private:
class IndexedDataMapNode : public NCollection_TListNode<TheItemType>
{
public:
//! Constructor with 'Next'
IndexedDataMapNode (const TheKeyType& theKey1,
const Standard_Integer theKey2,
const TheItemType& theItem,
NCollection_ListNode* theNext1,
NCollection_ListNode* theNext2) :
NCollection_TListNode<TheItemType>(theItem,theNext1)
{
myKey1 = theKey1;
myKey2 = theKey2;
myNext2 = (IndexedDataMapNode *) theNext2;
}
//! Key1
TheKeyType& Key1 (void)
{ return myKey1; }
//! Key2
const Standard_Integer& Key2 (void)
{ return myKey2; }
//! Next2
IndexedDataMapNode*& Next2 (void)
{ return myNext2; }
//! Static deleter to be passed to BaseList
static void delNode (NCollection_ListNode * theNode,
Handle(NCollection_BaseAllocator)& theAl)
{
((IndexedDataMapNode *) theNode)->~IndexedDataMapNode();
theAl->Free(theNode);
}
private:
TheKeyType myKey1;
Standard_Integer myKey2;
IndexedDataMapNode * myNext2;
};
public:
//! Implementation of the Iterator interface.
class Iterator : public NCollection_BaseCollection<TheItemType>::Iterator
{
public:
//! Empty constructor
Iterator (void) :
myMap(NULL),
myIndex(0) {}
//! Constructor
Iterator (const NCollection_IndexedDataMap& theMap) :
myMap((NCollection_IndexedDataMap *) &theMap),
myIndex(1) {}
//! Query if the end of collection is reached by iterator
virtual Standard_Boolean More(void) const
{ return (myIndex <= myMap->Extent()); }
//! Make a step along the collection
virtual void Next(void)
{ myIndex++; }
//! Value access
virtual const TheItemType& Value(void) const
{
#if !defined No_Exception && !defined No_Standard_NoSuchObject
if (!More())
Standard_NoSuchObject::Raise("NCollection_IndexedDataMap::Iterator::Value");
#endif
return myMap->FindFromIndex(myIndex);
}
//! ChangeValue access
virtual TheItemType& ChangeValue(void) const
{
#if !defined No_Exception && !defined No_Standard_NoSuchObject
if (!More())
Standard_NoSuchObject::Raise("NCollection_IndexedDataMap::Iterator::ChangeValue");
#endif
return myMap->ChangeFromIndex(myIndex);
}
//! Operator new for allocating iterators
void* operator new(size_t theSize,
const Handle(NCollection_BaseAllocator)& theAllocator)
{ return theAllocator->Allocate(theSize); }
private:
NCollection_IndexedDataMap * myMap; //!< Pointer to the map being iterated
Standard_Integer myIndex; //!< Current index
};
public:
// ---------- PUBLIC METHODS ------------
//! Constructor
NCollection_IndexedDataMap (const Standard_Integer NbBuckets=1,
const Handle(NCollection_BaseAllocator)& theAllocator = 0L)
: NCollection_BaseCollection<TheItemType>(theAllocator),
NCollection_BaseMap (NbBuckets, Standard_False) {}
//! Copy constructor
NCollection_IndexedDataMap (const NCollection_IndexedDataMap& theOther)
: NCollection_BaseCollection<TheItemType>(theOther.myAllocator),
NCollection_BaseMap (theOther.NbBuckets(), Standard_False)
{ *this = theOther; }
//! Assign another collection
virtual void Assign(const NCollection_BaseCollection<TheItemType>& theOther)
{
if (this == &theOther)
return;
Standard_TypeMismatch::Raise("NCollection_IndexedDataMap::Assign");
}
//! = another map
NCollection_IndexedDataMap& operator=
(const NCollection_IndexedDataMap& theOther)
{
if (this == &theOther)
return *this;
Clear(theOther.myAllocator);
ReSize (theOther.Extent()-1);
Standard_Integer i;
for (i=1; i<=theOther.Extent(); i++)
{
TheKeyType aKey1 = theOther.FindKey(i);
TheItemType anItem = theOther.FindFromIndex(i);
Standard_Integer iK1 = HashCode (aKey1, NbBuckets());
Standard_Integer iK2 = HashCode (i, NbBuckets());
IndexedDataMapNode * pNode =
new (this->myAllocator) IndexedDataMapNode (aKey1, i, anItem,
myData1[iK1], myData2[iK2]);
myData1[iK1] = pNode;
myData2[iK2] = pNode;
Increment();
}
return *this;
}
//! ReSize
void ReSize (const Standard_Integer N)
{
IndexedDataMapNode** ppNewData1 = NULL;
IndexedDataMapNode** ppNewData2 = NULL;
Standard_Integer newBuck;
if (BeginResize (N, newBuck,
(NCollection_ListNode**&)ppNewData1,
(NCollection_ListNode**&)ppNewData2,
this->myAllocator))
{
if (myData1)
{
IndexedDataMapNode *p, *q;
Standard_Integer i, iK1, iK2;
for (i = 0; i <= NbBuckets(); i++)
{
if (myData1[i])
{
p = (IndexedDataMapNode *) myData1[i];
while (p)
{
iK1 = HashCode (p->Key1(), newBuck);
iK2 = HashCode (p->Key2(), newBuck);
q = (IndexedDataMapNode*) p->Next();
p->Next() = ppNewData1[iK1];
p->Next2() = ppNewData2[iK2];
ppNewData1[iK1] = p;
ppNewData2[iK2] = p;
p = q;
}
}
}
}
EndResize(N,newBuck,
(NCollection_ListNode**&)ppNewData1,
(NCollection_ListNode**&)ppNewData2,
this->myAllocator);
}
}
//! Add
Standard_Integer Add (const TheKeyType& theKey1, const TheItemType& theItem)
{
if (Resizable())
ReSize(Extent());
Standard_Integer iK1 = HashCode (theKey1, NbBuckets());
IndexedDataMapNode * pNode;
pNode = (IndexedDataMapNode *) myData1[iK1];
while (pNode)
{
if (IsEqual (pNode->Key1(), theKey1))
return pNode->Key2();
pNode = (IndexedDataMapNode *) pNode->Next();
}
Increment();
Standard_Integer iK2 = HashCode(Extent(),NbBuckets());
pNode = new (this->myAllocator) IndexedDataMapNode (theKey1, Extent(), theItem,
myData1[iK1], myData2[iK2]);
myData1[iK1] = pNode;
myData2[iK2] = pNode;
return Extent();
}
//! Contains
Standard_Boolean Contains (const TheKeyType& theKey1) const
{
if (IsEmpty())
return Standard_False;
Standard_Integer iK1 = HashCode (theKey1, NbBuckets());
IndexedDataMapNode * pNode1;
pNode1 = (IndexedDataMapNode *) myData1[iK1];
while (pNode1)
{
if (IsEqual(pNode1->Key1(), theKey1))
return Standard_True;
pNode1 = (IndexedDataMapNode *) pNode1->Next();
}
return Standard_False;
}
//! Substitute
void Substitute (const Standard_Integer theIndex,
const TheKeyType& theKey1,
const TheItemType& theItem)
{
#if !defined No_Exception && !defined No_Standard_OutOfRange
if (theIndex < 1 || theIndex > Extent())
Standard_OutOfRange::Raise ("NCollection_IndexedDataMap::Substitute");
#endif
IndexedDataMapNode * p;
// check if theKey1 is not already in the map
Standard_Integer iK1 = HashCode (theKey1, NbBuckets());
p = (IndexedDataMapNode *) myData1[iK1];
while (p)
{
if (IsEqual (p->Key1(), theKey1))
Standard_DomainError::Raise("NCollection_IndexedDataMap::Substitute");
p = (IndexedDataMapNode *) p->Next();
}
// Find the node for the index I
Standard_Integer iK2 = HashCode (theIndex, NbBuckets());
p = (IndexedDataMapNode *) myData2[iK2];
while (p)
{
if (p->Key2() == theIndex)
break;
p = (IndexedDataMapNode*) p->Next2();
}
// remove the old key
Standard_Integer iK = HashCode (p->Key1(), NbBuckets());
IndexedDataMapNode * q = (IndexedDataMapNode *) myData1[iK];
if (q == p)
myData1[iK] = (IndexedDataMapNode *) p->Next();
else
{
while (q->Next() != p)
q = (IndexedDataMapNode *) q->Next();
q->Next() = p->Next();
}
// update the node
p->Key1() = theKey1;
p->ChangeValue() = theItem;
p->Next() = myData1[iK1];
myData1[iK1] = p;
}
//! RemoveLast
void RemoveLast (void)
{
#if !defined No_Exception && !defined No_Standard_OutOfRange
if (Extent() == 0)
Standard_OutOfRange::Raise ("NCollection_IndexedDataMap::RemoveLast");
#endif
IndexedDataMapNode * p, * q;
// Find the node for the last index and remove it
Standard_Integer iK2 = HashCode (Extent(), NbBuckets());
p = (IndexedDataMapNode *) myData2[iK2];
q = NULL;
while (p)
{
if (p->Key2() == Extent())
break;
q = p;
p = (IndexedDataMapNode*) p->Next2();
}
if (q == NULL)
myData2[iK2] = (IndexedDataMapNode *) p->Next2();
else
q->Next2() = p->Next2();
// remove the key
Standard_Integer iK1 = HashCode (p->Key1(), NbBuckets());
q = (IndexedDataMapNode *) myData1[iK1];
if (q == p)
myData1[iK1] = (IndexedDataMapNode *) p->Next();
else
{
while (q->Next() != p)
q = (IndexedDataMapNode *) q->Next();
q->Next() = p->Next();
}
p->~IndexedDataMapNode();
this->myAllocator->Free(p);
Decrement();
}
//! FindKey
const TheKeyType& FindKey (const Standard_Integer theKey2) const
{
#if !defined No_Exception && !defined No_Standard_OutOfRange
if (theKey2 < 1 || theKey2 > Extent())
Standard_OutOfRange::Raise ("NCollection_IndexedDataMap::FindKey");
#endif
IndexedDataMapNode * pNode2 =
(IndexedDataMapNode *) myData2[HashCode(theKey2,NbBuckets())];
while (pNode2)
{
if (pNode2->Key2() == theKey2)
return pNode2->Key1();
pNode2 = (IndexedDataMapNode*) pNode2->Next2();
}
Standard_NoSuchObject::Raise("NCollection_IndexedDataMap::FindKey");
return pNode2->Key1(); // This for compiler
}
//! FindFromIndex
const TheItemType& FindFromIndex (const Standard_Integer theKey2) const
{
#if !defined No_Exception && !defined No_Standard_OutOfRange
if (theKey2 < 1 || theKey2 > Extent())
Standard_OutOfRange::Raise ("NCollection_IndexedDataMap::FindFromIndex");
#endif
IndexedDataMapNode * pNode2 =
(IndexedDataMapNode *) myData2[HashCode(theKey2,NbBuckets())];
while (pNode2)
{
if (pNode2->Key2() == theKey2)
return pNode2->Value();
pNode2 = (IndexedDataMapNode*) pNode2->Next2();
}
Standard_NoSuchObject::Raise("NCollection_IndexedDataMap::FindFromIndex");
return pNode2->Value(); // This for compiler
}
//! operator ()
const TheItemType& operator() (const Standard_Integer theKey2) const
{ return FindFromIndex (theKey2); }
//! ChangeFromIndex
TheItemType& ChangeFromIndex (const Standard_Integer theKey2)
{
#if !defined No_Exception && !defined No_Standard_OutOfRange
if (theKey2 < 1 || theKey2 > Extent())
Standard_OutOfRange::Raise("NCollection_IndexedDataMap::ChangeFromIndex");
#endif
IndexedDataMapNode * pNode2 =
(IndexedDataMapNode *) myData2[HashCode(theKey2,NbBuckets())];
while (pNode2)
{
if (pNode2->Key2() == theKey2)
return pNode2->ChangeValue();
pNode2 = (IndexedDataMapNode*) pNode2->Next2();
}
Standard_NoSuchObject::Raise("NCollection_IndexedDataMap::FindFromIndex");
return pNode2->ChangeValue(); // This for compiler
}
//! operator ()
TheItemType& operator() (const Standard_Integer theKey2)
{ return ChangeFromIndex (theKey2); }
//! FindIndex
Standard_Integer FindIndex(const TheKeyType& theKey1) const
{
if (IsEmpty()) return 0;
IndexedDataMapNode * pNode1 =
(IndexedDataMapNode *) myData1[HashCode(theKey1,NbBuckets())];
while (pNode1)
{
if (IsEqual (pNode1->Key1(), theKey1))
return pNode1->Key2();
pNode1 = (IndexedDataMapNode*) pNode1->Next();
}
return 0;
}
//! FindFromKey
const TheItemType& FindFromKey(const TheKeyType& theKey1) const
{
#if !defined No_Exception && !defined No_Standard_NoSuchObject
if (IsEmpty())
Standard_NoSuchObject::Raise ("NCollection_IndexedDataMap::FindFromKey");
#endif
IndexedDataMapNode * pNode1 =
(IndexedDataMapNode *) myData1[HashCode(theKey1,NbBuckets())];
while (pNode1)
{
if (IsEqual (pNode1->Key1(), theKey1))
return pNode1->Value();
pNode1 = (IndexedDataMapNode*) pNode1->Next();
}
Standard_NoSuchObject::Raise("NCollection_IndexedDataMap::FindFromKey");
return pNode1->Value();
}
//! ChangeFromKey
TheItemType& ChangeFromKey (const TheKeyType& theKey1)
{
#if !defined No_Exception && !defined No_Standard_NoSuchObject
if (IsEmpty())
Standard_NoSuchObject::Raise("NCollection_IndexedDataMap::ChangeFromKey");
#endif
IndexedDataMapNode * pNode1 =
(IndexedDataMapNode *) myData1[HashCode(theKey1,NbBuckets())];
while (pNode1)
{
if (IsEqual (pNode1->Key1(), theKey1))
return pNode1->ChangeValue();
pNode1 = (IndexedDataMapNode*) pNode1->Next();
}
Standard_NoSuchObject::Raise("NCollection_IndexedDataMap::ChangeFromKey");
return pNode1->ChangeValue();
}
//! Clear data. If doReleaseMemory is false then the table of
//! buckets is not released and will be reused.
void Clear(const Standard_Boolean doReleaseMemory = Standard_True)
{ Destroy (IndexedDataMapNode::delNode, this->myAllocator, doReleaseMemory); }
//! Clear data and reset allocator
void Clear (const Handle(NCollection_BaseAllocator)& theAllocator)
{
Clear();
this->myAllocator = ( ! theAllocator.IsNull() ? theAllocator :
NCollection_BaseAllocator::CommonBaseAllocator() );
}
//! Destructor
~NCollection_IndexedDataMap (void)
{ Clear(); }
//! Size
virtual Standard_Integer Size(void) const
{ return Extent(); }
private:
// ----------- PRIVATE METHODS -----------
//! Creates Iterator for use on BaseCollection
virtual TYPENAME NCollection_BaseCollection<TheItemType>::Iterator&
CreateIterator(void) const
{ return *(new (this->IterAllocator()) Iterator(*this)); }
};
#ifdef WNT
#pragma warning (pop)
#endif
#endif

View File

@@ -0,0 +1,419 @@
// File: NCollection_IndexedMap.hxx
// Created: Thu Apr 24 15:02:53 2002
// Author: Alexander KARTOMIN (akm)
// <akm@opencascade.com>
#ifndef NCollection_IndexedMap_HeaderFile
#define NCollection_IndexedMap_HeaderFile
#include <NCollection_BaseCollection.hxx>
#include <NCollection_BaseMap.hxx>
#include <NCollection_TListNode.hxx>
#include <Standard_NoSuchObject.hxx>
#include <Standard_ImmutableObject.hxx>
#if !defined No_Exception && !defined No_Standard_OutOfRange
#include <Standard_OutOfRange.hxx>
#endif
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (push)
#pragma warning (disable:4291)
#endif
/**
* Purpose: An indexed map is used to store keys and to bind
* an index to them. Each new key stored in the map
* gets an index. Index are incremented as keys are
* stored in the map. A key can be found by the index
* and an index by the key. No key but the last can
* be removed so the indices are in the range 1..Extent.
* See the class Map from NCollection for a
* discussion about the number of buckets.
*/
template <class TheKeyType> class NCollection_IndexedMap
: public NCollection_BaseCollection<TheKeyType>,
public NCollection_BaseMap
{
// **************** Adaptation of the TListNode to the INDEXEDmap
private:
class IndexedMapNode : public NCollection_TListNode<TheKeyType>
{
public:
//! Constructor with 'Next'
IndexedMapNode (const TheKeyType& theKey1,
const Standard_Integer theKey2,
NCollection_ListNode* theNext1,
NCollection_ListNode* theNext2) :
NCollection_TListNode<TheKeyType> (theKey1, theNext1)
{
myKey2 = theKey2;
myNext2 = (IndexedMapNode *) theNext2;
}
//! Key1
TheKeyType& Key1 (void)
{ return this->ChangeValue(); }
//! Key2
const Standard_Integer& Key2 (void)
{ return myKey2; }
//! Next2
IndexedMapNode*& Next2 (void)
{ return myNext2; }
//! Static deleter to be passed to BaseList
static void delNode (NCollection_ListNode * theNode,
Handle(NCollection_BaseAllocator)& theAl)
{
((IndexedMapNode *) theNode)->~IndexedMapNode();
theAl->Free(theNode);
}
private:
Standard_Integer myKey2;
IndexedMapNode * myNext2;
};
public:
// **************** Implementation of the Iterator interface.
class Iterator
: public NCollection_BaseCollection<TheKeyType>::Iterator
{
public:
//! Empty constructor
Iterator (void) :
myMap(NULL),
myIndex(0) {}
//! Constructor
Iterator (const NCollection_IndexedMap& theMap) :
myMap((NCollection_IndexedMap *) &theMap),
myIndex(1) {}
//! Query if the end of collection is reached by iterator
virtual Standard_Boolean More(void) const
{ return (myIndex <= myMap->Extent()); }
//! Make a step along the collection
virtual void Next(void)
{ myIndex++; }
//! Value access
virtual const TheKeyType& Value(void) const
{
#if !defined No_Exception && !defined No_Standard_NoSuchObject
if (!More())
Standard_NoSuchObject::Raise("NCollection_IndexedMap::Iterator::Value");
#endif
return myMap->FindKey(myIndex);
}
//! Value change access denied - use Substitute
virtual TheKeyType& ChangeValue(void) const
{
Standard_ImmutableObject::Raise ("impossible to ChangeValue");
return * (TheKeyType *) NULL; // This for compiler
}
//! Operator new for allocating iterators
void* operator new(size_t theSize,
const Handle(NCollection_BaseAllocator)& theAllocator)
{ return theAllocator->Allocate(theSize); }
private:
NCollection_IndexedMap * myMap; // Pointer to the map being iterated
Standard_Integer myIndex; // Current index
};
public:
// ---------- PUBLIC METHODS ------------
//! Constructor
NCollection_IndexedMap (const Standard_Integer NbBuckets=1,
const Handle(NCollection_BaseAllocator)& theAllocator=0L) :
NCollection_BaseCollection<TheKeyType>(theAllocator),
NCollection_BaseMap (NbBuckets, Standard_False) {}
//! Copy constructor
NCollection_IndexedMap (const NCollection_IndexedMap& theOther) :
NCollection_BaseCollection<TheKeyType>(theOther.myAllocator),
NCollection_BaseMap (theOther.NbBuckets(), Standard_False)
{ *this = theOther; }
//! Assign another collection
virtual void Assign (const NCollection_BaseCollection<TheKeyType>& theOther)
{
if (this == &theOther)
return;
Clear();
ReSize (theOther.Size()-1);
TYPENAME NCollection_BaseCollection<TheKeyType>::Iterator& anIter =
theOther.CreateIterator();
for (; anIter.More(); anIter.Next())
Add(anIter.Value());
}
//! = another map
NCollection_IndexedMap& operator= (const NCollection_IndexedMap& theOther)
{
if (this == &theOther)
return *this;
Clear(theOther.myAllocator);
ReSize (theOther.Extent()-1);
Standard_Integer i, iLength=theOther.Extent();
for (i=1; i<=iLength; i++)
{
TheKeyType aKey1 = theOther(i);
Standard_Integer iK1 = HashCode (aKey1, NbBuckets());
Standard_Integer iK2 = HashCode (i, NbBuckets());
IndexedMapNode * pNode = new (this->myAllocator) IndexedMapNode (aKey1, i,
myData1[iK1],
myData2[iK2]);
myData1[iK1] = pNode;
myData2[iK2] = pNode;
Increment();
}
return *this;
}
//! ReSize
void ReSize (const Standard_Integer N)
{
IndexedMapNode** ppNewData1 = NULL;
IndexedMapNode** ppNewData2 = NULL;
Standard_Integer newBuck;
if (BeginResize (N, newBuck,
(NCollection_ListNode**&)ppNewData1,
(NCollection_ListNode**&)ppNewData2,
this->myAllocator))
{
if (myData1)
{
IndexedMapNode *p, *q;
Standard_Integer i, iK1, iK2;
for (i = 0; i <= NbBuckets(); i++)
{
if (myData1[i])
{
p = (IndexedMapNode *) myData1[i];
while (p)
{
iK1 = HashCode (p->Key1(), newBuck);
q = (IndexedMapNode*) p->Next();
p->Next() = ppNewData1[iK1];
ppNewData1[iK1] = p;
if (p->Key2() > 0)
{
iK2 = HashCode (p->Key2(), newBuck);
p->Next2() = ppNewData2[iK2];
ppNewData2[iK2] = p;
}
p = q;
}
}
}
}
EndResize(N,newBuck,
(NCollection_ListNode**&)ppNewData1,
(NCollection_ListNode**&)ppNewData2,
this->myAllocator);
}
}
//! Add
Standard_Integer Add (const TheKeyType& theKey1)
{
if (Resizable())
ReSize(Extent());
Standard_Integer iK1 = HashCode (theKey1, NbBuckets());
IndexedMapNode * pNode;
pNode = (IndexedMapNode *) myData1[iK1];
while (pNode)
{
if (IsEqual (pNode->Key1(), theKey1))
return pNode->Key2();
pNode = (IndexedMapNode *) pNode->Next();
}
Increment();
Standard_Integer iK2 = HashCode(Extent(),NbBuckets());
pNode = new (this->myAllocator) IndexedMapNode (theKey1, Extent(),
myData1[iK1], myData2[iK2]);
myData1[iK1] = pNode;
myData2[iK2] = pNode;
return Extent();
}
//! Contains
Standard_Boolean Contains (const TheKeyType& theKey1) const
{
if (IsEmpty())
return Standard_False;
Standard_Integer iK1 = HashCode (theKey1, NbBuckets());
IndexedMapNode * pNode1;
pNode1 = (IndexedMapNode *) myData1[iK1];
while (pNode1)
{
if (IsEqual(pNode1->Key1(), theKey1))
return Standard_True;
pNode1 = (IndexedMapNode *) pNode1->Next();
}
return Standard_False;
}
//! Substitute
void Substitute (const Standard_Integer theIndex,
const TheKeyType& theKey1)
{
#if !defined No_Exception && !defined No_Standard_OutOfRange
if (theIndex < 1 || theIndex > Extent())
Standard_OutOfRange::Raise ("NCollection_IndexedMap::Substitute");
#endif
IndexedMapNode * p;
// check if theKey1 is not already in the map
Standard_Integer iK1 = HashCode (theKey1, NbBuckets());
p = (IndexedMapNode *) myData1[iK1];
while (p)
{
if (IsEqual (p->Key1(), theKey1))
Standard_DomainError::Raise("NCollection_IndexedMap::Substitute");
p = (IndexedMapNode *) p->Next();
}
// Find the node for the index I
Standard_Integer iK2 = HashCode (theIndex, NbBuckets());
p = (IndexedMapNode *) myData2[iK2];
while (p)
{
if (p->Key2() == theIndex)
break;
p = (IndexedMapNode*) p->Next2();
}
// remove the old key
Standard_Integer iK = HashCode (p->Key1(), NbBuckets());
IndexedMapNode * q = (IndexedMapNode *) myData1[iK];
if (q == p)
myData1[iK] = (IndexedMapNode *) p->Next();
else
{
while (q->Next() != p)
q = (IndexedMapNode *) q->Next();
q->Next() = p->Next();
}
// update the node
p->Key1() = theKey1;
p->Next() = myData1[iK1];
myData1[iK1] = p;
}
//! RemoveLast
void RemoveLast (void)
{
#if !defined No_Exception && !defined No_Standard_OutOfRange
if (Extent() == 0)
Standard_OutOfRange::Raise ("NCollection_IndexedMap::RemoveLast");
#endif
IndexedMapNode * p, * q;
// Find the node for the last index and remove it
Standard_Integer iK2 = HashCode (Extent(), NbBuckets());
p = (IndexedMapNode *) myData2[iK2];
q = NULL;
while (p)
{
if (p->Key2() == Extent())
break;
q = p;
p = (IndexedMapNode*) p->Next2();
}
if (q == NULL)
myData2[iK2] = (IndexedMapNode *) p->Next2();
else
q->Next2() = p->Next2();
// remove the key
Standard_Integer iK1 = HashCode (p->Key1(), NbBuckets());
q = (IndexedMapNode *) myData1[iK1];
if (q == p)
myData1[iK1] = (IndexedMapNode *) p->Next();
else
{
while (q->Next() != p)
q = (IndexedMapNode *) q->Next();
q->Next() = p->Next();
}
p->~IndexedMapNode();
this->myAllocator->Free(p);
Decrement();
}
//! FindKey
const TheKeyType& FindKey (const Standard_Integer theKey2) const
{
#if !defined No_Exception && !defined No_Standard_OutOfRange
if (theKey2 < 1 || theKey2 > Extent())
Standard_OutOfRange::Raise ("NCollection_IndexedMap::FindKey");
#endif
IndexedMapNode * pNode2 =
(IndexedMapNode *) myData2[HashCode(theKey2,NbBuckets())];
while (pNode2)
{
if (pNode2->Key2() == theKey2)
return pNode2->Key1();
pNode2 = (IndexedMapNode*) pNode2->Next2();
}
Standard_NoSuchObject::Raise("NCollection_IndexedMap::FindKey");
return pNode2->Key1(); // This for compiler
}
//! operator ()
const TheKeyType& operator() (const Standard_Integer theKey2) const
{ return FindKey (theKey2); }
//! FindIndex
Standard_Integer FindIndex(const TheKeyType& theKey1) const
{
if (IsEmpty()) return 0;
IndexedMapNode * pNode1 =
(IndexedMapNode *) myData1[HashCode(theKey1,NbBuckets())];
while (pNode1)
{
if (IsEqual (pNode1->Key1(), theKey1))
return pNode1->Key2();
pNode1 = (IndexedMapNode*) pNode1->Next();
}
return 0;
}
//! Clear data. If doReleaseMemory is false then the table of
//! buckets is not released and will be reused.
void Clear(const Standard_Boolean doReleaseMemory = Standard_True)
{ Destroy (IndexedMapNode::delNode, this->myAllocator, doReleaseMemory); }
//! Clear data and reset allocator
void Clear (const Handle(NCollection_BaseAllocator)& theAllocator)
{
Clear();
this->myAllocator = ( ! theAllocator.IsNull() ? theAllocator :
NCollection_BaseAllocator::CommonBaseAllocator() );
}
//! Destructor
~NCollection_IndexedMap (void)
{ Clear(); }
//! Size
virtual Standard_Integer Size(void) const
{ return Extent(); }
private:
// ----------- PRIVATE METHODS -----------
//! Creates Iterator for use on BaseCollection
virtual TYPENAME NCollection_BaseCollection<TheKeyType>::Iterator&
CreateIterator(void) const
{ return *(new (this->IterAllocator()) Iterator(*this)); }
};
#ifdef WNT
#pragma warning (pop)
#endif
#endif

View File

@@ -0,0 +1,298 @@
// File: NCollection_List.hxx
// Created: 17.04.02 10:12:48
// Author: Alexander Kartomin (akm)
// <a-kartomin@opencascade.com>
// Copyright: Open Cascade 2002
#ifndef NCollection_List_HeaderFile
#define NCollection_List_HeaderFile
#include <NCollection_TListIterator.hxx>
#if !defined No_Exception && !defined No_Standard_NoSuchObject
#include <Standard_NoSuchObject.hxx>
#endif
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (push)
#pragma warning (disable:4291)
#endif
/**
* Purpose: Simple list to link items together keeping the first
* and the last one.
* Inherits BaseList, adding the data item to each node.
*/
template <class TheItemType> class NCollection_List
: public NCollection_BaseCollection<TheItemType>,
public NCollection_BaseList
{
public:
typedef NCollection_TListNode<TheItemType> ListNode;
typedef NCollection_TListIterator<TheItemType> Iterator;
public:
// ---------- PUBLIC METHODS ------------
//! Constructor
NCollection_List(const Handle(NCollection_BaseAllocator)& theAllocator=0L) :
NCollection_BaseCollection<TheItemType>(theAllocator),
NCollection_BaseList() {}
//! Copy constructor
NCollection_List (const NCollection_List& theOther) :
NCollection_BaseCollection<TheItemType>(theOther.myAllocator),
NCollection_BaseList()
{ *this = theOther; }
//! Size - Number of items
virtual Standard_Integer Size (void) const
{ return Extent(); }
//! Replace this list by the items of theOther collection
virtual void Assign (const NCollection_BaseCollection<TheItemType>& theOther)
{
if (this == &theOther)
return;
Clear();
TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& anIter =
theOther.CreateIterator();
for (; anIter.More(); anIter.Next())
{
ListNode* pNew = new (this->myAllocator) ListNode(anIter.Value());
PAppend(pNew);
}
}
//! Replace this list by the items of another list (theOther parameter)
void Assign (const NCollection_List& theOther)
{
if (this != &theOther) {
Clear();
appendList(theOther.PFirst());
}
}
//! Replace this list by the items of theOther list
NCollection_List& operator= (const NCollection_List& theOther)
{
if (this != &theOther) {
Clear (theOther.myAllocator);
appendList(theOther.PFirst());
}
return *this;
}
//! Clear this list
void Clear (const Handle(NCollection_BaseAllocator)& theAllocator=0L)
{
PClear (ListNode::delNode, this->myAllocator);
if (!theAllocator.IsNull())
this->myAllocator = theAllocator;
}
//! First item
const TheItemType& First (void) const
{
#if !defined No_Exception && !defined No_Standard_NoSuchObject
if (IsEmpty())
Standard_NoSuchObject::Raise ("NCollection_List::First");
#endif
return ((const ListNode *) PFirst())->Value();
}
//! Last item
const TheItemType& Last (void) const
{
#if !defined No_Exception && !defined No_Standard_NoSuchObject
if (IsEmpty())
Standard_NoSuchObject::Raise ("NCollection_List::Last");
#endif
return ((const ListNode *) PLast())->Value();
}
//! Append one item at the end
TheItemType& Append (const TheItemType& theItem)
{
ListNode * pNew = new (this->myAllocator) ListNode(theItem);
PAppend(pNew);
return ((ListNode *) PLast())->ChangeValue();
}
//! Append one item at the end and output iterator
//! pointing at the appended item
void Append (const TheItemType& theItem, Iterator& theIter)
{
ListNode * pNew = new (this->myAllocator) ListNode(theItem);
PAppend(pNew, theIter);
}
//! Append another list at the end
void Append (NCollection_List& theOther)
{
if (this == &theOther || theOther.Extent()<1)
return;
if (this->myAllocator == theOther.myAllocator)
{
// Then we take the list and glue it to our end -
// deallocation will bring no problem
PAppend(theOther);
}
else
{
// No - this list has different memory scope
appendList(theOther.myFirst);
theOther.Clear();
}
}
//! Prepend one item at the beginning
TheItemType& Prepend (const TheItemType& theItem)
{
ListNode * pNew = new (this->myAllocator) ListNode(theItem);
PPrepend(pNew);
return ((ListNode *) PFirst())->ChangeValue();
}
//! Prepend another list at the beginning
void Prepend (NCollection_List& theOther)
{
if (this == &theOther || theOther.Extent()<1)
return;
if (this->myAllocator == theOther.myAllocator)
{
// Then we take the list and glue it to our head -
// deallocation will bring no problem
PPrepend(theOther);
}
else
{
// No - this list has different memory scope
Iterator it(*this);
prependList(theOther.PFirst(), it);
theOther.Clear();
}
}
//! RemoveFirst item
void RemoveFirst (void)
{ PRemoveFirst (ListNode::delNode, this->myAllocator); }
//! Remove item
void Remove (Iterator& theIter)
{
PRemove (theIter, ListNode::delNode, this->myAllocator);
}
//! InsertBefore
TheItemType& InsertBefore (const TheItemType& theItem,
Iterator& theIter)
{
ListNode * pNew = new (this->myAllocator) ListNode(theItem);
PInsertBefore (pNew, theIter);
return pNew -> ChangeValue();
}
//! InsertBefore
void InsertBefore (NCollection_List& theOther,
Iterator& theIter)
{
if (this == &theOther)
return;
if (this->myAllocator == theOther.myAllocator)
{
// Then we take the list and glue it to our head -
// deallocation will bring no problem
PInsertBefore (theOther, theIter);
}
else
{
// No - this list has different memory scope
prependList(theOther.myFirst, theIter);
theOther.Clear();
}
}
//! InsertAfter
TheItemType& InsertAfter (const TheItemType& theItem,
Iterator& theIter)
{
ListNode * pNew = new (this->myAllocator) ListNode(theItem);
PInsertAfter (pNew, theIter);
return pNew -> ChangeValue();
}
//! InsertAfter
void InsertAfter (NCollection_List& theOther,
Iterator& theIter)
{
if (!theIter.More())
{
Append(theOther);
return;
}
if (this->myAllocator == theOther.myAllocator)
{
// Then we take the list and glue it to our head -
// deallocation will bring no problem
PInsertAfter (theOther, theIter);
}
else
{
// No - this list has different memory scope
#if !defined No_Exception && !defined No_Standard_NoSuchObject
if (!theIter.More())
Standard_NoSuchObject::Raise ("NCollection_List::InsertAfter");
#endif
Iterator anIter;
anIter.myPrevious = theIter.myCurrent;
anIter.myCurrent = theIter.myCurrent->Next();
prependList(theOther.PFirst(), anIter);
theOther.Clear();
}
}
//! Reverse the list
void Reverse ()
{ PReverse(); }
//! Destructor - clears the List
~NCollection_List (void)
{ Clear(); }
private:
// ----------- PRIVATE METHODS -----------
//! Creates Iterator for use on BaseCollection
virtual TYPENAME NCollection_BaseCollection<TheItemType>::Iterator&
CreateIterator(void) const
{ return *(new (this->IterAllocator()) Iterator(*this)); }
//! append the list headed by the given ListNode
void appendList(const NCollection_ListNode * pCur) {
while (pCur) {
NCollection_ListNode * pNew =
new (this->myAllocator) ListNode(((const ListNode *)(pCur))->Value());
PAppend(pNew);
pCur = pCur->Next();
}
}
//! insert the list headed by the given ListNode before the given iterator
void prependList(const NCollection_ListNode * pCur, Iterator& theIter) {
while (pCur) {
NCollection_ListNode * pNew =
new (this->myAllocator) ListNode (((const ListNode *)(pCur))->Value());
PInsertBefore(pNew, theIter);
pCur = pCur->Next();
}
}
};
#ifdef WNT
#pragma warning (pop)
#endif
#endif

View File

@@ -0,0 +1,46 @@
// File: NCollection_ListNode.hxx
// Created: Wed Apr 17 10:45:17 2002
// Author: Alexander KARTOMIN (akm)
// <akm@matrox.nnov.matra-dtv.fr>
#ifndef NCollection_ListNode_HeaderFile
#define NCollection_ListNode_HeaderFile
#include <NCollection_BaseAllocator.hxx>
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (disable:4291)
#endif
/**
* Purpose: This class is used to represent a node in the BaseList and
* BaseMap.
*/
class NCollection_ListNode
{
public:
//! The only constructor
NCollection_ListNode (NCollection_ListNode* theNext)
{ myNext = theNext; }
//! Next pointer access
NCollection_ListNode*& Next (void)
{ return myNext; }
//! Next pointer const access
NCollection_ListNode* Next (void) const
{ return myNext; }
private:
//! operator= - forbidden
NCollection_ListNode& operator=(const NCollection_ListNode& )
{return *this;}
//! copy constructor - forbidden
NCollection_ListNode (const NCollection_ListNode& ) {}
private:
NCollection_ListNode * myNext; //!< Pointer to the next node
};
#endif

View File

@@ -0,0 +1,319 @@
// File: NCollection_Map.hxx
// Created: Thu Apr 23 15:02:53 2002
// Author: Alexander KARTOMIN (akm)
// <a-kartomin@opencascade.com>
#ifndef NCollection_Map_HeaderFile
#define NCollection_Map_HeaderFile
#include <NCollection_BaseCollection.hxx>
#include <NCollection_BaseMap.hxx>
#include <NCollection_TListNode.hxx>
#include <Standard_ImmutableObject.hxx>
#if !defined No_Exception && !defined No_Standard_NoSuchObject
#include <Standard_NoSuchObject.hxx>
#endif
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (push)
#pragma warning (disable:4291)
#endif
/**
* Purpose: Single hashed Map. This Map is used to store and
* retrieve keys in linear time.
*
* The ::Iterator class can be used to explore the
* content of the map. It is not wise to iterate and
* modify a map in parallel.
*
* To compute the hashcode of the key the function
* ::HashCode must be defined in the global namespace
*
* To compare two keys the function ::IsEqual must be
* defined in the global namespace.
*
* The performance of a Map is conditionned by its
* number of buckets that should be kept greater to
* the number of keys. This map has an automatic
* management of the number of buckets. It is resized
* when the number of Keys becomes greater than the
* number of buckets.
*
* If you have a fair idea of the number of objects
* you can save on automatic resizing by giving a
* number of buckets at creation or using the ReSize
* method. This should be consider only for crucial
* optimisation issues.
*/
template <class TheKeyType> class NCollection_Map
: public NCollection_BaseCollection<TheKeyType>,
public NCollection_BaseMap
{
//! Adaptation of the TListNode to the map notations
public:
class MapNode : public NCollection_TListNode<TheKeyType>
{
public:
//! Constructor with 'Next'
MapNode (const TheKeyType& theKey,
NCollection_ListNode* theNext) :
NCollection_TListNode<TheKeyType> (theKey, theNext) {}
//! Key
const TheKeyType& Key (void)
{ return this->Value(); }
};
public:
//! Implementation of the Iterator interface.
class Iterator
: public NCollection_BaseCollection<TheKeyType>::Iterator,
public NCollection_BaseMap::Iterator
{
public:
//! Empty constructor
Iterator (void) :
NCollection_BaseMap::Iterator() {}
//! Constructor
Iterator (const NCollection_Map& theMap) :
NCollection_BaseMap::Iterator(theMap) {}
//! Query if the end of collection is reached by iterator
virtual Standard_Boolean More(void) const
{ return PMore(); }
//! Make a step along the collection
virtual void Next(void)
{ PNext(); }
//! Value inquiry
virtual const TheKeyType& Value(void) const
{
#if !defined No_Exception && !defined No_Standard_NoSuchObject
if (!More())
Standard_NoSuchObject::Raise ("NCollection_Map::Iterator::Value");
#endif
return ((MapNode *) myNode)->Value();
}
//! Value change access - denied
virtual TheKeyType& ChangeValue(void) const
{
Standard_ImmutableObject::Raise("NCollection_Map::Iterator::ChangeValue");
return * (TheKeyType *) NULL; // For compiler
}
//! Key
const TheKeyType& Key (void)
{
#if !defined No_Exception && !defined No_Standard_NoSuchObject
if (!More())
Standard_NoSuchObject::Raise ("NCollection_Map::Iterator::Key");
#endif
return ((MapNode *) myNode)->Value();
}
//! Operator new for allocating iterators
void* operator new(size_t theSize,
const Handle(NCollection_BaseAllocator)& theAllocator)
{ return theAllocator->Allocate(theSize); }
};
public:
// ---------- PUBLIC METHODS ------------
//! Constructor
NCollection_Map (const Standard_Integer NbBuckets = 1,
const Handle(NCollection_BaseAllocator)& theAllocator = 0L)
: NCollection_BaseCollection<TheKeyType>(theAllocator),
NCollection_BaseMap (NbBuckets, Standard_True) {}
//! Copy constructor
NCollection_Map (const NCollection_Map& theOther)
: NCollection_BaseCollection<TheKeyType>(theOther.myAllocator),
NCollection_BaseMap (theOther.NbBuckets(), Standard_True)
{ *this = theOther; }
//! Assign another collection
virtual void Assign (const NCollection_BaseCollection<TheKeyType>& theOther)
{
if (this == &theOther)
return;
Clear();
ReSize (theOther.Size()-1);
TYPENAME NCollection_BaseCollection<TheKeyType>::Iterator& anIter =
theOther.CreateIterator();
for (; anIter.More(); anIter.Next())
Add (anIter.Value());
}
//! = another map
NCollection_Map& operator= (const NCollection_Map& theOther)
{
if (this == &theOther)
return *this;
Clear(theOther.myAllocator);
ReSize (theOther.Extent()-1);
Iterator anIter(theOther);
for (; anIter.More(); anIter.Next())
Add (anIter.Key());
return *this;
}
//! ReSize
void ReSize (const Standard_Integer N)
{
MapNode** newdata = 0L;
MapNode** dummy = 0L;
Standard_Integer newBuck;
if (BeginResize (N, newBuck,
(NCollection_ListNode**&)newdata,
(NCollection_ListNode**&)dummy,
this->myAllocator))
{
if (myData1)
{
MapNode** olddata = (MapNode**) myData1;
MapNode *p, *q;
Standard_Integer i,k;
for (i = 0; i <= NbBuckets(); i++)
{
if (olddata[i])
{
p = olddata[i];
while (p)
{
k = HashCode(p->Key(),newBuck);
q = (MapNode*) p->Next();
p->Next() = newdata[k];
newdata[k] = p;
p = q;
}
}
}
}
EndResize(N,newBuck,
(NCollection_ListNode**&)newdata,
(NCollection_ListNode**&)dummy,
this->myAllocator);
}
}
//! Add
Standard_Boolean Add(const TheKeyType& K)
{
if (Resizable())
ReSize(Extent());
MapNode** data = (MapNode**)myData1;
Standard_Integer k = HashCode(K,NbBuckets());
MapNode* p = data[k];
while (p)
{
if (IsEqual(p->Key(),K))
return Standard_False;
p = (MapNode *) p->Next();
}
data[k] = new (this->myAllocator) MapNode(K,data[k]);
Increment();
return Standard_True;
}
//! Added: add a new key if not yet in the map, and return
//! reference to either newly added or previously existing object
const TheKeyType& Added(const TheKeyType& K)
{
if (Resizable())
ReSize(Extent());
MapNode** data = (MapNode**)myData1;
Standard_Integer k = HashCode(K,NbBuckets());
MapNode* p = data[k];
while (p)
{
if (IsEqual(p->Key(),K))
return p->Key();
p = (MapNode *) p->Next();
}
data[k] = new (this->myAllocator) MapNode(K,data[k]);
Increment();
return data[k]->Key();
}
//! Contains
Standard_Boolean Contains(const TheKeyType& K) const
{
if (IsEmpty())
return Standard_False;
MapNode** data = (MapNode**) myData1;
MapNode* p = data[HashCode(K,NbBuckets())];
while (p)
{
if (IsEqual(p->Key(),K))
return Standard_True;
p = (MapNode *) p->Next();
}
return Standard_False;
}
//! Remove
Standard_Boolean Remove(const TheKeyType& K)
{
if (IsEmpty())
return Standard_False;
MapNode** data = (MapNode**) myData1;
Standard_Integer k = HashCode(K,NbBuckets());
MapNode* p = data[k];
MapNode* q = NULL;
while (p)
{
if (IsEqual(p->Key(),K))
{
Decrement();
if (q)
q->Next() = p->Next();
else
data[k] = (MapNode*) p->Next();
p->~MapNode();
this->myAllocator->Free(p);
return Standard_True;
}
q = p;
p = (MapNode*) p->Next();
}
return Standard_False;
}
//! Clear data. If doReleaseMemory is false then the table of
//! buckets is not released and will be reused.
void Clear(const Standard_Boolean doReleaseMemory = Standard_True)
{ Destroy (MapNode::delNode, this->myAllocator, doReleaseMemory); }
//! Clear data and reset allocator
void Clear (const Handle(NCollection_BaseAllocator)& theAllocator)
{
Clear();
this->myAllocator = ( ! theAllocator.IsNull() ? theAllocator :
NCollection_BaseAllocator::CommonBaseAllocator() );
}
//! Destructor
~NCollection_Map (void)
{ Clear(); }
//! Size
virtual Standard_Integer Size(void) const
{ return Extent(); }
private:
// ----------- PRIVATE METHODS -----------
//! Creates Iterator for use on BaseCollection
virtual TYPENAME NCollection_BaseCollection<TheKeyType>::Iterator&
CreateIterator(void) const
{ return *(new (this->IterAllocator()) Iterator(*this)); }
};
#ifdef WNT
#pragma warning (pop)
#endif
#endif

View File

@@ -0,0 +1,142 @@
// File: NCollection_Queue.hxx
// Created: 17.04.02 10:12:48
// Author: Alexander Kartomin (akm)
// <a-kartomin@opencascade.com>
// Copyright: Open Cascade 2002
#ifndef NCollection_Queue_HeaderFile
#define NCollection_Queue_HeaderFile
#include <NCollection_TListIterator.hxx>
#if !defined No_Exception && !defined No_Standard_NoSuchObject
#include <Standard_NoSuchObject.hxx>
#endif
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (disable:4291)
#endif
/**
* Purpose: A queue is a structure where Items are added at
* the end and removed from the front. The first
* entered Item will be the first removed. This is
* called a FIFO (First In First Out).
* Inherits BaseList, adds the data item to each node.
*/
template <class TheItemType> class NCollection_Queue
: public NCollection_BaseCollection<TheItemType>,
public NCollection_BaseList
{
public:
typedef NCollection_TListNode<TheItemType> QueueNode;
typedef NCollection_TListIterator<TheItemType> Iterator;
public:
// ---------- PUBLIC METHODS ------------
//! Constructor
NCollection_Queue(const Handle(NCollection_BaseAllocator)& theAllocator=0L) :
NCollection_BaseCollection<TheItemType>(theAllocator),
NCollection_BaseList() {}
//! Copy constructor
NCollection_Queue (const NCollection_Queue& theOther) :
NCollection_BaseCollection<TheItemType>(theOther.myAllocator),
NCollection_BaseList()
{ *this = theOther; }
//! Size - Number of items
virtual Standard_Integer Size (void) const
{ return Extent(); }
//! Length - number of items
Standard_Integer Length (void) const
{ return Extent(); }
//! Replace this list by the items of theOther collection
virtual void Assign (const NCollection_BaseCollection<TheItemType>& theOther)
{
if (this == &theOther)
return;
Clear();
TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& anIter =
theOther.CreateIterator();
for (; anIter.More(); anIter.Next())
{
QueueNode* pNew = new (this->myAllocator) QueueNode(anIter.Value());
PAppend(pNew);
}
}
//! Replace this list by the items of theOther queue
NCollection_Queue& operator= (const NCollection_Queue& theOther)
{
if (this == &theOther)
return *this;
Clear ();
QueueNode * pCur = (QueueNode *) theOther.PFirst();
while (pCur)
{
QueueNode* pNew = new (this->myAllocator) QueueNode(pCur->Value());
PAppend(pNew);
pCur = (QueueNode *) pCur->Next();
}
return *this;
}
//! Clear this queue
void Clear (void)
{ PClear (QueueNode::delNode, this->myAllocator); }
//! Frontal item - constant
const TheItemType& Front (void) const
{
#if !defined No_Exception && !defined No_Standard_NoSuchObject
if (IsEmpty())
Standard_NoSuchObject::Raise ("NCollection_Queue::Front");
#endif
return ((const QueueNode *) PFirst())->Value();
}
//! Frontal item - variable
TheItemType& ChangeFront (void)
{
#if !defined No_Exception && !defined No_Standard_NoSuchObject
if (IsEmpty())
Standard_NoSuchObject::Raise ("NCollection_Queue::ChangeFront");
#endif
return ((QueueNode *) PFirst())->ChangeValue();
}
//! Push one item
void Push (const TheItemType& theItem)
{
QueueNode * pNew = new (this->myAllocator) QueueNode(theItem);
PAppend(pNew);
}
//! Pop first item
void Pop (void)
{ PRemoveFirst (QueueNode::delNode, this->myAllocator); }
//! Destructor - clears the List
~NCollection_Queue (void)
{ Clear(); }
private:
// ----------- PRIVATE METHODS -----------
//! Creates Iterator for use on BaseCollection
virtual TYPENAME NCollection_BaseCollection<TheItemType>::Iterator&
CreateIterator(void) const
{ return *(new (this->IterAllocator()) Iterator(*this)); }
};
#ifdef WNT
#pragma warning (default:4291)
#endif
#endif

View File

@@ -0,0 +1,294 @@
// File: NCollection_SList.hxx
// Created: 17.04.02 10:12:48
// Author: Alexander Kartomin (akm)
// Copyright: Open Cascade 2002
#ifndef NCollection_SList_HeaderFile
#define NCollection_SList_HeaderFile
#include <NCollection_BaseCollection.hxx>
#if !defined No_Exception && !defined No_Standard_NoSuchObject
#include <Standard_NoSuchObject.hxx>
#endif
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (disable:4291)
#endif
/**
* Purpose: An SList is a LISP like list of Items.
* An SList is :
* . Empty.
* . Or it has a Value and a Tail which is an other SList.
*
* The Tail of an empty list is an empty list.
* SList are shared. It means that they can be
* modified through other lists.
* SList may be used as Iterators. They have Next,
* More, and value methods. To iterate on the content
* of the list S just do.
*
* SList Iterator;
* for (Iterator = S; Iterator.More(); Iterator.Next())
* X = Iterator.Value();
*
* Memory usage is automatically managed for SLists
* (using reference counts).
*
* Example:
* If S1 and S2 are SLists :
* if S1.Value() is X.
*
* And the following is done :
* S2 = S1;
* S2.SetValue(Y);
*
* S1.Value() becomes also Y. So SList must be used
* with care. Mainly the SetValue() method is
* dangerous.
*/
template <class TheItemType> class NCollection_SList
: public NCollection_BaseCollection<TheItemType>,
public NCollection_BaseCollection<TheItemType>::Iterator
{
public:
//! The node of SList
class SListNode
{
private:
//! Constructor
SListNode (const TheItemType& theItem,
const NCollection_SList& theTail) :
myCount(1),
myValue(theItem)
{ myTail = new (theTail.myAllocator) NCollection_SList(theTail); }
//! Tail
NCollection_SList& Tail (void)
{ return (*myTail); }
//! Value
TheItemType& Value (void)
{ return myValue; }
//! Clear
void Clear (void)
{
myTail->Clear();
myTail->myAllocator->Free(myTail);
}
//! Operator new for allocating nodes
void* operator new(size_t theSize,
const Handle(NCollection_BaseAllocator)& theAllocator)
{ return theAllocator->Allocate(theSize); }
//! news to avoid warnings on hiding - not for use
void* operator new(size_t theSize)
{ return Standard::Allocate(theSize); }
void* operator new(size_t /*theSize*/, void* theAddress)
{ return theAddress; }
private:
// ---------- PRIVATE FIELDS ------------
Standard_Integer myCount; //!< Reference count
NCollection_SList * myTail; //!< The tail
TheItemType myValue; //!< Datum
// Everything above is private. Only SList has an access
friend class NCollection_SList<TheItemType>;
}; // End of nested class SListNode
public:
// ---------- PUBLIC METHODS ------------
//! Empty constructor
NCollection_SList(const Handle(NCollection_BaseAllocator)& theAllocator=0L) :
NCollection_BaseCollection<TheItemType>(theAllocator),
myNode(NULL) {}
//! Constructor
NCollection_SList(const TheItemType& theItem,
const NCollection_SList& theTail) :
NCollection_BaseCollection<TheItemType>(theTail.myAllocator)
{ myNode = new (theTail.myAllocator) SListNode(theItem,theTail); }
//! Copy constructor
NCollection_SList (const NCollection_SList& theOther) :
NCollection_BaseCollection<TheItemType>(theOther.myAllocator)
{
myNode = theOther.myNode;
if (myNode)
myNode->myCount++;
}
//! Operator new for creating 'iterator'
void* operator new(size_t theSize,
const Handle(NCollection_BaseAllocator)& theAllocator)
{ return theAllocator->Allocate(theSize); }
//! Clear the items out
void Clear (void)
{
if (!myNode)
return;
myNode->myCount--;
if (myNode->myCount < 1)
{
myNode->Clear();
this->myAllocator->Free(myNode);
}
myNode = NULL;
}
//! Make this list identical to theOther
NCollection_SList& operator= (const NCollection_SList& theOther)
{
if (myNode != theOther.myNode)
{
if (theOther.myNode)
theOther.myNode->myCount++;
Clear();
this->myAllocator = theOther.myAllocator;
myNode = theOther.myNode;
}
return *this;
}
//! Replace this list by the items of theOther collection
virtual void Assign (const NCollection_BaseCollection<TheItemType>& theOther)
{
if (this == &theOther)
return;
Clear();
TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& anIter =
theOther.CreateIterator();
if (!anIter.More())
return;
SListNode *aNode, *aPrevNode=NULL;
for (; anIter.More(); anIter.Next())
{
aNode = new (this->myAllocator) SListNode
(anIter.Value(), NCollection_SList(this->myAllocator));
if (IsEmpty())
myNode = aNode;
else
aPrevNode->Tail().myNode = aNode;
aPrevNode = aNode;
}
}
//! IsEmpty query
Standard_Boolean IsEmpty (void) const
{ return (myNode==NULL); }
//! Value - constant access
virtual const TheItemType& Value (void) const
{
#if !defined No_Exception && !defined No_Standard_NoSuchObject
if (IsEmpty())
Standard_NoSuchObject::Raise ("NCollection_SList::Value");
#endif
return myNode->Value();
}
//! ChangeValue - variable access
virtual TheItemType& ChangeValue (void) const
{
#if !defined No_Exception && !defined No_Standard_NoSuchObject
if (IsEmpty())
Standard_NoSuchObject::Raise ("NCollection_SList::ChangeValue");
#endif
return myNode->Value();
}
//! SetValue
void SetValue (const TheItemType& theItem)
{
#if !defined No_Exception && !defined No_Standard_NoSuchObject
if (IsEmpty())
Standard_NoSuchObject::Raise ("NCollection_SList::SetValue");
#endif
myNode->Value() = theItem;
}
//! Tail
const NCollection_SList& Tail (void) const
{
if (!IsEmpty())
return myNode->Tail();
else
return *this;
}
//! ChangeTail
NCollection_SList& ChangeTail (void)
{
if (!IsEmpty())
return myNode->Tail();
else
return *this;
}
//! SetTail
void SetTail (NCollection_SList& theList)
{
if (!IsEmpty())
myNode->Tail() = theList;
else
*this = theList;
}
//! Construct
void Construct(const TheItemType& theItem)
{ *this = NCollection_SList (theItem, *this); }
//! Constructed
NCollection_SList Constructed(const TheItemType& theItem) const
{ return NCollection_SList (theItem, *this); }
//! ToTail
void ToTail (void)
{ *this = Tail(); }
//! Initialize (~Assign)
void Initialize (const NCollection_SList& theOther)
{ *this = theOther; }
//! Init (virtual method of base iterator)
void Init (const NCollection_SList& theOther)
{ *this = theOther; }
//! More (~!IsEmpty)
virtual Standard_Boolean More (void) const
{ return !IsEmpty(); }
//! Next (~ToTail)
virtual void Next (void)
{ ToTail(); }
//! Size - Number of items
virtual Standard_Integer Size (void) const
{ return (IsEmpty() ? 0 : 1+myNode->Tail().Size()); }
//! Destructor - clears the SList
~NCollection_SList (void)
{ Clear(); }
private:
// ----------- PRIVATE METHODS -----------
//! Creates Iterator for use on BaseCollection
virtual TYPENAME NCollection_BaseCollection<TheItemType>::Iterator&
CreateIterator(void) const
{ return *(new (this->IterAllocator()) NCollection_SList(*this)); }
private:
// ---------- PRIVATE FIELDS ------------
SListNode* myNode;
friend class SListNode;
};
#ifdef WNT
#pragma warning (default:4291)
#endif
#endif

View File

@@ -0,0 +1,322 @@
// File: NCollection_Sequence.hxx
// Created: 28.03.02 20:41:43
// Author: Alexander GRIGORIEV
// Copyright: Open Cascade 2002
#ifndef NCollection_Sequence_HeaderFile
#define NCollection_Sequence_HeaderFile
#include <NCollection_BaseCollection.hxx>
#include <NCollection_BaseSequence.hxx>
#ifndef No_Exception
#include <Standard_OutOfRange.hxx>
#include <Standard_NoSuchObject.hxx>
#endif
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (push)
#pragma warning (disable:4291)
#endif
/**
* Purpose: Definition of a sequence of elements indexed by
* an Integer in range of 1..n
*/
template <class TheItemType> class NCollection_Sequence
: public NCollection_BaseCollection<TheItemType>,
public NCollection_BaseSequence
{
public:
//! Class defining sequence node - for internal use by Sequence
class Node : public NCollection_SeqNode
{
public:
//! Constructor
Node (const TheItemType& theItem) :
NCollection_SeqNode ()
{ myValue = theItem; }
//! Constant value access
const TheItemType& Value () const { return myValue; }
//! Variable value access
TheItemType& ChangeValue () { return myValue; }
//! Memory allocation
void* operator new(size_t theSize,
const Handle(NCollection_BaseAllocator)& theAllocator)
{ return theAllocator->Allocate(theSize); }
private:
TheItemType myValue;
}; // End of nested class Node
public:
//! Implementation of the Iterator interface.
class Iterator : public NCollection_BaseCollection<TheItemType>::Iterator,
public NCollection_BaseSequence::Iterator
{
public:
//! Empty constructor - for later Init
Iterator (void) {}
//! Constructor with initialisation
Iterator (const NCollection_Sequence& theSeq,
const Standard_Boolean isStart = Standard_True)
: NCollection_BaseSequence::Iterator (theSeq, isStart) {}
//! Assignment
Iterator& operator= (const Iterator& theIt)
{
NCollection_BaseSequence::Iterator& me = * this;
me.operator= (theIt);
return * this;
}
//! Check end
virtual Standard_Boolean More (void) const
{ return (myCurrent!=NULL); }
//! Make step
virtual void Next (void)
{ if (myCurrent) myCurrent = (NCollection_SeqNode *) myCurrent->Next(); }
//! Constant value access
virtual const TheItemType& Value (void) const
{ return ((const Node *)myCurrent)->Value(); }
//! Variable value access
virtual TheItemType& ChangeValue (void) const
{ return ((Node *)myCurrent)->ChangeValue(); }
//! Operator new for allocating iterators
void* operator new(size_t theSize,
const Handle(NCollection_BaseAllocator)& theAllocator)
{ return theAllocator->Allocate(theSize); }
}; // End of nested class Iterator
public:
// ---------- PUBLIC METHODS ------------
//! Constructor
NCollection_Sequence(const Handle(NCollection_BaseAllocator)& theAllocator=0L)
: NCollection_BaseCollection<TheItemType>(theAllocator),
NCollection_BaseSequence() {}
//! Copy constructor
NCollection_Sequence (const NCollection_Sequence& theOther) :
NCollection_BaseCollection<TheItemType>(theOther.myAllocator),
NCollection_BaseSequence()
{ *this = theOther; }
//! Number of items
virtual Standard_Integer Size (void) const
{ return mySize; }
//! Number of items
Standard_Integer Length (void) const
{ return mySize; }
//! Empty query
Standard_Boolean IsEmpty (void) const
{ return (mySize==0); }
//! Reverse sequence
void Reverse (void)
{ PReverse(); }
//! Exchange two members
void Exchange (const Standard_Integer I,
const Standard_Integer J )
{ PExchange(I, J); }
//! Static deleter to be passed to BaseSequence
static void delNode (NCollection_SeqNode * theNode,
Handle(NCollection_BaseAllocator)& theAl)
{
((Node *) theNode)->~Node();
theAl->Free(theNode);
}
//! Clear the items out, take a new allocator if non null
void Clear (const Handle(NCollection_BaseAllocator)& theAllocator=0L)
{
ClearSeq (delNode, this->myAllocator);
if (!theAllocator.IsNull())
this->myAllocator = theAllocator;
}
//! Replace this sequence by the items of theOther
NCollection_Sequence& operator= (const NCollection_Sequence& theOther)
{
if (this == &theOther)
return *this;
Clear (theOther.myAllocator);
Node * pCur = (Node *) theOther.myFirstItem;
while (pCur) {
Node* pNew = new (this->myAllocator) Node (pCur->Value());
PAppend (pNew);
pCur = (Node *) pCur->Next();
}
return * this;
}
//! Replace this sequence by the items of theOther collection
virtual void Assign (const NCollection_BaseCollection<TheItemType>& theOther)
{
if (this == &theOther)
return;
Clear ();
TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& anIter =
theOther.CreateIterator();
for (; anIter.More(); anIter.Next())
Append(anIter.Value());
}
//! Remove one item
void Remove (Iterator& thePosition)
{ RemoveSeq (thePosition, delNode, this->myAllocator); }
//! Remove one item
void Remove (const Standard_Integer theIndex)
{ RemoveSeq (theIndex, delNode, this->myAllocator); }
//! Remove range of items
void Remove (const Standard_Integer theFromIndex,
const Standard_Integer theToIndex)
{ RemoveSeq (theFromIndex, theToIndex, delNode, this->myAllocator); }
//! Append one item
void Append (const TheItemType& theItem)
{ PAppend (new (this->myAllocator) Node (theItem)); }
//! Append another sequence (making it empty)
void Append (NCollection_Sequence& theSeq)
{
if (myFirstItem == theSeq.myFirstItem) Assign (theSeq);
PAppend (theSeq);
}
//! Prepend one item
void Prepend (const TheItemType& theItem)
{ PPrepend (new (this->myAllocator) Node (theItem)); }
//! Prepend another sequence (making it empty)
void Prepend (NCollection_Sequence& theSeq)
{
if (myFirstItem == theSeq.myFirstItem) Assign (theSeq);
PPrepend (theSeq);
}
//! InsertBefore theIndex theItem
void InsertBefore (const Standard_Integer theIndex,
const TheItemType& theItem)
{ InsertAfter (theIndex-1, theItem); }
//! InsertBefore theIndex another sequence
void InsertBefore (const Standard_Integer theIndex,
NCollection_Sequence& theSeq)
{ InsertAfter (theIndex-1, theSeq); }
//! InsertAfter the position of iterator
void InsertAfter (Iterator& thePosition,
const TheItemType& theItem)
{ PInsertAfter (thePosition, new (this->myAllocator) Node (theItem)); }
//! InsertAfter theIndex theItem
void InsertAfter (const Standard_Integer theIndex,
NCollection_Sequence& theSeq)
{ PInsertAfter (theIndex, theSeq); }
//! InsertAfter theIndex another sequence
void InsertAfter (const Standard_Integer theIndex,
const TheItemType& theItem)
{
#if !defined No_Exception && !defined No_Standard_OutOfRange
if (theIndex < 0 || theIndex > mySize)
Standard_OutOfRange::Raise ("NCollection_Sequence::InsertAfter");
#endif
PInsertAfter (theIndex, new (this->myAllocator) Node (theItem));
}
//! Split in two sequences
void Split (const Standard_Integer theIndex, NCollection_Sequence& theSeq)
{
theSeq.Clear (this->myAllocator);
PSplit (theIndex, theSeq);
}
//! First item access
const TheItemType& First () const
{
#if !defined No_Exception && !defined No_Standard_NoSuchObject
if (mySize == 0)
Standard_NoSuchObject::Raise ("NCollection_Sequence::First");
#endif
return ((const Node *) myFirstItem) -> Value();
}
//! Last item access
const TheItemType& Last () const
{
#if !defined No_Exception && !defined No_Standard_NoSuchObject
if (mySize == 0)
Standard_NoSuchObject::Raise ("NCollection_Sequence::Last");
#endif
return ((const Node *) myLastItem) -> Value();
}
//! Constant item access by theIndex
const TheItemType& Value (const Standard_Integer theIndex) const
{
#if !defined No_Exception && !defined No_Standard_OutOfRange
if (theIndex <= 0 || theIndex > mySize)
Standard_OutOfRange::Raise ("NCollection_Sequence::Value");
#endif
NCollection_Sequence * const aLocalTHIS = (NCollection_Sequence *) this;
aLocalTHIS -> myCurrentItem = Find (theIndex);
aLocalTHIS -> myCurrentIndex = theIndex;
return ((const Node *) myCurrentItem) -> Value();
}
//! Constant operator()
const TheItemType& operator() (const Standard_Integer theIndex) const
{ return Value(theIndex); }
//! Variable item access by theIndex
TheItemType& ChangeValue (const Standard_Integer theIndex)
{
#if !defined No_Exception && !defined No_Standard_OutOfRange
if (theIndex <= 0 || theIndex > mySize)
Standard_OutOfRange::Raise ("NCollection_Sequence::ChangeValue");
#endif
myCurrentItem = Find (theIndex);
myCurrentIndex = theIndex;
return ((Node *) myCurrentItem) -> ChangeValue();
}
//! Variable operator()
TheItemType& operator() (const Standard_Integer theIndex)
{ return ChangeValue(theIndex); }
//! Set item value by theIndex
void SetValue (const Standard_Integer theIndex,
const TheItemType& theItem)
{ ChangeValue (theIndex) = theItem; }
// ******** Destructor - clears the Sequence
~NCollection_Sequence (void)
{ Clear(); }
private:
// ----------- PRIVATE METHODS -----------
//! Creates Iterator for use on BaseCollection
virtual TYPENAME NCollection_BaseCollection<TheItemType>::Iterator&
CreateIterator(void) const
{ return *(new (this->IterAllocator()) Iterator(*this)); }
// ---------- FRIEND CLASSES ------------
friend class Iterator;
};
#ifdef WNT
#pragma warning (pop)
#endif
#endif

View File

@@ -0,0 +1,227 @@
// File: NCollection_Set.hxx
// Created: 17.04.02 10:12:48
// Author: Alexander Kartomin (akm)
// <a-kartomin@opencascade.com>
// Copyright: Open Cascade 2002
#ifndef NCollection_Set_HeaderFile
#define NCollection_Set_HeaderFile
#include <NCollection_BaseCollection.hxx>
#include <NCollection_BaseList.hxx>
#include <NCollection_TListNode.hxx>
#include <NCollection_TListIterator.hxx>
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (disable:4291)
#endif
/**
* Purpose: A set is an unordered collection of items without
* duplications. To test for duplications the operators == and !=
* are used on the items.
* Inherits BaseList, adding the data item to each node.
*/
template <class TheItemType> class NCollection_Set
: public NCollection_BaseCollection<TheItemType>,
public NCollection_BaseList
{
public:
typedef NCollection_TListNode<TheItemType> SetNode;
typedef NCollection_TListIterator<TheItemType> Iterator;
public:
// ---------- PUBLIC METHODS ------------
//! Constructor
NCollection_Set(const Handle(NCollection_BaseAllocator)& theAllocator=0L) :
NCollection_BaseCollection<TheItemType>(theAllocator),
NCollection_BaseList() {}
//! Copy constructor
NCollection_Set (const NCollection_Set& theOther) :
NCollection_BaseCollection<TheItemType>(theOther.myAllocator),
NCollection_BaseList()
{ *this = theOther; }
//! Size - Number of items
virtual Standard_Integer Size (void) const
{ return Extent(); }
//! Replace this list by the items of theOther collection
virtual void Assign (const NCollection_BaseCollection<TheItemType>& theOther)
{
if (this == &theOther)
return;
Clear();
TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& anIter =
theOther.CreateIterator();
for (; anIter.More(); anIter.Next())
{
SetNode* pNew = new (this->myAllocator) SetNode(anIter.Value());
PAppend (pNew);
}
}
//! Replace this list by the items of theOther Set
NCollection_Set& operator= (const NCollection_Set& theOther)
{
if (this == &theOther)
return *this;
Clear ();
SetNode * pCur = (SetNode *) theOther.PFirst();
while (pCur)
{
SetNode* pNew = new (this->myAllocator) SetNode(pCur->Value());
PAppend (pNew);
pCur = (SetNode *) pCur->Next();
}
return *this;
}
//! Clear this set
void Clear (void)
{ PClear (SetNode::delNode, this->myAllocator); }
//! Add item
Standard_Boolean Add (const TheItemType& theItem)
{
Iterator anIter(*this);
while (anIter.More())
{
if (anIter.Value() == theItem)
return Standard_False;
anIter.Next();
}
SetNode * pNew = new (this->myAllocator) SetNode(theItem);
PPrepend (pNew);
return Standard_True;
}
//! Remove item
Standard_Boolean Remove (const TheItemType& theItem)
{
Iterator anIter(*this);
while (anIter.More())
{
if (anIter.Value() == theItem)
{
PRemove (anIter, SetNode::delNode, this->myAllocator);
return Standard_True;
}
anIter.Next();
}
return Standard_False;
}
//! Remove - wrapper against 'hiding' warnings
void Remove (Iterator& theIter)
{ NCollection_BaseList::PRemove (theIter,
SetNode::delNode,
this->myAllocator); }
//! Contains - item inclusion query
Standard_Boolean Contains (const TheItemType& theItem) const
{
Iterator anIter(*this);
for (; anIter.More(); anIter.Next())
if (anIter.Value() == theItem)
return Standard_True;
return Standard_False;
}
//! IsASubset
Standard_Boolean IsASubset (const NCollection_Set& theOther)
{
if (this == &theOther)
return Standard_True;
Iterator anIter(theOther);
for (; anIter.More(); anIter.Next())
if (!Contains(anIter.Value()))
return Standard_False;
return Standard_True;
}
//! IsAProperSubset
Standard_Boolean IsAProperSubset (const NCollection_Set& theOther)
{
if (myLength <= theOther.Extent())
return Standard_False;
Iterator anIter(theOther);
for (; anIter.More(); anIter.Next())
if (!Contains(anIter.Value()))
return Standard_False;
return Standard_True;
}
//! Union
void Union (const NCollection_Set& theOther)
{
if (this == &theOther)
return;
Iterator anIter(theOther);
Iterator aMyIter;
Standard_Integer i, iLength=myLength;
for (; anIter.More(); anIter.Next())
{
Standard_Boolean isIn=Standard_False;
const TheItemType& theItem = anIter.Value();
for (aMyIter.Init(*this), i=1;
i<=iLength;
aMyIter.Next(), i++)
if (theItem == aMyIter.Value())
isIn = Standard_True;
if (!isIn)
{
SetNode * pNew = new (this->myAllocator) SetNode(theItem);
PAppend (pNew);
}
}
}
//! Intersection
void Intersection (const NCollection_Set& theOther)
{
if (this == &theOther)
return;
Iterator anIter(*this);
while (anIter.More())
if (theOther.Contains(anIter.Value()))
anIter.Next();
else
NCollection_BaseList::PRemove (anIter, SetNode::delNode, this->myAllocator);
}
//! Difference (Subtraction)
void Difference (const NCollection_Set& theOther)
{
if (this == &theOther)
return;
Iterator anIter(*this);
while (anIter.More())
if (theOther.Contains(anIter.Value()))
NCollection_BaseList::PRemove (anIter, SetNode::delNode, this->myAllocator);
else
anIter.Next();
}
//! Destructor - clears the List
~NCollection_Set (void)
{ Clear(); }
private:
// ----------- PRIVATE METHODS -----------
//! Creates Iterator for use on BaseCollection
virtual TYPENAME NCollection_BaseCollection<TheItemType>::Iterator&
CreateIterator(void) const
{ return *(new (this->IterAllocator()) Iterator(*this)); }
};
#ifdef WNT
#pragma warning (default:4291)
#endif
#endif

View File

@@ -0,0 +1,274 @@
// File: NCollection_SparseArray.hxx
// Created: 23.11.06 11:12:02
// Author: Andrey BETENEV
// Copyright: Open Cascade 2006
#ifndef NCollection_SparseArray_HeaderFile
#define NCollection_SparseArray_HeaderFile
#include <NCollection_SparseArrayBase.hxx>
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (push)
#pragma warning (disable:4291)
#endif
/**
* Dynamically resizable sparse array of objects
*
* This class is similar to NCollection_Vector: it works like virtually
* unlimited array of items accessible by index; however unlike simple
* Vector it distinguishes items that have been set from the ones that
* have not been set explicitly.
*
* This class can be also seen as equivalence of
* NCollection_DataMap<Standard_Integer,TheItemType>
* with the only one practical difference: it can be much less
* memory-expensive if items are small (e.g. Integer or Handle).
*
* The index starts from 0, i.e. should be non-negative. Memory is allocated
* when item is set by SetValue().
*
* Iterator returns only defined items;
* the item can be tested for being defined by IsSet(),
* and undefined by UnsetValue().
*
* The attempt to access the item that has not been set will result
* in OutOfRange exception in Debug mode; in Release mode this will either
* return null-filled object or cause access violation.
*/
template <class TheItemType> class NCollection_SparseArray
: public NCollection_SparseArrayBase
{
public:
//! Constructor; accepts size of blocks
NCollection_SparseArray (Standard_Size theIncrement)
: NCollection_SparseArrayBase(sizeof(TheItemType),theIncrement)
{
}
//! Explicit assignment operator
NCollection_SparseArray& Assign (const NCollection_SparseArray& theOther)
{
this->assign (theOther);
return *this;
}
//! Exchange the data of two arrays;
//! can be used primarily to move contents of theOther into the new array
//! in a fast way (without creation of duplicated data)
void Exchange (NCollection_SparseArray& theOther)
{
this->exchange (theOther);
}
//! Destructor
virtual ~NCollection_SparseArray ()
{
Clear();
}
public:
//!@name Array-like interface (in addition to inherited methods)
//!@{
//! Direct const access to the item
const TheItemType& Value (const Standard_Integer theIndex) const
{
return *(const TheItemType*)this->getValue(theIndex);
}
//! Const access to the item - operator()
const TheItemType& operator () (const Standard_Integer theIndex) const
{
return Value (theIndex);
}
//! Modification access to the item
TheItemType& ChangeValue (const Standard_Integer theIndex)
{
return *(TheItemType*)(this->getValue (theIndex));
}
//! Access to the item - operator()
TheItemType& operator () (const Standard_Integer theIndex)
{
return ChangeValue (theIndex);
}
//! Set a value at specified index method
TheItemType& SetValue (const Standard_Integer theIndex,
const TheItemType& theValue)
{
return *(TheItemType*)this->setValue(theIndex, (Standard_Address)&theValue);
}
//!@}
public:
//!@name DataMap-like interface
//!@{
//! Returns number of items in the array
Standard_Size Extent () const
{
return Size();
}
//! Returns True if array is empty
Standard_Boolean IsEmpty () const
{
return Size() == 0;
}
//! Direct const access to the item
const TheItemType& Find (const Standard_Integer theIndex) const
{
return *(TheItemType*)this->getValue(theIndex);
}
//! Modification access to the item; allocates space if
//! necessary and marks the item as defined
TheItemType& ChangeFind (const Standard_Integer theIndex)
{
return *(TheItemType*)(this->changeValue (theIndex));
}
//! Set a value as explicit method
TheItemType& Bind (const Standard_Integer theIndex,
const TheItemType& theValue)
{
return SetValue(theIndex, theValue);
}
//! Returns True if the item is defined
Standard_Boolean IsBound (const Standard_Integer theIndex) const
{
return this->HasValue(theIndex);
}
//! Remove the item from array
Standard_Boolean UnBind (const Standard_Integer theIndex)
{
return this->UnsetValue(theIndex);
}
//!@}
public:
// Iterator interface
/**
* Implementation of type-specific const Iterator class
*/
class ConstIterator : public NCollection_SparseArrayBase::Iterator
{
public:
//! Empty constructor - for later Init
ConstIterator () {}
//! Constructor with initialisation
ConstIterator (const NCollection_SparseArray& theVector) :
NCollection_SparseArrayBase::Iterator (&theVector) {}
//! Initialisation
void Init (const NCollection_SparseArray& theVector)
{
this->init (&theVector);
}
//! Constant value access
const TheItemType& Value (void) const
{
return *(const TheItemType*)this->value();
}
//! Constant value access operator
const TheItemType& operator () (void) const
{
return *(const TheItemType*)this->value();
}
//! Access current index with 'a-la map' interface
Standard_Integer Key (void) const { return Index(); }
};
/**
* Implementation of type-specific non-const Iterator class
*/
class Iterator : public ConstIterator
{
public:
//! Empty constructor - for later Init
Iterator () {}
//! Constructor with initialisation
Iterator (NCollection_SparseArray& theVector) :
ConstIterator (theVector) {}
//! Initialisation
void Init (const NCollection_SparseArray& theVector)
{
this->init (&theVector);
}
//! Value access
TheItemType& ChangeValue (void)
{
return *(TheItemType*)this->value();
}
//! Value access operator
TheItemType& operator () (void)
{
return *(TheItemType*)this->value();
}
//! Const access operator - the same as in parent class
const TheItemType& operator () (void) const
{
return *(const TheItemType*)this->value();
}
};
private:
// Implementation of virtual methods providing type-specific behaviour
//! Create new item at the specified address with default constructor
// virtual void createItem (Standard_Address theAddress)
// {
// new (theAddress) TheItemType;
// }
//! Create new item at the specified address with copy constructor
//! from existing item
virtual void createItem (Standard_Address theAddress, Standard_Address theOther)
{
new (theAddress) TheItemType(*(const TheItemType*)theOther);
}
//! Call destructor to the item at given address
virtual void destroyItem (Standard_Address theAddress)
{
((TheItemType*)theAddress)->TheItemType::~TheItemType();
}
//! Call assignment operator to the item
virtual void copyItem (Standard_Address theAddress, Standard_Address theOther)
{
(*(TheItemType*)theAddress) = *(const TheItemType*)theOther;
}
};
#ifdef WNT
#pragma warning (pop)
#endif
#endif

View File

@@ -0,0 +1,345 @@
// File: NCollection_SparseArray.cxx
// Created: Tue Feb 6 18:54:25 2007
// Author: Andrey BETENEV
// Copyright: Open Cascade 2007
#include <NCollection_SparseArrayBase.hxx>
#include <Standard_ProgramError.hxx>
//=======================================================================
//function : allocData
//purpose :
//=======================================================================
void NCollection_SparseArrayBase::allocData (const Standard_Size iBlock)
{
if ( iBlock < myNbBlocks )
return;
// the allocation of blocks starts from myBlockSize items
// and then is multiplied by 2 every time reallocation is needed
Standard_Size newNbBlocks = ( myNbBlocks ? myNbBlocks * 2 : myBlockSize );
while (iBlock >= newNbBlocks) newNbBlocks *= 2;
Standard_Address* newData =
(Standard_Address*)malloc(newNbBlocks*sizeof(Standard_Address));
if ( myNbBlocks >0 )
memcpy (newData, myData, myNbBlocks*sizeof(Standard_Address));
memset (newData+myNbBlocks, 0, (newNbBlocks-myNbBlocks)*sizeof(Standard_Address));
free (myData);
myData = newData;
myNbBlocks = newNbBlocks;
}
//=======================================================================
//function : freeBlock
//purpose :
//=======================================================================
void NCollection_SparseArrayBase::freeBlock (const Standard_Size iBlock)
{
Standard_Address & anAddr = myData[iBlock];
Block aBlock = getBlock(anAddr);
for (Standard_Size anInd=0; anInd < myBlockSize; anInd++)
if ( aBlock.IsSet(anInd) )
{
destroyItem (getItem (aBlock, anInd));
mySize--;
}
free (anAddr);
anAddr = 0;
}
//=======================================================================
//function : Clear
//purpose :
//=======================================================================
void NCollection_SparseArrayBase::Clear ()
{
// free block data
for (Standard_Size iBlock=0; iBlock < myNbBlocks; iBlock++)
if ( myData[iBlock] )
freeBlock (iBlock);
// free blocks and reset counters
free (myData);
myData = 0;
myNbBlocks = 0;
// consistency check
Standard_ProgramError_Raise_if (mySize!=0,"NCollection_SparseArrayBase: Implementation error: inconsistent items count")
}
//=======================================================================
//function : assign
//purpose :
//=======================================================================
void NCollection_SparseArrayBase::assign (const NCollection_SparseArrayBase& theOther)
{
if (this == &theOther)
return;
// if block size is different, clear all data
if ( myBlockSize != theOther.myBlockSize )
Clear();
myBlockSize = theOther.myBlockSize;
// iterate by blocks in theOther
Standard_Size iBlock=0;
for (; iBlock < theOther.myNbBlocks; iBlock++)
{
if ( ! theOther.myData[iBlock] )
{
// if other block is empty, just make sure to empty that block in "this"
if ( iBlock < myNbBlocks && myData[iBlock] )
freeBlock (iBlock);
continue;
}
if ( iBlock >= myNbBlocks )
allocData(iBlock);
Block anOtherBlock = getBlock(theOther.myData[iBlock]);
// if block not yet allocated, just allocate and fill
Standard_Address & anAddr = myData[iBlock];
if ( ! anAddr )
{
anAddr = calloc (Block::Size(myBlockSize, myItemSize), sizeof(char));
Block aBlock ( getBlock(anAddr) );
for (Standard_Size anInd=0; anInd < myBlockSize; anInd++)
if ( anOtherBlock.IsSet(anInd) )
{
Standard_Address anItem = getItem (aBlock, anInd);
aBlock.Set(anInd);
(*aBlock.Count)++;
mySize++;
createItem (anItem, getItem(anOtherBlock, anInd));
}
}
// else perform copying item-by-item
else
{
Block aBlock ( getBlock(anAddr) );
for (Standard_Size anInd=0; anInd < myBlockSize; anInd++)
{
Standard_Address anItem = getItem (aBlock, anInd);
if ( anOtherBlock.IsSet(anInd) )
{
Standard_Address anOtherItem = getItem (anOtherBlock, anInd);
if ( aBlock.IsSet(anInd) ) // copy
{
copyItem (anItem, anOtherItem);
}
else // create
{
aBlock.Set(anInd);
(*aBlock.Count)++;
mySize++;
createItem (anItem, getItem(anOtherBlock, anInd));
}
}
else if ( aBlock.IsSet(anInd) ) // delete
{
aBlock.Set(anInd);
(*aBlock.Count)--;
mySize--;
destroyItem (anItem);
}
}
}
}
// clear any remaining blocks in this
for (; iBlock < myNbBlocks; iBlock++)
if ( myData[iBlock] )
freeBlock (iBlock);
// consistency check
Standard_ProgramError_Raise_if (mySize!=theOther.mySize,
"NCollection_SparseArrayBase: Implementation error: inconsistent items count")
}
//=======================================================================
//function : exchange
//purpose :
//=======================================================================
template<class T> static inline void sswap (T &a, T &b) { T c = a; a = b; b = c; }
void NCollection_SparseArrayBase::exchange (NCollection_SparseArrayBase& theOther)
{
if (this == &theOther)
return;
// swap fields of this and theOther
sswap (myItemSize, theOther.myItemSize);
sswap (myBlockSize,theOther.myBlockSize);
sswap (myNbBlocks, theOther.myNbBlocks);
sswap (mySize, theOther.mySize);
sswap (myData, theOther.myData);
}
//=======================================================================
//function : setValue
//purpose :
//=======================================================================
Standard_Address NCollection_SparseArrayBase::setValue (const Standard_Integer theIndex,
const Standard_Address theValue)
{
Standard_OutOfRange_Raise_if (theIndex<0,"NCollection_SparseArray::SetValue()")
Standard_Size anIndex = (Standard_Size)theIndex;
Standard_Size iBlock = anIndex / myBlockSize;
// resize blocks array if necessary
if ( iBlock >= myNbBlocks )
allocData (iBlock);
// allocate block if necessary
Standard_Address & anAddr = myData[iBlock];
if ( ! anAddr )
anAddr = calloc (Block::Size(myBlockSize, myItemSize), sizeof(char));
// get a block
Block aBlock (getBlock (anAddr));
// mark item as defined
Standard_Size anInd = anIndex % myBlockSize;
Standard_Address anItem = getItem (aBlock, anInd);
// either create an item by copy constructor if it is new, or assign it
if ( aBlock.Set(anInd) )
{
(*aBlock.Count)++;
mySize++;
createItem (anItem, theValue);
}
else
copyItem (anItem, theValue);
return anItem;
}
//=======================================================================
//function : HasValue
//purpose :
//=======================================================================
Standard_Boolean NCollection_SparseArrayBase::HasValue (const Standard_Integer theIndex) const
{
Standard_Size anIndex = (Standard_Size)theIndex;
Standard_Size iBlock = anIndex / myBlockSize;
if ( theIndex < 0 || iBlock >= myNbBlocks ||
! myData[iBlock] )
return Standard_False;
return getBlock(myData[iBlock]).IsSet(anIndex % myBlockSize) ? Standard_True : Standard_False;
}
//=======================================================================
//function : UnsetValue
//purpose :
//=======================================================================
Standard_Boolean NCollection_SparseArrayBase::UnsetValue (const Standard_Integer theIndex)
{
// check that the item is defined
Standard_Size anIndex = (Standard_Size)theIndex;
Standard_Size iBlock = anIndex / myBlockSize;
if ( theIndex < 0 || iBlock >= myNbBlocks || ! myData[iBlock] )
return Standard_False;
Block aBlock (getBlock(myData[iBlock]));
Standard_Size anInd = anIndex % myBlockSize;
if ( ! aBlock.Unset(anInd) )
return Standard_False;
// destroy the item
destroyItem (getItem (aBlock, anInd));
(*aBlock.Count)--;
mySize--;
// free block if it becomes empty
if ( ! (*aBlock.Count) )
freeBlock (iBlock);
return Standard_True;
}
//=======================================================================
//function : Iterator::Iterator
//purpose :
//=======================================================================
NCollection_SparseArrayBase::Iterator::Iterator (const NCollection_SparseArrayBase* theArray)
: myArr((NCollection_SparseArrayBase*)theArray),
myHasMore(Standard_False), myIBlock(0), myInd(0),
myBlock(0,0,0)
{
init(theArray);
}
//=======================================================================
//function : Iterator::Next
//purpose :
//=======================================================================
void NCollection_SparseArrayBase::Iterator::Next ()
{
if ( ! myArr || ! myHasMore )
return;
// iterate by items and blocks
for ( myInd++; ; myInd++ ) {
// if index is over the block size, advance to the next non-empty block
if ( myInd >= myArr->myBlockSize )
{
for ( myIBlock++; ; myIBlock++ ) {
if ( myIBlock >= myArr->myNbBlocks ) // end
{
myHasMore = Standard_False;
return;
}
if ( myArr->myData[myIBlock] )
{
myInd = 0;
myBlock = Block (myArr->myData[myIBlock], myArr->myBlockSize, myArr->myItemSize );
break;
}
}
}
// check if item is defined
if ( myBlock.IsSet (myInd) )
return;
}
}
//=======================================================================
//function : Iterator::init
//purpose :
//=======================================================================
void NCollection_SparseArrayBase::Iterator::init (const NCollection_SparseArrayBase* theArray)
{
myArr = (NCollection_SparseArrayBase*)theArray;
myHasMore = Standard_False;
if ( myArr )
{
myInd = 0;
// find first non-empty block
for ( myIBlock=0; myIBlock < myArr->myNbBlocks; myIBlock++ )
{
if ( ! myArr->myData[myIBlock] )
continue;
myHasMore = Standard_True;
myBlock = Block (myArr->myData[myIBlock], myArr->myBlockSize, myArr->myItemSize );
// if first item in the block is not set, advance to the next defined item
if ( ! myBlock.IsSet(myInd) )
Next();
return;
}
}
}

View File

@@ -0,0 +1,276 @@
// File: NCollection_SparseArrayBase.hxx
// Created: 23.01.07 11:12:02
// Author: Andrey BETENEV
// Copyright: Open Cascade 2007
#ifndef NCollection_SparseArrayBase_HeaderFile
#define NCollection_SparseArrayBase_HeaderFile
#include <Standard.hxx>
#include <Standard_OutOfRange.hxx>
typedef size_t Standard_Size;
/**
* Base class for NCollection_SparseArray;
* provides non-template implementation of general mechanics
* of block allocation, items creation / deletion etc.
*/
class NCollection_SparseArrayBase
{
public:
//!@name Type-independent public interface
//!@{
//! Clears all the data
Standard_EXPORT void Clear ();
//! Returns number of currently contained items
Standard_Integer Size () const { return mySize; }
//! Check whether the value at given index is set
Standard_EXPORT Standard_Boolean HasValue (const Standard_Integer theIndex) const;
//! Deletes the item from the array;
//! returns True if that item was defined
Standard_EXPORT Standard_Boolean UnsetValue (const Standard_Integer theIndex);
//!@}
#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)
public: // work-around against obsolete SUN WorkShop 5.3 compiler
#else
private:
#endif
/**
* The block of data contains array of items, counter
* and bit field, allocated as single piece of memory addressed
* from the blocks array (myData).
*
* The Block structure provides a logical view on the block,
* and provides methods to work with bit map.
*
* Note that NCollection_SparseArrayBase class takes responsibility
* for correct allocation/deallocation of all the data.
*/
class Block {
public:
typedef unsigned char Cell; //!< type of items used to hold bits
//! Number of bits in each cell
static Standard_Size BitsPerCell() { return sizeof(Cell) * 8/*BITSPERBYTE*/; }
public:
//! Initializes the block by pointer to block data
Block (const Standard_Address theAddr, const Standard_Size theNbItems,
const Standard_Size theItemSize)
: Count((Standard_Size*)theAddr),
Array((char*)theAddr + sizeof(Standard_Size)),
Bits ((Cell*)((char*)theAddr + sizeof(Standard_Size) + theNbItems * theItemSize))
{
}
//! Compute required size for block data, in bytes
static Standard_Size Size (const Standard_Size theNbItems,
const Standard_Size theItemSize)
{
return sizeof(Standard_Size) +
sizeof(Cell) * ( (theNbItems + BitsPerCell() - 1) / BitsPerCell() ) +
theNbItems * theItemSize;
}
//! Returns address of array from address of block
static char* ToArray (const Standard_Address theAddress,
const Standard_Size /*theNbItems*/,
const Standard_Size /*theItemSize*/)
{
return (char*)theAddress + sizeof(Standard_Size);
}
public:
//! Set bit for i-th item; returns non-null if that bit has
//! not been set previously
Cell Set (Standard_Size i)
{
Cell* abyte = Bits + i / BitsPerCell();
Cell amask = (Cell)( '\1' << ( i % BitsPerCell() ) );
Cell anold = ( *abyte & amask );
*abyte |= amask;
return ! anold;
}
//! Check bit for i-th item; returns non-null if that bit is set
Cell IsSet (Standard_Size i)
{
Cell* abyte = Bits + i / BitsPerCell();
Cell amask = (Cell)( '\1' << ( i % BitsPerCell() ) );
return ( *abyte & amask );
}
//! Unset bit for i-th item; returns non-null if that bit
//! has been set previously
Cell Unset (Standard_Size i)
{
Cell* abyte = Bits + i / BitsPerCell();
Cell amask = (Cell)( '\1' << ( i % BitsPerCell() ) );
Cell anold = ( *abyte & amask );
*abyte &= ~amask;
return anold;
}
public:
Standard_Size* Count; //!< items counter
Standard_Address Array; //!< pointer to the data items array
Cell* Bits; //!< bit map for defined/undefined flags
};
public:
/**
* Iterator
*/
class Iterator {
public:
// Public interface
//! Restart iterations on the same array
void Restart () { init(myArr); }
//! Returns True if current item is available
Standard_Boolean More () const { return myHasMore; }
//! Advances to the next item
Standard_EXPORT void Next ();
//! Returns current index
Standard_EXPORT Standard_Size Index () const
{
return myIBlock * myArr->myBlockSize + myInd;
}
protected:
// Methods for descendant
//! Empty constructor
Standard_EXPORT Iterator (const NCollection_SparseArrayBase* theArray=0);
//! Initialize by the specified array
Standard_EXPORT void init (const NCollection_SparseArrayBase* theArray);
//! Returns address of the current item
Standard_Address value () const
{
return myArr->getItem (myBlock, myInd);
}
private:
const NCollection_SparseArrayBase *myArr;
Standard_Boolean myHasMore;
Standard_Size myIBlock;
Standard_Size myInd;
Block myBlock;
};
friend class Iterator;
private:
// Copy constructor and assignment operator are private thus not accessible
NCollection_SparseArrayBase (const NCollection_SparseArrayBase&) {}
void operator = (const NCollection_SparseArrayBase&) {}
protected:
// Object life
//! Constructor; initialized by size of item and of block (in items)
NCollection_SparseArrayBase (Standard_Size theItemSize,
Standard_Size theBlockSize)
: myItemSize(theItemSize), myBlockSize(theBlockSize),
myNbBlocks(0), mySize(0), myData(0)
{
}
//! Destructor
virtual ~NCollection_SparseArrayBase ()
{
Clear();
}
protected:
// Data access interface for descendants
//! Creates Block structure for block pointed by theAddr
Block getBlock (const Standard_Address theAddr) const
{
return Block (theAddr, myBlockSize, myItemSize);
}
//! Find address of the item in the block by index (in the block)
Standard_Address getItem (const Block &theBlock, Standard_Size theInd) const
{
return ((char*)theBlock.Array) + myItemSize * theInd;
}
//! Direct const access to the item
Standard_Address getValue (const Standard_Integer theIndex) const
{
Standard_OutOfRange_Raise_if (!HasValue(theIndex),"NCollection_SparseArray::Value()")
return Block::ToArray(myData[theIndex/myBlockSize], myBlockSize, myItemSize) +
myItemSize * (theIndex % myBlockSize);
}
//! Set a value to the specified item; returns address of the set item
Standard_EXPORT Standard_Address setValue (const Standard_Integer theIndex,
const Standard_Address theValue);
//! Modification access to the item; allocates necessary space
//! and marks the item as defined
Standard_EXPORT Standard_Address changeValue (const Standard_Integer theIndex);
//! Copy contents of theOther to this;
//! assumes that this and theOther have exactly the same type of arguments
Standard_EXPORT void assign (const NCollection_SparseArrayBase& theOther);
//! Exchange contents of theOther and this;
//! assumes that this and theOther have exactly the same type of arguments
Standard_EXPORT void exchange (NCollection_SparseArrayBase& theOther);
protected:
// Methods to be provided by descendant
//! Create new item at the specified address with default constructor
// virtual void createItem (Standard_Address theAddress) = 0;
//! Create new item at the specified address with copy constructor
//! from existing item
virtual void createItem (Standard_Address theAddress, Standard_Address theOther) = 0;
//! Call destructor to the item
virtual void destroyItem (Standard_Address theAddress) = 0;
//! Call assignment operator to the item
virtual void copyItem (Standard_Address theAddress, Standard_Address theOther) = 0;
private:
// Implementation of memory allocation/deallocation and access mechanics
//! Allocate space for at least iBlock+1 blocks
void allocData (const Standard_Size iBlock);
//! Free specified block
void freeBlock (const Standard_Size iBlock);
protected:
Standard_Size myItemSize; //!< size of item
Standard_Size myBlockSize; //!< block size (in items)
Standard_Size myNbBlocks; //!< allocated size of blocks table
Standard_Size mySize; //!< number of currently defined items
Standard_Address *myData; //!< array of pointers to data blocks
};
#endif

View File

@@ -0,0 +1,142 @@
// File: NCollection_Stack.hxx
// Created: 17.04.02 10:12:48
// <a-kartomin@opencascade.com>
// Author: Alexander Kartomin (akm)
// Copyright: Open Cascade 2002
#ifndef NCollection_Stack_HeaderFile
#define NCollection_Stack_HeaderFile
#include <NCollection_BaseCollection.hxx>
#include <NCollection_BaseList.hxx>
#include <NCollection_TListNode.hxx>
#include <NCollection_TListIterator.hxx>
#if !defined No_Exception && !defined No_Standard_NoSuchObject
#include <Standard_NoSuchObject.hxx>
#endif
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (disable:4291)
#endif
/**
* Purpose: A stack is a structure where item can be added and
* removed from the top. Like a stack of plates in a
* kitchen. The last entered item will be be the
* first removed. This is called a LIFO (last In First Out).
* Inherits BaseList, adding the data item to each node.
*/
template <class TheItemType> class NCollection_Stack
: public NCollection_BaseCollection<TheItemType>,
public NCollection_BaseList
{
public:
typedef NCollection_TListNode<TheItemType> StackNode;
typedef NCollection_TListIterator<TheItemType> Iterator;
public:
// ---------- PUBLIC METHODS ------------
//! Constructor
NCollection_Stack(const Handle(NCollection_BaseAllocator)& theAllocator=0L) :
NCollection_BaseCollection<TheItemType>(theAllocator),
NCollection_BaseList() {}
//! Copy constructor
NCollection_Stack (const NCollection_Stack& theOther) :
NCollection_BaseCollection<TheItemType>(theOther.myAllocator),
NCollection_BaseList()
{ *this = theOther; }
//! Size - Number of items
virtual Standard_Integer Size (void) const
{ return Extent(); }
//! Depth - Number of items
Standard_Integer Depth (void) const
{ return Extent(); }
//! Replace this list by the items of theOther collection
virtual void Assign (const NCollection_BaseCollection<TheItemType>& theOther)
{
if (this == &theOther)
return;
Clear();
TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& anIter =
theOther.CreateIterator();
for (; anIter.More(); anIter.Next())
{
StackNode* pNew = new (this->myAllocator) StackNode(anIter.Value());
PAppend(pNew);
}
}
//! Replace this list by the items of theOther Stack
NCollection_Stack& operator= (const NCollection_Stack& theOther)
{
if (this == &theOther)
return *this;
Clear ();
StackNode * pCur = (StackNode *) theOther.PFirst();
while (pCur)
{
StackNode* pNew = new (this->myAllocator) StackNode(pCur->Value());
PAppend(pNew);
pCur = (StackNode *) pCur->Next();
}
return *this;
}
//! Clear this stack
void Clear (void)
{ PClear (StackNode::delNode, this->myAllocator); }
//! Top item - constant
const TheItemType& Top (void) const
{
#if !defined No_Exception && !defined No_Standard_NoSuchObject
if (IsEmpty()) Standard_NoSuchObject::Raise ("NCollection_Stack::Top");
#endif
return ((StackNode *) PFirst())->Value();
}
//! Top item - variable
TheItemType& ChangeTop (void)
{
#if !defined No_Exception && !defined No_Standard_NoSuchObject
if (IsEmpty()) Standard_NoSuchObject::Raise("NCollection_Stack::ChangeTop");
#endif
return ((StackNode *) PFirst())->ChangeValue();
}
//! Push one item
void Push (const TheItemType& theItem)
{
StackNode * pNew = new (this->myAllocator) StackNode(theItem);
PPrepend(pNew);
}
//! Pop top item
void Pop (void)
{ PRemoveFirst (StackNode::delNode, this->myAllocator); }
//! Destructor - clears the List
~NCollection_Stack (void)
{ Clear(); }
private:
// ----------- PRIVATE METHODS -----------
//! Creates Iterator for use on BaseCollection
virtual TYPENAME NCollection_BaseCollection<TheItemType>::Iterator&
CreateIterator(void) const
{ return *(new (this->IterAllocator()) Iterator(*this)); }
};
#ifdef WNT
#pragma warning (default:4291)
#endif
#endif

View File

@@ -0,0 +1,26 @@
// File: NCollection_StdBase.hxx
// Created: Sun May 04 17:30:38 2003
// Author: Alexander Grigoriev
// DEFINITION OF BASE COLLECTIONS FOR Open Cascade STANDARD TYPES
#ifndef _NCollection_StdBase_HeaderFile
#define _NCollection_StdBase_HeaderFile
#include <Standard_PrimitiveTypes.hxx>
#include <TCollection_AsciiString.hxx>
#include <TCollection_ExtendedString.hxx>
#include <NCollection_DefineBaseCollection.hxx>
DEFINE_BASECOLLECTION(NCollection_BaseCollInteger , Standard_Integer)
DEFINE_BASECOLLECTION(NCollection_BaseCollReal , Standard_Real)
DEFINE_BASECOLLECTION(NCollection_BaseCollCharacter , Standard_Character)
DEFINE_BASECOLLECTION(NCollection_BaseCollBoolean , Standard_Boolean)
DEFINE_BASECOLLECTION(NCollection_BaseCollAsciiString ,
TCollection_AsciiString)
DEFINE_BASECOLLECTION(NCollection_BaseCollExtendedString,
TCollection_ExtendedString)
DEFINE_BASECOLLECTION(NCollection_BaseCollTransient ,
Handle_Standard_Transient)
#endif

View File

@@ -0,0 +1,67 @@
// File: NCollection_TListIterator.hxx
// Created: Tue Apr 23 17:33:02 2002
// Author: Alexander KARTOMIN
// <a-kartomin@opencascade.com>
#ifndef NCollection_TListIterator_HeaderFile
#define NCollection_TListIterator_HeaderFile
#include <NCollection_BaseCollection.hxx>
#include <NCollection_BaseList.hxx>
#include <NCollection_TListNode.hxx>
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (push)
#pragma warning (disable:4291)
#endif
/**
* Purpose: This Iterator class iterates on BaseList of TListNode and is
* instantiated in List/Set/Queue/Stack
* Remark: TListIterator is internal class
*/
template <class TheItemType> class NCollection_TListIterator
: public NCollection_BaseCollection<TheItemType>::Iterator,
public NCollection_BaseList::Iterator
{
public:
//! Empty constructor - for later Init
NCollection_TListIterator (void) :
NCollection_BaseList::Iterator () {}
//! Constructor with initialisation
NCollection_TListIterator (const NCollection_BaseList& theList) :
NCollection_BaseList::Iterator (theList) {}
//! Assignment
NCollection_TListIterator& operator= (const NCollection_TListIterator& theIt)
{
NCollection_BaseList::Iterator& me = * this;
me.operator= (theIt);
return * this;
}
//! Check end
virtual Standard_Boolean More (void) const
{ return (myCurrent!=NULL); }
//! Make step
virtual void Next (void)
{
myPrevious = myCurrent;
myCurrent = myCurrent->Next();
}
//! Constant Value access
virtual const TheItemType& Value (void) const
{ return ((const NCollection_TListNode<TheItemType>*) myCurrent)->Value(); }
//! Variable Value access
virtual TheItemType& ChangeValue (void) const
{ return ((NCollection_TListNode<TheItemType> *)myCurrent)->ChangeValue(); }
//! Operator new for allocating iterators
void* operator new(size_t theSize,
const Handle(NCollection_BaseAllocator)& theAllocator)
{ return theAllocator->Allocate(theSize); }
};
#ifdef WNT
#pragma warning (pop)
#endif
#endif

View File

@@ -0,0 +1,56 @@
// File: NCollection_TListNode.hxx
// Created: Tue Apr 23 17:30:38 2002
// Author: Alexander KARTOMIN (akm)
// <akm@opencascade.com>
#ifndef NCollection_TListNode_HeaderFile
#define NCollection_TListNode_HeaderFile
#include <NCollection_ListNode.hxx>
#include <NCollection_BaseAllocator.hxx>
#ifdef WNT
// Disable the warning "operator new unmatched by delete"
#pragma warning (push)
#pragma warning (disable:4291)
#endif
/**
* Purpose: Abstract list node class. Used by BaseList
* Remark: Internal class
*/
template <class TheItemType> class NCollection_TListNode
: public NCollection_ListNode
{
public:
//! Constructor
NCollection_TListNode (const TheItemType& theItem,
NCollection_ListNode* theNext=NULL) :
NCollection_ListNode (theNext) { myValue = theItem; }
//! Constant value access
const TheItemType& Value () const { return myValue; }
//! Variable value access
TheItemType& ChangeValue () { return myValue; }
//! Memory allocation
void* operator new(size_t theSize,
const Handle(NCollection_BaseAllocator)& theAllocator)
{ return theAllocator->Allocate(theSize); }
//! Static deleter to be passed to BaseList
static void delNode (NCollection_ListNode * theNode,
Handle(NCollection_BaseAllocator)& theAl)
{
((NCollection_TListNode *) theNode)->myValue.~TheItemType();
theAl->Free(theNode);
}
protected:
TheItemType myValue; //!< The item stored in the node
};
#ifdef WNT
#pragma warning (pop)
#endif
#endif

View File

@@ -0,0 +1,19 @@
// File: NCollection_TypeDef.hxx
// Created: Wed Aug 24 09:22:55 2005
// Author: ABV
//
// Purpose: Defines some portability macros
#ifndef NCollection_TypeDef_HeaderFile
#define NCollection_TypeDef_HeaderFile
// Macro TYPENAME - either C++ keyword typename, or empty on
// platforms that do not support it
#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)
// work-around against obsolete SUN WorkShop 5.3 compiler
#define TYPENAME
#else
#define TYPENAME typename
#endif
#endif

View File

@@ -0,0 +1,502 @@
// File: NCollection_UBTree.hxx
// Created: 30.07.02 09:51:33
// Author: Michael SAZONOV
// Copyright: Open CASCADE 2002
#ifndef NCollection_UBTree_HeaderFile
#define NCollection_UBTree_HeaderFile
#include <NCollection_BaseAllocator.hxx>
#ifdef WNT
// Disable the warning: "operator new unmatched by delete"
#pragma warning (push)
#pragma warning (disable:4291)
#endif
/**
* The algorithm of unbalanced binary tree of overlapped bounding boxes.
*
* Once the tree of boxes of geometric objects is constructed, the algorithm
* is capable of fast geometric selection of objects. The tree can be easily
* updated by adding to it a new object with bounding box.
*
* The time of adding to the tree of one object is O(log(N)), where N is the
* total number of objects, so the time of building a tree of N objects is
* O(N(log(N)). The search time of one object is O(log(N)).
*
* Defining various classes inheriting NCollection_UBTree::Selector we can
* perform various kinds of selection over the same b-tree object
*
* The object may be of any type allowing copying. Among the best suitable
* solutions there can be a pointer to an object, handled object or integer
* index of object inside some collection. The bounding object may have any
* dimension and geometry. The minimal interface of TheBndType (besides
* public empty and copy constructor and operator =) used in UBTree algorithm
* is as the following:
* @code
* class MyBndType
* {
* public:
* inline void Add (const MyBndType& other);
* // Updates me with other bounding
*
* inline Standard_Boolean IsOut (const MyBndType& other) const;
* // Classifies other bounding relatively me
*
* inline Standard_Real SquareExtent() const;
* // Computes the squared maximal linear extent of me.
* // (For box it is the squared diagonal of box)
* };
* @endcode
* To select objects you need to define a class derived from UBTree::Selector
* that should redefine the necessary virtual methods to maintain the
* selection condition. The object of this class is also used to retrieve
* selected objects after search.
*/
template <class TheObjType, class TheBndType> class NCollection_UBTree
{
public:
// ---------- PUBLIC TYPES ----------
/**
* Class defining the minimal interface of selector.
*/
class Selector
{
public:
/**
* Constructor
*/
Selector () : myStop(Standard_False) {}
/**
* Rejection base on the bounding type.
* @return
* True if the bounding box does not conform to some selection conditions
*/
virtual Standard_Boolean Reject (const TheBndType&) const = 0;
/**
* Confirm the object while making necessary tests on it. This method is
* called when the bounding box of the object conforms to the conditions
* (see Reject()). It is also supposed to keep record of accepted objects.
* @return
* True if the object is accepted
*/
virtual Standard_Boolean Accept (const TheObjType&) = 0;
/**
* This condition is checked after each call to Accept().
* @return
* True signals that the selection process is stopped
*/
Standard_Boolean Stop () const { return myStop; }
/**
* Destructor
*/
virtual ~Selector () {}
protected:
/**
* The method Accept() should set this flag if the selection process
* is to be stopped
*/
Standard_Boolean myStop;
};
/**
* Class describing the node of the tree.
* Initially the tree consists of one leaf. A node can grow to a branch
* holding two childs:
* - one correspondent to initial node
* - the new one with a new object and bounding box
*/
class TreeNode
{
public:
TreeNode (const TheObjType& theObj, const TheBndType& theBnd)
: myBnd(theBnd), myObject(theObj), myChildren(0), myParent(0) {}
Standard_Boolean IsLeaf () const { return !myChildren; }
Standard_Boolean IsRoot () const { return !myParent; }
const TheBndType& Bnd () const { return myBnd; }
TheBndType& ChangeBnd () { return myBnd; }
const TheObjType& Object () const { return myObject; }
const TreeNode& Child (const Standard_Integer i) const
{ return myChildren[i]; }
TreeNode& ChangeChild (const Standard_Integer i)
{ return myChildren[i]; }
const TreeNode& Parent () const { return *myParent; }
TreeNode& ChangeParent () { return *myParent; }
/**
* Forces *this node being gemmated such a way that it becomes
* a branch holding the previous content of *this node at the
* first child and theObj at the second child.
* @param TheNewBnd
* new bounding box comprizing both child nodes.
* @param theObj
* added object.
* @param theBnd
* bounding box of theObj.
* @theAlloc
* allocator providing memory to the new child nodes, provided by the
* calling Tree instance.
*/
void Gemmate (const TheBndType& theNewBnd,
const TheObjType& theObj,
const TheBndType& theBnd,
const Handle(NCollection_BaseAllocator)& theAlloc)
{
//TreeNode *children = new TreeNode [2];
TreeNode *children = (TreeNode *) theAlloc->Allocate (2*sizeof(TreeNode));
new (&children[0]) TreeNode;
new (&children[1]) TreeNode;
children[0] = *this;
children[1].myObject = theObj;
children[1].myBnd = theBnd;
children[0].myParent = children[1].myParent = this;
if (!IsLeaf()) {
myChildren[0].myParent = children;
myChildren[1].myParent = children;
}
myChildren = children;
myBnd = theNewBnd;
myObject = TheObjType(); // nullify myObject
}
/**
* Kills the i-th child, and *this accepts the content of another child
*/
void Kill (const Standard_Integer i,
const Handle(NCollection_BaseAllocator)& theAlloc)
{
if (!IsLeaf()) {
TreeNode *oldChildren = myChildren;
const Standard_Integer iopp = 1 - i;
myBnd = oldChildren[iopp].myBnd;
myObject = oldChildren[iopp].myObject;
myChildren = oldChildren[iopp].myChildren;
if (!IsLeaf()) {
myChildren[0].myParent = this;
myChildren[1].myParent = this;
}
// oldChildren[0].myChildren = oldChildren[1].myChildren = 0L;
// delete [] oldChildren;
oldChildren[iopp].~TreeNode();
delNode(&oldChildren[i], theAlloc); // remove the whole branch
theAlloc->Free(oldChildren);
}
}
// ~TreeNode () { if (myChildren) delete [] myChildren; }
~TreeNode () { myChildren = 0L; }
/**
* Allocator of a tree node.
*/
void * operator new (size_t theSize,
const Handle(NCollection_BaseAllocator)& theAllocator)
{ return theAllocator->Allocate(theSize); }
/**
* Allocator of a tree node.
*/
void * operator new (size_t,
void * theMem)
{ return theMem; }
/**
* Deleter of tree node. The whole hierarchy of its children also deleted.
* This method should be used instead of operator delete.
*/
static void delNode (TreeNode * theNode,
Handle(NCollection_BaseAllocator)& theAlloc)
{
if (theNode) {
if (theNode -> myChildren) {
delNode (&theNode -> myChildren[0], theAlloc);
delNode (&theNode -> myChildren[1], theAlloc);
theAlloc->Free(theNode -> myChildren);
}
theNode->~TreeNode();
}
}
private:
TreeNode () : myChildren(0L), myParent(0L) {}
TheBndType myBnd; ///< bounding geometry
TheObjType myObject; ///< the object
TreeNode *myChildren; ///< 2 children forming a b-tree
TreeNode *myParent; ///< the pointer to a parent node
};
// ---------- PUBLIC METHODS ----------
/**
* Constructor.
*/
NCollection_UBTree
(const Handle(NCollection_BaseAllocator)& theAllocator=0L)
: myRoot(0L), myLastNode(0L)
{
if (theAllocator.IsNull())
myAlloc = NCollection_BaseAllocator::CommonBaseAllocator();
else
myAlloc = theAllocator;
}
/**
* Update the tree with a new object and its bounding box.
* @param theObj
* added object
* @param theBnd
* bounding box of the object.
* @return
* always True
*/
Standard_EXPORT virtual Standard_Boolean Add (const TheObjType& theObj,
const TheBndType& theBnd);
/**
* Searches in the tree all objects conforming to the given selector.
* return
* Number of objects accepted
*/
Standard_Integer Select (Selector& theSelector) const
{ return (IsEmpty() ? 0 : Select (Root(), theSelector)); }
/**
* Clears the contents of the tree.
* @param aNewAlloc
* Optional: a new allocator that will be used when the tree is rebuilt
* anew. This makes sense if the memory allocator needs re-initialisation
* (like NCollection_IncAllocator). By default the previous allocator is
* kept.
*/
virtual void Clear (const Handle(NCollection_BaseAllocator)& aNewAlloc = 0L)
// { if (myRoot) delete myRoot; myRoot = 0L; }
{
if (myRoot) {
TreeNode::delNode (myRoot, this->myAlloc);
this->myAlloc->Free (myRoot);
myRoot = 0L;
}
if (aNewAlloc.IsNull() == Standard_False)
myAlloc = aNewAlloc;
}
Standard_Boolean IsEmpty () const { return !myRoot; }
/**
* @return
* the root node of the tree
*/
const TreeNode& Root () const { return *myRoot; }
/**
* Desctructor.
*/
virtual ~NCollection_UBTree () { Clear(); }
/**
* Recommended to be used only in sub-classes.
* @return
* Allocator object used in this instance of UBTree.
*/
const Handle(NCollection_BaseAllocator)& Allocator () const
{ return myAlloc; }
protected:
// ---------- PROTECTED METHODS ----------
/**
* @return
* the last added node
*/
TreeNode& ChangeLastNode () { return *myLastNode; }
/**
* Searches in the branch all objects conforming to the given selector.
* @return
* the number of objects accepted
*/
Standard_EXPORT Standard_Integer Select (const TreeNode& theBranch,
Selector& theSelector) const;
private:
// ---------- PRIVATE METHODS ----------
/// Copy constructor (prohibited).
NCollection_UBTree (const NCollection_UBTree&);
/// Assignment operator (prohibited).
NCollection_UBTree& operator = (const NCollection_UBTree&);
// ---------- PRIVATE FIELDS ----------
TreeNode *myRoot; ///< root of the tree
TreeNode *myLastNode;///< the last added node
Handle(NCollection_BaseAllocator) myAlloc; ///< Allocator for TreeNode
};
// ================== METHODS TEMPLATES =====================
//=======================================================================
//function : Add
//purpose : Updates the tree with a new object and its bounding box
//=======================================================================
template <class TheObjType, class TheBndType>
Standard_Boolean NCollection_UBTree<TheObjType,TheBndType>::Add
(const TheObjType& theObj,
const TheBndType& theBnd)
{
if (IsEmpty()) {
// Accepting first object
myRoot = new (this->myAlloc) TreeNode (theObj, theBnd);
myLastNode = myRoot;
return Standard_True;
}
TreeNode *pBranch = myRoot;
Standard_Boolean isOutOfBranch = pBranch->Bnd().IsOut (theBnd);
for(;;) {
// condition of stopping the search
if (isOutOfBranch || pBranch->IsLeaf()) {
TheBndType aNewBnd = theBnd;
aNewBnd.Add (pBranch->Bnd());
// put the new leaf aside on the level of pBranch
pBranch->Gemmate (aNewBnd, theObj, theBnd, this->myAlloc);
myLastNode = &pBranch->ChangeChild(1);
break;
}
// Update the bounding box of the branch
pBranch->ChangeBnd().Add (theBnd);
// Select the best child branch to accept the object:
// 1. First check if one branch is out and another one is not.
// 2. Else select the child having the least union with theBnd
Standard_Integer iBest = 0;
Standard_Boolean isOut[] = { pBranch->Child(0).Bnd().IsOut (theBnd),
pBranch->Child(1).Bnd().IsOut (theBnd) };
if (isOut[0] != isOut[1])
iBest = (isOut[0] ? 1 : 0);
else {
TheBndType aUnion[] = { theBnd, theBnd };
aUnion[0].Add (pBranch->Child(0).Bnd());
aUnion[1].Add (pBranch->Child(1).Bnd());
const Standard_Real d1 = aUnion[0].SquareExtent();
const Standard_Real d2 = aUnion[1].SquareExtent();
if (d1 > d2)
iBest = 1;
}
// Continue with the selected branch
isOutOfBranch = isOut[iBest];
pBranch = &pBranch->ChangeChild(iBest);
}
return Standard_True;
}
//=======================================================================
//function : Select
//purpose : Recursively searches in the branch all objects conforming
// to the given selector.
// Returns the number of objects found.
//=======================================================================
template <class TheObjType, class TheBndType>
Standard_Integer NCollection_UBTree<TheObjType,TheBndType>::Select
(const TreeNode& theBranch,
Selector& theSelector) const
{
// Try to reject the branch by bounding box
if (theSelector.Reject (theBranch.Bnd()))
return 0;
Standard_Integer nSel = 0;
if (theBranch.IsLeaf()) {
// It is a leaf => try to accept the object
if (theSelector.Accept (theBranch.Object()))
nSel++;
}
else {
// It is a branch => select from its children
nSel += Select (theBranch.Child(0), theSelector);
if (!theSelector.Stop())
nSel += Select (theBranch.Child(1), theSelector);
}
return nSel;
}
// ======================================================================
/**
* Declaration of handled version of NCollection_UBTree.
* In the macros below the arguments are:
* _HUBTREE - the desired name of handled class
* _OBJTYPE - the name of the object type
* _BNDTYPE - the name of the bounding box type
* _HPARENT - the name of parent class (usually MMgt_TShared)
*/
#define DEFINE_HUBTREE(_HUBTREE, _OBJTYPE, _BNDTYPE, _HPARENT) \
class _HUBTREE : public _HPARENT \
{ \
public: \
typedef NCollection_UBTree <_OBJTYPE, _BNDTYPE> UBTree; \
\
_HUBTREE () : myTree(new UBTree) {} \
/* Empty constructor */ \
\
/* Access to the methods of UBTree */ \
\
Standard_Boolean Add (const _OBJTYPE& theObj, \
const _BNDTYPE& theBnd) \
{ return ChangeTree().Add (theObj, theBnd); } \
\
Standard_Integer Select (UBTree::Selector& theSelector) const \
{ return Tree().Select (theSelector); } \
\
void Clear () { ChangeTree().Clear (); } \
\
Standard_Boolean IsEmpty () const { return Tree().IsEmpty(); } \
\
const UBTree::TreeNode& Root () const { return Tree().Root(); } \
\
\
/* Access to the tree algorithm */ \
\
const UBTree& Tree () const { return *myTree; } \
UBTree& ChangeTree () { return *myTree; } \
\
~_HUBTREE () { delete myTree; } \
/* Destructor */ \
\
DEFINE_STANDARD_RTTI (_HUBTREE) \
/* Type management */ \
\
protected: \
_HUBTREE (UBTree *theTree) : myTree(theTree) {} \
/* Constructor from an existing tree. */ \
\
private: \
UBTree *myTree; /* pointer to the tree algorithm */ \
}; \
DEFINE_STANDARD_HANDLE (_HUBTREE, _HPARENT)
#define IMPLEMENT_HUBTREE(_HUBTREE, _HPARENT) \
IMPLEMENT_STANDARD_HANDLE (_HUBTREE, _HPARENT) \
IMPLEMENT_STANDARD_RTTIEXT(_HUBTREE, _HPARENT)
#ifdef WNT
#pragma warning (pop)
#endif
#endif

View File

@@ -0,0 +1,213 @@
// File: NCollection_UBTreeFiller.hxx
// Created: 18.10.02 10:34:57
// Author: Michael SAZONOV
// Copyright: Open CASCADE 2002
#ifndef NCollection_UBTreeFiller_HeaderFile
#define NCollection_UBTreeFiller_HeaderFile
#include <NCollection_UBTree.hxx>
#include <NCollection_Vector.hxx>
#include <stdlib.h>
#include <stdio.h>
/**
* This class is used to fill an UBTree in a random order.
* The quality of a tree is much better (from the point of view of
* the search time) if objects are added to it in a random order to
* avoid adding a chain of neerby objects one following each other.
*
* This class collects objects to be added, and then add them to the tree
* in a random order.
*/
template <class TheObjType, class TheBndType> class NCollection_UBTreeFiller
{
public:
// ---------- PUBLIC TYPES ----------
//! Structure of pair (object, bnd box)
struct ObjBnd
{
TheObjType myObj;
TheBndType myBnd;
ObjBnd (const TheObjType& theObj, const TheBndType& theBnd)
: myObj(theObj), myBnd(theBnd) {}
ObjBnd ()
: myObj(TheObjType()), myBnd(TheBndType()) {}
};
//! UBTree algorithm
typedef NCollection_UBTree<TheObjType, TheBndType> UBTree;
typedef TYPENAME UBTree::TreeNode UBTreeNode;
// ---------- PUBLIC METHODS ----------
/**
* Constructor.
* @param theTree
* Tree instance that is to be filled.
* @param isFullRandom
* Takes effect when the number of items is large (order of 50,000). When
* it is True, the code uses the maximal randomization allowing a better
* balanced tree. If False, the randomization/tree balance are worse but
* the tree filling is faster due to better utilisation of CPU L1/L2 cache.
*/
NCollection_UBTreeFiller (UBTree& theTree,
const Standard_Boolean isFullRandom = Standard_True)
: myTree(theTree), mySeed(1), myIsFullRandom (isFullRandom)
{
#ifndef _REENTRANT
// We use srand/rand for a single threaded application
// and rand_r for a multi threaded one.
// _REENTRANT must be defined for a multi threaded application.
srand (mySeed);
#endif
}
//! Adds a pair (theObj, theBnd) to my sequence
void Add (const TheObjType& theObj, const TheBndType& theBnd)
{ mySeqPtr.Append (ObjBnd (theObj, theBnd)); }
/**
* Fills the tree with the objects from my sequence. This method clears
* the internal buffer of added items making sure that no item would be added
* twice.
* @return
* the number of objects added to the tree.
*/
Standard_EXPORT Standard_Integer Fill ();
/**
* Check the filled tree for the total number of items and the balance
* outputting these results to ostream.
* @return
* the tree size (the same value is returned by method Fill()).
*/
Standard_EXPORT Standard_Integer CheckTree (Standard_OStream& theStream);
/**
* Destructor. Fills the tree with accumulated items if they have not been
* passed by a previous call of method Fill().
*/
~NCollection_UBTreeFiller ()
{
if (mySeqPtr.Length() > 0)
#ifdef DEB_UBTREE
cout << "~NCollection_UBTreeFiller: " << Fill()
<< " objects added to the tree" << endl;
#else
Fill();
#endif
}
private:
// Assignment operator is made empty and private in order to
// avoid warning on MSVC (C4512)
void operator = (const NCollection_UBTreeFiller&) {}
static Standard_Real checkNode (const UBTreeNode& theNode,
const Standard_Integer theLength,
Standard_Integer& theNumber);
private:
// ---------- PRIVATE FIELDS ----------
UBTree& myTree;
NCollection_Vector<ObjBnd> mySeqPtr;
int mySeed; //!< seed for rand
Standard_Boolean myIsFullRandom;
};
#ifdef _REENTRANT
inline int take_random (int * theSeed)
{
return rand_r ((unsigned *) theSeed);
}
#else
inline int take_random (int *)
{
return rand();
}
#endif
//=======================================================================
//function : Fill
//purpose :
//=======================================================================
template <class TheObjType, class TheBndType>
Standard_Integer NCollection_UBTreeFiller<TheObjType,TheBndType>::Fill ()
{
Standard_Integer i, nbAdd = mySeqPtr.Length();
// Fisher-Yates randomization
if (myIsFullRandom)
for (i = nbAdd; i > 0; i--) {
unsigned int ind = take_random(&mySeed);
if (i > RAND_MAX) {
const unsigned int ind1 = take_random(&mySeed);
ind += (ind1 << 15);
}
ind = ind % i;
const ObjBnd& aObjBnd = mySeqPtr(ind);
myTree.Add (aObjBnd.myObj, aObjBnd.myBnd);
mySeqPtr(ind) = mySeqPtr(i-1);
}
else
for (i = nbAdd; i > 0; i--) {
unsigned int ind = take_random(&mySeed);
ind = i - (ind % i) - 1;
const ObjBnd& aObjBnd = mySeqPtr(ind);
myTree.Add (aObjBnd.myObj, aObjBnd.myBnd);
mySeqPtr(ind) = mySeqPtr(i-1);
}
mySeqPtr.Clear();
return nbAdd;
}
//=======================================================================
//function : CheckTree
//purpose :
//=======================================================================
template <class TheObjType, class TheBndType>
Standard_Integer NCollection_UBTreeFiller<TheObjType,TheBndType>::CheckTree
(Standard_OStream& theStream)
{
Standard_Integer aNumber(0);
const Standard_Real aLen = checkNode (myTree.Root(), 0, aNumber);
const Standard_Real num = (double) aNumber;
const Standard_Real aLen1 = sqrt (aLen / num);
const Standard_Real aLen0 = log(num) / log(2.);
char buf[128];
sprintf (buf, "Checking UBTree:%8d leaves, balance =%7.2f",
aNumber, aLen1 / aLen0);
theStream << buf << endl;
return aNumber;
}
//=======================================================================
//function : checkNode
//purpose :
//=======================================================================
template <class TheObjType, class TheBndType>
Standard_Real NCollection_UBTreeFiller<TheObjType,TheBndType>::checkNode
(const TYPENAME NCollection_UBTree<TheObjType, TheBndType>::TreeNode& theNode,
const Standard_Integer theLength,
Standard_Integer& theNumber)
{
Standard_Real aLength;
if (!theNode.IsLeaf())
aLength = (checkNode (theNode.Child(0), theLength+1, theNumber) +
checkNode (theNode.Child(1), theLength+1, theNumber));
else {
theNumber++;
aLength = theLength * theLength;
}
return aLength;
}
#endif

View File

@@ -0,0 +1,285 @@
// File: NCollection_Vector.hxx
// Created: 23.04.02 19:24:33
// Author: Alexander GRIGORIEV
// Copyright: Open Cascade 2002
#ifndef NCollection_Vector_HeaderFile
#define NCollection_Vector_HeaderFile
#include <NCollection_BaseVector.hxx>
#include <NCollection_BaseCollection.hxx>
#if !defined No_Exception && !defined No_Standard_OutOfRange
#include <Standard_OutOfRange.hxx>
#endif
#ifdef WNT
// Disable the warning: "operator new unmatched by delete"
#pragma warning (push)
#pragma warning (disable:4291)
#endif
/**
* Class NCollection_Vector (dynamic array of objects)
*
* This class is similar to NCollection_Array1 though the indices always start
* at 0 (in Array1 the first index must be specified)
*
* The Vector is always created with 0 length. It can be enlarged by two means:
* 1. Calling the method Append (val) - then "val" is added to the end of the
* vector (the vector length is incremented)
* 2. Calling the method SetValue (i, val) - if "i" is greater than or equal
* to the current length of the vector, the vector is enlarged to accomo-
* date this index
*
* The methods Append and SetValue return a non-const reference to the copied
* object inside the vector. This reference is guaranteed to be valid until
* the vector is destroyed. It can be used to access the vector member directly
* or to pass its address to other data structures.
*
* The vector iterator remembers the length of the vector at the moment of the
* creation or initialisation of the iterator. Therefore the iteration begins
* at index 0 and stops at the index equal to (remembered_length-1). It is OK
* to enlarge the vector during the iteration.
*/
template <class TheItemType> class NCollection_Vector
: public NCollection_BaseCollection<TheItemType>,
public NCollection_BaseVector
{
// **************** Implementation of the Iterator interface.
public:
// ----------------------------------------------------------------------
//! Nested class MemBlock
class MemBlock : public NCollection_BaseVector::MemBlock
{
public:
void * operator new (size_t, void * theAddress) { return theAddress; }
//! Empty constructor
MemBlock () : NCollection_BaseVector::MemBlock(0,0) {}
//! Constructor
MemBlock (const Standard_Integer theFirstInd,
const Standard_Integer theSize)
: NCollection_BaseVector::MemBlock (theFirstInd, theSize)
{ myData = new TheItemType [theSize]; }
//! Copy constructor
MemBlock (const MemBlock& theOther)
: NCollection_BaseVector::MemBlock (theOther.FirstIndex(),theOther.Size())
{
myLength = theOther.Length();
myData = new TheItemType [Size()];
for (size_t i=0; i < Length(); i++)
((TheItemType *) myData)[i] = theOther.Value(i);
}
//! Reinit
virtual void Reinit (const Standard_Integer theFirst,
const size_t theSize)
{
if (myData) delete [] (TheItemType *) myData;
myData = (theSize > 0) ? new TheItemType [theSize] : NULL;
myFirstInd = theFirst;
mySize = theSize;
myLength = 0;
}
//! Destructor
virtual ~MemBlock () { if (myData) delete [] (TheItemType *) myData; }
//! Operator () const
const TheItemType& Value (const Standard_Integer theIndex) const
{ return ((TheItemType *) myData) [theIndex]; }
//! Operator ()
TheItemType& ChangeValue (const Standard_Integer theIndex)
{ return ((TheItemType *) myData) [theIndex]; }
//! GetIndex
Standard_Integer GetIndex (const TheItemType& theItem) const {
return GetIndexV ((void *)&theItem, sizeof(TheItemType));
}
}; // End of the nested class MemBlock
// ----------------------------------------------------------------------
// ------------------------ Nested class Iterator -----------------------
// ----------------------------------------------------------------------
class Iterator : public NCollection_BaseCollection<TheItemType>::Iterator,
public NCollection_BaseVector::Iterator
{
public:
//! Empty constructor - for later Init
Iterator (void) {}
//! Constructor with initialisation
Iterator (const NCollection_Vector& theVector) :
NCollection_BaseVector::Iterator (theVector) {}
//! Copy constructor
Iterator (const Iterator& theOther) :
NCollection_BaseVector::Iterator (theOther) {}
//! Initialisation
void Init (const NCollection_Vector& theVector) { InitV (theVector); }
//! Assignment
Iterator& operator = (const Iterator& theOther) {
CopyV (theOther);
return * this;
}
//! Check end
virtual Standard_Boolean More (void) const { return MoreV (); }
//! Make step
virtual void Next (void) { NextV(); }
//! Constant value access
virtual const TheItemType& Value (void) const {
return ((const MemBlock *) CurBlockV()) -> Value(myCurIndex); }
//! Variable value access
virtual TheItemType& ChangeValue (void) const {
return ((MemBlock *) CurBlockV()) -> ChangeValue(myCurIndex); }
//! Operator new for allocating iterators
void* operator new(size_t theSize,
const Handle(NCollection_BaseAllocator)& theAllocator)
{ return theAllocator->Allocate(theSize); }
}; // End of the nested class Iterator
// ----------------------------------------------------------------------
// ------------------------ Class Vector itself -------------------------
// ----------------------------------------------------------------------
public:
// ---------- PUBLIC METHODS ----------
//! Constructor
NCollection_Vector (const Standard_Integer theIncrement = 256,
const Handle_NCollection_BaseAllocator& theAlloc = 0L)
: NCollection_BaseCollection<TheItemType>(theAlloc),
NCollection_BaseVector (sizeof(TheItemType), theIncrement,
FuncDataInit, FuncDataFree) {}
//! Copy constructor
NCollection_Vector (const NCollection_Vector& theOther)
: NCollection_BaseCollection<TheItemType>(theOther.myAllocator),
NCollection_BaseVector (theOther, FuncDataInit, FuncDataFree)
{ CopyData (theOther); }
//! Operator =
NCollection_Vector& operator = (const NCollection_Vector& theOther) {
if (this != &theOther) {
this->myAllocator = theOther.myAllocator;
NCollection_BaseVector::operator = (theOther);
CopyData (theOther);
}
return * this;
}
//! Total number of items in the vector
virtual Standard_Integer Size () const { return Length(); }
//! Virtual assignment (any collection to this array)
virtual void Assign (const NCollection_BaseCollection<TheItemType>& theOther)
{
if (this != &theOther) {
TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& anIter2 =
theOther.CreateIterator();
while (anIter2.More()) {
Append (anIter2.Value());
anIter2.Next();
}
}
}
//! Assignment to the collection of the same type
void Assign (const NCollection_Vector& theOther)
{
if (this != &theOther) {
NCollection_BaseVector::operator = (theOther);
CopyData (theOther);
}
}
//! Method to create iterators for base collections
virtual TYPENAME NCollection_BaseCollection<TheItemType>::Iterator&
CreateIterator(void) const
{ return *(new (this->IterAllocator()) Iterator(*this)); }
//! Append
TheItemType& Append (const TheItemType& theValue) {
TheItemType& anAppended = * (TheItemType *) ExpandV (myLength);
anAppended = theValue;
return anAppended;
}
//! Operator () - query the const value
const TheItemType& operator () (const Standard_Integer theIndex) const
{ return Value (theIndex); }
const TheItemType& Value (const Standard_Integer theIndex) const {
// if (myNBlocks == 1) return ((MemBlock *) myData) -> Value(theIndex);
return * (const TheItemType *) Find (theIndex);
}
//! Operator () - query the value
TheItemType& operator () (const Standard_Integer theIndex)
{ return ChangeValue (theIndex); }
TheItemType& ChangeValue (const Standard_Integer theIndex) {
// if (myNBlocks == 1) return ((MemBlock *) myData) -> ChangeValue(theIndex);
return * (TheItemType *) Find (theIndex);
}
//! SetValue () - set or append a value
TheItemType& SetValue (const Standard_Integer theIndex,
const TheItemType& theValue) {
#if !defined No_Exception && !defined No_Standard_OutOfRange
if (theIndex < 0)
Standard_OutOfRange::Raise ("NCollection_Vector::SetValue");
#endif
TheItemType * const aVecValue =
(TheItemType *)(theIndex<myLength? Find(theIndex): ExpandV(theIndex));
* aVecValue = theValue;
return * aVecValue;
}
private:
// ---------- PRIVATE METHODS ----------
void CopyData (const NCollection_Vector& theOther) {
Standard_Integer i, iBlock = 0;
/*NCollection_Vector::*/Iterator anIter (theOther);
for (int aLength = 0; aLength < myLength; aLength += myIncrement) {
MemBlock& aBlock = (MemBlock&) myData[iBlock];
aBlock.Reinit (aLength, myIncrement);
for (i = 0; i < myIncrement; i++) {
if (!anIter.More()) break;
aBlock.ChangeValue(i) = anIter.Value();
anIter.Next();
}
aBlock.SetLength(i);
iBlock++;
}
}
static NCollection_BaseVector::MemBlock * FuncDataInit
(const NCollection_BaseVector& theVector,
const Standard_Integer aCapacity,
const void * aSource,
const Standard_Integer aSize)
{
const NCollection_Vector& aSelf =
static_cast<const NCollection_Vector&> (theVector);
MemBlock * aData =
(MemBlock *) aSelf.myAllocator->Allocate(aCapacity * sizeof(MemBlock));
Standard_Integer i = 0;
if (aSource != NULL) {
memcpy (aData, aSource, aSize * sizeof(MemBlock));
i = aSize;
}
while (i < aCapacity)
new (&aData[i++]) MemBlock;
return aData;
}
static void FuncDataFree (const NCollection_BaseVector& theVector,
NCollection_BaseVector::MemBlock * aData)
{
const NCollection_Vector& aSelf =
static_cast<const NCollection_Vector&> (theVector);
aSelf.myAllocator->Free(aData);
}
friend class Iterator;
};
#ifdef WNT
#pragma warning (pop)
#endif
#endif

View File

@@ -0,0 +1,237 @@
#!/bin/sh
FILES='
NCollection_Array1.hxx
NCollection_Array2.hxx
NCollection_List.hxx
NCollection_Map.hxx
NCollection_DataMap.hxx
NCollection_DoubleMap.hxx
NCollection_IndexedMap.hxx
NCollection_IndexedDataMap.hxx
NCollection_Queue.hxx
NCollection_SList.hxx
NCollection_Sequence.hxx
NCollection_Set.hxx
NCollection_Stack.hxx
NCollection_Vector.hxx
NCollection_BaseCollection.hxx
NCollection_TListIterator.hxx
NCollection_TListNode.hxx
NCollection_HArray1.hxx
NCollection_HArray2.hxx
NCollection_HSequence.hxx
NCollection_HSet.hxx'
#FILES=NCollection_Array2.hxx
for IN_FILE in $FILES; do
### for IN_FILE in $*; do
OUT_FILE=`echo $IN_FILE | sed 's/_/_Define/'`
gawk '
# ------ Function: Print the backslash in the 79th position
function PrintBSL(str) {
str0 = " "
len = length (str)
if (len > 78) $0 = str " \\"
else $0 = str substr(str0, 1, 79-len) "\\"
}
# -------------- Check and corect the file header -----------
/\/\/ *Copyright *:/ {
print "// Automatically created from " in_file " by GAWK"
}
/\/\/ *File *:/ ||
/#(ifndef|define) *NCollection_/ {
gsub ("NCollection_","NCollection_Define")
}
# --------------- Modify the include statement for used templates ------
/^ *\#include <NCollection_BaseCollection.hxx>/ {
print "\#include <NCollection_DefineBaseCollection.hxx>"
next
}
/^ *\#include <NCollection_T[A-Za-z]*\.hxx>/ {
gsub ("NCollection_T","NCollection_DefineT")
}
/^ *\#include <NCollection_Array[12]\.hxx>/ {
gsub ("NCollection_Array","NCollection_DefineArray")
}
/^ *\#include <NCollection_Sequence\.hxx>/ {
gsub ("NCollection_Sequence","NCollection_DefineSequence")
}
/^ *\#include <NCollection_Set\.hxx>/ {
gsub ("NCollection_Set","NCollection_DefineSet")
}
# -------------- Replace line #define NCOLLECTION_H... -----------------
/^ *#define NCOLLECTION_H.*\(.*\).*$/ {
defh = $0
do getline defcl; while (defcl ~ /^ *\\/)
coll_type = gensub ("^.*public *NCollection_\([A-Za-z0-9_]*\) *<Type>.*$",
"\\1", 1, defcl)
gsub (", *Type\\)",", _" coll_type "Type_\)", defh)
gsub (" *\\\\$","", defh)
PrintBSL(gensub ("NCOLLECTION_","DEFINE_", 1, defh))
print
PrintBSL("")
print
gsub ("NCollection_" coll_type " *<Type>", "_" coll_type "Type_", defcl)
PrintBSL(gensub ("^\(.*\) *\\\\$","\\1", 1, defcl))
print
flag = 10
next
}
# -------------- Replace the line "\#define ...." for "template ...." --
/^ *template *< *class/,/^ *{ *$/ {
if (flag == 0) {
type = gensub ("^ *template.*NCollection_\([A-Za-z0-9]*\).*$","\\1","g")
item_t = gensub("^ *template *< *class *\([A-Za-z0-9_]*\) *\(,|>\).*$",\
"\\1",1)
item_tt= gensub("^ *template.*, *class *\([A-Za-z0-9_]*\) *\(,|>\).*$",\
"\\1",1)
if (item_tt == $0) item_tt = ""
if (type == "BaseCollection")
PrintBSL("#define DEFINE_" toupper(type) "(_ClassName_, "item_t")")
else if (item_tt == "")
PrintBSL("#define DEFINE_" toupper(type) \
"(_ClassName_, _BaseCollection_, " item_t ")")
else
PrintBSL("#define DEFINE_" toupper(type) \
"(_ClassName_, _BaseCollection_, " item_t ", " item_tt ")")
# Special addition for the Iterator
if (type == "TListIterator")
{
print
PrintBSL("DEFINE_TLISTNODE(TListNode, _BaseCollection_, " item_t ")")
}
flag = 1
} else if (flag == 1) {
gsub ("^ *", "class _ClassName_ ")
flag = 2
}
}
# --------------- Detect the final line of the template class definition ----
/^}; *$/{ flag = 0 }
# --------------- Replace C-style comments for C++-style ones ---------------
/\/\// { if (flag == 2) $0=gensub ("// *\(.*\) *$","/\* \\1 \*/", "g") }
# --------------- Replace "Raise_if.." for "#ifdef DEB ..::Raise.. #endif" --
/^\# *ifdef *DEB/ {
nline = 0
if (flag == 0) {
while (1) {
getline debl
if (debl ~ /^\# *endif/) break;
print debl
}
} else {
getline debl;
if (debl !~ /^ *if *\(/) {
print "ERROR: in " in_file " cannot find if after \#ifdef DEB" \
> "/dev/stderr"
exit 1
}
if (debl ~ /^ *if *\(.*\) *$/)
condl = gensub ("^ *if *\\( *(.*) *\\) *$", "\\1", 1, debl)
else
condl = gensub ("^ *if *\\( *(.*) *$", "\\1", 1, debl)
while(1) {
getline debl;
if (debl ~ /^\# *endif/) break;
if (debl !~ /Standard.*::Raise/)
condl = gensub("^ *(.*[^\\)]) *($|\\) *$)", condl "\\1", 1, debl)
else {
PrintBSL(gensub ("^ \(.*\):: *Raise *\\(.*$",
"\\1_Raise_if", 1, debl))
print
PrintBSL(gensub ("^ ( *)Standard.*Raise *\\( *\"NCollection_" \
type "(.*)\" *\\) *\; *$",
"\\1 (" condl ", #_ClassName_ \"\\2\")\;",
1, debl))
print
}
}
}
next
}
# --------------- Remove #pragma warning (default:4291) from the output -----
/^\# *ifdef WNT/ {
defh = $0
has_printed = 0
while (1) {
getline defcl
if (defcl ~ /^[ \t]*$/) continue;
if (defcl ~ /^\# *pragma +warning *\(default *: *4291 *\)/) continue;
if (defcl ~ /^\# *endif/) {
if (has_printed) print defcl
break
}
if (has_printed == 0) {
has_printed = 1
print defh
}
print defcl
}
next
}
# --------------- Replace "DEFINE_T.*..." for typedef ... -------------------
# in classes List, Queue, Set, Stack
/^ *typedef NCollection_T[A-Za-z]*<TheItemType>/ {
if (flag > 1) {
tsup = gensub("^ *typedef.*NCollection_\([A-Za-z0-9]*\).*$","\\1",1)
tdef = gensub("^ *typedef.*<[A-Za-z0-9]*> *([A-Za-z0-9]*)\;.*$","\\1",1)
gsub ("typedef.*$", "DEFINE_" toupper(tsup) "(" tdef \
",_BaseCollection_," item_t ")")
}
}
# --------------- Replace public T* with DEFINE... --------------------------
/^ *class.*: *public *NCollection_T[A-Za-z]*<.*>/ {
if (flag > 1) {
ttempl = gensub("^ *class.*: *public *(NCollection_T[A-Za-z0-9]*<.*>).*$","\\1",1)
tshort = gensub("^ *class.*: *public *NCollection_(T[A-Za-z0-9]*)<.*$","\\1",1)
spub = gensub("(^ *class.*: *public *)NCollection_(T[A-Za-z0-9]*)<.*($)",
"\\1\\2\\3",1)
tpara = gensub("^.*<(.*)>","\\1",1)
PrintBSL(" DEFINE_" toupper(tshort) "(" tshort ",_BaseCollection_," tpara ")")
print
PrintBSL(spub)
print
next
}
}
# ------- General case: replace the macro parameter for class name and print -
{ if (flag == 10) {
nsub = gsub ("NCollection_" coll_type " *<Type>",
"_" coll_type "Type_")
if (nsub) {
gsub (" *\\\\$","")
PrintBSL($0)
}
} else if (flag > 1) {
gsub ("NCollection_BaseCollection *< *\("item_t"|"item_tt"\) *>", \
"_BaseCollection_")
gsub ("NCollection_TListNode *< *\("item_t"|"item_tt"\) *>", \
"TListNode")
gsub ("NCollection_TListIterator *< *\("item_t"|"item_tt"\) *>", \
"TListIterator")
gsub (ttempl, tshort)
gsub (":: *Raise *\\( *\"NCollection_" type,
"::Raise (#_ClassName_ \"")
PrintBSL(gensub ("NCollection_" type \
"\(<"item_t">|<"item_tt">|\)\(\[^A-Za-z\]|$\)", \
"_ClassName_\\2","g"))
}
print
}
' in_file=$IN_FILE out_file=$OUT_FILE $IN_FILE > $OUT_FILE
echo "\t$IN_FILE converted to $OUT_FILE"
done