// 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. #if defined(_MSC_VER) && ! defined(_SCL_SECURE_NO_WARNINGS) // suppress "std::Equal1" warning suggesting using msvc "Checked Iterators" #define _SCL_SECURE_NO_WARNINGS #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #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); } ptrdiff_t operator () (ptrdiff_t 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; } template struct Invoker { void operator()(T& theValue) const { theValue *= 2; } }; //======================================================================= //function : TestParallel //purpose : //======================================================================= template Standard_Boolean TestParallel() { StlType* aVector (NULL); CollectionType* aCollec (NULL); CollectionFiller::Perform (&aVector, &aCollec); OSD_Parallel::ForEach(aVector->begin(), aVector->end(), Invoker()); OSD_Parallel::ForEach(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 : TestDataMapParallel //purpose : //======================================================================= template Standard_Boolean TestDataMapParallel() { CollectionType* aCollec1 (NULL); CollectionType* aCollec2 (NULL); MapFiller::Perform (&aCollec1, &aCollec2); OSD_Parallel::ForEach(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; } //======================================================================= //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; (void)ct; // *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; aResult = TestParallel< NCollection_List, std::list >(); std::cout << "NCollection_List Parallel: " << (aResult ? "SUCCESS" : "FAIL") << std::endl; aResult = TestParallel, std::list >(); std::cout << "NCollection_List Parallel: " << (aResult ? "SUCCESS" : "FAIL") << std::endl; 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; aResult = TestDataMapParallel, Standard_Integer>(); std::cout << "NCollection_DataMap Parallel: " << (aResult ? "SUCCESS" : "FAIL") << std::endl; aResult = TestDataMapParallel, Standard_Real>(); std::cout << "NCollection_DataMap Parallel: " << (aResult ? "SUCCESS" : "FAIL") << std::endl; 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; aResult = TestDataMapParallel, Standard_Integer>(); std::cout << "NCollection_IndexedDataMap Parallel: " << (aResult ? "SUCCESS" : "FAIL") << std::endl; aResult = TestDataMapParallel, Standard_Real>(); std::cout << "NCollection_IndexedDataMap Parallel: " << (aResult ? "SUCCESS" : "FAIL") << std::endl; 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; aResult = TestParallel, std::list >(); std::cout << "NCollection_Sequence Parallel: " << (aResult ? "SUCCESS" : "FAIL") << std::endl; aResult = TestParallel, std::list >(); std::cout << "NCollection_Sequence Parallel: " << (aResult ? "SUCCESS" : "FAIL") << std::endl; 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; aResult = TestParallel, std::vector >(); std::cout << "NCollection_Vector Parallel: " << (aResult ? "SUCCESS" : "FAIL") << std::endl; aResult = TestParallel, std::vector >(); std::cout << "NCollection_Vector Parallel: " << (aResult ? "SUCCESS" : "FAIL") << std::endl; { // Test case for a corner case described in a bug #0027941 // when vector length matches the increment. // In this case NCollection_Vector::Iterator::Offset() produced mathematically equal // but not the same iterator as returned by NCollection_Vector::end() // so that their comparison was not equal. // As result, std::stable_sort() crashed due to out-of-range access. const int THE_INCREMENT = 256; NCollection_Vector aVector (THE_INCREMENT); for (int anIter = 0; anIter < THE_INCREMENT; ++anIter) { aVector.Append (THE_INCREMENT - anIter); } NCollection_Vector::iterator aBegin = aVector.begin(); NCollection_Vector::iterator anEnd = aVector.end(); NCollection_Vector::iterator aShift = aBegin + THE_INCREMENT; aResult = (aShift == anEnd); std::cout << "NCollection_Vector Offset: " << (aResult ? "SUCCESS" : "FAIL") << std::endl; std::stable_sort (aVector.begin(), aVector.end()); } 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; aResult = TestParallel, std::vector >(); std::cout << "NCollection_Array1 Parallel: " << (aResult ? "SUCCESS" : "FAIL") << std::endl; aResult = TestParallel, std::vector >(); std::cout << "NCollection_Array1 Parallel: " << (aResult ? "SUCCESS" : "FAIL") << std::endl; 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(Draw_Interpretor& di) { 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(); di << aSize << "\t" << aStlTime << "\t" << aOccTime << "\t" << aOccTime / aStlTime << "\n"; // check that result is the same if ( ! std::equal (aVector->begin(), aVector->end(), aCollec->begin()) ) di << "Error: sequences are not the same at the end!\n"; delete aVector; delete aCollec; } } //======================================================================= //function : TestPerformanceForwardIterator //purpose : //======================================================================= template void TestPerformanceForwardIterator(Draw_Interpretor& di) { 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(); di << aSize << "\t" << aStlTime << "\t" << aOccTime << "\t" << aOccTime / aStlTime << "\n"; // check that result is the same if ( ! std::equal (aVector->begin(), aVector->end(), aCollec->begin()) ) di << "Error: sequences are not the same at the end!\n"; delete aVector; delete aCollec; } } //======================================================================= //function : TestPerformanceBidirIterator //purpose : //======================================================================= template void TestPerformanceBidirIterator(Draw_Interpretor& di) { 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(); di << aSize << "\t" << aStlTime << "\t" << aOccTime << "\t" << aOccTime / aStlTime << "\n"; // check that result is the same if ( ! std::equal (aVector->begin(), aVector->end(), aCollec->begin()) ) di << "Error: sequences are not the same at the end!\n"; delete aVector; delete aCollec; } } //======================================================================= //function : TestPerformanceMapAccess //purpose : //======================================================================= template void TestPerformanceMapAccess(Draw_Interpretor& di) { 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) { di << aSize << "\t" << aStlTime << "\t" << aOccTime << "\t" << (aStlTime > 1e-16 ? aOccTime / aStlTime : -1) << "\n"; } delete aCollec; } } //======================================================================= //function : QANTestNCollectionPerformance //purpose : //======================================================================= static Standard_Integer QANTestNCollectionPerformance (Draw_Interpretor& di, Standard_Integer, const char**) { di << "Testing performance (Size | STL time | OCCT time | STL/OCCT boost)\n"; di << "\nstd::vector vs NCollection_Array1 (sort):\n\n"; TestPerformanceRandomIterator, std::vector >(di); di << "\nstd::vector vs NCollection_Vector (sort):\n\n"; TestPerformanceRandomIterator, std::vector >(di); di << "\nstd::vector vs NCollection_Array1 (replace):\n\n"; TestPerformanceForwardIterator, std::vector >(di); di << "\nstd::vector vs NCollection_Vector (replace):\n\n"; TestPerformanceForwardIterator, std::vector >(di); di << "\nstd::list vs NCollection_List (replace):\n\n"; TestPerformanceForwardIterator, std::list >(di); di << "\nstd::list vs NCollection_Sequence (replace):\n\n"; TestPerformanceForwardIterator, std::list >(di); di << "\nstd::list vs NCollection_Sequence (reverse):\n\n"; TestPerformanceBidirIterator, std::list >(di); di << "\nstd::set vs NCollection_Map (search):\n\n"; TestPerformanceMapAccess, int>(di); di << "\nstd::set vs NCollection_IndexedMap (search):\n\n"; TestPerformanceMapAccess, int>(di); return 0; } //======================================================================= //function : QANTestNCollectionIndexedMap //purpose : //======================================================================= static Standard_Integer QANTestNCollectionIndexedMap (Draw_Interpretor& di, Standard_Integer, const char**) { OSD_Timer aTimer; std::vector aIndxs; std::vector aItems; NCollection_IndexedMap aIndxMap; const Standard_Integer aNbItems = 1000000; srand (1); for (Standard_Integer anId = 1; anId <= aNbItems; ++anId) { const Standard_Integer aVal = anId * 2; aIndxs.push_back (anId); aItems.push_back (aVal); aIndxMap.Add (aVal); } aTimer.Start(); for (Standard_Integer anId = 0; anId < aNbItems; ++anId) { if (aIndxMap.FindIndex (aItems[anId]) != aIndxs[anId]) { std::cout << "failed FindIndex\n"; } if (aIndxMap.FindKey (aIndxs[anId]) != aItems[anId]) { std::cout << "failed FindKey\n"; } } aTimer.Stop(); const Standard_Real aTime1 = aTimer.ElapsedTime(); aTimer.Reset(); aTimer.Start(); for (Standard_Integer anId = 0; anId < aNbItems / 30; ++anId) { const Standard_Integer anId2 = Min (aNbItems - 1, static_cast (rand() / float (RAND_MAX) * aNbItems)); aIndxMap.Swap (aIndxs[anId], aIndxs[anId2]); std::swap (aIndxs[anId], aIndxs[anId2]); } aTimer.Stop(); const Standard_Real aTime2 = aTimer.ElapsedTime(); aTimer.Reset(); aTimer.Start(); for (Standard_Integer anId = 0; anId < aNbItems; ++anId) { if (aIndxMap.FindIndex (aItems[anId]) != aIndxs[anId]) { std::cout << "failed FindIndex\n"; } if (aIndxMap.FindKey (aIndxs[anId]) != aItems[anId]) { std::cout << "failed FindKey\n"; } } aTimer.Stop(); const Standard_Real aTime3 = aTimer.ElapsedTime(); aTimer.Reset(); aTimer.Start(); for (Standard_Integer anId = 0; anId < aNbItems; ++anId) { aIndxMap.RemoveLast(); } aTimer.Stop(); const Standard_Real aTime4 = aTimer.ElapsedTime(); di << "Search time 1: " << aTime1 << "\n" << "Swapping time: " << aTime2 << "\n" << "Search time 2: " << aTime3 << "\n" << "Remove time: " << aTime4 << "\n"; return 0; } //======================================================================= //function : QANTestNCollectionIndexedDataMap //purpose : //======================================================================= static Standard_Integer QANTestNCollectionIndexedDataMap (Draw_Interpretor& di, Standard_Integer, const char**) { OSD_Timer aTimer; std::vector aIndxs; std::vector aItems; NCollection_IndexedDataMap aIndxMap; const Standard_Integer aNbItems = 1000000; srand (1); for (Standard_Integer anId = 1; anId <= aNbItems; ++anId) { const Standard_Integer aVal = anId * 2; aIndxs.push_back (anId); aItems.push_back (aVal); aIndxMap.Add (aVal, aVal * 2); } aTimer.Start(); for (Standard_Integer anId = 0; anId < aNbItems; ++anId) { if (aIndxMap.FindIndex (aItems[anId]) != aIndxs[anId]) { std::cout << "failed FindIndex\n"; } if (aIndxMap.FindKey (aIndxs[anId]) != aItems[anId]) { std::cout << "failed FindKey\n"; } } aTimer.Stop(); const Standard_Real aTime1 = aTimer.ElapsedTime(); aTimer.Reset(); aTimer.Start(); for (Standard_Integer anId = 0; anId < aNbItems / 30; ++anId) { const Standard_Integer anId2 = Min (aNbItems - 1, static_cast (rand() / float (RAND_MAX) * aNbItems)); aIndxMap.Swap (aIndxs[anId], aIndxs[anId2]); std::swap (aIndxs[anId], aIndxs[anId2]); } aTimer.Stop(); const Standard_Real aTime2 = aTimer.ElapsedTime(); aTimer.Reset(); aTimer.Start(); for (Standard_Integer anId = 0; anId < aNbItems; ++anId) { if (aIndxMap.FindIndex (aItems[anId]) != aIndxs[anId]) { std::cout << "failed FindIndex\n"; } if (aIndxMap.FindKey (aIndxs[anId]) != aItems[anId]) { std::cout << "failed FindKey\n"; } } aTimer.Stop(); const Standard_Real aTime3 = aTimer.ElapsedTime(); aTimer.Reset(); aTimer.Start(); for (Standard_Integer anId = 0; anId < aNbItems; ++anId) { aIndxMap.RemoveLast(); } aTimer.Stop(); const Standard_Real aTime4 = aTimer.ElapsedTime(); di << "Search time 1: " << aTime1 << "\n" << "Swapping time: " << aTime2 << "\n" << "Search time 2: " << aTime3 << "\n" << "Remove time: " << aTime4 << "\n"; 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); theCommands.Add ("QANTestNCollectionIndexedMap", "QANTestNCollectionIndexedMap", __FILE__, QANTestNCollectionIndexedMap, aGroup); theCommands.Add ("QANTestNCollectionIndexedDataMap", "QANTestNCollectionIndexedDataMap", __FILE__, QANTestNCollectionIndexedDataMap, aGroup); return; }