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) |
37 | DEFINE_ARRAY1(QANCollection_Array1Func,QANCollection_BaseColFunc,ItemType) |
38 | DEFINE_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) |
44 | DEFINE_ARRAY2(QANCollection_Array2Func,QANCollection_BaseColFunc,ItemType) |
45 | DEFINE_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) |
57 | DEFINE_MAP(QANCollection_MapFunc,QANCollection_Key1BaseColFunc,Key1Type) |
58 | DEFINE_DATAMAP(QANCollection_DataMapFunc,QANCollection_BaseColFunc,Key1Type,ItemType) |
59 | DEFINE_DOUBLEMAP(QANCollection_DoubleMapFunc,QANCollection_Key2BaseColFunc,Key1Type,Key2Type) |
60 | DEFINE_INDEXEDMAP(QANCollection_IndexedMapFunc,QANCollection_Key1BaseColFunc,Key1Type) |
61 | DEFINE_INDEXEDDATAMAP(QANCollection_IDMapFunc,QANCollection_BaseColFunc,Key1Type,ItemType) |
62 | |
63 | #include <NCollection_DefineList.hxx> |
64 | ////////////////////////////////DEFINE_LIST(QANCollection_List,QANCollection_BaseCol,ItemType) |
65 | DEFINE_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) |
71 | DEFINE_SEQUENCE(QANCollection_SequenceFunc,QANCollection_BaseColFunc,ItemType) |
72 | DEFINE_HSEQUENCE(QANCollection_HSequenceFunc,QANCollection_SequenceFunc) |
3a01a933 |
73 | |
74 | // HashCode and IsEquel must be defined for key types of maps |
75 | Standard_Integer HashCode(const gp_Pnt thePnt, int theUpper) |
76 | { |
77 | return HashCode(thePnt.X(),theUpper); |
78 | } |
79 | |
80 | Standard_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, |
86 | template <class Coll> |
87 | void 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) |
110 | template <class Coll> |
111 | void 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) |
120 | static 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) |
154 | static 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) |
193 | static 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) |
247 | static 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 |
303 | static 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) |
372 | static 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) |
423 | static 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) |
486 | static 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) |
547 | static 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 | //======================================================================= |
617 | Standard_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 | //======================================================================= |
636 | Standard_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 | //======================================================================= |
662 | static 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 | //======================================================================= |
677 | static 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 | //======================================================================= |
692 | static 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 | //======================================================================= |
707 | static 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 | //======================================================================= |
722 | static 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 | //======================================================================= |
737 | static 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 | //======================================================================= |
752 | static 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 | //======================================================================= |
767 | static 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 | //======================================================================= |
782 | static 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 | //======================================================================= |
808 | static 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). |
832 | static 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 |
843 | static 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 | |
856 | static 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 | |
870 | static inline double test_atof (const char* theStr) |
871 | { |
872 | return atof (theStr); |
873 | } |
874 | |
875 | static inline double test_Atof (const char* theStr) |
876 | { |
877 | return Atof (theStr); |
878 | } |
879 | |
880 | static inline double test_strtod (const char* theStr) |
881 | { |
882 | char *end; |
883 | return strtod (theStr, &end); |
884 | } |
885 | |
886 | static inline double test_Strtod (const char* theStr) |
887 | { |
888 | char *end; |
889 | return Strtod (theStr, &end); |
890 | } |
891 | |
892 | static inline double test_sscanf (const char* theStr) |
893 | { |
894 | double val = 0.; |
895 | sscanf (theStr, "%lf", &val); |
896 | return val; |
897 | } |
898 | |
899 | static 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 |
928 | static 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 |
1112 | void 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 | } |