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:
76
src/NCollection/FILES
Executable file
76
src/NCollection/FILES
Executable 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
|
BIN
src/NCollection/NCollection.mdl.gz
Executable file
BIN
src/NCollection/NCollection.mdl.gz
Executable file
Binary file not shown.
284
src/NCollection/NCollection_Array1.hxx
Executable file
284
src/NCollection/NCollection_Array1.hxx
Executable 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
|
323
src/NCollection/NCollection_Array2.hxx
Executable file
323
src/NCollection/NCollection_Array2.hxx
Executable 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
|
133
src/NCollection/NCollection_BaseAllocator.cxx
Executable file
133
src/NCollection/NCollection_BaseAllocator.cxx
Executable 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);
|
||||
}
|
78
src/NCollection/NCollection_BaseAllocator.hxx
Executable file
78
src/NCollection/NCollection_BaseAllocator.hxx
Executable 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
|
105
src/NCollection/NCollection_BaseCollection.hxx
Executable file
105
src/NCollection/NCollection_BaseCollection.hxx
Executable 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
|
263
src/NCollection/NCollection_BaseList.cxx
Executable file
263
src/NCollection/NCollection_BaseList.cxx
Executable 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;
|
||||
}
|
||||
}
|
196
src/NCollection/NCollection_BaseList.hxx
Executable file
196
src/NCollection/NCollection_BaseList.hxx
Executable 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
|
174
src/NCollection/NCollection_BaseMap.cxx
Executable file
174
src/NCollection/NCollection_BaseMap.cxx
Executable 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 );
|
||||
}
|
||||
|
209
src/NCollection/NCollection_BaseMap.hxx
Executable file
209
src/NCollection/NCollection_BaseMap.hxx
Executable 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
|
445
src/NCollection/NCollection_BaseSequence.cxx
Executable file
445
src/NCollection/NCollection_BaseSequence.cxx
Executable 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;
|
||||
}
|
150
src/NCollection/NCollection_BaseSequence.hxx
Executable file
150
src/NCollection/NCollection_BaseSequence.hxx
Executable 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
|
200
src/NCollection/NCollection_BaseVector.cxx
Executable file
200
src/NCollection/NCollection_BaseVector.cxx
Executable 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
|
179
src/NCollection/NCollection_BaseVector.hxx
Executable file
179
src/NCollection/NCollection_BaseVector.hxx
Executable 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
|
502
src/NCollection/NCollection_CellFilter.hxx
Executable file
502
src/NCollection/NCollection_CellFilter.hxx
Executable 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
|
||||
|
343
src/NCollection/NCollection_DataMap.hxx
Executable file
343
src/NCollection/NCollection_DataMap.hxx
Executable 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
|
52
src/NCollection/NCollection_DefineArray1.hxx
Executable file
52
src/NCollection/NCollection_DefineArray1.hxx
Executable 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
|
36
src/NCollection/NCollection_DefineArray2.hxx
Executable file
36
src/NCollection/NCollection_DefineArray2.hxx
Executable 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
|
38
src/NCollection/NCollection_DefineBaseCollection.hxx
Executable file
38
src/NCollection/NCollection_DefineBaseCollection.hxx
Executable 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
|
39
src/NCollection/NCollection_DefineDataMap.hxx
Executable file
39
src/NCollection/NCollection_DefineDataMap.hxx
Executable 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
|
29
src/NCollection/NCollection_DefineDoubleMap.hxx
Executable file
29
src/NCollection/NCollection_DefineDoubleMap.hxx
Executable 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
|
51
src/NCollection/NCollection_DefineHArray1.hxx
Executable file
51
src/NCollection/NCollection_DefineHArray1.hxx
Executable 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
|
55
src/NCollection/NCollection_DefineHArray2.hxx
Executable file
55
src/NCollection/NCollection_DefineHArray2.hxx
Executable 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
|
48
src/NCollection/NCollection_DefineHSequence.hxx
Executable file
48
src/NCollection/NCollection_DefineHSequence.hxx
Executable 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
|
47
src/NCollection/NCollection_DefineHSet.hxx
Executable file
47
src/NCollection/NCollection_DefineHSet.hxx
Executable 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
|
40
src/NCollection/NCollection_DefineIndexedDataMap.hxx
Executable file
40
src/NCollection/NCollection_DefineIndexedDataMap.hxx
Executable 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
|
32
src/NCollection/NCollection_DefineIndexedMap.hxx
Executable file
32
src/NCollection/NCollection_DefineIndexedMap.hxx
Executable 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
|
29
src/NCollection/NCollection_DefineList.hxx
Executable file
29
src/NCollection/NCollection_DefineList.hxx
Executable 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
|
49
src/NCollection/NCollection_DefineMap.hxx
Executable file
49
src/NCollection/NCollection_DefineMap.hxx
Executable 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
|
31
src/NCollection/NCollection_DefineQueue.hxx
Executable file
31
src/NCollection/NCollection_DefineQueue.hxx
Executable 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
|
56
src/NCollection/NCollection_DefineSList.hxx
Executable file
56
src/NCollection/NCollection_DefineSList.hxx
Executable 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
|
28
src/NCollection/NCollection_DefineSequence.hxx
Executable file
28
src/NCollection/NCollection_DefineSequence.hxx
Executable 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
|
31
src/NCollection/NCollection_DefineSet.hxx
Executable file
31
src/NCollection/NCollection_DefineSet.hxx
Executable 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
|
32
src/NCollection/NCollection_DefineStack.hxx
Executable file
32
src/NCollection/NCollection_DefineStack.hxx
Executable 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
|
26
src/NCollection/NCollection_DefineTListIterator.hxx
Executable file
26
src/NCollection/NCollection_DefineTListIterator.hxx
Executable 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
|
24
src/NCollection/NCollection_DefineTListNode.hxx
Executable file
24
src/NCollection/NCollection_DefineTListNode.hxx
Executable 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
|
44
src/NCollection/NCollection_DefineVector.hxx
Executable file
44
src/NCollection/NCollection_DefineVector.hxx
Executable 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
|
477
src/NCollection/NCollection_DoubleMap.hxx
Executable file
477
src/NCollection/NCollection_DoubleMap.hxx
Executable 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
|
210
src/NCollection/NCollection_EBTree.hxx
Executable file
210
src/NCollection/NCollection_EBTree.hxx
Executable 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
|
18
src/NCollection/NCollection_HArray1.hxx
Executable file
18
src/NCollection/NCollection_HArray1.hxx
Executable 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
|
18
src/NCollection/NCollection_HArray2.hxx
Executable file
18
src/NCollection/NCollection_HArray2.hxx
Executable 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
|
17
src/NCollection/NCollection_HSequence.hxx
Executable file
17
src/NCollection/NCollection_HSequence.hxx
Executable 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
|
17
src/NCollection/NCollection_HSet.hxx
Executable file
17
src/NCollection/NCollection_HSet.hxx
Executable 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
|
24
src/NCollection/NCollection_Handle.cxx
Executable file
24
src/NCollection/NCollection_Handle.cxx
Executable 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;
|
||||
}
|
97
src/NCollection/NCollection_Handle.hxx
Executable file
97
src/NCollection/NCollection_Handle.hxx
Executable 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
|
59
src/NCollection/NCollection_HeapAllocator.cxx
Executable file
59
src/NCollection/NCollection_HeapAllocator.cxx
Executable 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;
|
||||
}
|
44
src/NCollection/NCollection_HeapAllocator.hxx
Executable file
44
src/NCollection/NCollection_HeapAllocator.hxx
Executable 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
|
245
src/NCollection/NCollection_IncAllocator.cxx
Executable file
245
src/NCollection/NCollection_IncAllocator.cxx
Executable 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;
|
||||
}
|
109
src/NCollection/NCollection_IncAllocator.hxx
Executable file
109
src/NCollection/NCollection_IncAllocator.hxx
Executable 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
|
505
src/NCollection/NCollection_IndexedDataMap.hxx
Executable file
505
src/NCollection/NCollection_IndexedDataMap.hxx
Executable 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
|
419
src/NCollection/NCollection_IndexedMap.hxx
Executable file
419
src/NCollection/NCollection_IndexedMap.hxx
Executable 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
|
298
src/NCollection/NCollection_List.hxx
Executable file
298
src/NCollection/NCollection_List.hxx
Executable 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
|
46
src/NCollection/NCollection_ListNode.hxx
Executable file
46
src/NCollection/NCollection_ListNode.hxx
Executable 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
|
319
src/NCollection/NCollection_Map.hxx
Executable file
319
src/NCollection/NCollection_Map.hxx
Executable 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
|
142
src/NCollection/NCollection_Queue.hxx
Executable file
142
src/NCollection/NCollection_Queue.hxx
Executable 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
|
294
src/NCollection/NCollection_SList.hxx
Executable file
294
src/NCollection/NCollection_SList.hxx
Executable 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
|
322
src/NCollection/NCollection_Sequence.hxx
Executable file
322
src/NCollection/NCollection_Sequence.hxx
Executable 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
|
227
src/NCollection/NCollection_Set.hxx
Executable file
227
src/NCollection/NCollection_Set.hxx
Executable 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
|
274
src/NCollection/NCollection_SparseArray.hxx
Executable file
274
src/NCollection/NCollection_SparseArray.hxx
Executable 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
|
||||
|
345
src/NCollection/NCollection_SparseArrayBase.cxx
Executable file
345
src/NCollection/NCollection_SparseArrayBase.cxx
Executable 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
276
src/NCollection/NCollection_SparseArrayBase.hxx
Executable file
276
src/NCollection/NCollection_SparseArrayBase.hxx
Executable 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
|
||||
|
142
src/NCollection/NCollection_Stack.hxx
Executable file
142
src/NCollection/NCollection_Stack.hxx
Executable 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
|
26
src/NCollection/NCollection_StdBase.hxx
Executable file
26
src/NCollection/NCollection_StdBase.hxx
Executable 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
|
67
src/NCollection/NCollection_TListIterator.hxx
Executable file
67
src/NCollection/NCollection_TListIterator.hxx
Executable 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
|
56
src/NCollection/NCollection_TListNode.hxx
Executable file
56
src/NCollection/NCollection_TListNode.hxx
Executable 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
|
19
src/NCollection/NCollection_TypeDef.hxx
Executable file
19
src/NCollection/NCollection_TypeDef.hxx
Executable 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
|
502
src/NCollection/NCollection_UBTree.hxx
Executable file
502
src/NCollection/NCollection_UBTree.hxx
Executable 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
|
213
src/NCollection/NCollection_UBTreeFiller.hxx
Executable file
213
src/NCollection/NCollection_UBTreeFiller.hxx
Executable 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
|
285
src/NCollection/NCollection_Vector.hxx
Executable file
285
src/NCollection/NCollection_Vector.hxx
Executable 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
|
237
src/NCollection/templates2macros.sh
Executable file
237
src/NCollection/templates2macros.sh
Executable 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
|
Reference in New Issue
Block a user