0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[occt.git] / src / QANCollection / QANCollection_Stl.cxx
1 // Created on: 2014-04-16
2 // Created by: Denis BOGOLEPOV
3 // Copyright (c) 2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #if defined(_MSC_VER) && ! defined(_SCL_SECURE_NO_WARNINGS)
17   // suppress "std::Equal1" warning suggesting using msvc "Checked Iterators"
18   #define _SCL_SECURE_NO_WARNINGS
19 #endif
20
21 #include <QANCollection.hxx>
22 #include <Draw_Interpretor.hxx>
23
24 #include <NCollection_List.hxx>
25 #include <NCollection_Sequence.hxx>
26 #include <NCollection_Vector.hxx>
27 #include <NCollection_Map.hxx>
28 #include <NCollection_DataMap.hxx>
29 #include <NCollection_IndexedMap.hxx>
30 #include <NCollection_IndexedDataMap.hxx>
31 #include <OSD_Timer.hxx>
32 #include <OSD_Parallel.hxx>
33
34 #include <algorithm>
35 #include <list>
36 #include <set>
37 #include <typeinfo>
38 #include <vector>
39 #include <random>
40
41 //! Size of test data sets.
42 const int THE_TEST_SIZE = 5000;
43
44 template<class CollectionType, class StlType>
45 struct CollectionFiller
46 {
47   static void Perform (CollectionType** theCollec, Standard_Integer theSize = THE_TEST_SIZE)
48   {
49     *theCollec = new CollectionType();
50     srand(1);
51     for (Standard_Integer anIdx = 0; anIdx < theSize; ++anIdx)
52     {
53       (*theCollec)->Append (rand());
54     }
55   }
56
57   static void Perform (StlType** theVector,
58     CollectionType** theCollec, Standard_Integer theSize = THE_TEST_SIZE)
59   {
60     CollectionFiller::Perform (theCollec, theSize);
61
62     *theVector = new StlType ((*theCollec)->begin(), (*theCollec)->end());
63   }
64 };
65
66 template<class T, typename StlType>
67 struct CollectionFiller<NCollection_Array1<T>, StlType>
68 {
69   static void Perform (NCollection_Array1<T>** theCollec,
70     Standard_Integer theSize = THE_TEST_SIZE)
71   {
72     *theCollec = new NCollection_Array1<T> (0, theSize - 1);
73     srand (1);
74     for (Standard_Integer anIdx = 0; anIdx < theSize; ++anIdx)
75     {
76       (*theCollec)->ChangeValue (anIdx) = rand();
77     }
78   }
79
80   static void Perform (StlType** theVector,
81     NCollection_Array1<T>** theCollec, Standard_Integer theSize = THE_TEST_SIZE)
82   {
83     CollectionFiller<NCollection_Array1<T>, StlType >::Perform (theCollec, theSize);
84
85     *theVector = new StlType ((*theCollec)->begin(), (*theCollec)->end());
86   }
87 };
88
89 template<class CollectionType, class T>
90 struct MapFiller
91 {
92   static void Perform (CollectionType** theCollec, Standard_Integer theSize = THE_TEST_SIZE)
93   {
94     *theCollec = new CollectionType();
95     srand(1);
96     for (Standard_Integer anIdx = 0; anIdx < theSize; ++anIdx)
97     {
98       (*theCollec)->Add (rand());
99     }
100   }
101 };
102
103 template<class T>
104 struct MapFiller<NCollection_DataMap<T, T>, T>
105 {
106   static void Perform (NCollection_DataMap<T, T>** theCollec1,
107     NCollection_DataMap<T, T>** theCollec2 = NULL, Standard_Integer theSize = THE_TEST_SIZE)
108   {
109     *theCollec1 = new NCollection_DataMap<T, T>();
110
111     if (theCollec2 != NULL)
112       *theCollec2 = new NCollection_DataMap<T, T>();
113     srand(1);
114     for (Standard_Integer anIdx = 0; anIdx < theSize; ++anIdx)
115     {
116       const T aVal1 = rand();
117       const T aVal2 = rand();
118
119       (*theCollec1)->Bind (aVal1, aVal2);
120
121       if (theCollec2 != NULL)
122         (*theCollec2)->Bind (aVal1, aVal2);
123     }
124   }
125 };
126
127 template<class T>
128 struct MapFiller<NCollection_IndexedDataMap<T, T>, T>
129 {
130   static void Perform (NCollection_IndexedDataMap<T, T>** theCollec1,
131     NCollection_IndexedDataMap<T, T>** theCollec2 = NULL, Standard_Integer theSize = THE_TEST_SIZE)
132   {
133     *theCollec1 = new NCollection_IndexedDataMap<T, T>();
134
135     if (theCollec2 != NULL)
136       *theCollec2 = new NCollection_IndexedDataMap<T, T>();
137     srand(1);
138     for (Standard_Integer anIdx = 0; anIdx < theSize; ++anIdx)
139     {
140       const T aVal1 = rand();
141       const T aVal2 = rand();
142
143       (*theCollec1)->Add (aVal1, aVal2);
144
145       if (theCollec2 != NULL)
146         (*theCollec2)->Add (aVal1, aVal2);
147     }
148   }
149 };
150
151 //=======================================================================
152 //function : TestIteration
153 //purpose  :
154 //=======================================================================
155 template<class CollectionType, class StlType>
156 Standard_Boolean TestIteration()
157 {
158   StlType* aVector (NULL);
159   CollectionType* aCollec (NULL);
160
161   CollectionFiller<CollectionType, StlType>::Perform (&aVector, &aCollec);
162
163   typename StlType::iterator aVecIter = aVector->begin();
164   typename CollectionType::iterator aColIter = aCollec->begin();
165
166   Standard_Boolean aResult (Standard_True);
167
168   for (; aVecIter != aVector->end(); ++aVecIter, ++aColIter)
169   {
170     if (*aVecIter != *aColIter)
171       aResult = Standard_False;
172   }
173
174   if (aColIter != aCollec->end())
175   {
176     aResult = Standard_False;
177   }
178
179   delete aVector;
180   delete aCollec;
181
182   return aResult;
183 }
184
185 //=======================================================================
186 //function : TestMinMax
187 //purpose  :
188 //=======================================================================
189 template<class CollectionType, class StlType>
190 Standard_Boolean TestMinMax()
191 {
192   StlType* aVector (NULL);
193   CollectionType* aCollec (NULL);
194
195   CollectionFiller<CollectionType, StlType>::Perform (&aVector, &aCollec);
196
197   typename StlType::value_type aValue1 = *std::min_element (aVector->begin(), aVector->end());
198   typename CollectionType::value_type aValue2 = *std::min_element (aCollec->begin(), aCollec->end());
199
200   Standard_Boolean aResult (Standard_True);
201
202   if (aValue1 != aValue2)
203     aResult = Standard_False;
204
205   aValue1 = *std::max_element (aVector->begin(), aVector->end());
206   aValue2 = *std::max_element (aCollec->begin(), aCollec->end());
207
208   if (aValue1 != aValue2)
209     aResult = Standard_False;
210
211   delete aVector;
212   delete aCollec;
213
214   return aResult;
215 }
216
217 //=======================================================================
218 //function : TestReplace
219 //purpose  :
220 //=======================================================================
221 template<class CollectionType, class StlType>
222 Standard_Boolean TestReplace()
223 {
224   StlType* aVector (NULL);
225   CollectionType* aCollec (NULL);
226
227   CollectionFiller<CollectionType, StlType>::Perform (&aVector, &aCollec);
228
229   const typename StlType::value_type aValue = aVector->back();
230
231   std::replace (aVector->begin(), aVector->end(), aValue, static_cast<typename StlType::value_type> (-1));
232   std::replace (aCollec->begin(), aCollec->end(), aValue, static_cast<typename CollectionType::value_type> (-1));
233
234   typename StlType::iterator aVecIter = aVector->begin();
235   typename CollectionType::iterator aColIter = aCollec->begin();
236
237   Standard_Boolean aResult (Standard_True);
238
239   for (; aVecIter != aVector->end(); ++aVecIter, ++aColIter)
240   {
241     if (*aVecIter != *aColIter)
242       aResult = Standard_False;
243   }
244
245   if (aColIter != aCollec->end())
246   {
247     aResult = Standard_False;
248   }
249
250   delete aVector;
251   delete aCollec;
252
253   return aResult;
254 }
255
256 //=======================================================================
257 //function : TestReverse
258 //purpose  :
259 //=======================================================================
260 template<class CollectionType, class StlType>
261 Standard_Boolean TestReverse()
262 {
263   StlType* aVector (NULL);
264   CollectionType* aCollec (NULL);
265
266   CollectionFiller<CollectionType, StlType>::Perform (&aVector, &aCollec);
267
268   std::reverse (aVector->begin(), aVector->end());
269   std::reverse (aCollec->begin(), aCollec->end());
270
271   typename StlType::iterator aVecIter = aVector->begin();
272   typename CollectionType::iterator aColIter = aCollec->begin();
273
274   Standard_Boolean aResult (Standard_True);
275
276   for (; aVecIter != aVector->end(); ++aVecIter, ++aColIter)
277   {
278     if (*aVecIter != *aColIter)
279       aResult = Standard_False;
280   }
281
282   if (aColIter != aCollec->end())
283   {
284     aResult = Standard_False;
285   }
286
287   delete aVector;
288   delete aCollec;
289
290   return aResult;
291 }
292
293 //=======================================================================
294 //function : TestSort
295 //purpose  :
296 //=======================================================================
297 template<class CollectionType, class StlType>
298 Standard_Boolean TestSort()
299 {
300   StlType* aVector (NULL);
301   CollectionType* aCollec (NULL);
302
303   CollectionFiller<CollectionType, StlType>::Perform (&aVector, &aCollec);
304
305   std::sort (aVector->begin(), aVector->end());
306   std::sort (aCollec->begin(), aCollec->end());
307
308   typename StlType::iterator aVecIter = aVector->begin();
309   typename CollectionType::iterator aColIter = aCollec->begin();
310
311   Standard_Boolean aResult (Standard_True);
312
313   for (; aVecIter != aVector->end(); ++aVecIter, ++aColIter)
314   {
315     if (*aVecIter != *aColIter)
316       aResult = Standard_False;
317   }
318
319   if (aColIter != aCollec->end())
320   {
321     aResult = Standard_False;
322   }
323
324   delete aVector;
325   delete aCollec;
326
327   return aResult;
328 }
329
330 template <typename T>
331 struct Invoker
332 {
333   void operator()(T& theValue) const
334   {
335     theValue *= 2;
336   }
337 };
338
339 //=======================================================================
340 //function : TestParallel
341 //purpose  :
342 //=======================================================================
343 template<class CollectionType, class StlType>
344 Standard_Boolean TestParallel()
345 {
346   StlType* aVector (NULL);
347   CollectionType* aCollec (NULL);
348
349   CollectionFiller<CollectionType, StlType>::Perform (&aVector, &aCollec);
350
351   OSD_Parallel::ForEach(aVector->begin(), aVector->end(), Invoker<typename StlType::value_type>());
352   OSD_Parallel::ForEach(aCollec->begin(), aCollec->end(), Invoker<typename CollectionType::value_type>());
353
354   typename StlType::iterator aVecIter = aVector->begin();
355   typename CollectionType::iterator aColIter = aCollec->begin();
356
357   Standard_Boolean aResult (Standard_True);
358
359   for (; aVecIter != aVector->end(); ++aVecIter, ++aColIter)
360   {
361     if (*aVecIter != *aColIter)
362       aResult = Standard_False;
363   }
364
365   if (aColIter != aCollec->end())
366   {
367     aResult = Standard_False;
368   }
369
370   delete aVector;
371   delete aCollec;
372
373   return aResult;
374 }
375
376 //=======================================================================
377 //function : TestDataMapParallel
378 //purpose  :
379 //=======================================================================
380 template<class CollectionType, class T>
381 Standard_Boolean TestDataMapParallel()
382 {
383   CollectionType* aCollec1 (NULL);
384   CollectionType* aCollec2 (NULL);
385
386   MapFiller<CollectionType, T>::Perform (&aCollec1, &aCollec2);
387
388   OSD_Parallel::ForEach(aCollec1->begin(), aCollec1->end(), Invoker<T>());
389
390   // create OCCT-style iterator
391   typename CollectionType::Iterator aOccIter (*aCollec2);
392
393   // create STL-compatible iterator
394   typename CollectionType::const_iterator aStlIter = aCollec1->cbegin();
395
396   Standard_Boolean aResult (Standard_True);
397
398   for (; aStlIter != aCollec1->cend(); ++aStlIter, aOccIter.Next())
399   {
400     if (static_cast<T> (2) * aOccIter.Value() != *aStlIter)
401       aResult = Standard_False;
402   }
403
404   if (aOccIter.More())
405   {
406     aResult = Standard_False;
407   }
408
409   delete aCollec1;
410   delete aCollec2;
411
412   return aResult;
413 }
414
415 //=======================================================================
416 //function : TestMapIteration
417 //purpose  :
418 //=======================================================================
419 template<class CollectionType, class T>
420 Standard_Boolean TestMapIteration()
421 {
422   CollectionType* aCollec (NULL);
423
424   MapFiller<CollectionType, T>::Perform (&aCollec);
425
426   // create OCCT-style iterator
427   typename CollectionType::Iterator aOccIter (*aCollec);
428
429   // create STL-compatible iterator
430   typename CollectionType::const_iterator aStlIter = aCollec->cbegin();
431
432   Standard_Boolean aResult (Standard_True);
433
434   for (; aStlIter != aCollec->cend(); ++aStlIter, aOccIter.Next())
435   {
436     if (aOccIter.Value() != *aStlIter)
437       aResult = Standard_False;
438   }
439
440   if (aOccIter.More())
441   {
442     aResult = Standard_False;
443   }
444
445   delete aCollec;
446
447   return aResult;
448 }
449
450 //=======================================================================
451 //function : TestForwardIterator
452 //purpose  : test basic features of iterator (forward)
453 //=======================================================================
454 template <class CollectionType>
455 void TestForwardIterator ()
456 {
457   CollectionType* aCollec (NULL);
458
459   CollectionFiller<CollectionType, void>::Perform (&aCollec);
460   
461   // test non-const iteration
462   typename CollectionType::iterator it = aCollec->begin(); // copy construction
463   typename CollectionType::iterator it2; // default constructor
464   it2 = it; // assignment
465   it2 = it++; // postfix increment
466   if (it2 == it || ! (it2 != it))
467     std::cout << "Failed " << typeid(it).name() << " equality check" << std::endl;
468   it2 = ++it; // prefix increment
469   if (it2 != it || ! (it2 == it))
470     std::cout << "Failed " << typeid(it).name() << " equality check" << std::endl;
471
472   typename CollectionType::iterator::value_type t = *it;
473   *it2 = t;
474   *(it2.operator-> ()) = t;
475
476   // test const iteration
477   typename CollectionType::const_iterator cit = aCollec->cbegin(); // copy construction
478   typename CollectionType::const_iterator cit2; // default constructor
479   cit2 = cit; // assignment
480   cit2 = cit++; // postfix increment
481   if (cit2 == cit || ! (cit2 != cit))
482     std::cout << "Failed " << typeid(cit).name() << " equality check" << std::endl;
483   cit2 = ++cit; // prefix increment
484   if (cit2 != it || ! (cit2 == cit))
485     std::cout << "Failed " << typeid(cit).name() << " equality check" << std::endl;
486
487   typename CollectionType::const_iterator::value_type ct = *cit;
488   ct = *cit;
489   (void)ct;
490 //  *cit2 = ct;
491 //  *(cit2.operator-> ()) = t;
492
493   delete aCollec;
494 }
495
496 //=======================================================================
497 //function : TestBidirIterator
498 //purpose  : test features of bidirectional iterator
499 //=======================================================================
500 template <class CollectionType>
501 void TestBidirIterator ()
502 {
503   CollectionType* aCollec (NULL);
504
505   CollectionFiller<CollectionType, void>::Perform (&aCollec);
506   
507   // test non-const iteration
508   typename CollectionType::iterator it = aCollec->end(); // copy construction
509   typename CollectionType::iterator it2 = it--; // postfix decrement
510   if (it2 == it || ! (it2 != it))
511     std::cout << "Failed " << typeid(it).name() << " equality check" << std::endl;
512   it2 = --it; // prefix decrement
513   if (it2 != it || ! (it2 == it))
514     std::cout << "Failed " << typeid(it).name() << " equality check" << std::endl;
515
516   delete aCollec;
517 }
518
519 //=======================================================================
520 //function : TestRandomIterator
521 //purpose  : test features of random iterator
522 //=======================================================================
523 template <class CollectionType>
524 void TestRandomIterator ()
525 {
526   CollectionType* aCollec (NULL);
527
528   CollectionFiller<CollectionType, void>::Perform (&aCollec);
529   
530   // test non-const iteration
531   typename CollectionType::iterator it = aCollec->begin(); // copy construction
532   typename CollectionType::iterator it2 = it + 5;
533   if ((it2 - it) != 5)
534     std::cout << "Failed " << typeid(it).name() << " arithmetics" << std::endl;
535   if (it2 < it || it2 <= it || ! (it2 > it) || ! (it2 >= it))
536     std::cout << "Failed " << typeid(it).name() << " comparison" << std::endl;
537   it += 5;
538   if (it2 != it)
539     std::cout << "Failed " << typeid(it).name() << " arithmetics" << std::endl;
540   it2 = it - 5;
541   if ((it2 - it) != -5)
542     std::cout << "Failed " << typeid(it).name() << " arithmetics" << std::endl;
543   if (it2 > it || it2 >= it || ! (it2 < it) || ! (it2 <= it))
544     std::cout << "Failed " << typeid(it).name() << " comparison" << std::endl;
545   it -= 5;
546   if (it2 != it)
547     std::cout << "Failed " << typeid(it).name() << " arithmetics" << std::endl;
548
549   typename CollectionType::value_type t = it[5]; // offset dereference
550   *it = t;
551
552   delete aCollec;
553 }
554
555 //=======================================================================
556 //function : QANListStlIterator
557 //purpose  :
558 //=======================================================================
559 static Standard_Integer QANListStlIterator (Draw_Interpretor&, Standard_Integer, const char**)
560 {
561   // compile-time tests
562   TestForwardIterator <NCollection_List<Standard_Integer> >();
563
564   // run-time tests
565   Standard_Boolean aResult = TestIteration<NCollection_List<int>, std::list<int> >();
566   std::cout << "NCollection_List<int> Iteration:                " <<
567     (aResult ? "SUCCESS" : "FAIL") << std::endl;
568
569   aResult = TestIteration<NCollection_List<double>, std::list<double> >();
570   std::cout << "NCollection_List<double> Iteration:             " <<
571     (aResult ? "SUCCESS" : "FAIL") << std::endl;
572
573   aResult = TestMinMax<NCollection_List<int>, std::list<int> >();
574   std::cout << "NCollection_List<int> Min-Max:                  " <<
575     (aResult ? "SUCCESS" : "FAIL") << std::endl;
576
577   aResult = TestMinMax<NCollection_List<double>, std::list<double> >();
578   std::cout << "NCollection_List<double> Min-Max:               " <<
579     (aResult ? "SUCCESS" : "FAIL") << std::endl;
580
581   aResult = TestReplace<NCollection_List<int>, std::list<int> >();
582   std::cout << "NCollection_List<int> Replace:                  " <<
583     (aResult ? "SUCCESS" : "FAIL") << std::endl;
584
585   aResult = TestReplace<NCollection_List<double>, std::list<double> >();
586   std::cout << "NCollection_List<double> Replace:               " <<
587     (aResult ? "SUCCESS" : "FAIL") << std::endl;
588
589   aResult = TestParallel< NCollection_List<int>, std::list<int> >();
590   std::cout << "NCollection_List<int> Parallel:                 " <<
591     (aResult ? "SUCCESS" : "FAIL") << std::endl;
592
593   aResult = TestParallel<NCollection_List<double>, std::list<double> >();
594   std::cout << "NCollection_List<double> Parallel:              " <<
595     (aResult ? "SUCCESS" : "FAIL") << std::endl;
596
597   return 0;
598 }
599
600 //=======================================================================
601 //function : QANMapStlIterator
602 //purpose  :
603 //=======================================================================
604 static Standard_Integer QANMapStlIterator (Draw_Interpretor&, Standard_Integer, const char**)
605 {
606   // compile-time tests
607 //  TestForwardIterator <NCollection_Map<Standard_Integer> >();
608
609   // run-time tests
610   Standard_Boolean aResult = TestMapIteration<NCollection_Map<Standard_Integer>, Standard_Integer>();
611   std::cout << "NCollection_Map<int> Iteration:                 " <<
612     (aResult ? "SUCCESS" : "FAIL") << std::endl;
613
614   aResult = TestMapIteration<NCollection_Map<Standard_Real>, Standard_Real>();
615   std::cout << "NCollection_Map<double> Iteration:              " <<
616     (aResult ? "SUCCESS" : "FAIL") << std::endl;
617
618   return 0;
619 }
620
621 //=======================================================================
622 //function : QANIndexedMapStlIterator
623 //purpose  :
624 //=======================================================================
625 static Standard_Integer QANIndexedMapStlIterator (Draw_Interpretor&, Standard_Integer, const char**)
626 {
627   // compile-time tests
628 //  TestForwardIterator <NCollection_IndexedMap<Standard_Integer> >();
629 //  TestBidirIterator <NCollection_IndexedMap<Standard_Integer> >();
630
631   // run-time tests
632   Standard_Boolean aResult = TestMapIteration<NCollection_IndexedMap<Standard_Integer>, Standard_Integer>();
633   std::cout << "NCollection_IndexedMap<int> Iteration:          " <<
634     (aResult ? "SUCCESS" : "FAIL") << std::endl;
635
636   aResult = TestMapIteration<NCollection_IndexedMap<Standard_Real>, Standard_Real>();
637   std::cout << "NCollection_IndexedMap<double> Iteration:       " <<
638     (aResult ? "SUCCESS" : "FAIL") << std::endl;
639
640   return 0;
641 }
642
643 //=======================================================================
644 //function : QANDataMapStlIterator
645 //purpose  :
646 //=======================================================================
647 static Standard_Integer QANDataMapStlIterator (Draw_Interpretor&, Standard_Integer, const char**)
648 {
649   // compile-time tests
650 //  TestForwardIterator <NCollection_DataMap<int, int> >();
651 //  TestBidirIterator <NCollection_DataMap<int, int> >();
652
653   // run-time tests
654   Standard_Boolean aResult = TestMapIteration<NCollection_DataMap<Standard_Integer, Standard_Integer>, Standard_Integer>();
655   std::cout << "NCollection_DataMap<int> Iteration:             " <<
656     (aResult ? "SUCCESS" : "FAIL") << std::endl;
657
658   aResult = TestMapIteration<NCollection_DataMap<Standard_Real, Standard_Real>, Standard_Real>();
659   std::cout << "NCollection_DataMap<double> Iteration:          " <<
660     (aResult ? "SUCCESS" : "FAIL") << std::endl;
661
662   aResult = TestDataMapParallel<NCollection_DataMap<Standard_Integer, Standard_Integer>, Standard_Integer>();
663   std::cout << "NCollection_DataMap<int> Parallel:              " <<
664     (aResult ? "SUCCESS" : "FAIL") << std::endl;
665
666   aResult = TestDataMapParallel<NCollection_DataMap<Standard_Real, Standard_Real>, Standard_Real>();
667   std::cout << "NCollection_DataMap<double> Parallel:           " <<
668     (aResult ? "SUCCESS" : "FAIL") << std::endl;
669
670   return 0;
671 }
672
673 //=======================================================================
674 //function : QANIndexedDataMapStlIterator
675 //purpose  :
676 //=======================================================================
677 static Standard_Integer QANIndexedDataMapStlIterator (Draw_Interpretor&, Standard_Integer, const char**)
678 {
679   // compile-time tests
680 //  TestForwardIterator <NCollection_IndexedDataMap<int, int> >();
681 //  TestBidirIterator <NCollection_IndexedDataMap<int, int> >();
682
683   // run-time tests
684   Standard_Boolean aResult = TestMapIteration<NCollection_IndexedDataMap<Standard_Integer, Standard_Integer>, Standard_Integer>();
685   std::cout << "NCollection_IndexedDataMap<int> Iteration:      " <<
686     (aResult ? "SUCCESS" : "FAIL") << std::endl;
687
688   aResult = TestMapIteration<NCollection_IndexedDataMap<Standard_Real, Standard_Real>, Standard_Real>();
689   std::cout << "NCollection_IndexedDataMap<double> Iteration:   " <<
690     (aResult ? "SUCCESS" : "FAIL") << std::endl;
691
692   aResult = TestDataMapParallel<NCollection_IndexedDataMap<Standard_Integer, Standard_Integer>, Standard_Integer>();
693   std::cout << "NCollection_IndexedDataMap<int> Parallel:       " <<
694     (aResult ? "SUCCESS" : "FAIL") << std::endl;
695
696   aResult = TestDataMapParallel<NCollection_IndexedDataMap<Standard_Real, Standard_Real>, Standard_Real>();
697   std::cout << "NCollection_IndexedDataMap<double> Parallel:    " <<
698     (aResult ? "SUCCESS" : "FAIL") << std::endl;
699
700   return 0;
701 }
702
703 //=======================================================================
704 //function : QANSequenceStlIterator
705 //purpose  :
706 //=======================================================================
707 static Standard_Integer QANSequenceStlIterator (Draw_Interpretor&, Standard_Integer, const char**)
708 {
709   // compile-time tests
710   TestForwardIterator <NCollection_Sequence<int> >();
711   TestBidirIterator <NCollection_Sequence<int> >();
712
713   // run-time tests
714   Standard_Boolean aResult = TestIteration<NCollection_Sequence<int>, std::list<int> >();
715   std::cout << "NCollection_Sequence<int> Iteration:            " <<
716     (aResult ? "SUCCESS" : "FAIL") << std::endl;
717
718   aResult = TestIteration<NCollection_Sequence<double>, std::list<double> >();
719   std::cout << "NCollection_Sequence<double> Iteration:         " <<
720     (aResult ? "SUCCESS" : "FAIL") << std::endl;
721
722   aResult = TestMinMax<NCollection_Sequence<int>, std::list<int> >();
723   std::cout << "NCollection_Sequence<int> Min-Max:              " <<
724     (aResult ? "SUCCESS" : "FAIL") << std::endl;
725
726   aResult = TestMinMax<NCollection_Sequence<double>, std::list<double> >();
727   std::cout << "NCollection_Sequence<double> Min-Max:           " <<
728     (aResult ? "SUCCESS" : "FAIL") << std::endl;
729
730   aResult = TestReplace<NCollection_Sequence<int>, std::list<int> >();
731   std::cout << "NCollection_Sequence<int> Replace:              " <<
732     (aResult ? "SUCCESS" : "FAIL") << std::endl;
733
734   aResult = TestReplace<NCollection_Sequence<double>, std::list<double> >();
735   std::cout << "NCollection_Sequence<double> Replace:           " <<
736     (aResult ? "SUCCESS" : "FAIL") << std::endl;
737
738   aResult = TestReverse<NCollection_Sequence<int>, std::list<int> >();
739   std::cout << "NCollection_Sequence<int> Reverse:              " <<
740     (aResult ? "SUCCESS" : "FAIL") << std::endl;
741
742   aResult = TestReverse<NCollection_Sequence<double>, std::list<double> >();
743   std::cout << "NCollection_Sequence<double> Reverse:           " <<
744     (aResult ? "SUCCESS" : "FAIL") << std::endl;
745
746   aResult = TestParallel<NCollection_Sequence<int>, std::list<int> >();
747   std::cout << "NCollection_Sequence<int> Parallel:             " <<
748     (aResult ? "SUCCESS" : "FAIL") << std::endl;
749
750   aResult = TestParallel<NCollection_Sequence<double>, std::list<double> >();
751   std::cout << "NCollection_Sequence<double> Parallel:          " <<
752     (aResult ? "SUCCESS" : "FAIL") << std::endl;
753
754   return 0;
755 }
756
757 //=======================================================================
758 //function : QANVectorStlIterator
759 //purpose  :
760 //=======================================================================
761 static Standard_Integer QANVectorStlIterator (Draw_Interpretor&, Standard_Integer, const char**)
762 {
763   // compile-time tests
764   TestForwardIterator <NCollection_Vector<int> >();
765   TestBidirIterator <NCollection_Vector<int> >();
766   TestRandomIterator <NCollection_Vector<int> >();
767
768   // run-time tests
769   Standard_Boolean aResult = TestIteration<NCollection_Vector<int>, std::vector<int> >();
770   std::cout << "NCollection_Vector<int> Iteration:              " <<
771     (aResult ? "SUCCESS" : "FAIL") << std::endl;
772
773   aResult = TestIteration<NCollection_Vector<double>, std::vector<double> >();
774   std::cout << "NCollection_Vector<double> Iteration:           " <<
775     (aResult ? "SUCCESS" : "FAIL") << std::endl;
776
777   aResult = TestMinMax<NCollection_Vector<int>, std::vector<int> >();
778   std::cout << "NCollection_Vector<int> Min-Max:                " <<
779     (aResult ? "SUCCESS" : "FAIL") << std::endl;
780
781   aResult = TestMinMax<NCollection_Vector<double>, std::vector<double> >();
782   std::cout << "NCollection_Vector<double> Min-Max:             " <<
783     (aResult ? "SUCCESS" : "FAIL") << std::endl;
784
785   aResult = TestReplace<NCollection_Vector<int>, std::vector<int> >();
786   std::cout << "NCollection_Vector<int> Replace:                " <<
787     (aResult ? "SUCCESS" : "FAIL") << std::endl;
788
789   aResult = TestReplace<NCollection_Vector<double>, std::vector<double> >();
790   std::cout << "NCollection_Vector<double> Replace:             " <<
791     (aResult ? "SUCCESS" : "FAIL") << std::endl;
792
793   aResult = TestReverse<NCollection_Vector<int>, std::vector<int> >();
794   std::cout << "NCollection_Vector<int> Reverse:                " <<
795     (aResult ? "SUCCESS" : "FAIL") << std::endl;
796
797   aResult = TestReverse<NCollection_Vector<double>, std::vector<double> >();
798   std::cout << "NCollection_Vector<double> Reverse:             " <<
799     (aResult ? "SUCCESS" : "FAIL") << std::endl;
800
801   aResult = TestSort<NCollection_Vector<int>, std::vector<int> >();
802   std::cout << "NCollection_Vector<int> Sort:                   " <<
803     (aResult ? "SUCCESS" : "FAIL") << std::endl;
804
805   aResult = TestSort<NCollection_Vector<double>, std::vector<double> >();
806   std::cout << "NCollection_Vector<double> Sort:                " <<
807     (aResult ? "SUCCESS" : "FAIL") << std::endl;
808
809   aResult = TestParallel<NCollection_Vector<int>, std::vector<int> >();
810   std::cout << "NCollection_Vector<int> Parallel:               " <<
811     (aResult ? "SUCCESS" : "FAIL") << std::endl;
812
813   aResult = TestParallel<NCollection_Vector<double>, std::vector<double> >();
814   std::cout << "NCollection_Vector<double> Parallel:            " <<
815     (aResult ? "SUCCESS" : "FAIL") << std::endl;
816
817   {
818     // Test case for a corner case described in a bug #0027941
819     // when vector length matches the increment.
820     // In this case NCollection_Vector::Iterator::Offset() produced mathematically equal
821     // but not the same iterator as returned by NCollection_Vector::end()
822     // so that their comparison was not equal.
823     // As result, std::stable_sort() crashed due to out-of-range access.
824     const int THE_INCREMENT = 256;
825     NCollection_Vector<int> aVector (THE_INCREMENT);
826     for (int anIter = 0; anIter < THE_INCREMENT; ++anIter)
827     {
828       aVector.Append (THE_INCREMENT - anIter);
829     }
830
831     NCollection_Vector<int>::iterator aBegin = aVector.begin();
832     NCollection_Vector<int>::iterator anEnd  = aVector.end();
833     NCollection_Vector<int>::iterator aShift = aBegin + THE_INCREMENT;
834     aResult = (aShift == anEnd);
835     std::cout << "NCollection_Vector<int> Offset:                 " <<
836       (aResult ? "SUCCESS" : "FAIL") << std::endl;
837
838     std::stable_sort (aVector.begin(), aVector.end());
839   }
840
841   return 0;
842 }
843
844 //=======================================================================
845 //function : QANArray1StlIterator
846 //purpose  :
847 //=======================================================================
848 static Standard_Integer QANArray1StlIterator (Draw_Interpretor&, Standard_Integer, const char**)
849 {
850   // compile-time tests
851   TestForwardIterator <NCollection_Vector<int> >();
852   TestBidirIterator <NCollection_Vector<int> >();
853   TestRandomIterator <NCollection_Vector<int> >();
854
855   // run-time tests
856   Standard_Boolean aResult = TestIteration<NCollection_Array1<int>, std::vector<int> >();
857   std::cout << "NCollection_Array1<int> Iteration:              " <<
858     (aResult ? "SUCCESS" : "FAIL") << std::endl;
859
860   aResult = TestIteration<NCollection_Array1<double>, std::vector<double> >();
861   std::cout << "NCollection_Array1<double> Iteration:           " <<
862     (aResult ? "SUCCESS" : "FAIL") << std::endl;
863
864   aResult = TestMinMax<NCollection_Array1<int>, std::vector<int> >();
865   std::cout << "NCollection_Array1<int> Min-Max:                " <<
866     (aResult ? "SUCCESS" : "FAIL") << std::endl;
867
868   aResult = TestMinMax<NCollection_Array1<double>, std::vector<double> >();
869   std::cout << "NCollection_Array1<double> Min-Max:             " <<
870     (aResult ? "SUCCESS" : "FAIL") << std::endl;
871
872   aResult = TestReplace<NCollection_Array1<int>, std::vector<int> >();
873   std::cout << "NCollection_Array1<int> Replace:                " <<
874     (aResult ? "SUCCESS" : "FAIL") << std::endl;
875
876   aResult = TestReplace<NCollection_Array1<double>, std::vector<double> >();
877   std::cout << "NCollection_Array1<double> Replace:             " <<
878     (aResult ? "SUCCESS" : "FAIL") << std::endl;
879
880   aResult = TestReverse<NCollection_Array1<int>, std::vector<int> >();
881   std::cout << "NCollection_Array1<int> Reverse:                " <<
882     (aResult ? "SUCCESS" : "FAIL") << std::endl;
883
884   aResult = TestReverse<NCollection_Array1<double>, std::vector<double> >();
885   std::cout << "NCollection_Array1<double> Reverse:             " <<
886     (aResult ? "SUCCESS" : "FAIL") << std::endl;
887
888   aResult = TestSort<NCollection_Array1<int>, std::vector<int> >();
889   std::cout << "NCollection_Array1<int> Sort:                   " <<
890     (aResult ? "SUCCESS" : "FAIL") << std::endl;
891
892   aResult = TestSort<NCollection_Array1<double>, std::vector<double> >();
893   std::cout << "NCollection_Array1<double> Sort:                " <<
894     (aResult ? "SUCCESS" : "FAIL") << std::endl;
895
896   aResult = TestParallel<NCollection_Array1<int>, std::vector<int> >();
897   std::cout << "NCollection_Array1<int> Parallel:               " <<
898     (aResult ? "SUCCESS" : "FAIL") << std::endl;
899
900   aResult = TestParallel<NCollection_Array1<double>, std::vector<double> >();
901   std::cout << "NCollection_Array1<double> Parallel:            " <<
902     (aResult ? "SUCCESS" : "FAIL") << std::endl;
903
904   return 0;
905 }
906
907 //=======================================================================
908 //function : QANTestStlIterators
909 //purpose  :
910 //=======================================================================
911 static Standard_Integer QANTestStlIterators (
912   Draw_Interpretor& theInterpretor, Standard_Integer, const char**)
913 {
914   QANListStlIterator           (theInterpretor, 0, NULL);
915   QANArray1StlIterator         (theInterpretor, 0, NULL);
916   QANVectorStlIterator         (theInterpretor, 0, NULL);
917   QANSequenceStlIterator       (theInterpretor, 0, NULL);
918   QANMapStlIterator            (theInterpretor, 0, NULL);
919   QANDataMapStlIterator        (theInterpretor, 0, NULL);
920   QANIndexedMapStlIterator     (theInterpretor, 0, NULL);
921   QANIndexedDataMapStlIterator (theInterpretor, 0, NULL);
922
923   return 0;
924 }
925
926 //=======================================================================
927 //function : TestPerformanceRandomIterator
928 //purpose  :
929 //=======================================================================
930 template<class CollectionType, class StlType>
931 void TestPerformanceRandomIterator(Draw_Interpretor& di)
932 {
933   OSD_Timer aTimer;
934
935   StlType* aVector (NULL);
936   CollectionType* aCollec (NULL);
937
938   for (Standard_Integer aSize = 10000; aSize <= 1280000; aSize *= 2)
939   {
940     CollectionFiller<CollectionType, StlType>::Perform (&aVector, &aCollec, aSize);
941
942     aTimer.Reset();
943     aTimer.Start();
944     {
945       std::random_device ran_dev;
946       std::mt19937 gen(ran_dev());
947       gen.seed(0x03ac38f2);
948       for (Standard_Integer anIdx = 0; anIdx < 10; ++anIdx)
949       {
950         std::sort    (aVector->begin(), aVector->end());
951         std::shuffle (aVector->begin(), aVector->end(), gen);
952       }
953     }
954     aTimer.Stop();
955
956     Standard_Real aStlTime = aTimer.ElapsedTime();
957
958     aTimer.Reset();
959     aTimer.Start();
960     {
961       std::random_device ran_dev;
962       std::mt19937 gen(ran_dev());
963       gen.seed(0x03ac38f2);
964       for (Standard_Integer anIdx = 0; anIdx < 10; ++anIdx)
965       {
966         std::sort    (aCollec->begin(), aCollec->end());
967         std::shuffle (aCollec->begin(), aCollec->end(), gen);
968       }
969     }
970     aTimer.Stop();
971
972     Standard_Real aOccTime = aTimer.ElapsedTime();
973
974     di << aSize << "\t" << aStlTime << "\t" <<
975       aOccTime << "\t" << aOccTime / aStlTime << "\n";
976
977     // check that result is the same
978     if ( ! std::equal (aVector->begin(), aVector->end(), aCollec->begin()) )
979       di << "Error: sequences are not the same at the end (random iterator)!\n";
980
981     delete aVector;
982     delete aCollec;
983   }
984 }
985
986 //=======================================================================
987 //function : TestPerformanceForwardIterator
988 //purpose  :
989 //=======================================================================
990 template<class CollectionType, class StlType>
991 void TestPerformanceForwardIterator(Draw_Interpretor& di)
992 {
993   OSD_Timer aTimer;
994
995   StlType* aVector = 0;
996   CollectionType* aCollec = 0;
997
998   for (Standard_Integer aSize = 10000; aSize <= 1280000; aSize *= 2)
999   {
1000     CollectionFiller<CollectionType, StlType>::Perform (&aVector, &aCollec, aSize);
1001
1002     aTimer.Reset();
1003     aTimer.Start();
1004     {
1005       for (Standard_Integer anIdx = 0; anIdx < 1000; ++anIdx)
1006       {
1007         std::replace (aVector->begin(), aVector->end(), *aVector->begin(), static_cast<typename StlType::value_type> (anIdx));
1008       }
1009     }
1010     aTimer.Stop();
1011
1012     Standard_Real aStlTime = aTimer.ElapsedTime();
1013
1014     aTimer.Reset();
1015     aTimer.Start();
1016     {
1017       for (Standard_Integer anIdx = 0; anIdx < 1000; ++anIdx)
1018       {
1019         std::replace (aCollec->begin(), aCollec->end(), *aCollec->begin(), static_cast<typename CollectionType::value_type> (anIdx));
1020       }
1021     }
1022     aTimer.Stop();
1023
1024     Standard_Real aOccTime = aTimer.ElapsedTime();
1025
1026     di << aSize << "\t" << aStlTime << "\t" <<
1027       aOccTime << "\t" << aOccTime / aStlTime << "\n";
1028
1029     // check that result is the same
1030     if ( ! std::equal (aVector->begin(), aVector->end(), aCollec->begin()) )
1031       di << "Error: sequences are not the same at the end (forward iterator)!\n";
1032
1033     delete aVector;
1034     delete aCollec;
1035   }
1036 }
1037
1038 //=======================================================================
1039 //function : TestPerformanceBidirIterator
1040 //purpose  :
1041 //=======================================================================
1042 template<class CollectionType, class StlType>
1043 void TestPerformanceBidirIterator(Draw_Interpretor& di)
1044 {
1045   OSD_Timer aTimer;
1046
1047   StlType* aVector = 0;
1048   CollectionType* aCollec = 0;
1049
1050   for (Standard_Integer aSize = 10000; aSize <= 1280000; aSize *= 2)
1051   {
1052     CollectionFiller<CollectionType, StlType>::Perform (&aVector, &aCollec, aSize);
1053
1054     aTimer.Reset();
1055     aTimer.Start();
1056     {
1057       for (Standard_Integer anIdx = 0; anIdx < 1000; ++anIdx)
1058       {
1059         std::reverse (aVector->begin(), aVector->end());
1060       }
1061     }
1062     aTimer.Stop();
1063
1064     Standard_Real aStlTime = aTimer.ElapsedTime();
1065
1066     aTimer.Reset();
1067     aTimer.Start();
1068     {
1069       for (Standard_Integer anIdx = 0; anIdx < 1000; ++anIdx)
1070       {
1071         std::reverse (aCollec->begin(), aCollec->end());
1072       }
1073     }
1074     aTimer.Stop();
1075
1076     Standard_Real aOccTime = aTimer.ElapsedTime();
1077
1078     di << aSize << "\t" << aStlTime << "\t" <<
1079       aOccTime << "\t" << aOccTime / aStlTime << "\n";
1080
1081     // check that result is the same
1082     if ( ! std::equal (aVector->begin(), aVector->end(), aCollec->begin()) )
1083       di << "Error: sequences are not the same at the end (bidir iterator)!\n";
1084
1085     delete aVector;
1086     delete aCollec;
1087   }
1088 }
1089
1090 //=======================================================================
1091 //function : TestPerformanceMapAccess
1092 //purpose  :
1093 //=======================================================================
1094 template<class CollectionType, class T>
1095 void TestPerformanceMapAccess(Draw_Interpretor& di)
1096 {
1097   OSD_Timer aTimer;
1098
1099   CollectionType* aCollec (NULL);
1100
1101   for (Standard_Integer aSize = 100000; aSize <= 3200000; aSize *= 2)
1102   {
1103     MapFiller<CollectionType, T>::Perform (&aCollec, aSize);
1104
1105     std::set<T>    aSet (aCollec->cbegin(), aCollec->cend());
1106     std::vector<T> aVec (aCollec->cbegin(), aCollec->cend());
1107
1108     Standard_Boolean aResult = Standard_True;
1109
1110     aTimer.Reset();
1111     aTimer.Start();
1112     {
1113       for (size_t anIdx = 0; anIdx < 10000; ++anIdx)
1114       {
1115         if (aSet.find (aVec[anIdx + 1000]) == aSet.end())
1116           aResult = Standard_False;
1117         if (aSet.find (aVec[anIdx + 2000]) == aSet.end())
1118           aResult = Standard_False;
1119         if (aSet.find (aVec[anIdx + 3000]) == aSet.end())
1120           aResult = Standard_False;
1121         if (aSet.find (aVec[anIdx + 4000]) == aSet.end())
1122           aResult = Standard_False;
1123         if (aSet.find (aVec[anIdx + 5000]) == aSet.end())
1124           aResult = Standard_False;
1125       }
1126     }
1127     aTimer.Stop();
1128
1129     Standard_Real aStlTime = aTimer.ElapsedTime();
1130
1131     aTimer.Reset();
1132     aTimer.Start();
1133     {
1134       for (size_t anIdx = 0; anIdx < 10000; ++anIdx)
1135       {
1136         if (!aCollec->Contains (aVec[anIdx + 1000]))
1137           aResult = Standard_False;
1138         if (!aCollec->Contains (aVec[anIdx + 2000]))
1139           aResult = Standard_False;
1140         if (!aCollec->Contains (aVec[anIdx + 3000]))
1141           aResult = Standard_False;
1142         if (!aCollec->Contains (aVec[anIdx + 4000]))
1143           aResult = Standard_False;
1144         if (!aCollec->Contains (aVec[anIdx + 5000]))
1145           aResult = Standard_False;
1146       }
1147     }
1148     aTimer.Stop();
1149
1150     Standard_Real aOccTime = aTimer.ElapsedTime();
1151
1152     if (aResult)
1153     {
1154       di << aSize << "\t" << aStlTime << "\t" <<
1155         aOccTime << "\t" << (aStlTime > 1e-16 ? aOccTime / aStlTime : -1) << "\n";
1156     }
1157
1158     delete aCollec;
1159   }
1160 }
1161
1162 //=======================================================================
1163 //function : QANTestNCollectionPerformance
1164 //purpose  :
1165 //=======================================================================
1166 static Standard_Integer QANTestNCollectionPerformance (Draw_Interpretor& di, Standard_Integer, const char**)
1167 {
1168   di << "Testing performance (Size | STL time | OCCT time | STL/OCCT boost)\n";
1169
1170   di << "\nstd::vector vs NCollection_Array1 (sort):\n\n";
1171   TestPerformanceRandomIterator<NCollection_Array1<double>, std::vector<double> >(di);
1172
1173   di << "\nstd::vector vs NCollection_Vector (sort):\n\n";
1174   TestPerformanceRandomIterator<NCollection_Vector<double>, std::vector<double> >(di);
1175
1176   di << "\nstd::vector vs NCollection_Array1 (replace):\n\n";
1177   TestPerformanceForwardIterator<NCollection_Array1<double>, std::vector<double> >(di);
1178
1179   di << "\nstd::vector vs NCollection_Vector (replace):\n\n";
1180   TestPerformanceForwardIterator<NCollection_Vector<double>, std::vector<double> >(di);
1181
1182   di << "\nstd::list vs NCollection_List (replace):\n\n";
1183   TestPerformanceForwardIterator<NCollection_List<double>, std::list<double> >(di);
1184
1185   di << "\nstd::list vs NCollection_Sequence (replace):\n\n";
1186   TestPerformanceForwardIterator<NCollection_Sequence<double>, std::list<double> >(di);
1187
1188   di << "\nstd::list vs NCollection_Sequence (reverse):\n\n";
1189   TestPerformanceBidirIterator<NCollection_Sequence<double>, std::list<double> >(di);
1190
1191   di << "\nstd::set vs NCollection_Map (search):\n\n";
1192   TestPerformanceMapAccess<NCollection_Map<int>, int>(di);
1193
1194   di << "\nstd::set vs NCollection_IndexedMap (search):\n\n";
1195   TestPerformanceMapAccess<NCollection_IndexedMap<int>, int>(di);
1196
1197   return 0;
1198 }
1199
1200 //=======================================================================
1201 //function : QANTestNCollectionIndexedMap
1202 //purpose  :
1203 //=======================================================================
1204 static Standard_Integer QANTestNCollectionIndexedMap (Draw_Interpretor& di, Standard_Integer, const char**)
1205 {
1206   OSD_Timer aTimer;
1207
1208   std::vector<Standard_Integer>            aIndxs;
1209   std::vector<Standard_Integer>            aItems;
1210   NCollection_IndexedMap<Standard_Integer> aIndxMap;
1211
1212   const Standard_Integer aNbItems = 1000000;
1213
1214   srand (1);
1215   for (Standard_Integer anId = 1; anId <= aNbItems; ++anId)
1216   {
1217     const Standard_Integer aVal = anId * 2;
1218
1219     aIndxs.push_back (anId);
1220     aItems.push_back (aVal);
1221
1222     aIndxMap.Add  (aVal);
1223   }
1224
1225   aTimer.Start();
1226   for (Standard_Integer anId = 0; anId < aNbItems; ++anId)
1227   {
1228     if (aIndxMap.FindIndex (aItems[anId]) != aIndxs[anId])
1229     {
1230       std::cout << "failed FindIndex\n";
1231     }
1232
1233     if (aIndxMap.FindKey (aIndxs[anId]) != aItems[anId])
1234     {
1235       std::cout << "failed FindKey\n";
1236     }
1237   }
1238   aTimer.Stop();
1239
1240   const Standard_Real aTime1 = aTimer.ElapsedTime();
1241
1242   aTimer.Reset();
1243   aTimer.Start();
1244   for (Standard_Integer anId = 0; anId < aNbItems / 30; ++anId)
1245   {
1246     const Standard_Integer anId2 = Min (aNbItems - 1,
1247       static_cast<Standard_Integer> (rand() / float (RAND_MAX) * aNbItems));
1248
1249     aIndxMap.Swap (aIndxs[anId], aIndxs[anId2]);
1250
1251     std::swap (aIndxs[anId], aIndxs[anId2]);
1252   }
1253   aTimer.Stop();
1254
1255   const Standard_Real aTime2 = aTimer.ElapsedTime();
1256
1257   aTimer.Reset();
1258   aTimer.Start();
1259   for (Standard_Integer anId = 0; anId < aNbItems; ++anId)
1260   {
1261     if (aIndxMap.FindIndex (aItems[anId]) != aIndxs[anId])
1262     {
1263       std::cout << "failed FindIndex\n";
1264     }
1265
1266     if (aIndxMap.FindKey (aIndxs[anId]) != aItems[anId])
1267     {
1268       std::cout << "failed FindKey\n";
1269     }
1270   }
1271   aTimer.Stop();
1272
1273   const Standard_Real aTime3 = aTimer.ElapsedTime();
1274
1275   aTimer.Reset();
1276   aTimer.Start();
1277   for (Standard_Integer anId = 0; anId < aNbItems; ++anId)
1278   {
1279     aIndxMap.RemoveLast();
1280   }
1281   aTimer.Stop();
1282
1283   const Standard_Real aTime4 = aTimer.ElapsedTime();
1284
1285   di << "Search time 1: " << aTime1 << "\n"
1286      << "Swapping time: " << aTime2 << "\n"
1287      << "Search time 2: " << aTime3 << "\n"
1288      << "Remove   time: " << aTime4 << "\n";
1289
1290   return 0;
1291 }
1292
1293 //=======================================================================
1294 //function : QANTestNCollectionIndexedDataMap
1295 //purpose  :
1296 //=======================================================================
1297 static Standard_Integer QANTestNCollectionIndexedDataMap (Draw_Interpretor& di, Standard_Integer, const char**)
1298 {
1299   OSD_Timer aTimer;
1300
1301   std::vector<Standard_Integer>                                  aIndxs;
1302   std::vector<Standard_Integer>                                  aItems;
1303   NCollection_IndexedDataMap<Standard_Integer, Standard_Integer> aIndxMap;
1304
1305   const Standard_Integer aNbItems = 1000000;
1306
1307   srand (1);
1308   for (Standard_Integer anId = 1; anId <= aNbItems; ++anId)
1309   {
1310     const Standard_Integer aVal = anId * 2;
1311
1312     aIndxs.push_back (anId);
1313     aItems.push_back (aVal);
1314
1315     aIndxMap.Add  (aVal, aVal * 2);
1316   }
1317
1318   aTimer.Start();
1319   for (Standard_Integer anId = 0; anId < aNbItems; ++anId)
1320   {
1321     if (aIndxMap.FindIndex (aItems[anId]) != aIndxs[anId])
1322     {
1323       std::cout << "failed FindIndex\n";
1324     }
1325
1326     if (aIndxMap.FindKey (aIndxs[anId]) != aItems[anId])
1327     {
1328       std::cout << "failed FindKey\n";
1329     }
1330   }
1331   aTimer.Stop();
1332
1333   const Standard_Real aTime1 = aTimer.ElapsedTime();
1334
1335   aTimer.Reset();
1336   aTimer.Start();
1337   for (Standard_Integer anId = 0; anId < aNbItems / 30; ++anId)
1338   {
1339     const Standard_Integer anId2 = Min (aNbItems - 1,
1340       static_cast<Standard_Integer> (rand() / float (RAND_MAX) * aNbItems));
1341
1342     aIndxMap.Swap (aIndxs[anId], aIndxs[anId2]);
1343
1344     std::swap (aIndxs[anId], aIndxs[anId2]);
1345   }
1346   aTimer.Stop();
1347
1348   const Standard_Real aTime2 = aTimer.ElapsedTime();
1349
1350   aTimer.Reset();
1351   aTimer.Start();
1352   for (Standard_Integer anId = 0; anId < aNbItems; ++anId)
1353   {
1354     if (aIndxMap.FindIndex (aItems[anId]) != aIndxs[anId])
1355     {
1356       std::cout << "failed FindIndex\n";
1357     }
1358
1359     if (aIndxMap.FindKey (aIndxs[anId]) != aItems[anId])
1360     {
1361       std::cout << "failed FindKey\n";
1362     }
1363   }
1364   aTimer.Stop();
1365
1366   const Standard_Real aTime3 = aTimer.ElapsedTime();
1367
1368   aTimer.Reset();
1369   aTimer.Start();
1370   for (Standard_Integer anId = 0; anId < aNbItems; ++anId)
1371   {
1372     aIndxMap.RemoveLast();
1373   }
1374   aTimer.Stop();
1375
1376   const Standard_Real aTime4 = aTimer.ElapsedTime();
1377
1378   di << "Search time 1: " << aTime1 << "\n"
1379      << "Swapping time: " << aTime2 << "\n"
1380      << "Search time 2: " << aTime3 << "\n"
1381      << "Remove   time: " << aTime4 << "\n";
1382
1383   return 0;
1384 }
1385
1386 //=======================================================================
1387 //function : CommandsStl
1388 //purpose  :
1389 //=======================================================================
1390 void QANCollection::CommandsStl (Draw_Interpretor& theCommands)
1391 {
1392   const char* aGroup = "QANCollection";
1393
1394   theCommands.Add ("QANArray1StlIterator",
1395                    "QANArray1StlIterator",
1396                    __FILE__,
1397                    QANArray1StlIterator,
1398                    aGroup);
1399
1400   theCommands.Add ("QANListStlIterator",
1401                    "QANListStlIterator",
1402                    __FILE__,
1403                    QANListStlIterator,
1404                    aGroup);
1405
1406   theCommands.Add ("QANSequenceStlIterator",
1407                    "QANSequenceStlIterator",
1408                    __FILE__,
1409                    QANSequenceStlIterator,
1410                    aGroup);
1411
1412   theCommands.Add ("QANVectorStlIterator",
1413                    "QANVectorStlIterator",
1414                    __FILE__,
1415                    QANVectorStlIterator,
1416                    aGroup);
1417
1418   theCommands.Add ("QANMapStlIterator",
1419                    "QANMapStlIterator",
1420                    __FILE__,
1421                    QANMapStlIterator,
1422                    aGroup);
1423
1424   theCommands.Add ("QANDataMapStlIterator",
1425                    "QANDataMapStlIterator",
1426                    __FILE__,
1427                    QANDataMapStlIterator,
1428                    aGroup);
1429
1430   theCommands.Add ("QANIndexedMapStlIterator",
1431                    "QANIndexedMapStlIterator",
1432                    __FILE__,
1433                    QANIndexedMapStlIterator,
1434                    aGroup);
1435
1436   theCommands.Add ("QANIndexedDataMapStlIterator",
1437                    "QANIndexedDataMapStlIterator",
1438                    __FILE__,
1439                    QANIndexedDataMapStlIterator,
1440                    aGroup);
1441
1442   theCommands.Add ("QANTestStlIterators",
1443                    "QANTestStlIterators",
1444                    __FILE__,
1445                    QANTestStlIterators,
1446                    aGroup);
1447
1448   theCommands.Add ("QANTestNCollectionPerformance",
1449                    "QANTestNCollectionPerformance",
1450                    __FILE__,
1451                    QANTestNCollectionPerformance,
1452                    aGroup);
1453
1454   theCommands.Add ("QANTestNCollectionIndexedMap",
1455                    "QANTestNCollectionIndexedMap",
1456                    __FILE__,
1457                    QANTestNCollectionIndexedMap,
1458                    aGroup);
1459
1460   theCommands.Add ("QANTestNCollectionIndexedDataMap",
1461                    "QANTestNCollectionIndexedDataMap",
1462                    __FILE__,
1463                    QANTestNCollectionIndexedDataMap,
1464                    aGroup);
1465
1466   return;
1467 }