mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-03 17:56:21 +03:00
0023284: Using 'memcpy' on class that contains a virtual method
NCollection_BaseVector::MemBlock class was converted to POD structure Added fix for compilation of multiple inherited classes on gcc/Linux
This commit is contained in:
parent
872f4e44da
commit
f4aad56f97
@ -1,6 +1,6 @@
|
||||
// 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
|
||||
@ -17,201 +17,149 @@
|
||||
// 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 :
|
||||
//function : NCollection_BaseVector::Iterator::copyV
|
||||
//purpose : Copy from another iterator
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer NCollection_BaseVector::MemBlock::GetIndexV
|
||||
(void * theItem, const size_t theItemSize) const
|
||||
void NCollection_BaseVector::Iterator::copyV (const NCollection_BaseVector::Iterator& theOth)
|
||||
{
|
||||
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;
|
||||
myVector = theOth.myVector;
|
||||
myICurBlock = theOth.myICurBlock;
|
||||
myIEndBlock = theOth.myIEndBlock;
|
||||
myCurIndex = theOth.myCurIndex;
|
||||
myEndIndex = theOth.myEndIndex;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ~NCollection_BaseVector
|
||||
//purpose : Destructor
|
||||
//function : initV
|
||||
//purpose : Initialisation of iterator by a vector
|
||||
//=======================================================================
|
||||
|
||||
NCollection_BaseVector::~NCollection_BaseVector()
|
||||
void NCollection_BaseVector::Iterator::initV (const NCollection_BaseVector& theVector)
|
||||
{
|
||||
for (Standard_Integer i = 0; i < myCapacity; i++)
|
||||
myData[i].Reinit (0, 0);
|
||||
myDataFree (* this, myData);
|
||||
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 : allocMemBlocks
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
NCollection_BaseVector::MemBlock* NCollection_BaseVector
|
||||
::allocMemBlocks (Handle(NCollection_BaseAllocator)& theAllocator,
|
||||
const Standard_Integer theCapacity,
|
||||
MemBlock* theSource,
|
||||
const Standard_Integer theSourceSize)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
// Nullify newly allocated blocks
|
||||
if (aCapacity < theCapacity)
|
||||
{
|
||||
memset (&aData[aCapacity], 0, (theCapacity - aCapacity) * sizeof(MemBlock));
|
||||
}
|
||||
return aData;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Clear
|
||||
//purpose :
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void NCollection_BaseVector::Clear()
|
||||
{
|
||||
if (myLength > 0) {
|
||||
for (Standard_Integer i = 0; i < myCapacity; i++)
|
||||
myData[i].Reinit (0, 0);
|
||||
myLength = 0;
|
||||
if (myLength > 0)
|
||||
{
|
||||
for (Standard_Integer anItemIter = 0; anItemIter < myCapacity; ++anItemIter)
|
||||
{
|
||||
myInitBlocks (*this, myData[anItemIter], 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 = GetCapacity(myIncrement) + myLength / myIncrement;
|
||||
myData = myDataInit (* this, myCapacity, NULL, 0);
|
||||
// }
|
||||
return * this;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//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);
|
||||
return aNewBlock->findV (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
|
||||
|
@ -1,6 +1,6 @@
|
||||
// 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
|
||||
@ -17,8 +17,6 @@
|
||||
// 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
|
||||
|
||||
@ -26,13 +24,11 @@
|
||||
#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
|
||||
@ -42,171 +38,167 @@ inline Standard_Integer GetCapacity (const Standard_Integer theIncrement)
|
||||
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]; }
|
||||
Iterator()
|
||||
: myICurBlock (0),
|
||||
myIEndBlock (0),
|
||||
myCurIndex (0),
|
||||
myEndIndex (0) {}
|
||||
|
||||
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 (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
|
||||
|
||||
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: //! @name protected methods
|
||||
|
||||
//! Empty constructor
|
||||
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
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
public: //! @name public API
|
||||
|
||||
//! Empty the vector of its objects
|
||||
Standard_EXPORT void Clear();
|
||||
|
||||
protected: //! @name Private fields
|
||||
|
||||
size_t myItemSize;
|
||||
Standard_Integer myIncrement;
|
||||
Standard_Integer myLength;
|
||||
Standard_Integer myCapacity;
|
||||
Standard_Integer myNBlocks;
|
||||
MemBlock* myData;
|
||||
initMemBlocks_t myInitBlocks;
|
||||
|
||||
protected:
|
||||
|
||||
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 (GetCapacity(myIncrement)),
|
||||
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 (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; }
|
||||
|
||||
//! 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)
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif // NCollection_BaseVector_HeaderFile
|
||||
|
@ -1,6 +1,6 @@
|
||||
// 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
|
||||
@ -23,180 +23,135 @@
|
||||
#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) {}
|
||||
//! 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); }
|
||||
}; // End of the nested class Iterator
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// ------------------------ Class Vector itself -------------------------
|
||||
// ----------------------------------------------------------------------
|
||||
public:
|
||||
// ---------- PUBLIC METHODS ----------
|
||||
//! Empty constructor - for later Init
|
||||
Iterator() {}
|
||||
|
||||
//! 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() const
|
||||
{
|
||||
return moreV();
|
||||
}
|
||||
|
||||
//! Make step
|
||||
virtual void Next()
|
||||
{
|
||||
nextV();
|
||||
}
|
||||
|
||||
//! Constant value access
|
||||
virtual const TheItemType& Value() const
|
||||
{
|
||||
return ((const TheItemType* )curBlockV()->DataPtr)[myCurIndex];
|
||||
}
|
||||
|
||||
//! Variable value access
|
||||
virtual TheItemType& ChangeValue() const
|
||||
{
|
||||
return ((TheItemType* )curBlockV()->DataPtr)[myCurIndex];
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
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); }
|
||||
: NCollection_BaseCollection<TheItemType> (theOther.myAllocator),
|
||||
NCollection_BaseVector (NCollection_BaseCollection<TheItemType>::myAllocator, initMemBlocks, theOther)
|
||||
{
|
||||
copyData (theOther);
|
||||
}
|
||||
|
||||
//! Operator =
|
||||
NCollection_Vector& operator = (const NCollection_Vector& theOther) {
|
||||
if (this != &theOther) {
|
||||
this->myAllocator = theOther.myAllocator;
|
||||
NCollection_BaseVector::operator = (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.
|
||||
@ -209,22 +164,23 @@ template <class TheItemType> class NCollection_Vector
|
||||
//! @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();
|
||||
}
|
||||
@ -232,126 +188,173 @@ template <class TheItemType> class NCollection_Vector
|
||||
}
|
||||
|
||||
//! 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;
|
||||
}
|
||||
while (i < aCapacity)
|
||||
new (&aData[i++]) MemBlock(aSelf.myAllocator.operator->());
|
||||
return aData;
|
||||
}
|
||||
NCollection_Vector& aSelf = static_cast<NCollection_Vector&> (theVector);
|
||||
Handle(NCollection_BaseAllocator)& anAllocator = aSelf.myAllocator;
|
||||
|
||||
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);
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user