// Created on: 2002-04-24
// Created by: Alexander GRIGORIEV
-// Copyright (c) 2002-2012 OPEN CASCADE SAS
+// Copyright (c) 2002-2013 OPEN CASCADE SAS
//
// The content of this file is subject to the Open CASCADE Technology Public
// License Version 6.5 (the "License"). You may not use the content of this file
// purpose or non-infringement. Please see the License for the specific terms
// and conditions governing the rights and limitations under the License.
-
#include <NCollection_BaseVector.hxx>
#include <Standard_RangeError.hxx>
-#ifdef DEB
-#include <Standard_OutOfRange.hxx>
-#endif
-#include <stdlib.h>
+#include <cstdlib>
//=======================================================================
-//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 = (Standard_Integer) (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
+//function : NCollection_BaseVector::Iterator::copyV
+//purpose : Copy from another iterator
//=======================================================================
-NCollection_BaseVector::~NCollection_BaseVector()
+void NCollection_BaseVector::Iterator::copyV (const NCollection_BaseVector::Iterator& theOth)
{
- for (Standard_Integer i = 0; i < myCapacity; i++)
- myData[i].Reinit (0, 0);
- myDataFree (* this, myData);
+ myVector = theOth.myVector;
+ myICurBlock = theOth.myICurBlock;
+ myIEndBlock = theOth.myIEndBlock;
+ myCurIndex = theOth.myCurIndex;
+ myEndIndex = theOth.myEndIndex;
}
//=======================================================================
-//function : Clear
-//purpose :
+//function : initV
+//purpose : Initialisation of iterator by a vector
//=======================================================================
-void NCollection_BaseVector::Clear()
+void NCollection_BaseVector::Iterator::initV (const NCollection_BaseVector& theVector)
{
- if (myLength > 0) {
- for (Standard_Integer i = 0; i < myCapacity; i++)
- myData[i].Reinit (0, 0);
- myLength = 0;
- myNBlocks = 0;
+ 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 : NCollection_BaseVector::Iterator::CopyV
-//purpose : Copy from another iterator
+//function : allocMemBlocks
+//purpose :
//=======================================================================
-void NCollection_BaseVector::Iterator::CopyV
- (const NCollection_BaseVector::Iterator& theOth)
+NCollection_BaseVector::MemBlock* NCollection_BaseVector
+ ::allocMemBlocks (Handle(NCollection_BaseAllocator)& theAllocator,
+ const Standard_Integer theCapacity,
+ MemBlock* theSource,
+ const Standard_Integer theSourceSize)
{
- myVector = theOth.myVector;
- myICurBlock = theOth.myICurBlock;
- myIEndBlock = theOth.myIEndBlock;
- myCurIndex = theOth.myCurIndex;
- myEndIndex = theOth.myEndIndex;
-}
-
-//=======================================================================
-//function : InitV
-//purpose : Initialisation of iterator by a vector
-//=======================================================================
+ MemBlock* aData = (MemBlock* )theAllocator->Allocate (theCapacity * sizeof(MemBlock));
+
+ // copy content from source array
+ Standard_Integer aCapacity = 0;
+ if (theSource != NULL)
+ {
+ memcpy (aData, theSource, theSourceSize * sizeof(MemBlock));
+ aCapacity = theSourceSize;
+ theAllocator->Free (theSource);
+ }
-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();
+ // Nullify newly allocated blocks
+ if (aCapacity < theCapacity)
+ {
+ memset (&aData[aCapacity], 0, (theCapacity - aCapacity) * sizeof(MemBlock));
}
+ return aData;
}
//=======================================================================
-//function : operator =
-//purpose : assignment
+//function : Clear
+//purpose :
//=======================================================================
-NCollection_BaseVector& NCollection_BaseVector::operator =
- (const NCollection_BaseVector& theOther)
+void NCollection_BaseVector::Clear()
{
-// 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 = GetCapacity(myIncrement) + myLength / myIncrement;
- myData = myDataInit (* this, myCapacity, NULL, 0);
-// }
- return * this;
+ if (myLength > 0)
+ {
+ for (Standard_Integer anItemIter = 0; anItemIter < myCapacity; ++anItemIter)
+ {
+ myInitBlocks (*this, myData[anItemIter], 0, 0);
+ }
+ myLength = 0;
+ myNBlocks = 0;
+ }
}
//=======================================================================
-//function : ExpandV
+//function : expandV
//purpose : returns the pointer where the new data item is supposed to be put
//=======================================================================
-void * NCollection_BaseVector::ExpandV (const Standard_Integer theIndex)
+void* NCollection_BaseVector::expandV (Handle(NCollection_BaseAllocator)& theAllocator,
+ 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");
- Standard_Integer anIndLastBlock = theIndex - aLastBlock.FirstIndex();
- // Is there still room for 1 item in the last array?
- if (anIndLastBlock < aLastBlock.Size()) {
+ if (myNBlocks > 0)
+ {
+ // Take the last array in the vector of arrays
+ MemBlock& aLastBlock = myData[myNBlocks - 1];
+ Standard_RangeError_Raise_if (theIndex < aLastBlock.FirstIndex,
+ "NColelction_BaseVector::expandV");
+ Standard_Integer 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);
+ aLastBlock.Length = anIndLastBlock + 1;
+ return aLastBlock.findV (anIndLastBlock, myItemSize);
}
- myLength = aLastBlock.FirstIndex() + aLastBlock.Size();
+ 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) {
+ // 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 += GetCapacity(myIncrement); while (myCapacity <= nNewBlock);
- MemBlock * aNewData = myDataInit (* this, myCapacity, myData, myNBlocks);
- myDataFree (* this, myData);
- myData = aNewData;
+
+ myData = allocMemBlocks (theAllocator, myCapacity, myData, myNBlocks);
}
- if (myNBlocks > 0) {
+ if (myNBlocks > 0)
+ {
// Change length of old last block to myIncrement
- MemBlock * aLastBlock = (MemBlock *) &myData[myNBlocks-1];
- aLastBlock -> SetLength (myIncrement);
+ MemBlock& aLastBlock = myData[myNBlocks - 1];
+ aLastBlock.Length = myIncrement;
}
+
// Initialise new blocks
- MemBlock * aNewBlock = (MemBlock *) &myData[myNBlocks++];
- aNewBlock -> Reinit (myLength, myIncrement);
- while (myNBlocks < nNewBlock) {
- aNewBlock -> SetLength (myIncrement);
+ MemBlock* aNewBlock = &myData[myNBlocks++];
+ myInitBlocks (*this, *aNewBlock, myLength, myIncrement);
+ while (myNBlocks < nNewBlock)
+ {
+ aNewBlock->Length = myIncrement;
myLength += myIncrement;
- aNewBlock = (MemBlock *) &myData[myNBlocks++];
- aNewBlock -> Reinit (myLength, myIncrement);
+ aNewBlock = &myData[myNBlocks++];
+ myInitBlocks (*this, *aNewBlock, myLength, myIncrement);
}
- aNewBlock -> SetLength (aNewLength - myLength);
+ aNewBlock->Length = 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);
+ return aNewBlock->findV (theIndex - aNewBlock->FirstIndex, myItemSize);
}
-#endif
// Created on: 2002-04-24
// Created by: Alexander GRIGORIEV
-// Copyright (c) 2002-2012 OPEN CASCADE SAS
+// Copyright (c) 2002-2013 OPEN CASCADE SAS
//
// The content of this file is subject to the Open CASCADE Technology Public
// License Version 6.5 (the "License"). You may not use the content of this file
// purpose or non-infringement. Please see the License for the specific terms
// and conditions governing the rights and limitations under the License.
-
-
#ifndef NCollection_BaseVector_HeaderFile
#define NCollection_BaseVector_HeaderFile
#include <NCollection_BaseAllocator.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)
+#if defined(_MSC_VER)
+ #pragma warning(push, 1)
+ #pragma warning(disable:4355)
#endif
// this value defines the number of blocks that are reserved
return Max(theIncrement/8, 1);
}
-/**
- * Class NCollection_BaseVector - base for generic vector
- */
+//! Class NCollection_BaseVector - base for NCollection_Vector template
class NCollection_BaseVector
{
- public:
- // ------------ Class MemBlock ------------
- class MemBlock {
- protected:
- MemBlock (NCollection_BaseAllocator* theAlloc)
- : myAlloc(theAlloc),
- myData(NULL),
- myFirstInd(0),
- myLength(0),
- mySize(0) {}
- MemBlock (const Standard_Integer theFirstInd,
- const Standard_Integer theLength,
- NCollection_BaseAllocator* theAlloc)
- : myAlloc(theAlloc),
- myData(NULL),
- myFirstInd(theFirstInd),
- myLength(0),
- mySize(theLength) {}
- virtual void Reinit (const Standard_Integer,
- const Standard_Integer) {}
- Standard_Integer FirstIndex () const { return myFirstInd; }
- Standard_Integer Size () const { return mySize; }
+
+protected:
+
+ // Auxiliary structure for memory blocks
+ struct MemBlock
+ {
+
public:
- virtual ~MemBlock () {}
- void SetLength (const Standard_Integer theLen)
- { myLength = theLen; }
- Standard_Integer 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:
- NCollection_BaseAllocator* myAlloc;
- void* myData;
- Standard_Integer myFirstInd;
- Standard_Integer myLength;
- Standard_Integer mySize;
- friend class NCollection_BaseVector;
+
+ //! @param theIndex Item index in the block
+ //! @param theItemSize Element size in bytes
+ //! @return the address of specified item in this memory block
+ void* findV (const Standard_Integer theIndex,
+ const size_t theItemSize) const
+ {
+ return (char* )DataPtr + size_t(theIndex) * theItemSize;
+ }
+
+ public:
+
+ void* DataPtr; //!< block of elements
+ Standard_Integer FirstIndex; //!< index of the first element (among all memory blocks in collection)
+ Standard_Integer Length;
+ Standard_Integer Size;
+
};
- class Iterator {
+ //! Base class for Iterator implementation
+ 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
- Standard_Integer myICurBlock; // # of the current block
- Standard_Integer myIEndBlock;
- Standard_Integer myCurIndex; // Index in the current block
- Standard_Integer myEndIndex;
+ 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
+ Standard_Integer myICurBlock; //!< # of the current block
+ Standard_Integer myIEndBlock;
+ Standard_Integer myCurIndex; //!< Index in the current block
+ Standard_Integer 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 *);
+protected: //! @name Block initializer
- friend class Iterator;
+ typedef void (*initMemBlocks_t) (NCollection_BaseVector& theVector,
+ MemBlock& theBlock,
+ const Standard_Integer theFirst,
+ const Standard_Integer theSize);
+
+ //! Allocate memory for array of memory blocks.
+ //! @param theAllocator Memory allocator to use
+ //! @param theCapacity Number of memory blocks in array
+ //! @param theSource Original array of memory blocks, will be automatically deallocated
+ //! @param theSourceSize Number of memory blocks in original array
+ Standard_EXPORT static MemBlock* allocMemBlocks (Handle(NCollection_BaseAllocator)& theAllocator,
+ const Standard_Integer theCapacity,
+ MemBlock* theSource = NULL,
+ const Standard_Integer theSourceSize = 0);
- // ---------- PROTECTED METHODS ----------
+protected: //! @name 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 (GetCapacity(myIncrement)),
- myNBlocks (0),
- myData (theDataInit (* this, myCapacity, NULL, 0)),
- myDataInit (theDataInit),
- myDataFree (theDataFree)
+ NCollection_BaseVector (Handle(NCollection_BaseAllocator)& theAllocator,
+ initMemBlocks_t theInitBlocks,
+ const size_t theSize,
+ const Standard_Integer theInc)
+ : myItemSize (theSize),
+ myIncrement (theInc),
+ myLength (0),
+ myCapacity (GetCapacity (myIncrement)),
+ myNBlocks (0),
+ myData (allocMemBlocks (theAllocator, myCapacity)),
+ myInitBlocks (theInitBlocks) {}
+
+ //! Copy constructor
+ NCollection_BaseVector (Handle(NCollection_BaseAllocator)& theAllocator,
+ initMemBlocks_t theInitBlocks,
+ const NCollection_BaseVector& theOther)
+ : myItemSize (theOther.myItemSize),
+ myIncrement (theOther.myIncrement),
+ myLength (theOther.myLength),
+ myCapacity (GetCapacity(myIncrement) + theOther.myLength / theOther.myIncrement),
+ myNBlocks (1 + (theOther.myLength - 1)/theOther.myIncrement),
+ myData (allocMemBlocks (theAllocator, myCapacity)),
+ myInitBlocks (theInitBlocks) {}
+
+ //! @return pointer to memory where to put the new item
+ Standard_EXPORT void* expandV (Handle(NCollection_BaseAllocator)& theAllocator,
+ const Standard_Integer theIndex);
+
+ //! Locate the memory holding the desired value
+ inline void* findV (const Standard_Integer theIndex) const
{
-// myData = (MemBlock *) new char [myCapacity * sizeof(MemBlock)];
-// for (Standard_Integer i = 0; i < myCapacity; i++)
-// new (&myData[i]) MemBlock;
+ Standard_OutOfRange_Raise_if (theIndex < 0 || theIndex >= myLength,
+ "NCollection_BaseVector::findV");
+ const Standard_Integer aBlock = theIndex / myIncrement;
+ return myData[aBlock].findV (theIndex - aBlock * myIncrement, myItemSize);
}
- //! Copy constructor
- NCollection_BaseVector (const NCollection_BaseVector& theOther,
- FuncPtrDataInit theDataInit,
- FuncPtrDataFree theDataFree)
- : myItemSize (theOther.myItemSize),
- myIncrement (theOther.myIncrement),
- myLength (theOther.Length()),
- myCapacity (GetCapacity(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; }
+public: //! @name public API
//! 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;
-};
+ Standard_EXPORT void Clear();
-//=======================================================================
-//function : Find
-//purpose : locate the memory holding the desired value
-//=======================================================================
+protected: //! @name Private fields
-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);
-}
+ size_t myItemSize;
+ Standard_Integer myIncrement;
+ Standard_Integer myLength;
+ Standard_Integer myCapacity;
+ Standard_Integer myNBlocks;
+ MemBlock* myData;
+ initMemBlocks_t myInitBlocks;
-#ifdef WNT
-#pragma warning(pop)
-#endif
+protected:
+
+ friend class Iterator;
+};
+
+#if defined(_MSC_VER)
+ #pragma warning(pop)
#endif
+
+#endif // NCollection_BaseVector_HeaderFile
// Created on: 2002-04-23
// Created by: Alexander GRIGORIEV
-// Copyright (c) 2002-2012 OPEN CASCADE SAS
+// Copyright (c) 2002-2013 OPEN CASCADE SAS
//
// The content of this file is subject to the Open CASCADE Technology Public
// License Version 6.5 (the "License"). You may not use the content of this file
#include <NCollection_BaseVector.hxx>
#include <NCollection_BaseCollection.hxx>
-#if !defined No_Exception && !defined No_Standard_OutOfRange
-#include <Standard_OutOfRange.hxx>
-#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.
-*/
-
+//! 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
+: public NCollection_BaseCollection<TheItemType>,
+ public NCollection_BaseVector
{
- public:
+public:
+
typedef TheItemType TheItemTypeD;
- // ----------------------------------------------------------------------
- //! Nested class MemBlock
- class MemBlock : public NCollection_BaseVector::MemBlock
- {
- public:
- DEFINE_STANDARD_ALLOC
-
- //! Empty constructor
- MemBlock (NCollection_BaseAllocator* theAlloc)
- : NCollection_BaseVector::MemBlock(0,0,theAlloc)
- {}
- //! Constructor
- MemBlock (const Standard_Integer theFirstInd,
- const Standard_Integer theSize,
- NCollection_BaseAllocator* theAlloc)
- : NCollection_BaseVector::MemBlock (theFirstInd, theSize, theAlloc)
- {
- myData = myAlloc->Allocate(theSize * sizeof(TheItemType));
- for (Standard_Integer i=0; i < theSize; i++)
- new (&((TheItemType *) myData)[i]) TheItemType;
- }
- //! Copy constructor
- MemBlock (const MemBlock& theOther)
- : NCollection_BaseVector::MemBlock (theOther.FirstIndex(),theOther.Size(),
- theOther.myAlloc)
- {
- myLength = theOther.Length();
- myData = myAlloc->Allocate(Size() * sizeof(TheItemType));
- Standard_Integer i;
- for (i=0; i < Length(); i++)
- new (&((TheItemType *) myData)[i]) TheItemType(theOther.Value(i));
- for (; i < Size(); i++)
- new (&((TheItemType *) myData)[i]) TheItemType;
- }
- //! Reinit
- virtual void Reinit (const Standard_Integer theFirst,
- const Standard_Integer theSize)
- {
- if (myData) {
- for (Standard_Integer i=0; i < mySize; i++)
- ((TheItemType *) myData)[i].~TheItemTypeD();
- myAlloc->Free(myData);
- myData = NULL;
- }
- if (theSize > 0) {
- myData = myAlloc->Allocate(theSize * sizeof(TheItemType));
- for (Standard_Integer i=0; i < theSize; i++)
- new (&((TheItemType *) myData)[i]) TheItemType;
- }
- myFirstInd = theFirst;
- mySize = theSize;
- myLength = 0;
- }
- //! Destructor
- virtual ~MemBlock ()
- {
- if (myData) {
- for (Standard_Integer i=0; i < Size(); i++)
- ((TheItemType *) myData)[i].~TheItemTypeD();
- myAlloc->Free(myData);
- myData = NULL;
- }
- }
- //! 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 -----------------------
- // ----------------------------------------------------------------------
+ //! Nested class Iterator
class Iterator : public NCollection_BaseCollection<TheItemType>::Iterator,
public NCollection_BaseVector::Iterator
{
public:
+
//! Empty constructor - for later Init
- Iterator (void) {}
+ Iterator() {}
+
//! Constructor with initialisation
- Iterator (const NCollection_Vector& theVector) :
- NCollection_BaseVector::Iterator (theVector) {}
+ Iterator (const NCollection_Vector& theVector)
+ : NCollection_BaseVector::Iterator (theVector) {}
+
//! Copy constructor
- Iterator (const Iterator& theOther) :
- NCollection_BaseVector::Iterator (theOther) {}
+ Iterator (const Iterator& theOther)
+ : NCollection_BaseVector::Iterator (theOther) {}
+
//! Initialisation
- void Init (const NCollection_Vector& theVector) { InitV (theVector); }
+ void Init (const NCollection_Vector& theVector)
+ {
+ initV (theVector);
+ }
+
//! Assignment
- Iterator& operator = (const Iterator& theOther) {
- CopyV (theOther);
- return * this;
+ Iterator& operator= (const Iterator& theOther)
+ {
+ copyV (theOther);
+ return *this;
}
+
//! Check end
- virtual Standard_Boolean More (void) const { return MoreV (); }
+ virtual Standard_Boolean More() const
+ {
+ return moreV();
+ }
+
//! Make step
- virtual void Next (void) { NextV(); }
+ virtual void Next()
+ {
+ nextV();
+ }
+
//! Constant value access
- virtual const TheItemType& Value (void) const {
- return ((const MemBlock *) CurBlockV()) -> Value(myCurIndex); }
+ virtual const TheItemType& Value() const
+ {
+ return ((const TheItemType* )curBlockV()->DataPtr)[myCurIndex];
+ }
+
//! Variable value access
- virtual TheItemType& ChangeValue (void) const {
- return ((MemBlock *) CurBlockV()) -> ChangeValue(myCurIndex); }
- }; // End of the nested class Iterator
+ virtual TheItemType& ChangeValue() const
+ {
+ return ((TheItemType* )curBlockV()->DataPtr)[myCurIndex];
+ }
+
+ };
- // ----------------------------------------------------------------------
- // ------------------------ Class Vector itself -------------------------
- // ----------------------------------------------------------------------
- public:
- // ---------- PUBLIC METHODS ----------
+public: //! @name 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) {}
+ const Handle_NCollection_BaseAllocator& theAlloc = NULL)
+ : NCollection_BaseCollection<TheItemType> (theAlloc),
+ NCollection_BaseVector (NCollection_BaseCollection<TheItemType>::myAllocator, initMemBlocks, sizeof(TheItemType), theIncrement) {}
//! 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);
+ : NCollection_BaseCollection<TheItemType> (theOther.myAllocator),
+ NCollection_BaseVector (NCollection_BaseCollection<TheItemType>::myAllocator, initMemBlocks, theOther)
+ {
+ copyData (theOther);
+ }
+
+ //! Destructor
+ ~NCollection_Vector()
+ {
+ for (Standard_Integer anItemIter = 0; anItemIter < myCapacity; ++anItemIter)
+ {
+ initMemBlocks (*this, myData[anItemIter], 0, 0);
}
- return * this;
+ NCollection_BaseCollection<TheItemType>::myAllocator->Free (myData);
+ }
+
+ //! Operator=
+ NCollection_Vector& operator= (const NCollection_Vector& theOther)
+ {
+ Assign (theOther, Standard_False);
+ return *this;
+ }
+
+ //! Total number of items
+ Standard_Integer Length() const
+ {
+ return myLength;
}
//! Total number of items in the vector
- virtual Standard_Integer Size () const { return Length(); }
+ virtual Standard_Integer Size() const
+ {
+ return myLength;
+ }
//! Method for consistency with other collections.
//! @return Lower bound (inclusive) for iteration.
//! @return Upper bound (inclusive) for iteration.
Standard_Integer Upper() const
{
- return Length() - 1;
+ return myLength - 1;
}
//! Empty query
Standard_Boolean IsEmpty() const
{
- return (Length() == 0);
+ return (myLength == 0);
}
//! 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()) {
+ 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);
- }
- }
+ inline void Assign (const NCollection_Vector& theOther,
+ const Standard_Boolean theOwnAllocator = Standard_True);
//! Method to create iterators for base collections
- virtual TYPENAME NCollection_BaseCollection<TheItemType>::Iterator&
- CreateIterator(void) const
- { return *(new (this->IterAllocator()) Iterator(*this)); }
+ virtual TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& CreateIterator() const
+ {
+ return *(new (this->IterAllocator()) Iterator(*this));
+ }
//! Append
- TheItemType& Append (const TheItemType& theValue) {
- TheItemType& anAppended = * (TheItemType *) ExpandV (myLength);
+ TheItemType& Append (const TheItemType& theValue)
+ {
+ TheItemType& anAppended = *(TheItemType* )expandV (NCollection_BaseCollection<TheItemType>::myAllocator, 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 const value
+ const TheItemType& operator() (const Standard_Integer theIndex) const
+ {
+ return Value (theIndex);
+ }
+
+ const TheItemType& Value (const Standard_Integer theIndex) const
+ {
+ return *(const TheItemType* )findV (theIndex);
}
//! @return first element
const TheItemType& First() const
{
- return *(const TheItemType* )Find (Lower());
+ return *(const TheItemType* )findV (Lower());
}
//! @return first element
TheItemType& ChangeFirst()
{
- return *(TheItemType* )Find (Lower());
+ return *(TheItemType* )findV (Lower());
}
//! @return last element
const TheItemType& Last() const
{
- return *(const TheItemType* )Find (Upper());
+ return *(const TheItemType* )findV (Upper());
}
//! @return last element
TheItemType& ChangeLast()
{
- return *(TheItemType* )Find (Upper());
+ return *(TheItemType* )findV (Upper());
}
- //! 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);
+ //! Operator() - query the value
+ TheItemType& operator() (const Standard_Integer theIndex)
+ {
+ return ChangeValue (theIndex);
+ }
+
+ TheItemType& ChangeValue (const Standard_Integer theIndex)
+ {
+ return *(TheItemType* )findV (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;
+ TheItemType& SetValue (const Standard_Integer theIndex,
+ const TheItemType& theValue)
+ {
+ Standard_OutOfRange_Raise_if (theIndex < 0, "NCollection_Vector::SetValue");
+ TheItemType* const aVecValue = (TheItemType* )(theIndex < myLength ? findV (theIndex) : expandV (NCollection_BaseCollection<TheItemType>::myAllocator, theIndex));
+ *aVecValue = theValue;
+ return *aVecValue;
}
- private:
- // ---------- PRIVATE METHODS ----------
- void CopyData (const NCollection_Vector& theOther) {
- Standard_Integer i, iBlock = 0;
+private: //! @name private methods
+
+ void copyData (const NCollection_Vector& theOther)
+ {
+ Standard_Integer 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();
+ for (Standard_Integer aLength = 0; aLength < myLength; aLength += myIncrement)
+ {
+ MemBlock& aBlock = myData[iBlock];
+ initMemBlocks (*this, aBlock, aLength, myIncrement);
+ Standard_Integer anItemIter = 0;
+ for (; anItemIter < myIncrement; ++anItemIter)
+ {
+ if (!anIter.More())
+ {
+ break;
+ }
+
+ ((TheItemType* )aBlock.DataPtr)[anItemIter] = anIter.Value();
anIter.Next();
}
- aBlock.SetLength(i);
+ aBlock.Length = anItemIter;
iBlock++;
}
}
- static NCollection_BaseVector::MemBlock * FuncDataInit
- (const NCollection_BaseVector& theVector,
- const Standard_Integer aCapacity,
- const void * aSource,
- const Standard_Integer aSize)
+ //! Method to initialize memory block content
+ static void initMemBlocks (NCollection_BaseVector& theVector,
+ NCollection_BaseVector::MemBlock& theBlock,
+ const Standard_Integer theFirst,
+ const Standard_Integer theSize)
{
- 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;
+ NCollection_Vector& aSelf = static_cast<NCollection_Vector&> (theVector);
+ Handle(NCollection_BaseAllocator)& anAllocator = aSelf.myAllocator;
+
+ // release current content
+ if (theBlock.DataPtr != NULL)
+ {
+ for (Standard_Integer anItemIter = 0; anItemIter < theBlock.Size; ++anItemIter)
+ {
+ ((TheItemType* )theBlock.DataPtr)[anItemIter].~TheItemTypeD();
+ }
+ anAllocator->Free (theBlock.DataPtr);
+ theBlock.DataPtr = NULL;
}
- while (i < aCapacity)
- new (&aData[i++]) MemBlock(aSelf.myAllocator.operator->());
- 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);
+ // allocate new content if requested
+ if (theSize > 0)
+ {
+ theBlock.DataPtr = anAllocator->Allocate (theSize * sizeof(TheItemType));
+ for (Standard_Integer anItemIter = 0; anItemIter < theSize; ++anItemIter)
+ {
+ new (&((TheItemType* )theBlock.DataPtr)[anItemIter]) TheItemType;
+ }
+ }
+ theBlock.FirstIndex = theFirst;
+ theBlock.Size = theSize;
+ theBlock.Length = 0;
}
friend class Iterator;
+
};
-#endif
+//! Assignment to the collection of the same type
+template <class TheItemType> inline
+void NCollection_Vector<TheItemType>::Assign (const NCollection_Vector& theOther,
+ const Standard_Boolean theOwnAllocator)
+{
+ if (this == &theOther)
+ {
+ return;
+ }
+
+ // destroy current data using current allocator
+ for (Standard_Integer anItemIter = 0; anItemIter < myCapacity; ++anItemIter)
+ {
+ initMemBlocks (*this, myData[anItemIter], 0, 0);
+ }
+ NCollection_BaseCollection<TheItemType>::myAllocator->Free (myData);
+
+ // allocate memory blocks with new allocator
+ if (!theOwnAllocator)
+ {
+ NCollection_BaseCollection<TheItemType>::myAllocator = theOther.myAllocator;
+ }
+ myIncrement = theOther.myIncrement;
+ myLength = theOther.myLength;
+ myNBlocks = (myLength == 0) ? 0 : (1 + (myLength - 1)/myIncrement);
+ myCapacity = GetCapacity (myIncrement) + myLength / myIncrement;
+ myData = allocMemBlocks (NCollection_BaseCollection<TheItemType>::myAllocator, myCapacity);
+
+ // copy data
+ copyData (theOther);
+}
+
+#endif // NCollection_Vector_HeaderFile