0029399: Optimize reading of floating point values from text strings
[occt.git] / src / QANCollection / QANCollection_Test.cxx
CommitLineData
3a01a933 1// Created on: 2004-03-05
2// Created by: Mikhail KUZMITCHEV
3// Copyright (c) 2004-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 <QANCollection_Common.hxx>
18
19#include <Draw.hxx>
20#include <Draw_Interpretor.hxx>
21
22#include <gp_Pnt.hxx>
23
985aed12 24#include <Precision.hxx>
07bbde45 25#include <Standard_Overflow.hxx>
985aed12 26
e3a6386d 27#include <NCollection_Vector.hxx>
28
3a01a933 29#define ItemType gp_Pnt
30#define Key1Type Standard_Real
31#define Key2Type Standard_Integer
32
33#include <NCollection_DefineArray1.hxx>
34#include <NCollection_DefineHArray1.hxx>
35////////////////////////////////DEFINE_ARRAY1(QANCollection_Array1,QANCollection_BaseCol,ItemType)
36////////////////////////////////DEFINE_HARRAY1(QANCollection_HArray1,QANCollection_Array1)
37DEFINE_ARRAY1(QANCollection_Array1Func,QANCollection_BaseColFunc,ItemType)
38DEFINE_HARRAY1(QANCollection_HArray1Func,QANCollection_Array1Func)
3a01a933 39
40#include <NCollection_DefineArray2.hxx>
41#include <NCollection_DefineHArray2.hxx>
42////////////////////////////////DEFINE_ARRAY2(QANCollection_Array2,QANCollection_BaseCol,ItemType)
43////////////////////////////////DEFINE_HARRAY2(QANCollection_HArray2,QANCollection_Array2)
44DEFINE_ARRAY2(QANCollection_Array2Func,QANCollection_BaseColFunc,ItemType)
45DEFINE_HARRAY2(QANCollection_HArray2Func,QANCollection_Array2Func)
3a01a933 46
47#include <NCollection_DefineMap.hxx>
48#include <NCollection_DefineDataMap.hxx>
49#include <NCollection_DefineDoubleMap.hxx>
50#include <NCollection_DefineIndexedMap.hxx>
51#include <NCollection_DefineIndexedDataMap.hxx>
52////////////////////////////////DEFINE_MAP(QANCollection_Map,QANCollection_Key1BaseCol,Key1Type)
53////////////////////////////////DEFINE_DATAMAP(QANCollection_DataMap,QANCollection_BaseCol,Key1Type,ItemType)
54////////////////////////////////DEFINE_DOUBLEMAP(QANCollection_DoubleMap,QANCollection_Key2BaseCol,Key1Type,Key2Type)
55////////////////////////////////DEFINE_INDEXEDMAP(QANCollection_IndexedMap,QANCollection_Key1BaseCol,Key1Type)
56////////////////////////////////DEFINE_INDEXEDDATAMAP(QANCollection_IDMap,QANCollection_BaseCol,Key1Type,ItemType)
57DEFINE_MAP(QANCollection_MapFunc,QANCollection_Key1BaseColFunc,Key1Type)
58DEFINE_DATAMAP(QANCollection_DataMapFunc,QANCollection_BaseColFunc,Key1Type,ItemType)
59DEFINE_DOUBLEMAP(QANCollection_DoubleMapFunc,QANCollection_Key2BaseColFunc,Key1Type,Key2Type)
60DEFINE_INDEXEDMAP(QANCollection_IndexedMapFunc,QANCollection_Key1BaseColFunc,Key1Type)
61DEFINE_INDEXEDDATAMAP(QANCollection_IDMapFunc,QANCollection_BaseColFunc,Key1Type,ItemType)
62
63#include <NCollection_DefineList.hxx>
64////////////////////////////////DEFINE_LIST(QANCollection_List,QANCollection_BaseCol,ItemType)
65DEFINE_LIST(QANCollection_ListFunc,QANCollection_BaseColFunc,ItemType)
66
67#include <NCollection_DefineSequence.hxx>
68#include <NCollection_DefineHSequence.hxx>
69////////////////////////////////DEFINE_SEQUENCE(QANCollection_Sequence,QANCollection_BaseCol,ItemType)
70////////////////////////////////DEFINE_HSEQUENCE(QANCollection_HSequence,QANCollection_Sequence)
71DEFINE_SEQUENCE(QANCollection_SequenceFunc,QANCollection_BaseColFunc,ItemType)
72DEFINE_HSEQUENCE(QANCollection_HSequenceFunc,QANCollection_SequenceFunc)
3a01a933 73
74// HashCode and IsEquel must be defined for key types of maps
75Standard_Integer HashCode(const gp_Pnt thePnt, int theUpper)
76{
77 return HashCode(thePnt.X(),theUpper);
78}
79
80Standard_Boolean IsEqual(const gp_Pnt& theP1, const gp_Pnt& theP2)
81{
82 return theP1.IsEqual(theP2,gp::Resolution());
83}
84
85////////////////////////////////void printCollection (QANCollection_Key1BaseCol& aColl,
86template <class Coll>
87void printCollection (Coll& aColl, const char * str)
88{
89 printf ("%s:\n",str);
90 Standard_Integer iSize = aColl.Size();
91 ////////////////////////////////QANCollection_Key1BaseCol::Iterator& anIter = aColl.CreateIterator();
92 typename Coll::Iterator anIter (aColl);
93 if (!anIter.More())
94 {
95 if (iSize==0)
96 printf (" <Empty collection>\n");
97 else
98 printf ("Error : empty collection has size==%d",iSize);
99 }
100 else
101 {
102 printf (" Size==%d\n",iSize);
103 for (; anIter.More(); anIter.Next())
104 PrintItem(anIter.Value());
105 }
106}
107
108////////////////////////////////void AssignCollection (QANCollection_BaseCol& aCollSrc,
109//////////////////////////////// QANCollection_BaseCol& aCollDst)
110template <class Coll>
111void AssignCollection (Coll& aCollSrc, Coll& aCollDst)
112{
113 printCollection (aCollSrc,"Source collection");
114 aCollDst.Assign(aCollSrc);
115 printCollection (aCollDst,"Target collection");
116}
117
118// ===================== Test methods of Array1 type ==========================
119////////////////////////////////void TestArray1 (QANCollection_Array1& theA1)
120static void TestArray1 (QANCollection_Array1Func& theA1)
121{
122 // Bounds
123 Standard_Integer iLow=theA1.Lower();
124 Standard_Integer iUpp=theA1.Upper();
125 Standard_Integer i;
126
127 printf ("Info: testing Array1(%d,%d), %s\n",
128 iLow, iUpp, (theA1.IsDeletable()?"deletable":"frozen"));
129 // C-array constructor, Length, Init
130 ItemType anItem;
131 Random(anItem);
132 theA1.Init (anItem);
133 ItemType * rBlock = new ItemType[theA1.Length()];
134 ////////////////////////////////QANCollection_Array1 aCArr(*rBlock, iLow-100, iUpp-100);
135 QANCollection_Array1Func aCArr(*rBlock, iLow-100, iUpp-100);
136 printf (" created the same sized preallocated array (%d,%d), %s\n",
137 aCArr.Lower(),aCArr.Upper(),(aCArr.IsDeletable()?"deletable":"frozen"));
138 // *Value, operator()
139 for (i=iLow+1; i<iUpp; i++)
140 {
141 Random (aCArr.ChangeValue (i-101));
142 aCArr.SetValue (i-100, ItemType(aCArr.Value(i-101)));
143 aCArr(i-99) = aCArr(i-100) = aCArr(i-101);
144 }
145 // Handle, copy constructor (including operator=)
146 ////////////////////////////////Handle(QANCollection_HArray1) aHa = new QANCollection_HArray1(aCArr);
147 Handle(QANCollection_HArray1Func) aHa = new QANCollection_HArray1Func(aCArr);
148 // Assign
149 AssignCollection (aHa->ChangeArray1(), theA1);
150}
151
152// ===================== Test methods of Array2 type ==========================
153////////////////////////////////void TestArray2 (QANCollection_Array2& theA2)
154static void TestArray2 (QANCollection_Array2Func& theA2)
155{
156 // Bounds
157 Standard_Integer iLR=theA2.LowerRow(), iLC=theA2.LowerCol();
158 Standard_Integer iUR=theA2.UpperRow(), iUC=theA2.UpperCol();
159 Standard_Integer i,j;
160
161 printf ("Info: testing Array2 (%d,%d)(%d,%d), %s\n",
162 iLR, iUR, iLC, iUC, (theA2.IsDeletable()?"deletable":"frozen"));
163 // C-array constructor, Length, Init, RowLength, ColLength
164 ItemType anItem;
165 Random(anItem);
166 theA2.Init (anItem);
167 ItemType * rBlock = new ItemType[theA2.Length()];
168 ////////////////////////////////QANCollection_Array2 aCArr(*rBlock, iLR-100, iUR-100, iLC, iUC);
169 QANCollection_Array2Func aCArr(*rBlock, iLR-100, iUR-100, iLC, iUC);
170 printf (" created the same sized preallocated array (%d*%d), %s\n",
171 aCArr.RowLength(), aCArr.ColLength(),
172 (aCArr.IsDeletable()?"deletable":"frozen"));
173 // *Value, operator()
174 for (i=iLR+1; i<iUR; i++)
175 {
176 for (j=iLC; j<=iUC; j++)
177 {
178 Random (aCArr.ChangeValue (i-101, j));
179 aCArr.SetValue (i-100, j,
180 ItemType(aCArr.Value(i-101,j)));
181 aCArr(i-99,j) = aCArr(i-100,j) = aCArr(i-101,j);
182 }
183 }
184 // Handle, copy constructor (including operator=)
185 ////////////////////////////////Handle(QANCollection_HArray2) aHa = new QANCollection_HArray2(aCArr);
186 Handle(QANCollection_HArray2Func) aHa = new QANCollection_HArray2Func(aCArr);
187 // Assign
188 AssignCollection (aHa->ChangeArray2(), theA2);
189}
190
191// ===================== Test methods of List type ==========================
192////////////////////////////////void TestList (QANCollection_List& theL)
193static void TestList (QANCollection_ListFunc& theL)
194{
195 // Extent
196 Standard_Integer iExt=theL.Extent();
197 Standard_Integer i;
198
199 printf ("Info: testing List(%d)\n", iExt);
200 // Append(2), Prepend(2), InsertBefore(2), InsertAfter(2),
201 // Remove, RemoveFirst, First, Last
202 ItemType anItem;
203 ////////////////////////////////QANCollection_List aL, aL1;
204 QANCollection_ListFunc aL, aL1;
205 for (i=0; i<4; i++)
206 {
207 Random (anItem);
208 aL.Append (anItem); // #1
209 aL.Append (aL1); // #2
210 Random (anItem);
211 aL1.Prepend (anItem); // #3
212 aL1.Prepend (aL); // #4
213 ////////////////////////////////QANCollection_List::Iterator anI(theL);
214 QANCollection_ListFunc::Iterator anI(theL);
215 if (anI.More())
216 {
217 Random (anItem);
218 theL.InsertBefore (anItem, anI); // #5
219 theL.InsertBefore (aL1, anI); // #6
220 Random (anItem);
221 theL.InsertAfter (anItem, anI); // #7
222 theL.InsertAfter (aL, anI); // #8
223 theL.Remove (anI); // #9
224 if (theL.Extent() > 0)
225 theL.RemoveFirst(); // #10
226 }
227 else
228 {
229 theL.Prepend (anItem);
230 PrintItem(theL.First());
231 PrintItem(theL.Last());
232 }
233 }
234 // Copy constructor + operator=
235 ////////////////////////////////aL = QANCollection_List(theL);
236 aL = QANCollection_ListFunc(theL);
237
238 // Assign
239 AssignCollection (theL, aL);
240
241 // Clear
242 aL.Clear();
243}
244
245// ===================== Test methods of Sequence type ========================
246////////////////////////////////void TestSequence (QANCollection_Sequence& theS)
247static void TestSequence (QANCollection_SequenceFunc& theS)
248{
249 Standard_Integer i;
250
251 printf ("Info: testing Sequence\n");
252 // Append(2)
253 ItemType anItem;
254 ////////////////////////////////QANCollection_Sequence aS, aS1;
255 QANCollection_SequenceFunc aS, aS1;
256 // Append(2), Prepend(2), InsertBefore(2), InsertAfter(2),
257 // Remove, RemoveFirst, First, Last
258 for (i=0; i<4; i++)
259 {
260 Random (anItem);
261 aS.Append (anItem); // #1
262 aS.Append (aS1); // #2
263 Random (anItem);
264 aS1.Prepend (anItem); // #3
265 aS1.Prepend (aS); // #4
266 if (theS.Length() > 0)
267 {
268 Random (anItem);
269 theS.InsertBefore (1, anItem); // #5
270 theS.InsertBefore (2, aS1); // #6
271 Random (anItem);
272 theS.InsertAfter (1, anItem); // #7
273 theS.InsertAfter (2, aS); // #8
274 theS.Remove (1); // #9
275 if (theS.Length() > 0)
276 theS.Remove(1); // #10
277 }
278 else
279 {
280 theS.Prepend (anItem);
281 PrintItem(theS.First());
282 PrintItem(theS.Last());
283 }
284 }
285
286 // ()
287 PrintItem(theS(1));
288
289 // Handle, Split
290 ////////////////////////////////Handle(QANCollection_HSequence) aHS = new QANCollection_HSequence(aS1);
291 Handle(QANCollection_HSequenceFunc) aHS = new QANCollection_HSequenceFunc(aS1);
292 theS.Split (3, aHS->ChangeSequence());
293
294 // Assign
295 AssignCollection (theS, aS);
296
297 // Clear
298 aS.Clear();
299}
300
301// ===================== Test methods of Map type =============================
302////////////////////////////////void TestMap (QANCollection_Map& theM)
d673da18 303static void TestMap(QANCollection_MapFunc& theM, Draw_Interpretor& theDI)
3a01a933 304{
3a01a933 305 {
d673da18 306 // Extent
307 Standard_Integer iExt=theM.Extent();
308 Standard_Integer i;
309
310 printf ("Info: testing Map(l=%d)\n", iExt);
311 theM.Statistics(cout);
312 // Resize
313 theM.ReSize(8);
314 theM.Statistics(cout);
315 cout.flush();
316 // Constructor
317 ////////////////////////////////QANCollection_Map aM;
318 QANCollection_MapFunc aM;
319 // Add
320 Key1Type aKey;
321 for (i=0; i<8; i++)
322 {
323 Random (aKey);
324 aM.Add (aKey);
325 }
326 // Contains, Remove
327 if (!aM.Contains(aKey))
328 {
329 theDI << "Error: map says that it does not contain its key " << aKey;
330 }
331 else
332 {
333 aM.Remove(aKey);
334 cout << " successfully removed item, l=%d\n" << aM.Size() << "\n";
335 }
336 // Copy constructor (including operator=)
337 ////////////////////////////////QANCollection_Map aM2 = QANCollection_Map(aM);
338 QANCollection_MapFunc aM2 = QANCollection_MapFunc(aM);
339 // Assign
340 AssignCollection (aM2,theM);
341
342 // Clear
343 aM.Clear();
3a01a933 344 }
d673da18 345
346 // Check method 'HasIntersection'.
3a01a933 347 {
d673da18 348 QANCollection_MapFunc aM1, aM2, aM3;
3a01a933 349
d673da18 350 aM1.Add(6);
351 aM1.Add(8);
352 aM1.Add(10);
353
354 aM2.Add(4);
355 aM2.Add(8);
356 aM2.Add(16);
357
358 aM3.Add(1);
359 aM3.Add(2);
360 aM3.Add(3);
361
362 if (!aM1.HasIntersection(aM2) || !aM2.HasIntersection(aM1) ||
363 aM1.HasIntersection(aM3) || aM3.HasIntersection(aM1))
364 {
365 theDI << "Error: method 'HasIntersection' failed.";
366 }
367 }
3a01a933 368}
369
370// ===================== Test methods of DataMap type =========================
371////////////////////////////////void TestDataMap (QANCollection_DataMap& theM)
372static void TestDataMap (QANCollection_DataMapFunc& theM)
373{
374 // Extent
375 Standard_Integer iExt=theM.Extent();
376 Standard_Integer i;
377
378 printf ("Info: testing DataMap(l=%d)\n", iExt);
379 theM.Statistics(cout);
380 // Resize
381 theM.ReSize(8);
382 theM.Statistics(cout);
383 cout.flush();
384 // Constructor
385 ////////////////////////////////QANCollection_DataMap aM;
386 QANCollection_DataMapFunc aM;
387 // Bind, Find, ChangeFind, ()
388 Key1Type aKey;
389 ItemType anItem;
390 for (i=0; i<8; i++)
391 {
392 Random (aKey);
393 Random (anItem);
394 aM.Bind (aKey, anItem);
395 PrintItem(aM.Find(aKey));
396 Random(aM(aKey));
397 }
398 // IsBound, UnBind
399 if (!aM.IsBound(aKey))
400 {
401 printf("Error : map says that it does not contain its key ");
402 PrintItem(aKey);
403 }
404 else
405 {
406 aM.UnBind(aKey);
407 printf(" successfully unbound the key, l=%d\n", aM.Size());
408 }
409 // Copy constructor (including operator=)
410 ////////////////////////////////theM = QANCollection_DataMap(aM);
411 theM = QANCollection_DataMapFunc(aM);
412 // Assign - prohibited
413 // AssignCollection (aM2,theM);
414 printCollection (theM, "DataMap:");
415
416 // Clear
417 aM.Clear();
418}
419
420
421// ===================== Test methods of DoubleMap type =======================
422////////////////////////////////void TestDoubleMap (QANCollection_DoubleMap& theM)
423static void TestDoubleMap (QANCollection_DoubleMapFunc& theM)
424{
425 // Extent
426 Standard_Integer iExt=theM.Extent();
427 Standard_Integer i;
428
429 printf ("Info: testing DoubleMap(l=%d)\n", iExt);
430 theM.Statistics(cout);
431 // Resize
432 theM.ReSize(8);
433 theM.Statistics(cout);
434 cout.flush();
435 // Constructor
436 ////////////////////////////////QANCollection_DoubleMap aM;
437 QANCollection_DoubleMapFunc aM;
438 // Bind, Find?,
439 Key1Type aKey1;
440 Key2Type aKey2;
441 for (i=0; i<8; i++)
442 {
443 Random (aKey1);
444 Random (aKey2);
445 aM.Bind (aKey1, aKey2);
446 PrintItem(aM.Find1(aKey1));
447 if (!aM.IsBound1(aKey1))
448 {
449 printf("Error : map says that it does not contain its key ");
450 PrintItem(aKey1);
451 }
452 PrintItem(aM.Find2(aKey2));
453 if (!aM.IsBound2(aKey2))
454 {
455 printf("Error : map says that it does not contain its key ");
456 PrintItem(aKey2);
457 }
458 }
459 // AreBound, UnBind
460 if (!aM.AreBound(aKey1,aKey2))
461 {
462 printf("Error : map says that it does not contain its keys ");
463 PrintItem(aKey1);
464 PrintItem(aKey2);
465 }
466 else
467 {
468 if (aM.UnBind2(aKey2))
469 printf(" successfully unbound the key, l=%d\n", aM.Size());
470 if (aM.UnBind1(aKey1))
471 printf("Error : unbound both keys?!\n");
472 }
473 // Copy constructor (including operator=)
474 ////////////////////////////////theM = QANCollection_DoubleMap(aM);
475 theM = QANCollection_DoubleMapFunc(aM);
476 // Assign - prohibited
477 // AssignCollection (aM2,theM);
478 printCollection (theM, "DoubleMap:");
479
480 // Clear
481 aM.Clear();
482}
483
484// ===================== Test methods of IndexedMap type ======================
485////////////////////////////////void TestIndexedMap (QANCollection_IndexedMap& theM)
486static void TestIndexedMap (QANCollection_IndexedMapFunc& theM)
487{
488 // Extent
489 Standard_Integer iExt=theM.Extent();
490 Standard_Integer i;
491
492 printf ("Info: testing IndexedMap(l=%d)\n", iExt);
493 theM.Statistics(cout);
494 // Resize
495 theM.ReSize(8);
496 theM.Statistics(cout);
497 cout.flush();
498 // Constructor
499 ////////////////////////////////QANCollection_IndexedMap aM;
500 QANCollection_IndexedMapFunc aM;
501 // Add, FindKey, FindIndex
502 Key1Type aKey;
503 for (i=0; i<8; i++)
504 {
505 Random (aKey);
506 aM.Add (aKey);
507 Standard_Integer iIndex=aM.FindIndex(aKey);
508 printf (" added a key, i=%d, k=",iIndex);
509 PrintItem(aM(iIndex));
510 }
511 // Contains, Remove
512 if (!aM.Contains(aM.FindKey(aM.FindIndex(aKey))))
513 {
514 printf("Error : map says that it does not contain its key ");
515 PrintItem(aKey);
516 }
517 else
518 {
519 aM.RemoveLast();
520 printf(" successfully removed item, l=%d\n", aM.Size());
521 }
522 // Substitute
523 Random(aKey);
524 aM.Substitute(1,aKey);
985aed12 525 if (!aM.Contains (aKey) || aM.FindIndex (aKey) != 1)
526 {
527 printf("Error : map does not contain valid key after substitute");
528 }
529 // Invoke substitute with the same key
530 aM.Substitute(1,aKey);
531 if (!aM.Contains (aKey) || aM.FindIndex (aKey) != 1)
532 {
533 printf("Error : map does not contain valid key after substitute");
534 }
3a01a933 535 // Copy constructor (including operator=)
536 ////////////////////////////////QANCollection_IndexedMap aM2 = QANCollection_IndexedMap(aM);
537 QANCollection_IndexedMapFunc aM2 = QANCollection_IndexedMapFunc(aM);
538 // Assign
539 AssignCollection (aM2,theM);
540
541 // Clear
542 aM.Clear();
543}
544
545// ===================== Test methods of IndexedDataMap type ==================
546////////////////////////////////void TestIndexedDataMap (QANCollection_IDMap& theM)
547static void TestIndexedDataMap (QANCollection_IDMapFunc& theM)
548{
549 // Extent
550 Standard_Integer iExt=theM.Extent();
551 Standard_Integer i;
552
553 printf ("Info: testing IndexedDataMap(l=%d)\n", iExt);
554 theM.Statistics(cout);
555 // Resize
556 theM.ReSize(8);
557 theM.Statistics(cout);
558 cout.flush();
559 // Constructor
560 ////////////////////////////////QANCollection_IDMap aM;
561 QANCollection_IDMapFunc aM;
562 // Add, FindKey, FindIndex, FindFromIndex, Change..., ()
563 Key1Type aKey;
564 ItemType anItem;
565 for (i=0; i<8; i++)
566 {
567 Random (aKey);
568 Random (anItem);
569 aM.Add (aKey, anItem);
570 Standard_Integer iIndex=aM.FindIndex(aKey);
571 printf (" added a key, i=%d, k=",iIndex);
572 PrintItem(aM.FindKey(iIndex));
573 PrintItem(aM(iIndex));
574 Random(aM.ChangeFromIndex(iIndex));
575 }
576 // Contains, Remove, FindFromKey
577 if (!aM.Contains(aM.FindKey(aM.FindIndex(aKey))))
578 {
579 printf("Error : map says that it does not contain its key ");
580 PrintItem(aKey);
581 }
582 else
583 {
584 anItem = aM.FindFromKey(aKey);
585 aM.RemoveLast();
586 printf(" successfully removed item, l=%d\n", aM.Size());
587 }
985aed12 588 // Substitute with different keys
3a01a933 589 Random(aKey);
590 aM.Substitute (1, aKey, anItem);
985aed12 591 if (!aM.Contains (aKey) || aM.FindIndex (aKey) != 1 || !aM.FindFromKey (aKey).IsEqual (anItem, Precision::Confusion()))
592 {
593 printf("Error : map does not contain valid key and item after substitute");
594 }
595 // Substitute with equal keys
596 Random(anItem);
597 aM.Substitute (1, aKey, anItem);
598 if (!aM.Contains (aKey) || aM.FindIndex (aKey) != 1 || !aM.FindFromKey (aKey).IsEqual (anItem, Precision::Confusion()))
599 {
600 printf("Error : map does not contain valid key and item after substitute");
601 }
3a01a933 602 // Copy constructor (including operator=)
603 ////////////////////////////////theM = QANCollection_IDMap(aM);
604 theM = QANCollection_IDMapFunc(aM);
605 // Assign - prohibited
606 // AssignCollection (aM2,theM);
607 printCollection (theM, "DoubleMap:");
608
609 // Clear
610 aM.Clear();
611}
612
613//=======================================================================
614//function : CheckArguments1
615//purpose :
616//=======================================================================
617Standard_Integer CheckArguments1(Draw_Interpretor& di, Standard_Integer argc, const char ** argv, Standard_Integer& Lower, Standard_Integer& Upper)
618{
619 if ( argc != 3) {
586db386 620 di << "Usage : " << argv[0] << " Lower Upper\n";
3a01a933 621 return 1;
622 }
623 Lower = Draw::Atoi(argv[1]);
624 Upper = Draw::Atoi(argv[2]);
625 if ( Lower > Upper ) {
586db386 626 di << "Lower > Upper\n";
3a01a933 627 return 1;
628 }
629 return 0;
630}
631
632//=======================================================================
633//function : CheckArguments2
634//purpose :
635//=======================================================================
636Standard_Integer CheckArguments2(Draw_Interpretor& di, Standard_Integer argc, const char ** argv, Standard_Integer& LowerRow, Standard_Integer& UpperRow, Standard_Integer& LowerCol, Standard_Integer& UpperCol)
637{
638 if ( argc != 5) {
586db386 639 di << "Usage : " << argv[0] << " LowerRow UpperRow LowerCol UpperCol\n";
3a01a933 640 return 1;
641 }
642 LowerRow = Draw::Atoi(argv[1]);
643 UpperRow = Draw::Atoi(argv[2]);
644 LowerCol = Draw::Atoi(argv[3]);
645 UpperCol = Draw::Atoi(argv[4]);
646 if ( LowerRow > UpperRow ) {
586db386 647 di << "LowerRow > UpperRow\n";
3a01a933 648 return 1;
649 }
650 if ( LowerCol > UpperCol ) {
586db386 651 di << "LowerCol UpperCol> \n";
3a01a933 652 return 1;
653 }
654 return 0;
655}
656
657
658//=======================================================================
659//function : QANColTestArray1
660//purpose :
661//=======================================================================
662static Standard_Integer QANColTestArray1(Draw_Interpretor& di, Standard_Integer argc, const char ** argv)
663{
664 Standard_Integer Lower, Upper;
665 if ( CheckArguments1(di, argc, argv, Lower, Upper) ) {
666 return 1;
667 }
668 QANCollection_Array1Func anArr1(Lower, Upper);
669 TestArray1(anArr1);
670 return 0;
671}
672
673//=======================================================================
674//function : QANColTestArray2
675//purpose :
676//=======================================================================
677static Standard_Integer QANColTestArray2(Draw_Interpretor& di, Standard_Integer argc, const char ** argv)
678{
679 Standard_Integer LowerRow, UpperRow, LowerCol, UpperCol;
680 if ( CheckArguments2(di, argc, argv, LowerRow, UpperRow, LowerCol, UpperCol) ) {
681 return 1;
682 }
683 QANCollection_Array2Func anArr2(LowerRow, UpperRow, LowerCol, UpperCol);
684 TestArray2(anArr2);
685 return 0;
686}
687
688//=======================================================================
689//function : QANColTestMap
690//purpose :
691//=======================================================================
692static Standard_Integer QANColTestMap(Draw_Interpretor& di, Standard_Integer argc, const char ** argv)
693{
694 if ( argc != 1) {
695 di << "Usage : " << argv[0] << "\n";
696 return 1;
697 }
698 QANCollection_MapFunc aMap;
d673da18 699 TestMap(aMap, di);
3a01a933 700 return 0;
701}
702
703//=======================================================================
704//function : QANColTestDataMap
705//purpose :
706//=======================================================================
707static Standard_Integer QANColTestDataMap(Draw_Interpretor& di, Standard_Integer argc, const char ** argv)
708{
709 if ( argc != 1) {
710 di << "Usage : " << argv[0] << "\n";
711 return 1;
712 }
713 QANCollection_DataMapFunc aDataMap;
714 TestDataMap(aDataMap);
715 return 0;
716}
717
718//=======================================================================
719//function : QANColTestDoubleMap
720//purpose :
721//=======================================================================
722static Standard_Integer QANColTestDoubleMap(Draw_Interpretor& di, Standard_Integer argc, const char ** argv)
723{
724 if ( argc != 1) {
725 di << "Usage : " << argv[0] << "\n";
726 return 1;
727 }
728 QANCollection_DoubleMapFunc aDoubleMap;
729 TestDoubleMap(aDoubleMap);
730 return 0;
731}
732
733//=======================================================================
734//function : QANColTestIndexedMap
735//purpose :
736//=======================================================================
737static Standard_Integer QANColTestIndexedMap(Draw_Interpretor& di, Standard_Integer argc, const char ** argv)
738{
739 if ( argc != 1) {
740 di << "Usage : " << argv[0] << "\n";
741 return 1;
742 }
743 QANCollection_IndexedMapFunc aIndexedMap;
744 TestIndexedMap(aIndexedMap);
745 return 0;
746}
747
748//=======================================================================
749//function : QANColTestIndexedDataMap
750//purpose :
751//=======================================================================
752static Standard_Integer QANColTestIndexedDataMap(Draw_Interpretor& di, Standard_Integer argc, const char ** argv)
753{
754 if ( argc != 1) {
755 di << "Usage : " << argv[0] << "\n";
756 return 1;
757 }
758 QANCollection_IDMapFunc aIDMap;
759 TestIndexedDataMap(aIDMap);
760 return 0;
761}
762
763//=======================================================================
764//function : QANColTestList
765//purpose :
766//=======================================================================
767static Standard_Integer QANColTestList(Draw_Interpretor& di, Standard_Integer argc, const char ** argv)
768{
769 if ( argc != 1) {
770 di << "Usage : " << argv[0] << "\n";
771 return 1;
772 }
773 QANCollection_ListFunc aList;
774 TestList(aList);
775 return 0;
776}
777
e3a6386d 778//=======================================================================
779//function : QANColTestVector
780//purpose :
781//=======================================================================
782static Standard_Integer QANColTestVector (Draw_Interpretor&, Standard_Integer, const char**)
783{
784 // test method Append and copying of empty vector
785 NCollection_Vector<int> aVec;
786 NCollection_Vector<int> aVec2 (aVec);
787 NCollection_Vector<int> aVec3;
788 aVec3 = aVec;
789
790 aVec.Append(5);
791 if (aVec(0) != 5)
792 std::cout << "Error: wrong value in original vector!" << endl;
793 aVec2.Append(5);
794 if (aVec2(0) != 5)
795 std::cout << "Error: wrong value in copy-constructed vector!" << endl;
796 aVec3.Append(5);
797 if (aVec3(0) != 5)
798 std::cout << "Error: wrong value in copied vector!" << endl;
799 std::cout << "Test OK" << endl;
800
801 return 0;
802}
803
3a01a933 804//=======================================================================
805//function : QANColTestSequence
806//purpose :
807//=======================================================================
808static Standard_Integer QANColTestSequence(Draw_Interpretor& di, Standard_Integer argc, const char ** argv)
809{
810 if ( argc != 1) {
811 di << "Usage : " << argv[0] << "\n";
812 return 1;
813 }
814 QANCollection_SequenceFunc aSeq;
815 TestSequence(aSeq);
816 return 0;
817}
818
6286195c 819//=======================================================================
820//function : QANColTestMove
821//purpose :
822//=======================================================================
823
824// Return array based on local C array buffer by value.
825// Note that this is expected to cause errors due
826// to the fact that returned copy will keep reference to the
827// buffer allocated in the stack of this function.
828// Unfortunately, this cannot be prevented due to the fact that
829// modern compilers use return value optimization in release mode
830// (object that is returned is constructed once at its target
831// place and never copied).
832static NCollection_Array1<double> GetArrayByValue()
833{
834 const int aLen = 1024;
835 double aCArray[aLen];
836 NCollection_Array1<double> anArray (aCArray[0], 1, aLen);
837 for (int i = 1; i <= aLen; i++)
838 anArray.SetValue(i, i + 113.);
839 return anArray;
840}
841
842// check array for possible corruption
843static bool CheckArrayByValue(NCollection_Array1<double> theArray)
844{
845 for (int i = 1; i <= theArray.Length(); i++)
846 {
847 if (theArray.Value(i) != i + 113.)
848 {
849 std::cout << "Error at item " << i << ": value = " << theArray.Value(i) << ", expected " << i + 113. << std::endl;
850 return false;
851 }
852 }
853 return true;
854}
855
856static Standard_Integer QANColTestArrayMove (Draw_Interpretor& di, Standard_Integer argc, const char ** argv)
857{
858 if ( argc != 1) {
859 di << "Usage : " << argv[0] << "\n";
860 return 1;
861 }
862 NCollection_Array1<double> anArray = GetArrayByValue();
863 di << (CheckArrayByValue(anArray) ? "Error: memory corruption is not detected" : "Expected behavior: memory is corrupted");
864 return 0;
865}
866
07bbde45 867#include <math_BullardGenerator.hxx>
868#include <OSD_Timer.hxx>
869
870static inline double test_atof (const char* theStr)
871{
872 return atof (theStr);
873}
874
875static inline double test_Atof (const char* theStr)
876{
877 return Atof (theStr);
878}
879
880static inline double test_strtod (const char* theStr)
881{
882 char *end;
883 return strtod (theStr, &end);
884}
885
886static inline double test_Strtod (const char* theStr)
887{
888 char *end;
889 return Strtod (theStr, &end);
890}
891
892static inline double test_sscanf (const char* theStr)
893{
894 double val = 0.;
895 sscanf (theStr, "%lf", &val);
896 return val;
897}
898
899static int check_atof (const NCollection_Array2<char>& theStrings, const char* theFormat,
900 double (*test_func)(const char*), Draw_Interpretor& di)
901{
902 int aNbErr = 0;
903 for (int i = 0; i < theStrings.UpperRow(); i++)
904 {
905 const char *aStr= &theStrings(i,0);
906 char buff[256];
907 double aVal = test_func (aStr);
908 Sprintf (buff, theFormat, aVal);
909 if (strcasecmp (buff, &theStrings(i,0)))
910 {
911#if defined(_MSC_VER) && _MSC_VER < 1900
912 // MSVC < 2015 prints nan and inf as 1.#NAN or 1.INF, and noes not recognize nan or inf on read
913 if (strstr (aStr, "1.#") || strstr (aStr, "nan") || strstr (aStr, "inf") ||
914 strstr (aStr, "NAN") || strstr (aStr, "INF"))
915 continue;
916#endif
917 if (aNbErr < 5)
918 {
919 di << "Deviation parsing " << aStr << " and print back: " << buff << "\n";
920 }
921 aNbErr++;
922 }
923 }
924 return aNbErr;
925}
926
927// Test speed of standard and OCCT-specific (accelerated) functions to parse string to double
928static Standard_Integer QATestAtof (Draw_Interpretor& di, Standard_Integer argc, const char ** argv)
929{
930 int aNbToTest = Max (100, (argc > 1 ? Draw::Atoi(argv[1]) : 1000000));
931 int aNbDigits = (argc > 2 ? Draw::Atoi(argv[2]) : 10);
932 double aRangeMin = (argc > 3 ? Draw::Atof(argv[3]) : -1e9);
933 double aRangeMax = (argc > 4 ? Draw::Atof(argv[4]) : 1e9);
934
935 char aFormat[256];
936 Sprintf (aFormat, "%%.%dlg", Max (2, Min (20, aNbDigits)));
937
938 // prepare data
939 const int MAXLEN = 256;
940 NCollection_Array2<char> aValuesStr (0, aNbToTest - 1, 0, MAXLEN);
941 math_BullardGenerator aRandom;
942
943 if (aRangeMin < aRangeMax)
944 {
945 // random values within specified range
946// std::default_random_engine aRandomEngine;
947// std::uniform_real_distribution<double> aRandomDistr (aRangeMin, aRangeMax);
948 const uint64_t aMaxUInt64 = ~(uint64_t)0; // could be (not supported by old GCC): std::numeric_limits<uint64_t>::max()
949 for (int i = 0; i < aNbToTest; i++)
950 {
951// double aVal = aRandomDistr (aRandomEngine);
952 uint64_t aIVal = ((uint64_t)aRandom.NextInt() << 32) + aRandom.NextInt();
953 double aVal = aRangeMin + (aIVal / (double)aMaxUInt64) * (aRangeMax - aRangeMin);
954 Sprintf(&aValuesStr(i,0), aFormat, aVal);
955 }
956 }
957 else
958 {
959 // special values
960 int i = 0;
961
962 strcpy (&aValuesStr(i++,0), "nan");
963 strcpy (&aValuesStr(i++,0), "nan(qnan)");
964 strcpy (&aValuesStr(i++,0), "NAN");
965 strcpy (&aValuesStr(i++,0), "-nan");
966 strcpy (&aValuesStr(i++,0), "-NAN");
967 strcpy (&aValuesStr(i++,0), "inf");
968 strcpy (&aValuesStr(i++,0), "INF");
969 strcpy (&aValuesStr(i++,0), "-inf");
970 strcpy (&aValuesStr(i++,0), "-INF");
971
972 strcpy (&aValuesStr(i++,0), " ."); // standalone period should not be considered as a number
973 strcpy (&aValuesStr(i++,0), "nanabcdef_128 xx"); // extra non-parenthised sequence after "nan"
974
975 strcpy (&aValuesStr(i++,0), "905791934.11394954"); // value that gets rounded in a wrong way by fast Strtod()
976 strcpy (&aValuesStr(i++,0), "9.343962790444495e+148"); // value where strtod() and Strtod() differ by 2 Epsilon
977
978 strcpy (&aValuesStr(i++,0), " 12345.67text"); // test for leading whitespaces and trailing text
979 strcpy (&aValuesStr(i++,0), "000.000"); // test for zero
980 strcpy (&aValuesStr(i++,0), "000.000e-0002"); // test for zero
981
982 strcpy (&aValuesStr(i++,0), "1000000000000000000000000000012345678901234567890"); // huge mantissa
983 strcpy (&aValuesStr(i++,0), "0000000000.00000000000000000012345678901234567890"); // leading zeros
984 strcpy (&aValuesStr(i++,0), "1.00000000000000000000000000012345678901234567890"); // long fractional part
985
986 strcpy (&aValuesStr(i++,0), "0.0000000001e318"); // large exponent but no overflow
987 strcpy (&aValuesStr(i++,0), "-1.7976931348623158e+308"); // -DBL_MAX
988 strcpy (&aValuesStr(i++,0), "1.79769313486232e+308"); // overflow
989
990 strcpy (&aValuesStr(i++,0), "10000000000e-310"); // large negative exponent but no underflow
991 strcpy (&aValuesStr(i++,0), "1.1e-310"); // underflow
992 strcpy (&aValuesStr(i++,0), "0.000001e-310"); // underflow
993 strcpy (&aValuesStr(i++,0), "2.2250738585072014e-308"); // underflow, DBL_MIN
994 strcpy (&aValuesStr(i++,0), "2.2250738585e-308"); // underflow, value less than DBL_MIN
995
996 strcpy (&aValuesStr(i++,0), "2.2204460492503131e-016"); // DBL_EPSILON
997
998 // random binary data
999// std::default_random_engine aRandomEngine;
1000// std::uniform_int_distribution<uint64_t> aRandomDistr (0, ~(uint64_t)0);
1001 for (; i < aNbToTest; i++)
1002 {
1003 union {
1004 uint64_t valint;
1005 double valdbl;
1006 } aVal;
1007// aVal.valint = aRandomDistr (aRandomEngine);
1008 aVal.valint = ((uint64_t)aRandom.NextInt() << 32) + aRandom.NextInt();
1009 Sprintf(&aValuesStr(i,0), aFormat, aVal.valdbl);
1010 }
1011 }
1012
1013 // test different methods
1014#define TEST_ATOF(method) \
1015 OSD_Timer aT_##method; aT_##method.Start(); \
1016 double aRes_##method = 0.; \
1017 for (int i = 0; i < aNbToTest; i++) { aRes_##method += test_##method (&aValuesStr(i,0)); } \
1018 aT_##method.Stop()
1019
1020 TEST_ATOF(sscanf);
1021 TEST_ATOF(strtod);
1022 TEST_ATOF(atof);
1023 TEST_ATOF(Strtod);
1024 TEST_ATOF(Atof);
1025#undef TEST_ATOF
1026
1027 // test different methods
1028#define CHECK_ATOF(method) \
1029 int aNbErr_##method = check_atof (aValuesStr, aFormat, test_##method, di); \
1030 di << "Checking " << #method << ": " << aNbErr_##method << " deviations\n"
1031
1032 CHECK_ATOF(sscanf);
1033 CHECK_ATOF(strtod);
1034 CHECK_ATOF(atof);
1035 CHECK_ATOF(Strtod);
1036 CHECK_ATOF(Atof);
1037#undef CHECK_ATOF
1038
1039/* compare results with atof */
1040#ifdef _MSC_VER
1041#define ISFINITE _finite
1042#else
1043#define ISFINITE std::isfinite
1044#endif
1045 int nbErr = 0;
1046 for (int i = 0; i < aNbToTest; i++)
1047 {
1048 char *aStr = &aValuesStr(i,0), *anEndOCCT, *anEndStd;
1049 double aRes = Strtod (aStr, &anEndOCCT);
1050 double aRef = strtod (aStr, &anEndStd);
1051 if (ISFINITE(aRes) != ISFINITE(aRef))
1052 {
1053 nbErr++;
1054#if defined(_MSC_VER) && _MSC_VER < 1900
1055 // MSVC < 2015 prints nan and inf as 1.#NAN or 1.INF, and noes not recognize nan or inf on read
1056 if (strstr (aStr, "1.#") || strstr (aStr, "nan") || strstr (aStr, "inf") ||
1057 strstr (aStr, "NAN") || strstr (aStr, "INF"))
1058 continue;
1059#endif
1060 if (nbErr < 5)
1061 {
1062 char aBuff[256];
1063 Sprintf (aBuff, "Error parsing %s: %.20lg / %.20lg\n", aStr, aRes, aRef);
1064 di << aBuff;
1065 }
1066 }
1067 else if (ISFINITE(aRef) && Abs (aRes - aRef) > Epsilon (aRef))
1068 {
1069 nbErr++;
1070 if (nbErr < 5)
1071 {
1072 char aBuff[256];
1073 Sprintf (aBuff, "Error parsing %s: %.20lg / %.20lg\n", aStr, aRes, aRef);
1074 di << aBuff;
1075 Sprintf (aBuff, "[Delta = %.8lg, Epsilon = %.8lg]\n", Abs (aRes - aRef), Epsilon (aRef));
1076 di << aBuff;
1077 }
1078 }
1079
1080 // check that Strtod() and strtod() stop at the same place;
1081 // this makes sense for reading special values such as "nan" and thus
1082 // is not relevant for MSVC 2010 and earlier than do not support these
1083#if ! defined(_MSC_VER) || _MSC_VER >= 1700
1084 if (anEndOCCT != anEndStd)
1085 {
1086 nbErr++;
1087 if (nbErr < 5)
1088 di << "Error: different number of symbols parsed in "
1089 << aStr << ": " << (int)(anEndOCCT - aStr) << " / " << (int)(anEndStd - aStr) << "\n";
1090 }
1091#endif
1092 }
1093 di << "Total " << nbErr << " defiations from strtod() found\n";
1094/* */
1095
1096 // print results
1097 di << "Method\t CPU\t Elapsed \t Deviations \tChecksum\n";
1098
1099#define PRINT_RES(method) \
1100 di << #method "\t" << aT_##method.UserTimeCPU() << " \t" << aT_##method.ElapsedTime() << "\t" \
1101 << aNbErr_##method << "\t" << aRes_##method << "\n"
1102 PRINT_RES(sscanf);
1103 PRINT_RES(strtod);
1104 PRINT_RES(atof);
1105 PRINT_RES(Strtod);
1106 PRINT_RES(Atof);
1107#undef PRINT_RES
1108
1109 return 0;
1110}
1111
3a01a933 1112void QANCollection::CommandsTest(Draw_Interpretor& theCommands) {
1113 const char *group = "QANCollection";
1114
1115 // from agvCollTest/src/CollectionEXE/FuncTestEXE.cxx
1116 theCommands.Add("QANColTestArray1", "QANColTestArray1", __FILE__, QANColTestArray1, group);
1117 theCommands.Add("QANColTestArray2", "QANColTestArray2", __FILE__, QANColTestArray2, group);
1118 theCommands.Add("QANColTestMap", "QANColTestMap", __FILE__, QANColTestMap, group);
1119 theCommands.Add("QANColTestDataMap", "QANColTestDataMap", __FILE__, QANColTestDataMap, group);
1120 theCommands.Add("QANColTestDoubleMap", "QANColTestDoubleMap", __FILE__, QANColTestDoubleMap, group);
1121 theCommands.Add("QANColTestIndexedMap", "QANColTestIndexedMap", __FILE__, QANColTestIndexedMap, group);
1122 theCommands.Add("QANColTestIndexedDataMap", "QANColTestIndexedDataMap", __FILE__, QANColTestIndexedDataMap, group);
1123 theCommands.Add("QANColTestList", "QANColTestList", __FILE__, QANColTestList, group);
1124 theCommands.Add("QANColTestSequence", "QANColTestSequence", __FILE__, QANColTestSequence, group);
e3a6386d 1125 theCommands.Add("QANColTestVector", "QANColTestVector", __FILE__, QANColTestVector, group);
07bbde45 1126 theCommands.Add("QANColTestArrayMove", "QANColTestArrayMove (is expected to give error)", __FILE__, QANColTestArrayMove, group);
1127 theCommands.Add("QATestAtof", "QATestAtof [nbvalues [nbdigits [min [max]]]]", __FILE__, QATestAtof, group);
3a01a933 1128}