-// File: NCollection_BaseVector.hxx
-// Created: 24.04.02 09:41:39
-// Author: Alexander GRIGORIEV
-// Copyright: Open Cascade 2002
-
+// 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 <NCollection_BaseAllocator.hxx>
-#include <stddef.h>
-
-#if !defined No_Exception && !defined No_Standard_OutOfRange
#include <Standard_OutOfRange.hxx>
-#endif
+#include <NCollection_BaseAllocator.hxx>
+#include <NCollection_DefineAlloc.hxx>
-#ifdef WNT
-#pragma warning(push, 1)
-#pragma warning(disable:4355)
-#endif
+#include <stddef.h>
// this value defines the number of blocks that are reserved
// when the capacity of vector is increased
return Max(theIncrement/8, 1);
}
-/**
- * Class NCollection_BaseVector - base for generic vector
- */
-class NCollection_BaseVector
+//! Class NCollection_BaseVector - base for NCollection_Vector template
+class NCollection_BaseVector
{
- public:
- // ------------ Class MemBlock ------------
- class MemBlock {
- protected:
- MemBlock (NCollection_BaseAllocator* theAlloc)
- : myAlloc(theAlloc),
- myFirstInd(0), myLength(0), mySize(0), myData(0L) {}
- MemBlock (const Standard_Integer theFirstInd,
- const Standard_Integer theLength,
- NCollection_BaseAllocator* theAlloc)
- : myAlloc(theAlloc),
- myFirstInd(theFirstInd), myLength(0), mySize(theLength), myData(0L) {}
- virtual void Reinit (const Standard_Integer,
- const size_t) {}
- Standard_Integer FirstIndex () const { return myFirstInd; }
- size_t Size () const { return mySize; }
+public:
+ //! Memory allocation
+ DEFINE_STANDARD_ALLOC
+ DEFINE_NCOLLECTION_ALLOC
+
+protected:
+
+ // Auxiliary structure for memory blocks
+ struct MemBlock
+ {
+
public:
- virtual ~MemBlock () {}
- void SetLength (const size_t theLen)
- { myLength = theLen; }
- size_t Length () const { return myLength; }
- void * Find (const Standard_Integer theInd,
- const size_t theSize) const
- { return ((char *) myData)+theInd*theSize;}
- Standard_EXPORT Standard_Integer
- GetIndexV (void * theItem, const size_t theSz) const;
- protected:
- Standard_Integer myFirstInd;
- size_t myLength;
- size_t mySize;
- NCollection_BaseAllocator * myAlloc;
- void * myData;
- 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
- size_t myICurBlock; // # of the current block
- size_t myIEndBlock;
- size_t myCurIndex; // Index in the current block
- size_t myEndIndex;
+ 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;
+ }
+
+ 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:
- // ------------ 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);
- // ---------- PROTECTED METHODS ----------
+ //! 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 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 (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)
{
-// myData = (MemBlock *) new char [myCapacity * sizeof(MemBlock)];
-// for (Standard_Integer i = 0; i < myCapacity; i++)
-// new (&myData[i]) MemBlock;
+ myAllocator = (theAllocator.IsNull() ? NCollection_BaseAllocator::CommonBaseAllocator() : theAllocator);
+ myData = allocMemBlocks (myCapacity);
}
//! 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; }
+ 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 (1 + (theOther.myLength - 1)/theOther.myIncrement),
+ myInitBlocks (theInitBlocks)
+ {
+ myAllocator = (theAllocator.IsNull() ? NCollection_BaseAllocator::CommonBaseAllocator() : theAllocator);
+ myData = allocMemBlocks (myCapacity);
+ }
+
+ //! @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 ();
-
- 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 Protected 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);
-}
+ 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:
-#ifdef WNT
-#pragma warning(pop)
-#endif
+ friend class Iterator;
+};
-#endif
+#endif // NCollection_BaseVector_HeaderFile