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