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