From 79a35943dd18b5fb5480c47e551dd693fc2473c8 Mon Sep 17 00:00:00 2001 From: dbp Date: Wed, 23 Apr 2014 09:38:58 +0400 Subject: [PATCH] 0024831: Make iterators of NCollection classes STL-compatible 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). --- src/GeomFill/GeomFill_Frenet.cxx | 14 +- src/NCollection/FILES | 2 + src/NCollection/NCollection_Array1.hxx | 95 +- src/NCollection/NCollection_Array2.hxx | 6 +- src/NCollection/NCollection_BaseList.hxx | 7 +- src/NCollection/NCollection_BaseMap.hxx | 6 + src/NCollection/NCollection_BaseSequence.cxx | 136 +- src/NCollection/NCollection_BaseSequence.hxx | 84 +- src/NCollection/NCollection_BaseVector.cxx | 14 +- src/NCollection/NCollection_BaseVector.hxx | 27 +- src/NCollection/NCollection_DataMap.hxx | 20 +- .../NCollection_IndexedDataMap.hxx | 29 +- src/NCollection/NCollection_IndexedMap.hxx | 17 +- src/NCollection/NCollection_List.hxx | 25 +- src/NCollection/NCollection_Map.hxx | 11 +- src/NCollection/NCollection_Sequence.hxx | 39 +- src/NCollection/NCollection_StlIterator.hxx | 246 ++++ src/NCollection/NCollection_Vector.hxx | 58 +- src/QANCollection/FILES | 1 + src/QANCollection/QANCollection.cdl | 1 + src/QANCollection/QANCollection.cxx | 13 +- src/QANCollection/QANCollection_Stl.cxx | 1289 +++++++++++++++++ .../QANewModTopOpe_Glue_shell.cxx | 2 +- src/QANewModTopOpe/QANewModTopOpe_Tools.cxx | 11 +- src/TopOpeBRepTool/TopOpeBRepTool_TOOL.cxx | 8 +- 25 files changed, 1988 insertions(+), 173 deletions(-) create mode 100644 src/NCollection/NCollection_StlIterator.hxx create mode 100644 src/QANCollection/QANCollection_Stl.cxx diff --git a/src/GeomFill/GeomFill_Frenet.cxx b/src/GeomFill/GeomFill_Frenet.cxx index 8f442bdc0e..ef6c16a7e6 100644 --- a/src/GeomFill/GeomFill_Frenet.cxx +++ b/src/GeomFill/GeomFill_Frenet.cxx @@ -22,9 +22,9 @@ #include #include #include -#include -#include #include +#include +#include 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 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 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); diff --git a/src/NCollection/FILES b/src/NCollection/FILES index d47520f2b7..f900ec5c6b 100755 --- a/src/NCollection/FILES +++ b/src/NCollection/FILES @@ -86,3 +86,5 @@ NCollection_Vec2.hxx NCollection_Vec3.hxx NCollection_Vec4.hxx NCollection_Mat4.hxx + +NCollection_StlIterator.hxx diff --git a/src/NCollection/NCollection_Array1.hxx b/src/NCollection/NCollection_Array1.hxx index 3d7c87a890..8c6989bdcb 100644 --- a/src/NCollection/NCollection_Array1.hxx +++ b/src/NCollection/NCollection_Array1.hxx @@ -23,6 +23,7 @@ #endif #include +#include // *********************************************** Template for Array1 class @@ -57,43 +58,101 @@ template class NCollection_Array1 : public NCollection_BaseCollection { +public: + //! STL-compliant typedef for value type + typedef TheItemType value_type; - public: +public: //! Implementation of the Iterator interface. class Iterator : public NCollection_BaseCollection::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 (&theArray.Last() + 1)) + { + myPtrCur = theToEnd ? myPtrEnd : const_cast (&theArray.First()); + } + //! Initialisation void Init (const NCollection_Array1& theArray) { - myCurrent = theArray.Lower(); - myArray = (NCollection_Array1 *) &theArray; + myPtrCur = const_cast (&theArray.First()); + myPtrEnd = const_cast (&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 iterator; + + //! Shorthand for a constant iterator type. + typedef NCollection_StlIterator 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 ------------ diff --git a/src/NCollection/NCollection_Array2.hxx b/src/NCollection/NCollection_Array2.hxx index e95fa6922c..c8a13aa9b0 100644 --- a/src/NCollection/NCollection_Array2.hxx +++ b/src/NCollection/NCollection_Array2.hxx @@ -40,7 +40,11 @@ template class NCollection_Array2 : public NCollection_BaseCollection { - public: +public: + //! STL-compliant typedef for value type + typedef TheItemType value_type; + +public: // **************** Implementation of the Iterator interface. class Iterator : public NCollection_BaseCollection::Iterator { diff --git a/src/NCollection/NCollection_BaseList.hxx b/src/NCollection/NCollection_BaseList.hxx index 705448581e..2f159e607e 100644 --- a/src/NCollection/NCollection_BaseList.hxx +++ b/src/NCollection/NCollection_BaseList.hxx @@ -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) diff --git a/src/NCollection/NCollection_BaseMap.hxx b/src/NCollection/NCollection_BaseMap.hxx index 6060a334ed..c564f97753 100644 --- a/src/NCollection/NCollection_BaseMap.hxx +++ b/src/NCollection/NCollection_BaseMap.hxx @@ -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 diff --git a/src/NCollection/NCollection_BaseSequence.cxx b/src/NCollection/NCollection_BaseSequence.cxx index c9569aaa95..171b8e8ca5 100644 --- a/src/NCollection/NCollection_BaseSequence.cxx +++ b/src/NCollection/NCollection_BaseSequence.cxx @@ -28,10 +28,9 @@ 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; diff --git a/src/NCollection/NCollection_BaseSequence.hxx b/src/NCollection/NCollection_BaseSequence.hxx index 8be52d8884..46790d6d8d 100644 --- a/src/NCollection/NCollection_BaseSequence.hxx +++ b/src/NCollection/NCollection_BaseSequence.hxx @@ -24,26 +24,15 @@ 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 diff --git a/src/NCollection/NCollection_BaseVector.cxx b/src/NCollection/NCollection_BaseVector.cxx index 56c31b9d02..208e7753b2 100755 --- a/src/NCollection/NCollection_BaseVector.cxx +++ b/src/NCollection/NCollection_BaseVector.cxx @@ -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; } } diff --git a/src/NCollection/NCollection_BaseVector.hxx b/src/NCollection/NCollection_BaseVector.hxx index 12a7b311c7..1f1b30cc6a 100755 --- a/src/NCollection/NCollection_BaseVector.hxx +++ b/src/NCollection/NCollection_BaseVector.hxx @@ -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]; diff --git a/src/NCollection/NCollection_DataMap.hxx b/src/NCollection/NCollection_DataMap.hxx index 2b7cdbd71b..704bc1d283 100644 --- a/src/NCollection/NCollection_DataMap.hxx +++ b/src/NCollection/NCollection_DataMap.hxx @@ -19,7 +19,7 @@ #include #include #include - +#include #include #include @@ -124,6 +124,24 @@ template < class TheKeyType, return ((DataMapNode *) myNode)->Key(); } }; + + //! Shorthand for a regular iterator type. + typedef NCollection_StlIterator iterator; + + //! Shorthand for a constant iterator type. + typedef NCollection_StlIterator 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 ------------ diff --git a/src/NCollection/NCollection_IndexedDataMap.hxx b/src/NCollection/NCollection_IndexedDataMap.hxx index 806d810528..939db85eda 100644 --- a/src/NCollection/NCollection_IndexedDataMap.hxx +++ b/src/NCollection/NCollection_IndexedDataMap.hxx @@ -21,7 +21,7 @@ #include #include #include - +#include #include #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 iterator; + + //! Shorthand for a constant iterator type. + typedef NCollection_StlIterator 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 ------------ diff --git a/src/NCollection/NCollection_IndexedMap.hxx b/src/NCollection/NCollection_IndexedMap.hxx index 2beb11729e..f76f7d425d 100644 --- a/src/NCollection/NCollection_IndexedMap.hxx +++ b/src/NCollection/NCollection_IndexedMap.hxx @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -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 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 ------------ diff --git a/src/NCollection/NCollection_List.hxx b/src/NCollection/NCollection_List.hxx index 4d45ddd53c..410a6a927d 100644 --- a/src/NCollection/NCollection_List.hxx +++ b/src/NCollection/NCollection_List.hxx @@ -17,6 +17,7 @@ #define NCollection_List_HeaderFile #include +#include #if !defined No_Exception && !defined No_Standard_NoSuchObject #include @@ -31,10 +32,32 @@ template class NCollection_List : public NCollection_BaseCollection, public NCollection_BaseList { - public: +public: + //! STL-compliant typedef for value type + typedef TheItemType value_type; + +public: typedef NCollection_TListNode ListNode; typedef NCollection_TListIterator Iterator; + //! Shorthand for a regular iterator type. + typedef NCollection_StlIterator iterator; + + //! Shorthand for a constant iterator type. + typedef NCollection_StlIterator 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 ------------ diff --git a/src/NCollection/NCollection_Map.hxx b/src/NCollection/NCollection_Map.hxx index a133972d44..2cdefd4fb3 100644 --- a/src/NCollection/NCollection_Map.hxx +++ b/src/NCollection/NCollection_Map.hxx @@ -20,7 +20,7 @@ #include #include #include - +#include #include #include @@ -122,6 +122,15 @@ template < class TheKeyType, return ((MapNode *) myNode)->Value(); } }; + + //! Shorthand for a constant iterator type. + typedef NCollection_StlIterator 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 ------------ diff --git a/src/NCollection/NCollection_Sequence.hxx b/src/NCollection/NCollection_Sequence.hxx index f43cef76c1..4ef17ad7fe 100644 --- a/src/NCollection/NCollection_Sequence.hxx +++ b/src/NCollection/NCollection_Sequence.hxx @@ -18,6 +18,7 @@ #include #include +#include #ifndef No_Exception #include @@ -32,8 +33,11 @@ template class NCollection_Sequence : public NCollection_BaseCollection, 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 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 iterator; + + //! Shorthand for a constant iterator type. + typedef NCollection_StlIterator 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 index 0000000000..dca1c2a77b --- /dev/null +++ b/src/NCollection/NCollection_StlIterator.hxx @@ -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 +#include + +// 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 + struct enable_if + { + typedef T type; + }; + + template + struct enable_if + { + }; + + template + struct is_same + { + enum { value = 0 }; + }; + + template + struct is_same + { + enum { value = 1 }; + }; + + template + struct conditional + { + typedef TypeTrue type; + }; + + template + struct conditional + { + 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 NCollection_StlIterator : private BaseIterator, + public std::iterator::type, + typename opencascade::conditional::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& theIterator) + : BaseIterator (theIterator) + { } + + //! Assignment of non-const iterator to const one + NCollection_StlIterator& operator= (const NCollection_StlIterator& theIterator) + { + BaseIterator::operator= (theIterator); + return *this; + } + + friend class NCollection_StlIterator; + +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 + typename opencascade::enable_if::type Reference() + { + return BaseIterator::ChangeValue(); + } + + template + typename opencascade::enable_if::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(); + } + + //! Dereferencing operator + typename NCollection_StlIterator::pointer operator->() + { + return &Reference(); + } + + //! 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::value || + opencascade::is_same::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::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::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 diff --git a/src/NCollection/NCollection_Vector.hxx b/src/NCollection/NCollection_Vector.hxx index 479090391c..bb9db3150a 100755 --- a/src/NCollection/NCollection_Vector.hxx +++ b/src/NCollection/NCollection_Vector.hxx @@ -18,6 +18,7 @@ #include #include +#include //! Class NCollection_Vector (dynamic array of objects) //! @@ -45,8 +46,10 @@ template 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::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 iterator; + + //! Shorthand for a constant iterator type. + typedef NCollection_StlIterator 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; diff --git a/src/QANCollection/FILES b/src/QANCollection/FILES index 0e7de083d5..36e738e076 100755 --- a/src/QANCollection/FILES +++ b/src/QANCollection/FILES @@ -5,6 +5,7 @@ QANCollection1.cxx QANCollection2.cxx QANCollection3.cxx QANCollection4.cxx +QANCollection_Stl.cxx QANCollection_Common.cxx QANCollection_Common.hxx QANCollection_Common2.hxx diff --git a/src/QANCollection/QANCollection.cdl b/src/QANCollection/QANCollection.cdl index 29e7d329f0..0d35dc9cad 100644 --- a/src/QANCollection/QANCollection.cdl +++ b/src/QANCollection/QANCollection.cdl @@ -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; diff --git a/src/QANCollection/QANCollection.cxx b/src/QANCollection/QANCollection.cxx index ba40d295d7..3a6e3eb992 100644 --- a/src/QANCollection/QANCollection.cxx +++ b/src/QANCollection/QANCollection.cxx @@ -19,10 +19,11 @@ #include //#include -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 index 0000000000..248e8f9199 --- /dev/null +++ b/src/QANCollection/QANCollection_Stl.cxx @@ -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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 + #include +#endif + +#include +#include +#include +#include +#include + +//! 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 +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 +struct CollectionFiller, StlType> +{ + static void Perform (NCollection_Array1** theCollec, + Standard_Integer theSize = THE_TEST_SIZE) + { + *theCollec = new NCollection_Array1 (0, theSize - 1); + srand (1); + for (Standard_Integer anIdx = 0; anIdx < theSize; ++anIdx) + { + (*theCollec)->ChangeValue (anIdx) = rand(); + } + } + + static void Perform (StlType** theVector, + NCollection_Array1** theCollec, Standard_Integer theSize = THE_TEST_SIZE) + { + CollectionFiller, StlType >::Perform (theCollec, theSize); + + *theVector = new StlType ((*theCollec)->begin(), (*theCollec)->end()); + } +}; + +template +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 +struct MapFiller, T> +{ + static void Perform (NCollection_DataMap** theCollec1, + NCollection_DataMap** theCollec2 = NULL, Standard_Integer theSize = THE_TEST_SIZE) + { + *theCollec1 = new NCollection_DataMap(); + + if (theCollec2 != NULL) + *theCollec2 = new NCollection_DataMap(); + 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 +struct MapFiller, T> +{ + static void Perform (NCollection_IndexedDataMap** theCollec1, + NCollection_IndexedDataMap** theCollec2 = NULL, Standard_Integer theSize = THE_TEST_SIZE) + { + *theCollec1 = new NCollection_IndexedDataMap(); + + if (theCollec2 != NULL) + *theCollec2 = new NCollection_IndexedDataMap(); + 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 +Standard_Boolean TestIteration() +{ + StlType* aVector (NULL); + CollectionType* aCollec (NULL); + + CollectionFiller::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 +Standard_Boolean TestMinMax() +{ + StlType* aVector (NULL); + CollectionType* aCollec (NULL); + + CollectionFiller::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 +Standard_Boolean TestReplace() +{ + StlType* aVector (NULL); + CollectionType* aCollec (NULL); + + CollectionFiller::Perform (&aVector, &aCollec); + + const typename StlType::value_type aValue = aVector->back(); + + std::replace (aVector->begin(), aVector->end(), aValue, static_cast (-1)); + std::replace (aCollec->begin(), aCollec->end(), aValue, static_cast (-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 +Standard_Boolean TestReverse() +{ + StlType* aVector (NULL); + CollectionType* aCollec (NULL); + + CollectionFiller::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 +Standard_Boolean TestSort() +{ + StlType* aVector (NULL); + CollectionType* aCollec (NULL); + + CollectionFiller::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 +struct Invoker +{ + void operator()(T& theValue) const + { + theValue *= 2; + } +}; + +//======================================================================= +//function : TestTBB +//purpose : +//======================================================================= +template +Standard_Boolean TestTBB() +{ + StlType* aVector (NULL); + CollectionType* aCollec (NULL); + + CollectionFiller::Perform (&aVector, &aCollec); + + tbb::parallel_for_each (aVector->begin(), aVector->end(), Invoker()); + tbb::parallel_for_each (aCollec->begin(), aCollec->end(), Invoker()); + + 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 +Standard_Boolean TestDataMapTBB() +{ + CollectionType* aCollec1 (NULL); + CollectionType* aCollec2 (NULL); + + MapFiller::Perform (&aCollec1, &aCollec2); + + tbb::parallel_for_each (aCollec1->begin(), aCollec1->end(), Invoker()); + + // 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 (2) * aOccIter.Value() != *aStlIter) + aResult = Standard_False; + } + + if (aOccIter.More()) + { + aResult = Standard_False; + } + + delete aCollec1; + delete aCollec2; + + return aResult; +} + +#endif + +//======================================================================= +//function : TestMapIteration +//purpose : +//======================================================================= +template +Standard_Boolean TestMapIteration() +{ + CollectionType* aCollec (NULL); + + MapFiller::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 +void TestForwardIterator () +{ + CollectionType* aCollec (NULL); + + CollectionFiller::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 +void TestBidirIterator () +{ + CollectionType* aCollec (NULL); + + CollectionFiller::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 +void TestRandomIterator () +{ + CollectionType* aCollec (NULL); + + CollectionFiller::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 >(); + + // run-time tests + Standard_Boolean aResult = TestIteration, std::list >(); + std::cout << "NCollection_List Iteration: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestIteration, std::list >(); + std::cout << "NCollection_List Iteration: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestMinMax, std::list >(); + std::cout << "NCollection_List Min-Max: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestMinMax, std::list >(); + std::cout << "NCollection_List Min-Max: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestReplace, std::list >(); + std::cout << "NCollection_List Replace: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestReplace, std::list >(); + std::cout << "NCollection_List Replace: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + +#ifdef HAVE_TBB + + aResult = TestTBB, std::list >(); + std::cout << "NCollection_List TBB: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestTBB, std::list >(); + std::cout << "NCollection_List 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 >(); + + // run-time tests + Standard_Boolean aResult = TestMapIteration, Standard_Integer>(); + std::cout << "NCollection_Map Iteration: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestMapIteration, Standard_Real>(); + std::cout << "NCollection_Map 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 >(); +// TestBidirIterator >(); + + // run-time tests + Standard_Boolean aResult = TestMapIteration, Standard_Integer>(); + std::cout << "NCollection_IndexedMap Iteration: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestMapIteration, Standard_Real>(); + std::cout << "NCollection_IndexedMap 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 >(); +// TestBidirIterator >(); + + // run-time tests + Standard_Boolean aResult = TestMapIteration, Standard_Integer>(); + std::cout << "NCollection_DataMap Iteration: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestMapIteration, Standard_Real>(); + std::cout << "NCollection_DataMap Iteration: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + +#ifdef HAVE_TBB + + aResult = TestDataMapTBB, Standard_Integer>(); + std::cout << "NCollection_DataMap TBB: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestDataMapTBB, Standard_Real>(); + std::cout << "NCollection_DataMap 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 >(); +// TestBidirIterator >(); + + // run-time tests + Standard_Boolean aResult = TestMapIteration, Standard_Integer>(); + std::cout << "NCollection_IndexedDataMap Iteration: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestMapIteration, Standard_Real>(); + std::cout << "NCollection_IndexedDataMap Iteration: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + +#ifdef HAVE_TBB + + aResult = TestDataMapTBB, Standard_Integer>(); + std::cout << "NCollection_IndexedDataMap TBB: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestDataMapTBB, Standard_Real>(); + std::cout << "NCollection_IndexedDataMap 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 >(); + TestBidirIterator >(); + + // run-time tests + Standard_Boolean aResult = TestIteration, std::list >(); + std::cout << "NCollection_Sequence Iteration: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestIteration, std::list >(); + std::cout << "NCollection_Sequence Iteration: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestMinMax, std::list >(); + std::cout << "NCollection_Sequence Min-Max: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestMinMax, std::list >(); + std::cout << "NCollection_Sequence Min-Max: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestReplace, std::list >(); + std::cout << "NCollection_Sequence Replace: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestReplace, std::list >(); + std::cout << "NCollection_Sequence Replace: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestReverse, std::list >(); + std::cout << "NCollection_Sequence Reverse: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestReverse, std::list >(); + std::cout << "NCollection_Sequence Reverse: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + +#ifdef HAVE_TBB + + aResult = TestTBB, std::list >(); + std::cout << "NCollection_Sequence TBB: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestTBB, std::list >(); + std::cout << "NCollection_Sequence 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 >(); + TestBidirIterator >(); + TestRandomIterator >(); + + // run-time tests + Standard_Boolean aResult = TestIteration, std::vector >(); + std::cout << "NCollection_Vector Iteration: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestIteration, std::vector >(); + std::cout << "NCollection_Vector Iteration: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestMinMax, std::vector >(); + std::cout << "NCollection_Vector Min-Max: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestMinMax, std::vector >(); + std::cout << "NCollection_Vector Min-Max: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestReplace, std::vector >(); + std::cout << "NCollection_Vector Replace: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestReplace, std::vector >(); + std::cout << "NCollection_Vector Replace: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestReverse, std::vector >(); + std::cout << "NCollection_Vector Reverse: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestReverse, std::vector >(); + std::cout << "NCollection_Vector Reverse: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestSort, std::vector >(); + std::cout << "NCollection_Vector Sort: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestSort, std::vector >(); + std::cout << "NCollection_Vector Sort: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + +#ifdef HAVE_TBB + + aResult = TestTBB, std::vector >(); + std::cout << "NCollection_Vector TBB: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestTBB, std::vector >(); + std::cout << "NCollection_Vector 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 >(); + TestBidirIterator >(); + TestRandomIterator >(); + + // run-time tests + Standard_Boolean aResult = TestIteration, std::vector >(); + std::cout << "NCollection_Array1 Iteration: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestIteration, std::vector >(); + std::cout << "NCollection_Array1 Iteration: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestMinMax, std::vector >(); + std::cout << "NCollection_Array1 Min-Max: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestMinMax, std::vector >(); + std::cout << "NCollection_Array1 Min-Max: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestReplace, std::vector >(); + std::cout << "NCollection_Array1 Replace: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestReplace, std::vector >(); + std::cout << "NCollection_Array1 Replace: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestReverse, std::vector >(); + std::cout << "NCollection_Array1 Reverse: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestReverse, std::vector >(); + std::cout << "NCollection_Array1 Reverse: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestSort, std::vector >(); + std::cout << "NCollection_Array1 Sort: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestSort, std::vector >(); + std::cout << "NCollection_Array1 Sort: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + +#ifdef HAVE_TBB + + aResult = TestTBB, std::vector >(); + std::cout << "NCollection_Array1 TBB: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + aResult = TestTBB, std::vector >(); + std::cout << "NCollection_Array1 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 +void TestPerformanceRandomIterator() +{ + OSD_Timer aTimer; + + StlType* aVector (NULL); + CollectionType* aCollec (NULL); + + for (Standard_Integer aSize = 10000; aSize <= 1280000; aSize *= 2) + { + CollectionFiller::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 +void TestPerformanceForwardIterator() +{ + OSD_Timer aTimer; + + StlType* aVector = 0; + CollectionType* aCollec = 0; + + for (Standard_Integer aSize = 10000; aSize <= 1280000; aSize *= 2) + { + CollectionFiller::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 (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 (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 +void TestPerformanceBidirIterator() +{ + OSD_Timer aTimer; + + StlType* aVector = 0; + CollectionType* aCollec = 0; + + for (Standard_Integer aSize = 10000; aSize <= 1280000; aSize *= 2) + { + CollectionFiller::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 +void TestPerformanceMapAccess() +{ + OSD_Timer aTimer; + + CollectionType* aCollec (NULL); + + for (Standard_Integer aSize = 100000; aSize <= 3200000; aSize *= 2) + { + MapFiller::Perform (&aCollec, aSize); + + std::set aSet (aCollec->cbegin(), aCollec->cend()); + std::vector 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, std::vector >(); + + std::cout << std::endl << "std::vector vs NCollection_Vector (sort):\n" << std::endl; + TestPerformanceRandomIterator, std::vector >(); + + std::cout << std::endl << "std::vector vs NCollection_Array1 (replace):\n" << std::endl; + TestPerformanceForwardIterator, std::vector >(); + + std::cout << std::endl << "std::vector vs NCollection_Vector (replace):\n" << std::endl; + TestPerformanceForwardIterator, std::vector >(); + + std::cout << std::endl << "std::list vs NCollection_List (replace):\n" << std::endl; + TestPerformanceForwardIterator, std::list >(); + + std::cout << std::endl << "std::list vs NCollection_Sequence (replace):\n" << std::endl; + TestPerformanceForwardIterator, std::list >(); + + std::cout << std::endl << "std::list vs NCollection_Sequence (reverse):\n" << std::endl; + TestPerformanceBidirIterator, std::list >(); + + std::cout << std::endl << "std::set vs NCollection_Map (search):\n" << std::endl; + TestPerformanceMapAccess, int>(); + + std::cout << std::endl << "std::set vs NCollection_IndexedMap (search):\n" << std::endl; + TestPerformanceMapAccess, 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; +} diff --git a/src/QANewModTopOpe/QANewModTopOpe_Glue_shell.cxx b/src/QANewModTopOpe/QANewModTopOpe_Glue_shell.cxx index fba77fc10f..1974a47ce5 100644 --- a/src/QANewModTopOpe/QANewModTopOpe_Glue_shell.cxx +++ b/src/QANewModTopOpe/QANewModTopOpe_Glue_shell.cxx @@ -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; diff --git a/src/QANewModTopOpe/QANewModTopOpe_Tools.cxx b/src/QANewModTopOpe/QANewModTopOpe_Tools.cxx index 9319392c51..1438359b06 100644 --- a/src/QANewModTopOpe/QANewModTopOpe_Tools.cxx +++ b/src/QANewModTopOpe/QANewModTopOpe_Tools.cxx @@ -31,9 +31,6 @@ #include #include -#include -#include - #include #include #include @@ -48,6 +45,9 @@ #include #include +#include +#include + 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 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); diff --git a/src/TopOpeBRepTool/TopOpeBRepTool_TOOL.cxx b/src/TopOpeBRepTool/TopOpeBRepTool_TOOL.cxx index b7c527525d..c7ae44660c 100644 --- a/src/TopOpeBRepTool/TopOpeBRepTool_TOOL.cxx +++ b/src/TopOpeBRepTool/TopOpeBRepTool_TOOL.cxx @@ -41,8 +41,7 @@ #include #include #include -#include -#include +#include #include #include #include @@ -51,6 +50,7 @@ #include #include #include +#include #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 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);