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