0023284: Using 'memcpy' on class that contains a virtual method
[occt.git] / src / NCollection / NCollection_BaseVector.hxx
index 5506ec0..08c4e60 100755 (executable)
@@ -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
 
 #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]; }
-
-    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