0024831: Make iterators of NCollection classes STL-compatible
authordbp <dbp@opencascade.com>
Wed, 23 Apr 2014 05:38:58 +0000 (09:38 +0400)
committerapn <apn@opencascade.com>
Thu, 29 May 2014 12:19:55 +0000 (16:19 +0400)
STL-compatible iterators returned methods begin() and end() are provided in collection classes from NCollection package.
NCollection_Array1::Iterator is redesigned to use pointer instead of index.
Iterators of Sequence, Array, and Vector are extended by new methods to iterate backwards.

Use of SortTools_QuickSortOfReal is replaced by std::sort() in a few places (where possible).

25 files changed:
src/GeomFill/GeomFill_Frenet.cxx
src/NCollection/FILES
src/NCollection/NCollection_Array1.hxx
src/NCollection/NCollection_Array2.hxx
src/NCollection/NCollection_BaseList.hxx
src/NCollection/NCollection_BaseMap.hxx
src/NCollection/NCollection_BaseSequence.cxx
src/NCollection/NCollection_BaseSequence.hxx
src/NCollection/NCollection_BaseVector.cxx
src/NCollection/NCollection_BaseVector.hxx
src/NCollection/NCollection_DataMap.hxx
src/NCollection/NCollection_IndexedDataMap.hxx
src/NCollection/NCollection_IndexedMap.hxx
src/NCollection/NCollection_List.hxx
src/NCollection/NCollection_Map.hxx
src/NCollection/NCollection_Sequence.hxx
src/NCollection/NCollection_StlIterator.hxx [new file with mode: 0644]
src/NCollection/NCollection_Vector.hxx
src/QANCollection/FILES
src/QANCollection/QANCollection.cdl
src/QANCollection/QANCollection.cxx
src/QANCollection/QANCollection_Stl.cxx [new file with mode: 0644]
src/QANewModTopOpe/QANewModTopOpe_Glue_shell.cxx
src/QANewModTopOpe/QANewModTopOpe_Tools.cxx
src/TopOpeBRepTool/TopOpeBRepTool_TOOL.cxx

index 8f442bd..ef6c16a 100644 (file)
@@ -22,9 +22,9 @@
 #include <GeomFill_SnglrFunc.hxx>
 #include <Extrema_ExtPC.hxx>
 #include <TColStd_HArray1OfBoolean.hxx>
-#include <SortTools_QuickSortOfReal.hxx>
-#include <TCollection_CompareOfReal.hxx>
 #include <TColgp_SequenceOfPnt2d.hxx>
+#include <NCollection_Array1.hxx>
+#include <algorithm>
 
 static const Standard_Real NullTol = 1.e-10;
 static const Standard_Real MaxSingular = 1.e-5;
@@ -211,11 +211,10 @@ Handle(GeomFill_TrihedronLaw) GeomFill_Frenet::Copy() const
          }
        // sorting
        if(SeqArray[i-1].Length() != 0) {
-         TColStd_Array1OfReal anArray( 1, SeqArray[i-1].Length() );
+         NCollection_Array1<Standard_Real> anArray( 1, SeqArray[i-1].Length() );
          for (j = 1; j <= anArray.Length(); j++)
            anArray(j) = SeqArray[i-1](j);
-         TCollection_CompareOfReal Compar;
-         SortTools_QuickSortOfReal::Sort( anArray, Compar);
+         std::sort (anArray.begin(), anArray.end());
          for (j = 1; j <= anArray.Length(); j++)
            SeqArray[i-1](j) = anArray(j);
        }
