mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-16 10:08:36 +03:00
245 lines
7.7 KiB
C++
Executable File
245 lines
7.7 KiB
C++
Executable File
// Created on: 2002-04-24
|
|
// Created by: Alexander GRIGORIEV
|
|
// Copyright (c) 2002-2013 OPEN CASCADE SAS
|
|
//
|
|
// This file is part of Open CASCADE Technology software library.
|
|
//
|
|
// This library is free software; you can redistribute it and/or modify it under
|
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
|
// by the Free Software Foundation, with special exception defined in the file
|
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
|
// distribution for complete text of the license and disclaimer of any warranty.
|
|
//
|
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
|
// commercial license or contractual agreement.
|
|
|
|
#ifndef NCollection_BaseVector_HeaderFile
|
|
#define NCollection_BaseVector_HeaderFile
|
|
|
|
#include <Standard_TypeDef.hxx>
|
|
#include <Standard_OutOfRange.hxx>
|
|
#include <NCollection_BaseAllocator.hxx>
|
|
#include <NCollection_DefineAlloc.hxx>
|
|
|
|
#include <stddef.h>
|
|
|
|
// this value defines the number of blocks that are reserved
|
|
// when the capacity of vector is increased
|
|
inline Standard_Integer GetCapacity (const Standard_Integer theIncrement)
|
|
{
|
|
return Max(theIncrement/8, 1);
|
|
}
|
|
|
|
//! Class NCollection_BaseVector - base for NCollection_Vector template
|
|
class NCollection_BaseVector
|
|
{
|
|
public:
|
|
//! Memory allocation
|
|
DEFINE_STANDARD_ALLOC
|
|
DEFINE_NCOLLECTION_ALLOC
|
|
|
|
protected:
|
|
|
|
// Auxiliary structure for memory blocks
|
|
struct MemBlock
|
|
{
|
|
|
|
public:
|
|
|
|
//! @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;
|
|
|
|
};
|
|
|
|
//! Base class for Iterator implementation
|
|
class Iterator
|
|
{
|
|
protected:
|
|
Iterator()
|
|
: myICurBlock (0),
|
|
myIEndBlock (0),
|
|
myCurIndex (0),
|
|
myEndIndex (0) {}
|
|
|
|
Iterator (const NCollection_BaseVector& theVector, Standard_Boolean theToEnd = Standard_False)
|
|
{
|
|
initV (theVector, theToEnd);
|
|
}
|
|
|
|
Iterator (const Iterator& theVector)
|
|
{
|
|
copyV (theVector);
|
|
}
|
|
|
|
Standard_EXPORT void initV (const NCollection_BaseVector& theVector, Standard_Boolean theToEnd = Standard_False);
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
void prevV()
|
|
{
|
|
if (--myCurIndex < 0 && myICurBlock > 0)
|
|
{
|
|
--myICurBlock;
|
|
myCurIndex = myVector->myData[myICurBlock].Length - 1;
|
|
}
|
|
}
|
|
|
|
void offsetV (Standard_Integer theOffset)
|
|
{
|
|
const Standard_Integer anIndex = myCurIndex + myICurBlock * myVector->myIncrement + theOffset;
|
|
myICurBlock = anIndex / myVector->myIncrement;
|
|
myCurIndex = anIndex % myVector->myIncrement;
|
|
if (myICurBlock > myIEndBlock)
|
|
{
|
|
// make sure that iterator produced by Offset()
|
|
// is equal to the end() iterator
|
|
--myICurBlock;
|
|
myCurIndex += myVector->myIncrement;
|
|
}
|
|
}
|
|
|
|
Standard_Integer differV (const Iterator& theOther) const
|
|
{
|
|
return (myCurIndex - theOther.myCurIndex) + (myICurBlock - theOther.myICurBlock) * myVector->myIncrement;
|
|
}
|
|
|
|
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: //! @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 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 MemBlock* allocMemBlocks (const Standard_Integer theCapacity,
|
|
MemBlock* theSource = NULL,
|
|
const Standard_Integer theSourceSize = 0);
|
|
|
|
protected: //! @name protected methods
|
|
|
|
//! Empty constructor
|
|
NCollection_BaseVector (const 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),
|
|
myInitBlocks (theInitBlocks)
|
|
{
|
|
myAllocator = (theAllocator.IsNull() ? NCollection_BaseAllocator::CommonBaseAllocator() : theAllocator);
|
|
myData = allocMemBlocks (myCapacity);
|
|
}
|
|
|
|
//! Copy constructor
|
|
NCollection_BaseVector (const 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 (theOther.myLength == 0 ? 0 : 1 + (theOther.myLength - 1)/theOther.myIncrement),
|
|
myInitBlocks (theInitBlocks)
|
|
{
|
|
myAllocator = (theAllocator.IsNull() ? NCollection_BaseAllocator::CommonBaseAllocator() : theAllocator);
|
|
myData = allocMemBlocks (myCapacity);
|
|
}
|
|
|
|
//! Destructor
|
|
virtual ~NCollection_BaseVector() {}
|
|
|
|
//! @return pointer to memory where to put the new item
|
|
Standard_EXPORT void* expandV (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();
|
|
// to set the size of increment dynamically
|
|
void SetIncrement(const Standard_Integer aIncrement) {
|
|
if (aIncrement > 0) {
|
|
if (!myIncrement) {
|
|
myIncrement=aIncrement;
|
|
}
|
|
}
|
|
}
|
|
|
|
//! Returns attached allocator
|
|
const Handle(NCollection_BaseAllocator)& Allocator() const
|
|
{
|
|
return myAllocator;
|
|
}
|
|
|
|
protected: //! @name Protected fields
|
|
|
|
Handle(NCollection_BaseAllocator) myAllocator;
|
|
size_t myItemSize;
|
|
Standard_Integer myIncrement;
|
|
Standard_Integer myLength;
|
|
Standard_Integer myCapacity;
|
|
Standard_Integer myNBlocks;
|
|
MemBlock* myData;
|
|
initMemBlocks_t myInitBlocks;
|
|
|
|
protected:
|
|
|
|
friend class Iterator;
|
|
};
|
|
|
|
#endif // NCollection_BaseVector_HeaderFile
|