0024911: Avoid using virtual functions in NCollection classes
[occt.git] / src / NCollection / NCollection_BaseVector.hxx
index f57cac7..e0fc574 100755 (executable)
@@ -1,24 +1,27 @@
-// 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
@@ -27,165 +30,191 @@ inline Standard_Integer GetCapacity (const Standard_Integer theIncrement)
   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 Standard_Integer) {}
-    Standard_Integer    FirstIndex () const     { return myFirstInd; }
-    Standard_Integer    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 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:
-    Standard_Integer             myFirstInd;
-    Standard_Integer             myLength;
-    Standard_Integer             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
-    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, 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