@@ -258,11 +257,10 @@ Handle(GeomFill_TrihedronLaw) GeomFill_Frenet::Copy() const
 
   if(SnglSeq.Length() > 0) {
     // sorting
-    TColStd_Array1OfReal anArray( 1, SnglSeq.Length() );
+    NCollection_Array1<Standard_Real> anArray( 1, SnglSeq.Length() );
     for (i = 1; i <= SnglSeq.Length(); i++)
       anArray(i) = SnglSeq(i);
-    TCollection_CompareOfReal Compar;
-    SortTools_QuickSortOfReal::Sort( anArray, Compar );
+    std::sort (anArray.begin(), anArray.end());
     for (i = 1; i <= SnglSeq.Length(); i++)
       SnglSeq(i) = anArray(i);
     
index d47520f..f900ec5 100755 (executable)
@@ -86,3 +86,5 @@ NCollection_Vec2.hxx
 NCollection_Vec3.hxx
 NCollection_Vec4.hxx
 NCollection_Mat4.hxx
+
+NCollection_StlIterator.hxx
index 3d7c87a..8c6989b 100644 (file)
@@ -23,6 +23,7 @@
 #endif
 
 #include <NCollection_BaseCollection.hxx>
+#include <NCollection_StlIterator.hxx>
 
 // *********************************************** Template for Array1 class
 
 template <class TheItemType> class NCollection_Array1
   : public NCollection_BaseCollection<TheItemType>
 {
+public:
+  //! STL-compliant typedef for value type
+  typedef TheItemType value_type;
 
- public:
+public:
   //! Implementation of the Iterator interface.
   class Iterator : public NCollection_BaseCollection<TheItemType>::Iterator
   {
   public:
+
     //! Empty constructor - for later Init
-    Iterator  (void) :
-      myCurrent (0),
-      myArray   (NULL) {}
-    //! Constructor with initialisation
-    Iterator  (const NCollection_Array1& theArray) :
-      myCurrent (theArray.Lower()),
-      myArray   ((NCollection_Array1 *) &theArray) {}
+    Iterator (void) :
+      myPtrCur (NULL),
+      myPtrEnd (NULL)
+    {
+      //
+    }
+
+    //! Constructor with initialization
+    Iterator (const NCollection_Array1& theArray, Standard_Boolean theToEnd = Standard_False) :
+      myPtrEnd (const_cast<TheItemType*> (&theArray.Last() + 1))
+    {
+      myPtrCur = theToEnd ? myPtrEnd : const_cast<TheItemType*> (&theArray.First());
+    }
+
     //! Initialisation
     void Init (const NCollection_Array1& theArray)
     { 
-      myCurrent = theArray.Lower();
-      myArray   = (NCollection_Array1 *) &theArray; 
+      myPtrCur = const_cast<TheItemType*> (&theArray.First());
+      myPtrEnd = const_cast<TheItemType*> (&theArray.Last() + 1);
     }
+
+    //! Assignment
+    Iterator& operator= (const Iterator& theOther)
+    {
+      myPtrCur = theOther.myPtrCur;
+      myPtrEnd = theOther.myPtrEnd;
+      return *this;
+    }
+
     //! Check end
     virtual Standard_Boolean More (void) const
-    { return (myCurrent<=myArray->Upper()); }
-    //! Make step
-    virtual void Next (void)         
-    { myCurrent++; }
+    { return myPtrCur < myPtrEnd; }
+    
+    //! Increment operator
+    virtual void Next (void)
+    { ++myPtrCur; }
+
+    //! Decrement operator
+    virtual void Previous()
+    { --myPtrCur; }
+
+    //! Offset operator.
+    virtual void Offset (ptrdiff_t theOffset)
+    { myPtrCur += theOffset; }
+
+    //! Difference operator.
+    virtual ptrdiff_t Differ (const Iterator& theOther) const
+    { return myPtrCur - theOther.myPtrCur; }
+
     //! Constant value access
     virtual const TheItemType& Value (void) const
-    { return myArray->Value(myCurrent); }
+    { return *myPtrCur; }
+
     //! Variable value access
     virtual TheItemType& ChangeValue (void) const 
-    { return myArray->ChangeValue(myCurrent); }
+    { return *myPtrCur; }
+
+    //! Performs comparison of two iterators
+    virtual Standard_Boolean IsEqual (const Iterator& theOther) const
+    { return myPtrCur == theOther.myPtrCur; }
+
   private:
-    Standard_Integer    myCurrent; //!< Index of the current item
-    NCollection_Array1* myArray;   //!< Pointer to the array being iterated
+    TheItemType* myPtrCur; //!< Pointer to the current element in the array
+    TheItemType* myPtrEnd; //!< Pointer to the past-the-end element in the array
   }; // End of the nested class Iterator
 
+  //! Shorthand for a regular iterator type.
+  typedef NCollection_StlIterator<std::random_access_iterator_tag, Iterator, TheItemType, false> iterator;
+
+  //! Shorthand for a constant iterator type.
+  typedef NCollection_StlIterator<std::random_access_iterator_tag, Iterator, TheItemType, true> const_iterator;
+
+  //! Returns an iterator pointing to the first element in the array.
+  iterator begin() const { return Iterator (*this, false); }
+
+  //! Returns an iterator referring to the past-the-end element in the array.
+  iterator end() const { return Iterator (*this, true); }
+  
+  //! Returns a const iterator pointing to the first element in the array.
+  const_iterator cbegin() const { return Iterator (*this, false); }
+
+  //! Returns a const iterator referring to the past-the-end element in the array.
+  const_iterator cend() const { return Iterator (*this, true); }
+
  public:
   // ---------- PUBLIC METHODS ------------
 
index e95fa69..c8a13aa 100644 (file)
 template <class TheItemType> class NCollection_Array2
   : public NCollection_BaseCollection<TheItemType>
 {
- public:
+public:
+  //! STL-compliant typedef for value type
+  typedef TheItemType value_type;
+
+public:
   // **************** Implementation of the Iterator interface.
   class Iterator : public NCollection_BaseCollection<TheItemType>::Iterator
   {
index 7054485..2f159e6 100644 (file)
@@ -72,11 +72,16 @@ class NCollection_BaseList
     }
 //skt----------------------------------------------------
     // ******** Comparison operator
-    Standard_Boolean operator== (const Iterator& theIt)
+    Standard_Boolean operator== (const Iterator& theIt) const
     {
       return myCurrent == theIt.myCurrent;
     }
 //-------------------------------------------------------
+    //! Performs comparison of two iterators
+    virtual Standard_Boolean IsEqual (const Iterator& theOther) const
+    {
+      return *this == theOther;
+    }
   protected:
     void Init (const NCollection_BaseList& theList,
                NCollection_ListNode * const thePrev)
index 6060a33..c564f97 100644 (file)
@@ -90,6 +90,12 @@ class NCollection_BaseMap
       myNode = NULL;
       PNext();
     }
+    
+    //! Performs comparison of two iterators.
+    virtual Standard_Boolean IsEqual (const Iterator& theOther) const
+    {
+      return myBucket == theOther.myBucket && myNode == theOther.myNode;
+    }
 
   protected:
     //! PMore
index c9569aa..171b8e8 100644 (file)
 void NCollection_BaseSequence::ClearSeq 
   (NCollection_DelSeqNode fDel, Handle(NCollection_BaseAllocator)& theAl)
 {
-  const NCollection_SeqNode * p = myFirstItem;
-  NCollection_SeqNode * q;
+  NCollection_SeqNode* p = myFirstItem;
   while (p) {
-    q = (NCollection_SeqNode *) p;
+    NCollection_SeqNode* q = p;
     p = p->Next();
     fDel (q, theAl);
   }
@@ -49,7 +48,7 @@ void NCollection_BaseSequence::PAppend (NCollection_SeqNode * theItem)
     myFirstItem = myLastItem = myCurrentItem = theItem;
     myCurrentIndex = mySize = 1;
   } else {
-    ((NCollection_SeqNode *) myLastItem)->SetNext(theItem);
+    myLastItem->SetNext(theItem);
     theItem->SetPrevious(myLastItem);
     theItem->SetNext(NULL);
     myLastItem = theItem;
@@ -72,9 +71,9 @@ void NCollection_BaseSequence::PAppend(NCollection_BaseSequence& Other)
     myCurrentIndex = 1;
   } else {
     mySize += Other.mySize;
-    ((NCollection_SeqNode *) myLastItem)->SetNext(Other.myFirstItem);
+    myLastItem->SetNext(Other.myFirstItem);
     if (Other.myFirstItem) {
-      ((NCollection_SeqNode *) Other.myFirstItem)->SetPrevious(myLastItem);
+      Other.myFirstItem->SetPrevious(myLastItem);
       myLastItem = Other.myLastItem;
     }
   }
@@ -92,8 +91,8 @@ void NCollection_BaseSequence::PPrepend (NCollection_SeqNode * theItem)
     myFirstItem = myLastItem = myCurrentItem = theItem;
     myCurrentIndex = mySize = 1;
   } else {
-    ((NCollection_SeqNode *) myFirstItem)->SetPrevious (theItem);
-    ((NCollection_SeqNode *) theItem)->SetNext (myFirstItem); 
+    myFirstItem->SetPrevious (theItem);
+    theItem->SetNext (myFirstItem); 
     theItem->SetPrevious(NULL);
     theItem->SetNext(myFirstItem);
     myFirstItem = theItem;
@@ -118,8 +117,8 @@ void NCollection_BaseSequence::PPrepend (NCollection_BaseSequence& Other)
   } else {
     mySize += Other.mySize;
     if (Other.myLastItem)
-      ((NCollection_SeqNode *) Other.myLastItem)->SetNext (myFirstItem);
-    ((NCollection_SeqNode *) myFirstItem)->SetPrevious(Other.myLastItem);
+      Other.myLastItem->SetNext (myFirstItem);
+    myFirstItem->SetPrevious(Other.myLastItem);
     myFirstItem = Other.myFirstItem;
     myCurrentIndex += Other.mySize;
   }
@@ -133,18 +132,18 @@ void NCollection_BaseSequence::PPrepend (NCollection_BaseSequence& Other)
 
 void NCollection_BaseSequence::PReverse()
 {
-  const NCollection_SeqNode * p = myFirstItem;
-  const NCollection_SeqNode * tmp;
+  NCollection_SeqNode* p = myFirstItem;
   while (p) {
-    tmp = p->Next();
-    ((NCollection_SeqNode *) p)->SetNext (p->Previous());
-    ((NCollection_SeqNode *) p)->SetPrevious (tmp);
+    NCollection_SeqNode* tmp = p->Next();
+    p->SetNext (p->Previous());
+    p->SetPrevious (tmp);
     p = tmp;
   }
-  tmp = myFirstItem;
+  NCollection_SeqNode* tmp = myFirstItem;
   myFirstItem = myLastItem;
   myLastItem = tmp;
-  if (mySize != 0) myCurrentIndex = mySize + 1 - myCurrentIndex;
+  if (mySize != 0)
+    myCurrentIndex = mySize + 1 - myCurrentIndex;
 }
 
 
@@ -163,8 +162,10 @@ void NCollection_BaseSequence::PInsertAfter
   else {
     theItem->SetNext (aPos->Next());
     theItem->SetPrevious (aPos);
-    if (aPos->Next() == NULL) myLastItem = theItem;
-    else ((NCollection_SeqNode *) aPos->Next())->SetPrevious(theItem);
+    if (aPos->Next() == NULL)
+      myLastItem = theItem;
+    else
+      aPos->Next()->SetPrevious(theItem);
     aPos->SetNext(theItem);
     ++ mySize;
     myCurrentItem = myFirstItem;
@@ -183,12 +184,14 @@ void NCollection_BaseSequence::PInsertAfter(const Standard_Integer theIndex,
   if (theIndex == 0)
     PPrepend (theItem);
   else {
-    const NCollection_SeqNode * p = Find (theIndex);
+    NCollection_SeqNode * p = Find (theIndex);
     theItem->SetNext(p->Next());
     theItem->SetPrevious(p);
-    if (theIndex == mySize) myLastItem = theItem;
-    else ((NCollection_SeqNode *) p->Next())->SetPrevious(theItem);
-    ((NCollection_SeqNode *) p)->SetNext(theItem);
+    if (theIndex == mySize)
+      myLastItem = theItem;
+    else
+      p->Next()->SetPrevious(theItem);
+    p->SetNext(theItem);
     ++ mySize;
     if (theIndex < myCurrentIndex)
       ++ myCurrentIndex;
@@ -209,14 +212,14 @@ void NCollection_BaseSequence::PInsertAfter (const Standard_Integer theIndex,
     if (theIndex == 0) 
       PPrepend (Other);
     else {
-      const NCollection_SeqNode * p = Find (theIndex);
-      ((NCollection_SeqNode *) Other.myFirstItem)->SetPrevious (p);
-      ((NCollection_SeqNode *) Other.myLastItem)->SetNext (p->Next());
+      NCollection_SeqNode * p = Find (theIndex);
+      Other.myFirstItem->SetPrevious (p);
+      Other.myLastItem->SetNext (p->Next());
       if (theIndex == mySize)
         myLastItem = Other.myLastItem;
       else
-        ((NCollection_SeqNode *) p->Next())->SetPrevious (Other.myLastItem);
-      ((NCollection_SeqNode *) p)->SetNext (Other.myFirstItem);
+        p->Next()->SetPrevious (Other.myLastItem);
+      p->SetNext (Other.myFirstItem);
       mySize += Other.mySize;
       if (theIndex < myCurrentIndex)
         myCurrentIndex += Other.mySize;
@@ -240,39 +243,39 @@ void NCollection_BaseSequence::PExchange (const Standard_Integer I,
   if (J < I)
     PExchange(J,I);
   else if (I < J) {
-    const NCollection_SeqNode * pi = Find(I);
-    const NCollection_SeqNode * pj = Find(J);
+    NCollection_SeqNode * pi = Find(I);
+    NCollection_SeqNode * pj = Find(J);
 
     // update the node before I
     if (pi->Previous())
-      ((NCollection_SeqNode *) pi->Previous())->SetNext (pj);
+      pi->Previous()->SetNext (pj);
     else 
       myFirstItem = pj;
 
     // update the node after J
     if (pj->Next())
-      ((NCollection_SeqNode *) pj->Next())->SetPrevious(pi);
+      pj->Next()->SetPrevious(pi);
     else
       myLastItem = pi;
 
     if (pi->Next() == pj) {          // I and J are consecutives, update them
-      ((NCollection_SeqNode *) pj)->SetPrevious (pi->Previous());
-      ((NCollection_SeqNode *) pi)->SetPrevious (pj);
-      ((NCollection_SeqNode *) pi)->SetNext (pj->Next());
-      ((NCollection_SeqNode *) pj)->SetNext (pi);
+      pj->SetPrevious (pi->Previous());
+      pi->SetPrevious (pj);
+      pi->SetNext (pj->Next());
+      pj->SetNext (pi);
     }
     else {                        // I and J are not consecutive
       // update the node after I
-      ((NCollection_SeqNode *) pi->Next())->SetPrevious (pj);
+      pi->Next()->SetPrevious (pj);
       // update the node before J
-      ((NCollection_SeqNode *) pj->Previous())->SetNext (pi);
+      pj->Previous()->SetNext (pi);
       // update nodes I and J
-      const NCollection_SeqNode* tmp = pi->Next();       
-      ((NCollection_SeqNode *) pi)->SetNext (pj->Next());
-      ((NCollection_SeqNode *) pj)->SetNext (tmp);
+      NCollection_SeqNode* tmp = pi->Next();       
+      pi->SetNext (pj->Next());
+      pj->SetNext (tmp);
       tmp = pi->Previous();
-      ((NCollection_SeqNode *) pi)->SetPrevious (pj->Previous());
-      ((NCollection_SeqNode *) pj)->SetPrevious (tmp);
+      pi->SetPrevious (pj->Previous());
+      pj->SetPrevious (tmp);
     }
 
     if      (myCurrentIndex == I) myCurrentItem = pj;
@@ -291,14 +294,14 @@ void NCollection_BaseSequence::PSplit (const Standard_Integer theIndex,
   Standard_OutOfRange_Raise_if (theIndex <= 0 || theIndex > mySize,"" );
   Standard_DomainError_Raise_if (this == &Sub, "No Split on myself!!");
 
-  const NCollection_SeqNode * p = Find (theIndex);
+  NCollection_SeqNode * p = Find (theIndex);
 
   Sub.myLastItem = myLastItem;
   Sub.mySize = mySize - theIndex + 1;
 
   myLastItem = p->Previous();
   if (myLastItem) {
-    ((NCollection_SeqNode *) myLastItem)->SetNext(NULL);
+    myLastItem->SetNext(NULL);
     mySize = theIndex - 1;
     if (myCurrentIndex >= theIndex) {
       myCurrentIndex = 1;
@@ -310,7 +313,7 @@ void NCollection_BaseSequence::PSplit (const Standard_Integer theIndex,
   }
 
   Sub.myFirstItem = Sub.myCurrentItem = p;
-  ((NCollection_SeqNode *) p)->SetPrevious (NULL);
+  p->SetPrevious (NULL);
   Sub.myCurrentIndex = 1;
 }
 
@@ -327,15 +330,15 @@ void NCollection_BaseSequence::RemoveSeq
   NCollection_SeqNode * aPos = thePosition.myCurrent;
   if (aPos == NULL)
     return;
-  thePosition.myCurrent = (NCollection_SeqNode *) aPos -> Next();
+  thePosition.myCurrent = aPos -> Next();
 
   if (aPos->Previous())
-    ((NCollection_SeqNode *) aPos->Previous())->SetNext (aPos->Next());
+    aPos->Previous()->SetNext (aPos->Next());
   else
     myFirstItem = aPos->Next();
 
   if (aPos->Next())
-    ((NCollection_SeqNode *) aPos->Next())->SetPrevious (aPos->Previous());
+    aPos->Next()->SetPrevious (aPos->Previous());
   else
     myLastItem = aPos->Previous();
 
@@ -358,13 +361,13 @@ void NCollection_BaseSequence::RemoveSeq
 {
   Standard_OutOfRange_Raise_if (theIndex <= 0 || theIndex > mySize, "");
   
-  const NCollection_SeqNode * p = Find (theIndex);
+  NCollection_SeqNode * p = Find (theIndex);
   if (p->Previous())
-    ((NCollection_SeqNode *) p->Previous())->SetNext (p->Next());
+    p->Previous()->SetNext (p->Next());
   else
     myFirstItem = p->Next();
   if (p->Next())
-    ((NCollection_SeqNode *) p->Next())->SetPrevious (p->Previous());
+    p->Next()->SetPrevious (p->Previous());
   else
     myLastItem = p->Previous();
 
@@ -378,7 +381,7 @@ void NCollection_BaseSequence::RemoveSeq
       myCurrentIndex = mySize;
     }
   }
-  fDel ((NCollection_SeqNode *) p, theAl);
+  fDel (p, theAl);
 }
 
 //=======================================================================
@@ -394,15 +397,15 @@ void NCollection_BaseSequence::RemoveSeq
 {
   Standard_OutOfRange_Raise_if (From <= 0 || To > mySize || From > To, "");
 
-  const NCollection_SeqNode * pfrom = Find(From);
-  const NCollection_SeqNode * pto   = Find(To);
+  NCollection_SeqNode * pfrom = Find(From);
+  NCollection_SeqNode * pto   = Find(To);
   
   if (pfrom->Previous())
-    ((NCollection_SeqNode *) pfrom->Previous())->SetNext (pto->Next());
+    pfrom->Previous()->SetNext (pto->Next());
   else
     myFirstItem = pto->Next();
   if (pto->Next())
-    ((NCollection_SeqNode *) pto->Next())->SetPrevious (pfrom->Previous());
+    pto->Next()->SetPrevious (pfrom->Previous());
   else
     myLastItem = pfrom->Previous();
   
@@ -420,7 +423,7 @@ void NCollection_BaseSequence::RemoveSeq
   }
   
   for (Standard_Integer i = From; i <= To; i++) {
-    NCollection_SeqNode * tmp = (NCollection_SeqNode *)pfrom;
+    NCollection_SeqNode * tmp = pfrom;
     pfrom = pfrom->Next();
     fDel (tmp, theAl);
   }
@@ -431,26 +434,29 @@ void NCollection_BaseSequence::RemoveSeq
 //purpose  : 
 //=======================================================================
 
-const NCollection_SeqNode * NCollection_BaseSequence::Find
-                                        (const Standard_Integer theIndex) const 
+NCollection_SeqNode * NCollection_BaseSequence::Find (const Standard_Integer theIndex) const 
 {
   Standard_Integer i;
-  const NCollection_SeqNode * p;
+  NCollection_SeqNode * p;
   if (theIndex <= myCurrentIndex) {
     if (theIndex < myCurrentIndex / 2) {
       p = myFirstItem;
-      for (i = 1; i < theIndex; i++) p = p->Next();
+      for (i = 1; i < theIndex; i++)
+        p = p->Next();
     } else {
       p = myCurrentItem;
-      for (i = myCurrentIndex; i > theIndex; i--) p = p->Previous();
+      for (i = myCurrentIndex; i > theIndex; i--)
+        p = p->Previous();
     }
   } else {
     if (theIndex < (myCurrentIndex + mySize) / 2) {
       p = myCurrentItem;
-      for (i = myCurrentIndex; i < theIndex; i++) p = p->Next();
+      for (i = myCurrentIndex; i < theIndex; i++)
+        p = p->Next();
     } else {
       p = myLastItem;
-      for (i = mySize; i > theIndex; i--) p = p->Previous();
+      for (i = mySize; i > theIndex; i--)
+        p = p->Previous();
     }
   }
   return p;
index 8be52d8..46790d6 100644 (file)
 class NCollection_SeqNode 
 {
  public:
-  // Methods PUBLIC
-  // 
-  NCollection_SeqNode (void)
-    : myNext (NULL), myPrevious (NULL)                {}
-  const NCollection_SeqNode * Next      () const      { return myNext; }
-  const NCollection_SeqNode * Previous  () const      { return myPrevious; }
-  void                      SetNext     (const NCollection_SeqNode * theNext)
-                                                      { myNext = theNext; }
-  void                      SetPrevious (const NCollection_SeqNode * thePrev)
-                                                      { myPrevious = thePrev; }
-  //~NCollection_SeqNode() {
-  //  if (myNext)           myNext -> myPrevious = myPrevious;
-  //  if (myPrevious)       myPrevious -> myNext = myNext;
-  //}
+  NCollection_SeqNode () : myNext (NULL), myPrevious (NULL) {}
+  NCollection_SeqNode * Next      () const { return myNext; }
+  NCollection_SeqNode * Previous  () const { return myPrevious; }
+  void SetNext     (NCollection_SeqNode * theNext) { myNext = theNext; }
+  void SetPrevious (NCollection_SeqNode * thePrev) { myPrevious = thePrev; }
   
  private:
-  // Fields PRIVATE
-  //
-  const NCollection_SeqNode     * myNext;
-  const NCollection_SeqNode     * myPrevious;
+  NCollection_SeqNode* myNext;
+  NCollection_SeqNode* myPrevious;
 };
 
 typedef void (* NCollection_DelSeqNode) 
@@ -60,28 +49,41 @@ class NCollection_BaseSequence
   {
   public:
     //! Empty constructor
-    Iterator                    (void) : myCurrent (NULL) {}
+    Iterator (void) : myCurrent (NULL), myPrevious(NULL) {}
+
     //! Constructor with initialisation
-    Iterator                    (const NCollection_BaseSequence& theSeq,
-                                 const Standard_Boolean          isStart)
-      : myCurrent(isStart ? (NCollection_SeqNode *)theSeq.myFirstItem
-                          : (NCollection_SeqNode *)theSeq.myLastItem) {}
-    //! Initialisation
-    void             Init       (const NCollection_BaseSequence& theSeq,
-                                 const Standard_Boolean          isStart
-                                                                = Standard_True)
-    { myCurrent = isStart ? (NCollection_SeqNode *)theSeq.myFirstItem
-                          : (NCollection_SeqNode *)theSeq.myLastItem; }
+    Iterator (const NCollection_BaseSequence& theSeq,
+              const Standard_Boolean isStart)
+    {
+      Init (theSeq, isStart);
+    }
+
+     //! Initialisation
+    void Init (const NCollection_BaseSequence& theSeq,
+               const Standard_Boolean isStart = Standard_True)
+    {
+      myCurrent  = (isStart ? theSeq.myFirstItem : NULL);
+      myPrevious = (isStart ? NULL : theSeq.myLastItem);
+    }
+
     //! Assignment
     Iterator& operator = (const Iterator& theOther)
-    { myCurrent = theOther.myCurrent; return *this; }
-    //! Previous
-    void             Previous   ()
-    { if (myCurrent)
-        myCurrent = (NCollection_SeqNode *)myCurrent -> Previous(); }
+    {
+      myCurrent = theOther.myCurrent;
+      myPrevious = theOther.myPrevious;
+      return *this;
+    }
+    //! Switch to previous element; note that it will reset 
+    void Previous()
+    {
+      myCurrent = myPrevious;
+      if (myCurrent)
+        myPrevious = myCurrent->Previous();
+    }
       
   protected:
-    NCollection_SeqNode * myCurrent; //!< Pointer to the current node
+    NCollection_SeqNode* myCurrent;  //!< Pointer to the current node
+    NCollection_SeqNode* myPrevious; //!< Pointer to the previous node
     friend class NCollection_BaseSequence;
   };
 
@@ -122,17 +124,17 @@ class NCollection_BaseSequence
   Standard_EXPORT void   PReverse    ();
   Standard_EXPORT void   PExchange   (const Standard_Integer I,
                                       const Standard_Integer J) ;
-  Standard_EXPORT const NCollection_SeqNode *
+  Standard_EXPORT NCollection_SeqNode *
                          Find        (const Standard_Integer) const;
 
  protected:
   // Fields PROTECTED
   //
-  const NCollection_SeqNode         * myFirstItem;
-  const NCollection_SeqNode         * myLastItem;
-  const NCollection_SeqNode         * myCurrentItem;
-  Standard_Integer                  myCurrentIndex;
-  Standard_Integer                  mySize;
+  NCollection_SeqNode* myFirstItem;
+  NCollection_SeqNode* myLastItem;
+  NCollection_SeqNode* myCurrentItem;
+  Standard_Integer myCurrentIndex;
+  Standard_Integer mySize;
 
  private: 
   // Methods PRIVATE
index 56c31b9..208e775 100755 (executable)
@@ -36,20 +36,24 @@ void NCollection_BaseVector::Iterator::copyV (const NCollection_BaseVector::Iter
 //purpose  : Initialisation of iterator by a vector
 //=======================================================================
 
-void NCollection_BaseVector::Iterator::initV (const NCollection_BaseVector& theVector)
+void NCollection_BaseVector::Iterator::initV (const NCollection_BaseVector& theVector, Standard_Boolean theToEnd)
 {
-  myVector    = &theVector;
-  myICurBlock = 0;
-  myCurIndex  = 0;
+  myVector = &theVector;
+
   if (theVector.myNBlocks == 0)
   {
-    myIEndBlock = 0;
+    myCurIndex  = 0;
     myEndIndex  = 0;
+    myICurBlock = 0;
+    myIEndBlock = 0;
   }
   else
   {
     myIEndBlock = theVector.myNBlocks - 1;
     myEndIndex  = theVector.myData[myIEndBlock].Length;
+
+    myICurBlock = !theToEnd ? 0 : myIEndBlock;
+    myCurIndex  = !theToEnd ? 0 : myEndIndex;
   }
 }
 
index 12a7b31..1f1b30c 100755 (executable)
@@ -74,9 +74,9 @@ protected:
       myCurIndex  (0),
       myEndIndex  (0) {}
 
-    Iterator (const NCollection_BaseVector& theVector)
+    Iterator (const NCollection_BaseVector& theVector, Standard_Boolean theToEnd = Standard_False)
     {
-      initV (theVector);
+      initV (theVector, theToEnd);
     }
 
     Iterator (const Iterator& theVector)
@@ -84,7 +84,7 @@ protected:
       copyV (theVector);
     }
 
-    Standard_EXPORT void initV (const NCollection_BaseVector& theVector);
+    Standard_EXPORT void initV (const NCollection_BaseVector& theVector, Standard_Boolean theToEnd = Standard_False);
 
     Standard_EXPORT void copyV (const Iterator&);
 
@@ -103,6 +103,27 @@ protected:
       }
     }
 
+    void prevV()
+    {
+      if (--myCurIndex < 0 && myICurBlock > 0)
+      {
+        --myICurBlock;
+        myCurIndex = myVector->myData[myICurBlock].Length - 1;
+      }
+    }
+
+    virtual void offsetV (Standard_Integer theOffset)
+    {
+      const Standard_Integer anIndex = myCurIndex + myICurBlock * myVector->myIncrement + theOffset;
+      myICurBlock = anIndex / myVector->myIncrement;
+      myCurIndex = anIndex % myVector->myIncrement;
+    }
+
+    virtual Standard_Integer differV (const Iterator& theOther) const
+    {
+      return (myCurIndex - theOther.myCurIndex) + (myICurBlock - theOther.myICurBlock) * myVector->myIncrement;
+    }
+
     const MemBlock* curBlockV() const
     {
       return &myVector->myData[myICurBlock];
index 2b7cdbd..704bc1d 100644 (file)
@@ -19,7 +19,7 @@
 #include <NCollection_BaseCollection.hxx>
 #include <NCollection_BaseMap.hxx>
 #include <NCollection_TListNode.hxx>
-
+#include <NCollection_StlIterator.hxx>
 #include <NCollection_DefaultHasher.hxx>
 
 #include <Standard_TypeMismatch.hxx>
@@ -124,6 +124,24 @@ template < class TheKeyType,
       return ((DataMapNode *) myNode)->Key();
     }
   };
+  
+  //! Shorthand for a regular iterator type.
+  typedef NCollection_StlIterator<std::forward_iterator_tag, Iterator, TheItemType, false> iterator;
+
+  //! Shorthand for a constant iterator type.
+  typedef NCollection_StlIterator<std::forward_iterator_tag, Iterator, TheItemType, true> const_iterator;
+
+  //! Returns an iterator pointing to the first element in the map.
+  iterator begin() const { return Iterator (*this); }
+
+  //! Returns an iterator referring to the past-the-end element in the map.
+  iterator end() const { return Iterator(); }
+
+  //! Returns a const iterator pointing to the first element in the map.
+  const_iterator cbegin() const { return Iterator (*this); }
+
+  //! Returns a const iterator referring to the past-the-end element in the map.
+  const_iterator cend() const { return Iterator(); }
 
  public:
   // ---------- PUBLIC METHODS ------------
index 806d810..939db85 100644 (file)
@@ -21,7 +21,7 @@
 #include <NCollection_TListNode.hxx>
 #include <Standard_TypeMismatch.hxx>
 #include <Standard_NoSuchObject.hxx>
-
+#include <NCollection_StlIterator.hxx>
 #include <NCollection_DefaultHasher.hxx>
 
 #if !defined No_Exception && !defined No_Standard_OutOfRange
@@ -110,7 +110,7 @@ template < class TheKeyType,
       myIndex (1) {}
     //! Query if the end of collection is reached by iterator
     virtual Standard_Boolean More(void) const
-    { return (myIndex <= myMap->Extent()); }
+    { return (myMap != NULL) && (myIndex <= myMap->Extent()); }
     //! Make a step along the collection
     virtual void Next(void)
     {
@@ -143,12 +143,37 @@ template < class TheKeyType,
 #endif
       return myNode->Key1();
     }
+    //! Performs comparison of two iterators.
+    virtual Standard_Boolean IsEqual (const Iterator& theOther) const
+    {
+      return myMap == theOther.myMap &&
+             myNode == theOther.myNode &&
+             myIndex == theOther.myIndex;
+    }
   private:
     NCollection_IndexedDataMap* myMap;   //!< Pointer to the map being iterated
     IndexedDataMapNode*         myNode;  //!< Current node
     Standard_Integer            myIndex; //!< Current index
   };
   
+  //! Shorthand for a regular iterator type.
+  typedef NCollection_StlIterator<std::forward_iterator_tag, Iterator, TheItemType, false> iterator;
+
+  //! Shorthand for a constant iterator type.
+  typedef NCollection_StlIterator<std::forward_iterator_tag, Iterator, TheItemType, true> const_iterator;
+
+  //! Returns an iterator pointing to the first element in the map.
+  iterator begin() const { return Iterator (*this); }
+
+  //! Returns an iterator referring to the past-the-end element in the map.
+  iterator end() const { return Iterator(); }
+
+  //! Returns a const iterator pointing to the first element in the map.
+  const_iterator cbegin() const { return Iterator (*this); }
+
+  //! Returns a const iterator referring to the past-the-end element in the map.
+  const_iterator cend() const { return Iterator(); }
+  
  public:
   // ---------- PUBLIC METHODS ------------
 
index 2beb117..f76f7d4 100644 (file)
@@ -19,6 +19,7 @@
 #include <NCollection_BaseCollection.hxx>
 #include <NCollection_BaseMap.hxx>
 #include <NCollection_TListNode.hxx>
+#include <NCollection_StlIterator.hxx>
 #include <Standard_NoSuchObject.hxx>
 #include <Standard_ImmutableObject.hxx>
 
@@ -99,7 +100,7 @@ template < class TheKeyType,
       myIndex(1) {}
     //! Query if the end of collection is reached by iterator
     virtual Standard_Boolean More(void) const
-    { return (myIndex <= myMap->Extent()); }
+    { return (myMap != NULL) && (myIndex <= myMap->Extent()); }
     //! Make a step along the collection
     virtual void Next(void)
     { myIndex++; }
@@ -118,12 +119,26 @@ template < class TheKeyType,
       Standard_ImmutableObject::Raise ("impossible to ChangeValue");
       return * (TheKeyType *) NULL; // This for compiler
     }
+    //! Performs comparison of two iterators.
+    virtual Standard_Boolean IsEqual (const Iterator& theOther) const
+    {
+      return myMap == theOther.myMap && myIndex == theOther.myIndex;
+    }
     
   private:
     NCollection_IndexedMap * myMap;   // Pointer to the map being iterated
     Standard_Integer         myIndex; // Current index
   };
   
+  //! Shorthand for a constant iterator type.
+  typedef NCollection_StlIterator<std::forward_iterator_tag, Iterator, TheKeyType, true> const_iterator;
+
+  //! Returns a const iterator pointing to the first element in the map.
+  const_iterator cbegin() const { return Iterator (*this); }
+
+  //! Returns a const iterator referring to the past-the-end element in the map.
+  const_iterator cend() const { return Iterator(); }
+  
  public:
   // ---------- PUBLIC METHODS ------------
 
index 4d45ddd..410a6a9 100644 (file)
@@ -17,6 +17,7 @@
 #define NCollection_List_HeaderFile
 
 #include <NCollection_TListIterator.hxx>
+#include <NCollection_StlIterator.hxx>
 
 #if !defined No_Exception && !defined No_Standard_NoSuchObject
 #include <Standard_NoSuchObject.hxx>
@@ -31,10 +32,32 @@ template <class TheItemType> class NCollection_List
   : public NCollection_BaseCollection<TheItemType>,
     public NCollection_BaseList
 {
- public:
+public:
+  //! STL-compliant typedef for value type
+  typedef TheItemType value_type;
+
+public:
   typedef NCollection_TListNode<TheItemType>     ListNode;
   typedef NCollection_TListIterator<TheItemType> Iterator;
 
+  //! Shorthand for a regular iterator type.
+  typedef NCollection_StlIterator<std::forward_iterator_tag, Iterator, TheItemType, false> iterator;
+
+  //! Shorthand for a constant iterator type.
+  typedef NCollection_StlIterator<std::forward_iterator_tag, Iterator, TheItemType, true> const_iterator;
+
+  //! Returns an iterator pointing to the first element in the list.
+  iterator begin() const { return Iterator (*this); }
+
+  //! Returns an iterator referring to the past-the-end element in the list.
+  iterator end() const { return Iterator(); }
+
+  //! Returns a const iterator pointing to the first element in the list.
+  const_iterator cbegin() const { return Iterator (*this); }
+
+  //! Returns a const iterator referring to the past-the-end element in the list.
+  const_iterator cend() const { return Iterator(); }
+
  public:
   // ---------- PUBLIC METHODS ------------
 
index a133972..2cdefd4 100644 (file)
@@ -20,7 +20,7 @@
 #include <NCollection_BaseMap.hxx>
 #include <NCollection_DataMap.hxx>
 #include <NCollection_TListNode.hxx>
-
+#include <NCollection_StlIterator.hxx>
 #include <NCollection_DefaultHasher.hxx>
 
 #include <Standard_ImmutableObject.hxx>
@@ -122,6 +122,15 @@ template < class TheKeyType,
       return ((MapNode *) myNode)->Value();
     }
   };
+  
+  //! Shorthand for a constant iterator type.
+  typedef NCollection_StlIterator<std::forward_iterator_tag, Iterator, TheKeyType, true> const_iterator;
+
+  //! Returns a const iterator pointing to the first element in the map.
+  const_iterator cbegin() const { return Iterator (*this); }
+
+  //! Returns a const iterator referring to the past-the-end element in the map.
+  const_iterator cend() const { return Iterator(); }
 
  public:
   // ---------- PUBLIC METHODS ------------
index f43cef7..4ef17ad 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <NCollection_BaseCollection.hxx>
 #include <NCollection_BaseSequence.hxx>
+#include <NCollection_StlIterator.hxx>
 
 #ifndef No_Exception
 #include <Standard_OutOfRange.hxx>
@@ -32,8 +33,11 @@ template <class TheItemType> class NCollection_Sequence
   : public NCollection_BaseCollection<TheItemType>,
     public NCollection_BaseSequence
 {
+public:
+  //! STL-compliant typedef for value type
+  typedef TheItemType value_type;
 
- public:
+public:
   //!   Class defining sequence node - for internal use by Sequence
   class Node : public NCollection_SeqNode
   {
@@ -77,16 +81,45 @@ template <class TheItemType> class NCollection_Sequence
     virtual Standard_Boolean More (void) const
     { return (myCurrent!=NULL); }
     //! Make step
-    virtual void Next (void)         
-    { if (myCurrent) myCurrent = (NCollection_SeqNode *) myCurrent->Next(); }
+    virtual void Next (void)
+    {
+      if (myCurrent)
+      {
+        myPrevious = myCurrent;
+        myCurrent = myCurrent->Next();
+      }
+    }
     //! Constant value access
     virtual const TheItemType& Value (void) const
     { return ((const Node *)myCurrent)->Value(); }
     //! Variable value access
     virtual TheItemType& ChangeValue (void) const
     { return ((Node *)myCurrent)->ChangeValue(); }
+    //! Performs comparison of two iterators.
+    virtual Standard_Boolean IsEqual (const Iterator& theOther) const
+    {
+      return myCurrent == theOther.myCurrent;
+    }
   }; // End of nested class Iterator
 
+  //! Shorthand for a regular iterator type.
+  typedef NCollection_StlIterator<std::bidirectional_iterator_tag, Iterator, TheItemType, false> iterator;
+
+  //! Shorthand for a constant iterator type.
+  typedef NCollection_StlIterator<std::bidirectional_iterator_tag, Iterator, TheItemType, true> const_iterator;
+
+  //! Returns an iterator pointing to the first element in the sequence.
+  iterator begin() const { return Iterator (*this, true); }
+
+  //! Returns an iterator referring to the past-the-end element in the sequence.
+  iterator end() const { Iterator anIter (*this, false); anIter.Next(); return anIter; }
+  
+  //! Returns a const iterator pointing to the first element in the sequence.
+  const_iterator cbegin() const { return Iterator (*this, true); }
+
+  //! Returns a const iterator referring to the past-the-end element in the sequence.
+  const_iterator cend() const { Iterator anIter (*this, false); anIter.Next(); return anIter; }
+
  public:
   // ---------- PUBLIC METHODS ------------
 
diff --git a/src/NCollection/NCollection_StlIterator.hxx b/src/NCollection/NCollection_StlIterator.hxx
new file mode 100644 (file)
index 0000000..dca1c2a
--- /dev/null
@@ -0,0 +1,246 @@
+// Created on: 2014-04-15
+// Created by: Denis BOGOLEPOV
+// Copyright (c) 2014 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_StlIterator_HeaderFile
+#define NCollection_StlIterator_HeaderFile
+
+#include <Standard_Assert.hxx>
+#include <iterator>
+
+// This file uses C++11 utilities like std::is_base<>, which are not 
+// available in some environments (e.g. MSVC includes them since VS 2008).
+// Hence here we define our own implementation of these tools in namespace opencascade.
+// When all compilers support this, this namespace can be removed and replaced by std.
+namespace opencascade
+{
+  template<bool Condition, typename T>
+  struct enable_if
+  {
+    typedef T type;
+  };
+  
+  template<typename T>
+  struct enable_if<false, T>
+  {
+  };
+  
+  template<typename T1, typename T2>
+  struct is_same
+  {
+    enum { value = 0 };
+  };
+  
+  template<typename T>
+  struct is_same<T, T>
+  {
+    enum { value = 1 };
+  };
+  
+  template<bool Condition, typename TypeTrue, typename TypeFalse>
+  struct conditional
+  {
+    typedef TypeTrue type;
+  };
+
+  template<typename TypeTrue, typename TypeFalse>
+  struct conditional<false, TypeTrue, TypeFalse>
+  {
+    typedef TypeFalse type;
+  };
+}
+
+//! Helper class that allows to use NCollection iterators as STL iterators.
+//! NCollection iterator can be extended to STL iterator of any category by
+//! adding necessary methods: STL forward iterator requires IsEqual method,
+//! STL bidirectional iterator requires Previous method, and STL random access
+//! iterator requires Offset and Differ methods. See NCollection_Vector as
+//! example of declaring custom STL iterators.
+template<class Category, class BaseIterator, class ItemType, bool IsConstant>
+class NCollection_StlIterator : private BaseIterator, 
+  public std::iterator<Category, ItemType, ptrdiff_t,
+                       typename opencascade::conditional<IsConstant, const ItemType*, ItemType*>::type,
+                       typename opencascade::conditional<IsConstant, const ItemType&, ItemType&>::type>
+{
+public:
+
+  //! Default constructor
+  NCollection_StlIterator () {}
+
+  //! Constructor from NCollection iterator
+  NCollection_StlIterator (const BaseIterator& theIterator)
+    : BaseIterator (theIterator)
+  { }
+
+  //! Cast from non-const variant to const one
+  NCollection_StlIterator (const NCollection_StlIterator<Category, BaseIterator, ItemType, false>& theIterator)
+    : BaseIterator (theIterator)
+  { }
+
+  //! Assignment of non-const iterator to const one
+  NCollection_StlIterator& operator= (const NCollection_StlIterator<Category, BaseIterator, ItemType, false>& theIterator)
+  {
+    BaseIterator::operator= (theIterator);
+    return *this;
+  }
+
+  friend class NCollection_StlIterator<Category, BaseIterator, ItemType, !IsConstant>;
+
+protected: //! @name methods related to forward STL iterator
+
+  // Note: Here we use SFINAE (Substitution failure is not an error) to choose
+  // an appropriate method based on template arguments (at instantiation time).
+
+  template<bool Condition>
+  typename opencascade::enable_if<!Condition, ItemType&>::type Reference()
+  {
+    return BaseIterator::ChangeValue();
+  }
+
+  template<bool Condition>
+  typename opencascade::enable_if<Condition, const ItemType&>::type Reference()
+  {
+    return BaseIterator::Value();
+  }
+
+public: //! @name methods related to forward STL iterator
+
+  //! Test for equality
+  bool operator== (const NCollection_StlIterator& theOther) const
+  {
+    return BaseIterator::More() == theOther.More() &&
+           (!BaseIterator::More() || BaseIterator::IsEqual (theOther));
+  }
+
+  //! Test for inequality
+  bool operator!= (const NCollection_StlIterator& theOther) const
+  {
+    return !(*this == theOther);
+  }
+
+  //! Get reference to current item
+  typename NCollection_StlIterator::reference operator*()
+  {
+    return Reference<IsConstant>();
+  }
+
+  //! Dereferencing operator
+  typename NCollection_StlIterator::pointer operator->()
+  {
+    return &Reference<IsConstant>();
+  }
+
+  //! Prefix increment
+  NCollection_StlIterator& operator++()
+  {
+    BaseIterator::Next();
+    return *this;
+  }
+
+  //! Postfix increment
+  NCollection_StlIterator operator++(int)
+  {
+    const NCollection_StlIterator theOld (*this);
+    ++(*this);
+    return theOld;
+  }
+
+public: //! @name methods related to bidirectional STL iterator
+  
+  //! Prefix decrement
+  NCollection_StlIterator& operator--()
+  {
+    Standard_STATIC_ASSERT((opencascade::is_same<std::bidirectional_iterator_tag,Category>::value ||
+                            opencascade::is_same<std::random_access_iterator_tag,Category>::value));
+    BaseIterator::Previous();
+    return *this;
+  }
+  
+  //! Postfix decrement
+  NCollection_StlIterator operator--(int)
+  {
+    NCollection_StlIterator theOld (*this);
+    --(*this);
+    return theOld;
+  }
+  
+public: //! @name methods related to random access STL iterator
+
+  //! Move forward
+  NCollection_StlIterator& operator+= (typename NCollection_StlIterator::difference_type theOffset)
+  {
+    Standard_STATIC_ASSERT((opencascade::is_same<std::random_access_iterator_tag,Category>::value));
+    BaseIterator::Offset (theOffset);
+    return *this;
+  }
+
+  //! Addition
+  NCollection_StlIterator operator+ (typename NCollection_StlIterator::difference_type theOffset) const
+  {
+    NCollection_StlIterator aTemp (*this);
+    return aTemp += theOffset;
+  }
+
+  //! Move backward
+  NCollection_StlIterator& operator-= (typename NCollection_StlIterator::difference_type theOffset)
+  {
+    return *this += -theOffset;
+  }
+
+  //! Decrease
+  NCollection_StlIterator operator- (typename NCollection_StlIterator::difference_type theOffset) const
+  {
+    NCollection_StlIterator aTemp (*this);
+    return aTemp += -theOffset;
+  }
+
+  //! Difference
+  typename NCollection_StlIterator::difference_type operator- (const NCollection_StlIterator& theOther) const
+  {
+    Standard_STATIC_ASSERT((opencascade::is_same<std::random_access_iterator_tag,Category>::value));
+    return BaseIterator::Differ (theOther);
+  }
+
+  //! Get item at offset from current
+  typename NCollection_StlIterator::reference operator[] (typename NCollection_StlIterator::difference_type theOffset) const
+  {
+    return *(*this + theOffset);
+  }
+  
+  //! Comparison
+  bool operator< (const NCollection_StlIterator& theOther) const
+  {
+    return (*this - theOther) < 0;
+  }
+
+  //! Comparison
+  bool operator> (const NCollection_StlIterator& theOther) const
+  {
+    return theOther < *this;
+  }
+
+  //! Comparison
+  bool operator<= (const NCollection_StlIterator& theOther) const
+  {
+    return !(theOther < *this);
+  }
+
+  //! Comparison
+  bool operator>= (const NCollection_StlIterator& theOther) const
+  {
+    return !(*this < theOther);
+  }
+};
+
+#endif // NCollection_StlIterator_HeaderFile
index 4790903..bb9db31 100755 (executable)
@@ -18,6 +18,7 @@
 
 #include <NCollection_BaseVector.hxx>
 #include <NCollection_BaseCollection.hxx>
+#include <NCollection_StlIterator.hxx>
 
 //! Class NCollection_Vector (dynamic array of objects)
 //!
@@ -45,8 +46,10 @@ template <class TheItemType> class NCollection_Vector
   public NCollection_BaseVector
 {
 public:
+  //! STL-compliant typedef for value type
+  typedef TheItemType value_type;
 
-  typedef TheItemType TheItemTypeD;
+public:
 
   //! Nested class Iterator
   class Iterator : public NCollection_BaseCollection<TheItemType>::Iterator,
@@ -58,8 +61,8 @@ public:
     Iterator() {}
 
     //! Constructor with initialisation
-    Iterator (const NCollection_Vector& theVector)
-    : NCollection_BaseVector::Iterator (theVector) {}
+    Iterator (const NCollection_Vector& theVector, Standard_Boolean theToEnd = Standard_False)
+    : NCollection_BaseVector::Iterator (theVector, theToEnd) {}
 
     //! Copy constructor
     Iterator (const Iterator& theOther)
@@ -84,12 +87,30 @@ public:
       return moreV();
     }
 
-    //! Make step
+    //! Increment operator.
     virtual void Next()
     {
       nextV();
     }
 
+    //! Decrement operator.
+    virtual void Previous()
+    {
+      prevV();
+    }
+
+    //! Offset operator.
+    virtual void Offset (ptrdiff_t theOffset)
+    {
+      offsetV ((int)theOffset);
+    }
+
+    //! Difference operator.
+    virtual ptrdiff_t Differ (const Iterator& theOther) const
+    {
+      return differV (theOther);
+    }
+
     //! Constant value access
     virtual const TheItemType& Value() const
     {
@@ -102,8 +123,35 @@ public:
       return ((TheItemType* )curBlockV()->DataPtr)[myCurIndex];
     }
 
+    //! Performs comparison of two iterators.
+    virtual Standard_Boolean IsEqual (const Iterator& theOther) const
+    {
+      return myVector    == theOther.myVector
+          && myCurIndex  == theOther.myCurIndex
+          && myEndIndex  == theOther.myEndIndex  
+          && myICurBlock == theOther.myICurBlock
+          && myIEndBlock == theOther.myIEndBlock;
+    }
   };
 
+  //! Shorthand for a regular iterator type.
+  typedef NCollection_StlIterator<std::random_access_iterator_tag, Iterator, TheItemType, false> iterator;
+
+  //! Shorthand for a constant iterator type.
+  typedef NCollection_StlIterator<std::random_access_iterator_tag, Iterator, TheItemType, true> const_iterator;
+
+  //! Returns an iterator pointing to the first element in the vector.
+  iterator begin() const { return Iterator (*this, false); }
+
+  //! Returns an iterator referring to the past-the-end element in the vector.
+  iterator end() const { return Iterator (*this, true); }
+
+  //! Returns a const iterator pointing to the first element in the vector.
+  const_iterator cbegin() const { return Iterator (*this, false); }
+
+  //! Returns a const iterator referring to the past-the-end element in the vector.
+  const_iterator cend() const { return Iterator (*this, true); }
+
 public: //! @name public methods
 
   //! Constructor
@@ -297,7 +345,7 @@ private: //! @name private methods
     {
       for (Standard_Integer anItemIter = 0; anItemIter < theBlock.Size; ++anItemIter)
       {
-        ((TheItemType* )theBlock.DataPtr)[anItemIter].~TheItemTypeD();
+        ((TheItemType* )theBlock.DataPtr)[anItemIter].~TheItemType();
       }
       anAllocator->Free (theBlock.DataPtr);
       theBlock.DataPtr = NULL;
index 0e7de08..36e738e 100755 (executable)
@@ -5,6 +5,7 @@ QANCollection1.cxx
 QANCollection2.cxx
 QANCollection3.cxx
 QANCollection4.cxx
+QANCollection_Stl.cxx
 QANCollection_Common.cxx
 QANCollection_Common.hxx
 QANCollection_Common2.hxx
index 29e7d32..0d35dc9 100644 (file)
@@ -51,5 +51,6 @@ is
     Commands2(DI : in out Interpretor from Draw);
     Commands3(DI : in out Interpretor from Draw);
     Commands4(DI : in out Interpretor from Draw);
+    CommandsStl(DI : in out Interpretor from Draw);
 
 end;
index ba40d29..3a6e3eb 100644 (file)
 #include <gp_Pnt.hxx>
 //#include <QANCollection_Common.hxx>
 
-void QANCollection::Commands(Draw_Interpretor& theCommands) {
-  QANCollection::Commands1(theCommands);
-  QANCollection::Commands2(theCommands);
-  QANCollection::Commands3(theCommands);
-  QANCollection::Commands4(theCommands);
-  return;
+void QANCollection::Commands (Draw_Interpretor& theCommands)
+{
+  QANCollection::Commands1   (theCommands);
+  QANCollection::Commands2   (theCommands);
+  QANCollection::Commands3   (theCommands);
+  QANCollection::Commands4   (theCommands);
+  QANCollection::CommandsStl (theCommands);
 }
diff --git a/src/QANCollection/QANCollection_Stl.cxx b/src/QANCollection/QANCollection_Stl.cxx
new file mode 100644 (file)
index 0000000..248e8f9
--- /dev/null
@@ -0,0 +1,1289 @@
+// Created on: 2014-04-16
+// Created by: Denis BOGOLEPOV
+// Copyright (c) 2014 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.
+
+#include <QANCollection.hxx>
+#include <Draw_Interpretor.hxx>
+
+#include <NCollection_Array1.hxx>
+#include <NCollection_List.hxx>
+#include <NCollection_Sequence.hxx>
+#include <NCollection_Vector.hxx>
+#include <NCollection_Map.hxx>
+#include <NCollection_DataMap.hxx>
+#include <NCollection_IndexedMap.hxx>
+#include <NCollection_IndexedDataMap.hxx>
+#include <Standard_Assert.hxx>
+#include <OSD_Timer.hxx>
+
+#ifdef HAVE_TBB
+  // On Windows, function TryEnterCriticalSection has appeared in Windows NT
+  // and is surrounded by #ifdef in MS VC++ 7.1 headers.
+  // Thus to use it we need to define appropriate macro saying that we will
+  // run on Windows NT 4.0 at least
+  #if ((defined(_WIN32) || defined(__WIN32__)) && !defined(_WIN32_WINNT))
+    #define _WIN32_WINNT 0x0501
+  #endif
+
+  #include <tbb/tbb.h>
+  #include <tbb/parallel_for.h>
+#endif
+
+#include <algorithm>
+#include <list>
+#include <set>
+#include <typeinfo>
+#include <vector>
+
+//! Size of test data sets.
+const int THE_TEST_SIZE = 5000;
+
+namespace {
+  // Auxiliary class to use in std::random_shuffle()
+  struct RandomGenerator {
+    RandomGenerator () { srand(1); }
+    int operator () (int upper) const { return rand() % upper; }
+  };
+}
+
+template<class CollectionType, class StlType>
+struct CollectionFiller
+{
+  static void Perform (CollectionType** theCollec, Standard_Integer theSize = THE_TEST_SIZE)
+  {
+    *theCollec = new CollectionType();
+    srand(1);
+    for (Standard_Integer anIdx = 0; anIdx < theSize; ++anIdx)
+    {
+      (*theCollec)->Append (rand());
+    }
+  }
+
+  static void Perform (StlType** theVector,
+    CollectionType** theCollec, Standard_Integer theSize = THE_TEST_SIZE)
+  {
+    CollectionFiller::Perform (theCollec, theSize);
+
+    *theVector = new StlType ((*theCollec)->begin(), (*theCollec)->end());
+  }
+};
+
+template<class T, typename StlType>
+struct CollectionFiller<NCollection_Array1<T>, StlType>
+{
+  static void Perform (NCollection_Array1<T>** theCollec,
+    Standard_Integer theSize = THE_TEST_SIZE)
+  {
+    *theCollec = new NCollection_Array1<T> (0, theSize - 1);
+    srand (1);
+    for (Standard_Integer anIdx = 0; anIdx < theSize; ++anIdx)
+    {
+      (*theCollec)->ChangeValue (anIdx) = rand();
+    }
+  }
+
+  static void Perform (StlType** theVector,
+    NCollection_Array1<T>** theCollec, Standard_Integer theSize = THE_TEST_SIZE)
+  {
+    CollectionFiller<NCollection_Array1<T>, StlType >::Perform (theCollec, theSize);
+
+    *theVector = new StlType ((*theCollec)->begin(), (*theCollec)->end());
+  }
+};
+
+template<class CollectionType, class T>
+struct MapFiller
+{
+  static void Perform (CollectionType** theCollec, Standard_Integer theSize = THE_TEST_SIZE)
+  {
+    *theCollec = new CollectionType();
+    srand(1);
+    for (Standard_Integer anIdx = 0; anIdx < theSize; ++anIdx)
+    {
+      (*theCollec)->Add (rand());
+    }
+  }
+};
+
+template<class T>
+struct MapFiller<NCollection_DataMap<T, T>, T>
+{
+  static void Perform (NCollection_DataMap<T, T>** theCollec1,
+    NCollection_DataMap<T, T>** theCollec2 = NULL, Standard_Integer theSize = THE_TEST_SIZE)
+  {
+    *theCollec1 = new NCollection_DataMap<T, T>();
+
+    if (theCollec2 != NULL)
+      *theCollec2 = new NCollection_DataMap<T, T>();
+    srand(1);
+    for (Standard_Integer anIdx = 0; anIdx < theSize; ++anIdx)
+    {
+      const T aVal1 = rand();
+      const T aVal2 = rand();
+
+      (*theCollec1)->Bind (aVal1, aVal2);
+
+      if (theCollec2 != NULL)
+        (*theCollec2)->Bind (aVal1, aVal2);
+    }
+  }
+};
+
+template<class T>
+struct MapFiller<NCollection_IndexedDataMap<T, T>, T>
+{
+  static void Perform (NCollection_IndexedDataMap<T, T>** theCollec1,
+    NCollection_IndexedDataMap<T, T>** theCollec2 = NULL, Standard_Integer theSize = THE_TEST_SIZE)
+  {
+    *theCollec1 = new NCollection_IndexedDataMap<T, T>();
+
+    if (theCollec2 != NULL)
+      *theCollec2 = new NCollection_IndexedDataMap<T, T>();
+    srand(1);
+    for (Standard_Integer anIdx = 0; anIdx < theSize; ++anIdx)
+    {
+      const T aVal1 = rand();
+      const T aVal2 = rand();
+
+      (*theCollec1)->Add (aVal1, aVal2);
+
+      if (theCollec2 != NULL)
+        (*theCollec2)->Add (aVal1, aVal2);
+    }
+  }
+};
+
+//=======================================================================
+//function : TestIteration
+//purpose  :
+//=======================================================================
+template<class CollectionType, class StlType>
+Standard_Boolean TestIteration()
+{
+  StlType* aVector (NULL);
+  CollectionType* aCollec (NULL);
+
+  CollectionFiller<CollectionType, StlType>::Perform (&aVector, &aCollec);
+
+  typename StlType::iterator aVecIter = aVector->begin();
+  typename CollectionType::iterator aColIter = aCollec->begin();
+
+  Standard_Boolean aResult (Standard_True);
+
+  for (; aVecIter != aVector->end(); ++aVecIter, ++aColIter)
+  {
+    if (*aVecIter != *aColIter)
+      aResult = Standard_False;
+  }
+
+  if (aColIter != aCollec->end())
+  {
+    aResult = Standard_False;
+  }
+
+  delete aVector;
+  delete aCollec;
+
+  return aResult;
+}
+
+//=======================================================================
+//function : TestMinMax
+//purpose  :
+//=======================================================================
+template<class CollectionType, class StlType>
+Standard_Boolean TestMinMax()
+{
+  StlType* aVector (NULL);
+  CollectionType* aCollec (NULL);
+
+  CollectionFiller<CollectionType, StlType>::Perform (&aVector, &aCollec);
+
+  typename StlType::value_type aValue1 = *std::min_element (aVector->begin(), aVector->end());
+  typename CollectionType::value_type aValue2 = *std::min_element (aCollec->begin(), aCollec->end());
+
+  Standard_Boolean aResult (Standard_True);
+
+  if (aValue1 != aValue2)
+    aResult = Standard_False;
+
+  aValue1 = *std::max_element (aVector->begin(), aVector->end());
+  aValue2 = *std::max_element (aCollec->begin(), aCollec->end());
+
+  if (aValue1 != aValue2)
+    aResult = Standard_False;
+
+  delete aVector;
+  delete aCollec;
+
+  return aResult;
+}
+
+//=======================================================================
+//function : TestReplace
+//purpose  :
+//=======================================================================
+template<class CollectionType, class StlType>
+Standard_Boolean TestReplace()
+{
+  StlType* aVector (NULL);
+  CollectionType* aCollec (NULL);
+
+  CollectionFiller<CollectionType, StlType>::Perform (&aVector, &aCollec);
+
+  const typename StlType::value_type aValue = aVector->back();
+
+  std::replace (aVector->begin(), aVector->end(), aValue, static_cast<typename StlType::value_type> (-1));
+  std::replace (aCollec->begin(), aCollec->end(), aValue, static_cast<typename CollectionType::value_type> (-1));
+
+  typename StlType::iterator aVecIter = aVector->begin();
+  typename CollectionType::iterator aColIter = aCollec->begin();
+
+  Standard_Boolean aResult (Standard_True);
+
+  for (; aVecIter != aVector->end(); ++aVecIter, ++aColIter)
+  {
+    if (*aVecIter != *aColIter)
+      aResult = Standard_False;
+  }
+
+  if (aColIter != aCollec->end())
+  {
+    aResult = Standard_False;
+  }
+
+  delete aVector;
+  delete aCollec;
+
+  return aResult;
+}
+
+//=======================================================================
+//function : TestReverse
+//purpose  :
+//=======================================================================
+template<class CollectionType, class StlType>
+Standard_Boolean TestReverse()
+{
+  StlType* aVector (NULL);
+  CollectionType* aCollec (NULL);
+
+  CollectionFiller<CollectionType, StlType>::Perform (&aVector, &aCollec);
+
+  std::reverse (aVector->begin(), aVector->end());
+  std::reverse (aCollec->begin(), aCollec->end());
+
+  typename StlType::iterator aVecIter = aVector->begin();
+  typename CollectionType::iterator aColIter = aCollec->begin();
+
+  Standard_Boolean aResult (Standard_True);
+
+  for (; aVecIter != aVector->end(); ++aVecIter, ++aColIter)
+  {
+    if (*aVecIter != *aColIter)
+      aResult = Standard_False;
+  }
+
+  if (aColIter != aCollec->end())
+  {
+    aResult = Standard_False;
+  }
+
+  delete aVector;
+  delete aCollec;
+
+  return aResult;
+}
+
+//=======================================================================
+//function : TestSort
+//purpose  :
+//=======================================================================
+template<class CollectionType, class StlType>
+Standard_Boolean TestSort()
+{
+  StlType* aVector (NULL);
+  CollectionType* aCollec (NULL);
+
+  CollectionFiller<CollectionType, StlType>::Perform (&aVector, &aCollec);
+
+  std::sort (aVector->begin(), aVector->end());
+  std::sort (aCollec->begin(), aCollec->end());
+
+  typename StlType::iterator aVecIter = aVector->begin();
+  typename CollectionType::iterator aColIter = aCollec->begin();
+
+  Standard_Boolean aResult (Standard_True);
+
+  for (; aVecIter != aVector->end(); ++aVecIter, ++aColIter)
+  {
+    if (*aVecIter != *aColIter)
+      aResult = Standard_False;
+  }
+
+  if (aColIter != aCollec->end())
+  {
+    aResult = Standard_False;
+  }
+
+  delete aVector;
+  delete aCollec;
+
+  return aResult;
+}
+
+#ifdef HAVE_TBB
+
+template <typename T>
+struct Invoker
+{
+  void operator()(T& theValue) const
+  {
+    theValue *= 2;
+  }
+};
+
+//=======================================================================
+//function : TestTBB
+//purpose  :
+//=======================================================================
+template<class CollectionType, class StlType>
+Standard_Boolean TestTBB()
+{
+  StlType* aVector (NULL);
+  CollectionType* aCollec (NULL);
+
+  CollectionFiller<CollectionType, StlType>::Perform (&aVector, &aCollec);
+
+  tbb::parallel_for_each (aVector->begin(), aVector->end(), Invoker<typename StlType::value_type>());
+  tbb::parallel_for_each (aCollec->begin(), aCollec->end(), Invoker<typename CollectionType::value_type>());
+
+  typename StlType::iterator aVecIter = aVector->begin();
+  typename CollectionType::iterator aColIter = aCollec->begin();
+
+  Standard_Boolean aResult (Standard_True);
+
+  for (; aVecIter != aVector->end(); ++aVecIter, ++aColIter)
+  {
+    if (*aVecIter != *aColIter)
+      aResult = Standard_False;
+  }
+
+  if (aColIter != aCollec->end())
+  {
+    aResult = Standard_False;
+  }
+
+  delete aVector;
+  delete aCollec;
+
+  return aResult;
+}
+
+//=======================================================================
+//function : TestDataMapTBB
+//purpose  :
+//=======================================================================
+template<class CollectionType, class T>
+Standard_Boolean TestDataMapTBB()
+{
+  CollectionType* aCollec1 (NULL);
+  CollectionType* aCollec2 (NULL);
+
+  MapFiller<CollectionType, T>::Perform (&aCollec1, &aCollec2);
+
+  tbb::parallel_for_each (aCollec1->begin(), aCollec1->end(), Invoker<T>());
+
+  // create OCCT-style iterator
+  typename CollectionType::Iterator aOccIter (*aCollec2);
+
+  // create STL-compatible iterator
+  typename CollectionType::const_iterator aStlIter = aCollec1->cbegin();
+
+  Standard_Boolean aResult (Standard_True);
+
+  for (; aStlIter != aCollec1->cend(); ++aStlIter, aOccIter.Next())
+  {
+    if (static_cast<T> (2) * aOccIter.Value() != *aStlIter)
+      aResult = Standard_False;
+  }
+
+  if (aOccIter.More())
+  {
+    aResult = Standard_False;
+  }
+
+  delete aCollec1;
+  delete aCollec2;
+
+  return aResult;
+}
+
+#endif
+
+//=======================================================================
+//function : TestMapIteration
+//purpose  :
+//=======================================================================
+template<class CollectionType, class T>
+Standard_Boolean TestMapIteration()
+{
+  CollectionType* aCollec (NULL);
+
+  MapFiller<CollectionType, T>::Perform (&aCollec);
+
+  // create OCCT-style iterator
+  typename CollectionType::Iterator aOccIter (*aCollec);
+
+  // create STL-compatible iterator
+  typename CollectionType::const_iterator aStlIter = aCollec->cbegin();
+
+  Standard_Boolean aResult (Standard_True);
+
+  for (; aStlIter != aCollec->cend(); ++aStlIter, aOccIter.Next())
+  {
+    if (aOccIter.Value() != *aStlIter)
+      aResult = Standard_False;
+  }
+
+  if (aOccIter.More())
+  {
+    aResult = Standard_False;
+  }
+
+  delete aCollec;
+
+  return aResult;
+}
+
+//=======================================================================
+//function : TestForwardIterator
+//purpose  : test basic features of iterator (forward)
+//=======================================================================
+template <class CollectionType>
+void TestForwardIterator ()
+{
+  CollectionType* aCollec (NULL);
+
+  CollectionFiller<CollectionType, void>::Perform (&aCollec);
+  
+  // test non-const iteration
+  typename CollectionType::iterator it = aCollec->begin(); // copy construction
+  typename CollectionType::iterator it2; // default constructor
+  it2 = it; // assignment
+  it2 = it++; // postfix increment
+  if (it2 == it || ! (it2 != it))
+    std::cout << "Failed " << typeid(it).name() << " equality check" << std::endl;
+  it2 = ++it; // prefix increment
+  if (it2 != it || ! (it2 == it))
+    std::cout << "Failed " << typeid(it).name() << " equality check" << std::endl;
+
+  typename CollectionType::iterator::value_type t = *it;
+  *it2 = t;
+  *(it2.operator-> ()) = t;
+
+  // test const iteration
+  typename CollectionType::const_iterator cit = aCollec->cbegin(); // copy construction
+  typename CollectionType::const_iterator cit2; // default constructor
+  cit2 = cit; // assignment
+  cit2 = cit++; // postfix increment
+  if (cit2 == cit || ! (cit2 != cit))
+    std::cout << "Failed " << typeid(cit).name() << " equality check" << std::endl;
+  cit2 = ++cit; // prefix increment
+  if (cit2 != it || ! (cit2 == cit))
+    std::cout << "Failed " << typeid(cit).name() << " equality check" << std::endl;
+
+  typename CollectionType::const_iterator::value_type ct = *cit;
+  ct = *cit;
+//  *cit2 = ct;
+//  *(cit2.operator-> ()) = t;
+
+  delete aCollec;
+}
+
+//=======================================================================
+//function : TestBidirIterator
+//purpose  : test features of bidirectional iterator
+//=======================================================================
+template <class CollectionType>
+void TestBidirIterator ()
+{
+  CollectionType* aCollec (NULL);
+
+  CollectionFiller<CollectionType, void>::Perform (&aCollec);
+  
+  // test non-const iteration
+  typename CollectionType::iterator it = aCollec->end(); // copy construction
+  typename CollectionType::iterator it2 = it--; // postfix decrement
+  if (it2 == it || ! (it2 != it))
+    std::cout << "Failed " << typeid(it).name() << " equality check" << std::endl;
+  it2 = --it; // prefix decrement
+  if (it2 != it || ! (it2 == it))
+    std::cout << "Failed " << typeid(it).name() << " equality check" << std::endl;
+
+  delete aCollec;
+}
+
+//=======================================================================
+//function : TestRandomIterator
+//purpose  : test features of random iterator
+//=======================================================================
+template <class CollectionType>
+void TestRandomIterator ()
+{
+  CollectionType* aCollec (NULL);
+
+  CollectionFiller<CollectionType, void>::Perform (&aCollec);
+  
+  // test non-const iteration
+  typename CollectionType::iterator it = aCollec->begin(); // copy construction
+  typename CollectionType::iterator it2 = it + 5;
+  if ((it2 - it) != 5)
+    std::cout << "Failed " << typeid(it).name() << " arithmetics" << std::endl;
+  if (it2 < it || it2 <= it || ! (it2 > it) || ! (it2 >= it))
+    std::cout << "Failed " << typeid(it).name() << " comparison" << std::endl;
+  it += 5;
+  if (it2 != it)
+    std::cout << "Failed " << typeid(it).name() << " arithmetics" << std::endl;
+  it2 = it - 5;
+  if ((it2 - it) != -5)
+    std::cout << "Failed " << typeid(it).name() << " arithmetics" << std::endl;
+  if (it2 > it || it2 >= it || ! (it2 < it) || ! (it2 <= it))
+    std::cout << "Failed " << typeid(it).name() << " comparison" << std::endl;
+  it -= 5;
+  if (it2 != it)
+    std::cout << "Failed " << typeid(it).name() << " arithmetics" << std::endl;
+
+  typename CollectionType::value_type t = it[5]; // offset dereference
+  *it = t;
+
+  delete aCollec;
+}
+
+//=======================================================================
+//function : QANListStlIterator
+//purpose  :
+//=======================================================================
+static Standard_Integer QANListStlIterator (Draw_Interpretor&, Standard_Integer, const char**)
+{
+  // compile-time tests
+  TestForwardIterator <NCollection_List<Standard_Integer> >();
+
+  // run-time tests
+  Standard_Boolean aResult = TestIteration<NCollection_List<int>, std::list<int> >();
+  std::cout << "NCollection_List<int> Iteration:                " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestIteration<NCollection_List<double>, std::list<double> >();
+  std::cout << "NCollection_List<double> Iteration:             " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestMinMax<NCollection_List<int>, std::list<int> >();
+  std::cout << "NCollection_List<int> Min-Max:                  " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestMinMax<NCollection_List<double>, std::list<double> >();
+  std::cout << "NCollection_List<double> Min-Max:               " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestReplace<NCollection_List<int>, std::list<int> >();
+  std::cout << "NCollection_List<int> Replace:                  " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestReplace<NCollection_List<double>, std::list<double> >();
+  std::cout << "NCollection_List<double> Replace:               " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+#ifdef HAVE_TBB
+
+  aResult = TestTBB<NCollection_List<int>, std::list<int> >();
+  std::cout << "NCollection_List<int> TBB:                      " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestTBB<NCollection_List<double>, std::list<double> >();
+  std::cout << "NCollection_List<double> TBB:                   " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+#endif
+
+  return 0;
+}
+
+//=======================================================================
+//function : QANMapStlIterator
+//purpose  :
+//=======================================================================
+static Standard_Integer QANMapStlIterator (Draw_Interpretor&, Standard_Integer, const char**)
+{
+  // compile-time tests
+//  TestForwardIterator <NCollection_Map<Standard_Integer> >();
+
+  // run-time tests
+  Standard_Boolean aResult = TestMapIteration<NCollection_Map<Standard_Integer>, Standard_Integer>();
+  std::cout << "NCollection_Map<int> Iteration:                 " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestMapIteration<NCollection_Map<Standard_Real>, Standard_Real>();
+  std::cout << "NCollection_Map<double> Iteration:              " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  return 0;
+}
+
+//=======================================================================
+//function : QANIndexedMapStlIterator
+//purpose  :
+//=======================================================================
+static Standard_Integer QANIndexedMapStlIterator (Draw_Interpretor&, Standard_Integer, const char**)
+{
+  // compile-time tests
+//  TestForwardIterator <NCollection_IndexedMap<Standard_Integer> >();
+//  TestBidirIterator <NCollection_IndexedMap<Standard_Integer> >();
+
+  // run-time tests
+  Standard_Boolean aResult = TestMapIteration<NCollection_IndexedMap<Standard_Integer>, Standard_Integer>();
+  std::cout << "NCollection_IndexedMap<int> Iteration:          " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestMapIteration<NCollection_IndexedMap<Standard_Real>, Standard_Real>();
+  std::cout << "NCollection_IndexedMap<double> Iteration:       " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  return 0;
+}
+
+//=======================================================================
+//function : QANDataMapStlIterator
+//purpose  :
+//=======================================================================
+static Standard_Integer QANDataMapStlIterator (Draw_Interpretor&, Standard_Integer, const char**)
+{
+  // compile-time tests
+//  TestForwardIterator <NCollection_DataMap<int, int> >();
+//  TestBidirIterator <NCollection_DataMap<int, int> >();
+
+  // run-time tests
+  Standard_Boolean aResult = TestMapIteration<NCollection_DataMap<Standard_Integer, Standard_Integer>, Standard_Integer>();
+  std::cout << "NCollection_DataMap<int> Iteration:             " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestMapIteration<NCollection_DataMap<Standard_Real, Standard_Real>, Standard_Real>();
+  std::cout << "NCollection_DataMap<double> Iteration:          " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+#ifdef HAVE_TBB
+  
+  aResult = TestDataMapTBB<NCollection_DataMap<Standard_Integer, Standard_Integer>, Standard_Integer>();
+  std::cout << "NCollection_DataMap<int> TBB:                   " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestDataMapTBB<NCollection_DataMap<Standard_Real, Standard_Real>, Standard_Real>();
+  std::cout << "NCollection_DataMap<double> TBB:                " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+#endif
+
+  return 0;
+}
+
+//=======================================================================
+//function : QANIndexedDataMapStlIterator
+//purpose  :
+//=======================================================================
+static Standard_Integer QANIndexedDataMapStlIterator (Draw_Interpretor&, Standard_Integer, const char**)
+{
+  // compile-time tests
+//  TestForwardIterator <NCollection_IndexedDataMap<int, int> >();
+//  TestBidirIterator <NCollection_IndexedDataMap<int, int> >();
+
+  // run-time tests
+  Standard_Boolean aResult = TestMapIteration<NCollection_IndexedDataMap<Standard_Integer, Standard_Integer>, Standard_Integer>();
+  std::cout << "NCollection_IndexedDataMap<int> Iteration:      " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestMapIteration<NCollection_IndexedDataMap<Standard_Real, Standard_Real>, Standard_Real>();
+  std::cout << "NCollection_IndexedDataMap<double> Iteration:   " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+#ifdef HAVE_TBB
+
+  aResult = TestDataMapTBB<NCollection_IndexedDataMap<Standard_Integer, Standard_Integer>, Standard_Integer>();
+  std::cout << "NCollection_IndexedDataMap<int> TBB:            " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestDataMapTBB<NCollection_IndexedDataMap<Standard_Real, Standard_Real>, Standard_Real>();
+  std::cout << "NCollection_IndexedDataMap<double> TBB:         " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+#endif
+
+  return 0;
+}
+
+//=======================================================================
+//function : QANSequenceStlIterator
+//purpose  :
+//=======================================================================
+static Standard_Integer QANSequenceStlIterator (Draw_Interpretor&, Standard_Integer, const char**)
+{
+  // compile-time tests
+  TestForwardIterator <NCollection_Sequence<int> >();
+  TestBidirIterator <NCollection_Sequence<int> >();
+
+  // run-time tests
+  Standard_Boolean aResult = TestIteration<NCollection_Sequence<int>, std::list<int> >();
+  std::cout << "NCollection_Sequence<int> Iteration:            " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestIteration<NCollection_Sequence<double>, std::list<double> >();
+  std::cout << "NCollection_Sequence<double> Iteration:         " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestMinMax<NCollection_Sequence<int>, std::list<int> >();
+  std::cout << "NCollection_Sequence<int> Min-Max:              " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestMinMax<NCollection_Sequence<double>, std::list<double> >();
+  std::cout << "NCollection_Sequence<double> Min-Max:           " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestReplace<NCollection_Sequence<int>, std::list<int> >();
+  std::cout << "NCollection_Sequence<int> Replace:              " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestReplace<NCollection_Sequence<double>, std::list<double> >();
+  std::cout << "NCollection_Sequence<double> Replace:           " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestReverse<NCollection_Sequence<int>, std::list<int> >();
+  std::cout << "NCollection_Sequence<int> Reverse:              " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestReverse<NCollection_Sequence<double>, std::list<double> >();
+  std::cout << "NCollection_Sequence<double> Reverse:           " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+#ifdef HAVE_TBB
+
+  aResult = TestTBB<NCollection_Sequence<int>, std::list<int> >();
+  std::cout << "NCollection_Sequence<int> TBB:                  " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestTBB<NCollection_Sequence<double>, std::list<double> >();
+  std::cout << "NCollection_Sequence<double> TBB:               " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+#endif
+
+  return 0;
+}
+
+//=======================================================================
+//function : QANVectorStlIterator
+//purpose  :
+//=======================================================================
+static Standard_Integer QANVectorStlIterator (Draw_Interpretor&, Standard_Integer, const char**)
+{
+  // compile-time tests
+  TestForwardIterator <NCollection_Vector<int> >();
+  TestBidirIterator <NCollection_Vector<int> >();
+  TestRandomIterator <NCollection_Vector<int> >();
+
+  // run-time tests
+  Standard_Boolean aResult = TestIteration<NCollection_Vector<int>, std::vector<int> >();
+  std::cout << "NCollection_Vector<int> Iteration:              " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestIteration<NCollection_Vector<double>, std::vector<double> >();
+  std::cout << "NCollection_Vector<double> Iteration:           " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestMinMax<NCollection_Vector<int>, std::vector<int> >();
+  std::cout << "NCollection_Vector<int> Min-Max:                " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestMinMax<NCollection_Vector<double>, std::vector<double> >();
+  std::cout << "NCollection_Vector<double> Min-Max:             " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestReplace<NCollection_Vector<int>, std::vector<int> >();
+  std::cout << "NCollection_Vector<int> Replace:                " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestReplace<NCollection_Vector<double>, std::vector<double> >();
+  std::cout << "NCollection_Vector<double> Replace:             " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestReverse<NCollection_Vector<int>, std::vector<int> >();
+  std::cout << "NCollection_Vector<int> Reverse:                " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestReverse<NCollection_Vector<double>, std::vector<double> >();
+  std::cout << "NCollection_Vector<double> Reverse:             " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestSort<NCollection_Vector<int>, std::vector<int> >();
+  std::cout << "NCollection_Vector<int> Sort:                   " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestSort<NCollection_Vector<double>, std::vector<double> >();
+  std::cout << "NCollection_Vector<double> Sort:                " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+#ifdef HAVE_TBB
+
+  aResult = TestTBB<NCollection_Vector<int>, std::vector<int> >();
+  std::cout << "NCollection_Vector<int> TBB:                    " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestTBB<NCollection_Vector<double>, std::vector<double> >();
+  std::cout << "NCollection_Vector<double> TBB:                 " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+#endif
+
+  return 0;
+}
+
+//=======================================================================
+//function : QANArray1StlIterator
+//purpose  :
+//=======================================================================
+static Standard_Integer QANArray1StlIterator (Draw_Interpretor&, Standard_Integer, const char**)
+{
+  // compile-time tests
+  TestForwardIterator <NCollection_Vector<int> >();
+  TestBidirIterator <NCollection_Vector<int> >();
+  TestRandomIterator <NCollection_Vector<int> >();
+
+  // run-time tests
+  Standard_Boolean aResult = TestIteration<NCollection_Array1<int>, std::vector<int> >();
+  std::cout << "NCollection_Array1<int> Iteration:              " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestIteration<NCollection_Array1<double>, std::vector<double> >();
+  std::cout << "NCollection_Array1<double> Iteration:           " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestMinMax<NCollection_Array1<int>, std::vector<int> >();
+  std::cout << "NCollection_Array1<int> Min-Max:                " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestMinMax<NCollection_Array1<double>, std::vector<double> >();
+  std::cout << "NCollection_Array1<double> Min-Max:             " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestReplace<NCollection_Array1<int>, std::vector<int> >();
+  std::cout << "NCollection_Array1<int> Replace:                " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestReplace<NCollection_Array1<double>, std::vector<double> >();
+  std::cout << "NCollection_Array1<double> Replace:             " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestReverse<NCollection_Array1<int>, std::vector<int> >();
+  std::cout << "NCollection_Array1<int> Reverse:                " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestReverse<NCollection_Array1<double>, std::vector<double> >();
+  std::cout << "NCollection_Array1<double> Reverse:             " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestSort<NCollection_Array1<int>, std::vector<int> >();
+  std::cout << "NCollection_Array1<int> Sort:                   " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestSort<NCollection_Array1<double>, std::vector<double> >();
+  std::cout << "NCollection_Array1<double> Sort:                " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+#ifdef HAVE_TBB
+
+  aResult = TestTBB<NCollection_Array1<int>, std::vector<int> >();
+  std::cout << "NCollection_Array1<int> TBB:                    " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+  aResult = TestTBB<NCollection_Array1<double>, std::vector<double> >();
+  std::cout << "NCollection_Array1<double> TBB:                 " <<
+    (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+#endif
+
+  return 0;
+}
+
+//=======================================================================
+//function : QANTestStlIterators
+//purpose  :
+//=======================================================================
+static Standard_Integer QANTestStlIterators (
+  Draw_Interpretor& theInterpretor, Standard_Integer, const char**)
+{
+  QANListStlIterator           (theInterpretor, 0, NULL);
+  QANArray1StlIterator         (theInterpretor, 0, NULL);
+  QANVectorStlIterator         (theInterpretor, 0, NULL);
+  QANSequenceStlIterator       (theInterpretor, 0, NULL);
+  QANMapStlIterator            (theInterpretor, 0, NULL);
+  QANDataMapStlIterator        (theInterpretor, 0, NULL);
+  QANIndexedMapStlIterator     (theInterpretor, 0, NULL);
+  QANIndexedDataMapStlIterator (theInterpretor, 0, NULL);
+
+  return 0;
+}
+
+//=======================================================================
+//function : TestPerformanceRandomIterator
+//purpose  :
+//=======================================================================
+template<class CollectionType, class StlType>
+void TestPerformanceRandomIterator()
+{
+  OSD_Timer aTimer;
+
+  StlType* aVector (NULL);
+  CollectionType* aCollec (NULL);
+
+  for (Standard_Integer aSize = 10000; aSize <= 1280000; aSize *= 2)
+  {
+    CollectionFiller<CollectionType, StlType>::Perform (&aVector, &aCollec, aSize);
+
+    aTimer.Reset();
+    aTimer.Start();
+    {
+      RandomGenerator aRandomGen;
+      for (Standard_Integer anIdx = 0; anIdx < 10; ++anIdx)
+      {
+        std::sort           (aVector->begin(), aVector->end());
+        std::random_shuffle (aVector->begin(), aVector->end(), aRandomGen);
+      }
+    }
+    aTimer.Stop();
+
+    Standard_Real aStlTime = aTimer.ElapsedTime();
+
+    aTimer.Reset();
+    aTimer.Start();
+    {
+      RandomGenerator aRandomGen;
+      for (Standard_Integer anIdx = 0; anIdx < 10; ++anIdx)
+      {
+        std::sort           (aCollec->begin(), aCollec->end());
+        std::random_shuffle (aCollec->begin(), aCollec->end(), aRandomGen);
+      }
+    }
+    aTimer.Stop();
+
+    Standard_Real aOccTime = aTimer.ElapsedTime();
+
+    std::cout << aSize << "\t" << aStlTime << "\t" <<
+      aOccTime << "\t" << aOccTime / aStlTime << std::endl;
+
+    // check that result is the same
+    if ( ! std::equal (aVector->begin(), aVector->end(), aCollec->begin()) )
+      std::cout << "Error: sequences are not the same at the end!" << std::endl;
+
+    delete aVector;
+    delete aCollec;
+  }
+}
+
+//=======================================================================
+//function : TestPerformanceForwardIterator
+//purpose  :
+//=======================================================================
+template<class CollectionType, class StlType>
+void TestPerformanceForwardIterator()
+{
+  OSD_Timer aTimer;
+
+  StlType* aVector = 0;
+  CollectionType* aCollec = 0;
+
+  for (Standard_Integer aSize = 10000; aSize <= 1280000; aSize *= 2)
+  {
+    CollectionFiller<CollectionType, StlType>::Perform (&aVector, &aCollec, aSize);
+
+    aTimer.Reset();
+    aTimer.Start();
+    {
+      for (Standard_Integer anIdx = 0; anIdx < 1000; ++anIdx)
+      {
+        std::replace (aVector->begin(), aVector->end(), *aVector->begin(), static_cast<typename StlType::value_type> (anIdx));
+      }
+    }
+    aTimer.Stop();
+
+    Standard_Real aStlTime = aTimer.ElapsedTime();
+
+    aTimer.Reset();
+    aTimer.Start();
+    {
+      for (Standard_Integer anIdx = 0; anIdx < 1000; ++anIdx)
+      {
+        std::replace (aCollec->begin(), aCollec->end(), *aCollec->begin(), static_cast<typename CollectionType::value_type> (anIdx));
+      }
+    }
+    aTimer.Stop();
+
+    Standard_Real aOccTime = aTimer.ElapsedTime();
+
+    std::cout << aSize << "\t" << aStlTime << "\t" <<
+      aOccTime << "\t" << aOccTime / aStlTime << std::endl;
+
+    // check that result is the same
+    if ( ! std::equal (aVector->begin(), aVector->end(), aCollec->begin()) )
+      std::cout << "Error: sequences are not the same at the end!" << std::endl;
+
+    delete aVector;
+    delete aCollec;
+  }
+}
+
+//=======================================================================
+//function : TestPerformanceBidirIterator
+//purpose  :
+//=======================================================================
+template<class CollectionType, class StlType>
+void TestPerformanceBidirIterator()
+{
+  OSD_Timer aTimer;
+
+  StlType* aVector = 0;
+  CollectionType* aCollec = 0;
+
+  for (Standard_Integer aSize = 10000; aSize <= 1280000; aSize *= 2)
+  {
+    CollectionFiller<CollectionType, StlType>::Perform (&aVector, &aCollec, aSize);
+
+    aTimer.Reset();
+    aTimer.Start();
+    {
+      for (Standard_Integer anIdx = 0; anIdx < 1000; ++anIdx)
+      {
+        std::reverse (aVector->begin(), aVector->end());
+      }
+    }
+    aTimer.Stop();
+
+    Standard_Real aStlTime = aTimer.ElapsedTime();
+
+    aTimer.Reset();
+    aTimer.Start();
+    {
+      for (Standard_Integer anIdx = 0; anIdx < 1000; ++anIdx)
+      {
+        std::reverse (aCollec->begin(), aCollec->end());
+      }
+    }
+    aTimer.Stop();
+
+    Standard_Real aOccTime = aTimer.ElapsedTime();
+
+    std::cout << aSize << "\t" << aStlTime << "\t" <<
+      aOccTime << "\t" << aOccTime / aStlTime << std::endl;
+
+    // check that result is the same
+    if ( ! std::equal (aVector->begin(), aVector->end(), aCollec->begin()) )
+      std::cout << "Error: sequences are not the same at the end!" << std::endl;
+
+    delete aVector;
+    delete aCollec;
+  }
+}
+
+//=======================================================================
+//function : TestPerformanceMapAccess
+//purpose  :
+//=======================================================================
+template<class CollectionType, class T>
+void TestPerformanceMapAccess()
+{
+  OSD_Timer aTimer;
+
+  CollectionType* aCollec (NULL);
+
+  for (Standard_Integer aSize = 100000; aSize <= 3200000; aSize *= 2)
+  {
+    MapFiller<CollectionType, T>::Perform (&aCollec, aSize);
+
+    std::set<T>    aSet (aCollec->cbegin(), aCollec->cend());
+    std::vector<T> aVec (aCollec->cbegin(), aCollec->cend());
+
+    Standard_Boolean aResult = Standard_True;
+
+    aTimer.Reset();
+    aTimer.Start();
+    {
+      for (Standard_Integer anIdx = 0; anIdx < 10000; ++anIdx)
+      {
+        if (aSet.find (aVec[anIdx + 1000]) == aSet.end())
+          aResult = Standard_False;
+        if (aSet.find (aVec[anIdx + 2000]) == aSet.end())
+          aResult = Standard_False;
+        if (aSet.find (aVec[anIdx + 3000]) == aSet.end())
+          aResult = Standard_False;
+        if (aSet.find (aVec[anIdx + 4000]) == aSet.end())
+          aResult = Standard_False;
+        if (aSet.find (aVec[anIdx + 5000]) == aSet.end())
+          aResult = Standard_False;
+      }
+    }
+    aTimer.Stop();
+
+    Standard_Real aStlTime = aTimer.ElapsedTime();
+
+    aTimer.Reset();
+    aTimer.Start();
+    {
+      for (Standard_Integer anIdx = 0; anIdx < 10000; ++anIdx)
+      {
+        if (!aCollec->Contains (aVec[anIdx + 1000]))
+          aResult = Standard_False;
+        if (!aCollec->Contains (aVec[anIdx + 2000]))
+          aResult = Standard_False;
+        if (!aCollec->Contains (aVec[anIdx + 3000]))
+          aResult = Standard_False;
+        if (!aCollec->Contains (aVec[anIdx + 4000]))
+          aResult = Standard_False;
+        if (!aCollec->Contains (aVec[anIdx + 5000]))
+          aResult = Standard_False;
+      }
+    }
+    aTimer.Stop();
+
+    Standard_Real aOccTime = aTimer.ElapsedTime();
+
+    if (aResult)
+    {
+      std::cout << aSize << "\t" << aStlTime << "\t" <<
+        aOccTime << "\t" << (aStlTime > 1e-16 ? aOccTime / aStlTime : -1) << std::endl;
+    }
+
+    delete aCollec;
+  }
+}
+
+//=======================================================================
+//function : QANTestNCollectionPerformance
+//purpose  :
+//=======================================================================
+static Standard_Integer QANTestNCollectionPerformance (
+  Draw_Interpretor& /*theInterpretor*/, Standard_Integer, const char**)
+{
+  std::cout.precision (8);
+
+  std::cout << "Testing performance (Size | STL time | OCCT time | STL/OCCT boost)\n";
+
+  std::cout << std::endl << "std::vector vs NCollection_Array1 (sort):\n" << std::endl;
+  TestPerformanceRandomIterator<NCollection_Array1<double>, std::vector<double> >();
+
+  std::cout << std::endl << "std::vector vs NCollection_Vector (sort):\n" << std::endl;
+  TestPerformanceRandomIterator<NCollection_Vector<double>, std::vector<double> >();
+
+  std::cout << std::endl << "std::vector vs NCollection_Array1 (replace):\n" << std::endl;
+  TestPerformanceForwardIterator<NCollection_Array1<double>, std::vector<double> >();
+
+  std::cout << std::endl << "std::vector vs NCollection_Vector (replace):\n" << std::endl;
+  TestPerformanceForwardIterator<NCollection_Vector<double>, std::vector<double> >();
+
+  std::cout << std::endl << "std::list vs NCollection_List (replace):\n" << std::endl;
+  TestPerformanceForwardIterator<NCollection_List<double>, std::list<double> >();
+
+  std::cout << std::endl << "std::list vs NCollection_Sequence (replace):\n" << std::endl;
+  TestPerformanceForwardIterator<NCollection_Sequence<double>, std::list<double> >();
+
+  std::cout << std::endl << "std::list vs NCollection_Sequence (reverse):\n" << std::endl;
+  TestPerformanceBidirIterator<NCollection_Sequence<double>, std::list<double> >();
+
+  std::cout << std::endl << "std::set vs NCollection_Map (search):\n" << std::endl;
+  TestPerformanceMapAccess<NCollection_Map<int>, int>();
+
+  std::cout << std::endl << "std::set vs NCollection_IndexedMap (search):\n" << std::endl;
+  TestPerformanceMapAccess<NCollection_IndexedMap<int>, int>();
+
+  std::cout.unsetf (std::ios::floatfield);
+
+  return 0;
+}
+
+//=======================================================================
+//function : CommandsStl
+//purpose  :
+//=======================================================================
+void QANCollection::CommandsStl (Draw_Interpretor& theCommands)
+{
+  const char* aGroup = "QANCollection";
+
+  theCommands.Add ("QANArray1StlIterator",
+                   "QANArray1StlIterator",
+                   __FILE__,
+                   QANArray1StlIterator,
+                   aGroup);
+
+  theCommands.Add ("QANListStlIterator",
+                   "QANListStlIterator",
+                   __FILE__,
+                   QANListStlIterator,
+                   aGroup);
+
+  theCommands.Add ("QANSequenceStlIterator",
+                   "QANSequenceStlIterator",
+                   __FILE__,
+                   QANSequenceStlIterator,
+                   aGroup);
+
+  theCommands.Add ("QANVectorStlIterator",
+                   "QANVectorStlIterator",
+                   __FILE__,
+                   QANVectorStlIterator,
+                   aGroup);
+
+  theCommands.Add ("QANMapStlIterator",
+                   "QANMapStlIterator",
+                   __FILE__,
+                   QANMapStlIterator,
+                   aGroup);
+
+  theCommands.Add ("QANDataMapStlIterator",
+                   "QANDataMapStlIterator",
+                   __FILE__,
+                   QANDataMapStlIterator,
+                   aGroup);
+
+  theCommands.Add ("QANIndexedMapStlIterator",
+                   "QANIndexedMapStlIterator",
+                   __FILE__,
+                   QANIndexedMapStlIterator,
+                   aGroup);
+
+  theCommands.Add ("QANIndexedDataMapStlIterator",
+                   "QANIndexedDataMapStlIterator",
+                   __FILE__,
+                   QANIndexedDataMapStlIterator,
+                   aGroup);
+
+  theCommands.Add ("QANTestStlIterators",
+                   "QANTestStlIterators",
+                   __FILE__,
+                   QANTestStlIterators,
+                   aGroup);
+
+  theCommands.Add ("QANTestNCollectionPerformance",
+                   "QANTestNCollectionPerformance",
+                   __FILE__,
+                   QANTestNCollectionPerformance,
+                   aGroup);
+
+  return;
+}
index fba77fc..1974a47 100644 (file)
@@ -1356,7 +1356,7 @@ QANewModTopOpe_Glue::SectionInsideFace(const TopoDS_Face& theFace,
     // check if vertices of aSEdge contacts edges of aFace
     TopoDS_Iterator aIter (aSEdge, Standard_False);
     for (; aIter.More(); aIter.Next()) {
-      const TopoDS_Vertex& aSVer = TopoDS::Vertex (aIter.Value());
+      TopoDS_Vertex aSVer = TopoDS::Vertex (aIter.Value());
       if (aSVer.Orientation() != TopAbs_FORWARD &&
          aSVer.Orientation() != TopAbs_REVERSED) continue;
 
index 9319392..1438359 100644 (file)
@@ -31,9 +31,6 @@
 #include <TopTools_IndexedMapOfShape.hxx>
 #include <TopTools_DataMapOfIntegerShape.hxx>
 
-#include <TCollection_CompareOfReal.hxx>
-#include <SortTools_QuickSortOfReal.hxx>
-
 #include <TColStd_Array1OfReal.hxx>
 #include <TColStd_IndexedMapOfReal.hxx>
 #include <TColStd_ListOfInteger.hxx>
@@ -48,6 +45,9 @@
 #include <BOPDS_CommonBlock.hxx>
 #include <BOPTools_AlgoTools3D.hxx>
 
+#include <NCollection_Array1.hxx>
+#include <algorithm>
+
 static Standard_Boolean AddShapeToHistoryMap(const TopoDS_Shape& theOldShape,
                                              const TopoDS_Shape& theNewShape,
                                              TopTools_IndexedDataMapOfShapeListOfShape& theHistoryMap);
@@ -815,7 +815,7 @@ void SortVertexOnEdge(const TopoDS_Edge&          theEdge,
     mapiv.Bind(iv,v);
   }
   Standard_Integer nv = mapiv.Extent();
-  TColStd_Array1OfReal tabpar(1,nv);
+  NCollection_Array1<Standard_Real> tabpar(1,nv);
   Standard_Integer i = 0;
 
   for ( i = 1; i <= nv; i++) {
@@ -823,8 +823,7 @@ void SortVertexOnEdge(const TopoDS_Edge&          theEdge,
     tabpar.SetValue(i,p);
   }
   theListOfVertexSorted.Clear();
-  TCollection_CompareOfReal compare;
-  SortTools_QuickSortOfReal::Sort(tabpar, compare);
+  std::sort (tabpar.begin(), tabpar.end());
 
   for (i = 1; i <= nv; i++) {
     Standard_Real par = tabpar.Value(i);
index b7c5275..c7ae446 100644 (file)
@@ -41,8 +41,7 @@
 #include <TopTools_DataMapOfIntegerShape.hxx>
 #include <TColStd_Array1OfReal.hxx>
 #include <TColStd_IndexedMapOfReal.hxx>
-#include <TCollection_CompareOfReal.hxx>
-#include <SortTools_QuickSortOfReal.hxx>
+#include <NCollection_Array1.hxx>
 #include <BRepLProp_CLProps.hxx>
 #include <GeomLProp_SLProps.hxx>
 #include <gp_Torus.hxx>
@@ -51,6 +50,7 @@
 #include <Bnd_Box.hxx>
 #include <BRepBndLib.hxx>
 #include <ElCLib.hxx>
+#include <algorithm>
 
 #define M_FORWARD(sta)  (sta == TopAbs_FORWARD)
 #define M_REVERSED(sta) (sta == TopAbs_REVERSED)
@@ -335,7 +335,7 @@ static void FUN_tool_sortVonE(TopTools_ListOfShape& lov, const TopoDS_Edge E)
     mapiv.Bind(iv,v);
   }
   Standard_Integer nv = mapiv.Extent();
-  TColStd_Array1OfReal tabpar(1,nv);
+  NCollection_Array1<Standard_Real> tabpar(1,nv);
 //  for (Standard_Integer i = 1; i <= nv; i++) {
   Standard_Integer i ;
   for ( i = 1; i <= nv; i++) {
@@ -344,7 +344,7 @@ static void FUN_tool_sortVonE(TopTools_ListOfShape& lov, const TopoDS_Edge E)
   }
   
   TopTools_ListOfShape newlov;
-  TCollection_CompareOfReal compare; SortTools_QuickSortOfReal::Sort(tabpar, compare);
+  std::sort (tabpar.begin(), tabpar.end());
   for (i = 1; i <= nv; i++) {
     Standard_Real par = tabpar.Value(i);
     Standard_Integer iv = mappar.FindIndex(par);