-
Notifications
You must be signed in to change notification settings - Fork 140
/
opennurbs_array.h
1814 lines (1549 loc) · 56.3 KB
/
opennurbs_array.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
//
// Copyright (c) 1993-2022 Robert McNeel & Associates. All rights reserved.
// OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
// McNeel & Associates.
//
// THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
// ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
// MERCHANTABILITY ARE HEREBY DISCLAIMED.
//
// For complete openNURBS copyright information see <http://www.opennurbs.org>.
//
////////////////////////////////////////////////////////////////
#if !defined(ON_ARRAY_INC_)
#define ON_ARRAY_INC_
////////////////////////////////////////////////////////////////
//
// The ON_SimpleArray<> template is more efficient than the
// ON_ClassArray<> template, but ON_SimpleArray<> should not
// be used for arrays of classes that require explicit
// construction, destruction, or copy operators.
//
// Elements returned by AppendNew() are memset to zero.
//
// By default, ON_SimpleArray<> uses onrealloc() to manage
// the dynamic array memory. If you want to use something
// besides onrealloc() to manage the array memory, then override
// ON_SimpleArray::Realloc().
template <class T> class ON_SimpleArray
{
public:
// construction ////////////////////////////////////////////////////////
// These constructors create an array that uses onrealloc() to manage
// the array memory.
ON_SimpleArray() ON_NOEXCEPT;
virtual
~ON_SimpleArray();
// Copy constructor
ON_SimpleArray( const ON_SimpleArray<T>& );
////// Assignment operator
////// Making a virtual operator= was a mistake.
////// One reason might have been that the operator is virtual
////// so ON_UuidList::operator= will be called when one is
////// passed as an ON_SimpleArray<ON_UUID>& to a function?
////virtual
ON_SimpleArray<T>& operator=( const ON_SimpleArray<T>& );
#if defined(ON_HAS_RVALUEREF)
// Clone constructor
ON_SimpleArray( ON_SimpleArray<T>&& ) ON_NOEXCEPT;
// Clone assignment
ON_SimpleArray<T>& operator=( ON_SimpleArray<T>&& ) ON_NOEXCEPT;
#endif
ON_SimpleArray(size_t); // size_t parameter = initial capacity
// emergency bailout ///////////////////////////////////////////////////
void EmergencyDestroy(void); // call only when memory used by this array
// may have become invalid for reasons beyond
// your control. EmergencyDestroy() zeros
// anything that could possibly cause
// ~ON_SimpleArray() to crash.
// query ///////////////////////////////////////////////////////////////
int Count() const; // number of elements in array
unsigned int UnsignedCount() const;
int Capacity() const; // capacity of array
unsigned int SizeOfArray() const; // amount of memory in the m_a[] array
unsigned int SizeOfElement() const; // amount of memory in an m_a[] array element
ON__UINT32 DataCRC(ON__UINT32 current_remainder) const;
// The operator[] does to not check for valid indices.
// The caller is responsible for insuring that 0 <= i < Capacity()
T& operator[]( int );
T& operator[]( unsigned int );
T& operator[]( ON__INT64 );
T& operator[]( ON__UINT64 );
#if defined(ON_RUNTIME_APPLE)
T& operator[]( size_t );
#endif
const T& operator[]( int ) const;
const T& operator[]( unsigned int ) const;
const T& operator[]( ON__INT64 ) const;
const T& operator[]( ON__UINT64 ) const;
#if defined(ON_RUNTIME_APPLE)
const T& operator[]( size_t ) const;
#endif
operator T*(); // The cast operators return a pointer
operator const T*() const; // to the array. If Count() is zero,
// this pointer is nullptr.
T* First();
const T* First() const; // returns nullptr if count = 0
// At(index) returns nullptr if index < 0 or index >= count
T* At( int );
T* At( unsigned int );
T* At( ON__INT64 );
T* At( ON__UINT64 );
const T* At( int ) const;
const T* At( unsigned int ) const;
const T* At( ON__INT64 ) const;
const T* At( ON__UINT64 ) const;
T* Last();
const T* Last() const; // returns nullptr if count = 0
// array operations ////////////////////////////////////////////////////
T& AppendNew(); // Most efficient way to add a new element
// to the array. Increases count by 1.
// Returned element is memset to zero.
void Append( const T& ); // Append copy of element.
// Increments count by 1.
void Append( int, const T* ); // Append copy of an array T[count]
void Prepend( int, const T* ); // Prepend copy of an array T[count]
void Insert( int, const T& ); // Insert copy of element. Uses
// memmove() to perform any
// necessary moving.
// Increases count by 1.
void Remove(); // Removes last element. Decrements
// count by 1. Does not change capacity.
virtual
void Remove( int ); // Removes element. Uses memmove() to
// perform any necessary shifting.
// Decrements count by 1. Does not change
// capacity
void RemoveValue(const T&); // Removes elements. Uses memcmp() to compare
// Decrements count by removed items. Does
// not change capacity
void RemoveIf(bool predicate(const T& key));
// Removes elements for which predicate
// returns true. Decrements count
// by removed items.
// Does not change capacity
void Empty(); // Sets count to 0, leaves capacity untouched.
void Reverse(); // reverse order
void Swap(int,int); // swap elements i and j
//////////
// Search( e ) does a SLOW search of the array starting at array[0]
// and returns the index "i" of the first element that satisfies
// e == array[i]. (== is really memcmp()). If the search is not
// successful, then Search() returns -1. For Search(T) to work
// correctly, T must be a simple type. Use Search(p,compare())
// for Ts that are structs/classes that contain pointers. Search()
// is only suitable for performing infrequent searches of small
// arrays. Sort the array and use BinarySearch() for performing
// efficient searches.
int Search( const T& ) const;
//////////
// Search( p, compare ) does a SLOW search of the array starting
// at array[0] and returns the index "i" of the first element
// that satisfies compare(p,&array[i])==0. If the search is not
// successful, then Search() returns -1. Search() is only suitable
// for performing infrequent searches of small arrays. Sort the
// array and use BinarySearch() for performing efficient searches.
// See Also: ON_CompareIncreasing<T> and ON_CompareDeccreasing<T>
int Search( const T*, int (*)(const T*,const T*) ) const;
//////////
// BinarySearch( p, compare ) does a fast search of a sorted array
// and returns the smallest index "i" of the element that satisfies
// 0==compare(p,&array[i]).
//
// BinarySearch( p, compare, count ) does a fast search of the first
// count element sorted array and returns the smallest index "i" of
// the element that satisfies 0==compare(p,&array[i]). The version
// that takes a "count" is useful when elements are being appended
// during a calculation and the appended elements are not sorted.
//
// If the search is successful,
// BinarySearch() returns the index of the element (>=0).
// If the search is not successful, BinarySearch() returns -1.
// Use QuickSort( compare ) or, in rare cases and after meaningful
// performance testing using optimzed release builds,
// HeapSort( compare ) to sort the array.
// See Also: ON_CompareIncreasing<T> and ON_CompareDeccreasing<T>
int BinarySearch( const T*, int (*)(const T*,const T*) ) const;
int BinarySearch( const T*, int (*)(const T*,const T*), int ) const;
const T* BinarySearchPtr(const T*, int (*)(const T*, const T*)) const;
const T* BinarySearchPtr(const T*, int (*)(const T*, const T*), int) const;
int InsertInSortedList(const T&, int (*)(const T*, const T*));
int InsertInSortedList(const T&, int (*)(const T*, const T*), int);
//////////
// Sorts the array using the heap sort algorithm.
// QuickSort() is generally the better choice.
bool HeapSort( int (*)(const T*,const T*) );
//////////
// Sorts the array using the quick sort algorithm.
// See Also: ON_CompareIncreasing<T> and ON_CompareDeccreasing<T>
bool QuickSort( int (*)(const T*,const T*) );
//////////
// Sorts the array using the quick sort algorithma and then removes duplicates.
// See Also: ON_CompareIncreasing<T> and ON_CompareDeccreasing<T>
bool QuickSortAndRemoveDuplicates( int (*)(const T*,const T*) );
/*
Description:
Sort() fills in the index[] array so that
array[index[i]] <= array[index[i+1]].
The array is not modified.
Parameters:
sort_algorithm - [in]
ON::sort_algorithm::quick_sort (best in general) or ON::sort_algorithm::heap_sort
Use ON::sort_algorithm::heap_sort only if you have done extensive testing with
optimized release builds and are confident heap sort is
significantly faster.
index - [out] an array of length Count() that is returned with
some permutation of (0,1,...,Count()-1).
compare - [in] compare function compare(a,b,p) should return
<0 if a<b, 0, if a==b, and >0 if a>b.
Returns:
true if successful
*/
bool Sort(
ON::sort_algorithm sort_algorithm,
int* /* index[] */ ,
int (*)(const T*,const T*)
) const;
/*
Description:
Sort() fills in the index[] array so that
array[index[i]] <= array[index[i+1]].
The array is not modified.
Parameters:
sort_algorithm - [in]
ON::sort_algorithm::quick_sort (best in general) or ON::sort_algorithm::heap_sort
Use ON::sort_algorithm::heap_sort only if you have done extensive testing with
optimized release builds and are confident heap sort is
significantly faster.
index - [out] an array of length Count() that is returned with
some permutation of (0,1,...,Count()-1).
compare - [in] compare function compare(a,b,p) should return
<0 if a<b, 0, if a==b, and >0 if a>b.
p - [in] pointer passed as third argument to compare.
Returns:
true if successful
*/
bool Sort(
ON::sort_algorithm sort_algorithm,
int*, // index[]
int (*)(const T*,const T*,void*), // int compare(const T*,const T*,void* p)
void* // p
) const;
//////////
// Permutes the array so that output[i] = input[index[i]].
// The index[] array should be a permutation of (0,...,Count()-1).
bool Permute( const int* /*index[]*/ );
//////////
// Zeros all array memory.
// Count and capacity are not changed.
void Zero();
//////////
// Sets all bytes in array memory to value.
// Count and capacity are not changed.
void MemSet(unsigned char);
//////////
// Sets all specified items in an array range to a value.
// Count and capacity are not changed.
void SetRange(int from, int count, T);
// memory management ////////////////////////////////////////////////////
T* Reserve( size_t ); // increase capacity to at least the requested value
void Shrink(); // remove unused capacity
void Destroy(); // onfree any memory and set count and capacity to zero
// low level memory management //////////////////////////////////////////
// By default, ON_SimpleArray<> uses onrealloc() to manage
// the dynamic array memory. If you want to use something
// besides onrealloc() to manage the array memory, then override
// Realloc(). The T* Realloc(ptr, capacity) should do the following:
//
// 1) If ptr and capacity are zero, return nullptr.
// 2) If ptr is nullptr, an capacity > 0, allocate a memory block of
// capacity*sizeof(T) bytes and return a pointer to this block.
// If the allocation request fails, return nullptr.
// 3) If ptr is not nullptr and capacity is 0, free the memory block
// pointed to by ptr and return nullptr.
// 4) If ptr is not nullptr and capacity > 0, then reallocate the memory
// block and return a pointer to the reallocated block. If the
// reallocation request fails, return nullptr.
//
// NOTE WELL:
// Microsoft's VC 6.0 realloc() contains a bug that can cause
// crashes and should be avoided. See MSDN Knowledge Base article
// ID Q225099 for more information.
virtual
T* Realloc(T*,int); // (re)allocated capacity*sizeof(T) bytes
T* Array(); // The Array() function return the
const T* Array() const; // m_a pointer value.
void SetCount( int ); // If value is <= Capacity(), then
// sets count to specified value.
T* SetCapacity( size_t ); // Shrink/grows capacity. If value
// is < current Count(), then count
// is reduced to value.
//
int NewCapacity() const; // When the dynamic array needs to grow,
// this calculates the new value for m_capacity.
/*
Description:
Expert user tool to take charge of the memory used by
the dynamic array.
Returns:
A pointer to the array and zeros out this class.
The returned pointer is on the heap and must be
deallocated by calling onfree().
*/
T* KeepArray();
/*
Description:
Do not use this version of SetArray(). Use the one that takes
a pointer, count and capacity.
*/
void SetArray(T*);
/*
Description:
Expert user tool to set the memory used by the dynamic array.
Parameters:
T* pointer - [in]
int count [in]
int capacity - [in]
m_a is set to pointer, m_count is set to count, and m_capacity
is set to capacity. It is critical that the pointer be one
returned by onmalloc(sz), where sz >= capacity*sizeof(T[0]).
*/
void SetArray(T*, int, int);
protected:
// implementation //////////////////////////////////////////////////////
void Move( int /* dest index*/, int /* src index */, int /* element count*/ );
T* m_a; // pointer to array memory
int m_count; // 0 <= m_count <= m_capacity
int m_capacity; // actual length of m_a[]
};
////////////////////////////////////////////////////////////////
//
#if defined(ON_DLL_TEMPLATE)
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<bool>;
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<char>;
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON__INT8>;
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON__UINT8>;
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON__INT16>;
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON__UINT16>;
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON__INT32>;
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON__UINT32>;
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<float>;
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<double>;
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<bool*>;
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<char*>;
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON__INT8*>;
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON__UINT8*>;
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON__INT16*>;
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON__UINT16*>;
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON__INT32*>;
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON__UINT32*>;
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<float*>;
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<double*>;
#endif
////////////////////////////////////////////////////////////////
//
// The ON_ClassArray<> template is designed to be used with
// classes that require non-trivial construction or destruction.
// Any class used with the ON_ClassArray<> template must have a
// robust operator=().
//
// By default, ON_ClassArray<> uses onrealloc() to manage
// the dynamic array memory. If you want to use something
// besides onrealloc() to manage the array memory, then override
// ON_ClassArray::Realloc(). In practice this means that if your
// class has members with back-pointers, then you cannot use
// it in the default ON_ClassArray. See ON_ObjectArray
// for an example.
//
template <class T> class ON_ClassArray
{
public:
// construction ////////////////////////////////////////////////////////
ON_ClassArray() ON_NOEXCEPT;
ON_ClassArray( size_t ); // size_t parameter = initial capacity
// Copy constructor
ON_ClassArray( const ON_ClassArray<T>& );
virtual
~ON_ClassArray(); // override for struct member deallocation, etc.
// Assignment operator
ON_ClassArray<T>& operator=( const ON_ClassArray<T>& );
#if defined(ON_HAS_RVALUEREF)
// Clone constructor
ON_ClassArray( ON_ClassArray<T>&& ) ON_NOEXCEPT;
// Clone Assignment operator
ON_ClassArray<T>& operator=( ON_ClassArray<T>&& ) ON_NOEXCEPT;
#endif
// emergency bailout ///////////////////////////////////////////////////
void EmergencyDestroy(void); // call only when memory used by this array
// may have become invalid for reasons beyond
// your control. EmergencyDestroy() zeros
// anything that could possibly cause
// ~ON_ClassArray() to crash.
// query ///////////////////////////////////////////////////////////////
int Count() const; // number of elements in array
unsigned int UnsignedCount() const;
int Capacity() const; // capacity of array
unsigned int SizeOfArray() const; // amount of memory in the m_a[] array
unsigned int SizeOfElement() const; // amount of memory in an m_a[] array element
// The operator[] does to not check for valid indices.
// The caller is responsible for insuring that 0 <= i < Capacity()
T& operator[]( int );
T& operator[]( unsigned int );
T& operator[]( ON__INT64 );
T& operator[]( ON__UINT64 );
#if defined(ON_RUNTIME_APPLE)
T& operator[]( size_t );
#endif
const T& operator[]( int ) const;
const T& operator[]( unsigned int ) const;
const T& operator[]( ON__INT64 ) const;
const T& operator[]( ON__UINT64 ) const;
#if defined(ON_RUNTIME_APPLE)
const T& operator[]( size_t ) const;
#endif
operator T*(); // The cast operators return a pointer
operator const T*() const; // to the array. If Count() is zero,
// this pointer is nullptr.
T* First();
const T* First() const; // returns nullptr if count = 0
// At(index) returns nullptr if index < 0 or index >= count
T* At( int );
T* At( unsigned int );
T* At( ON__INT64 );
T* At( ON__UINT64 );
const T* At( int ) const;
const T* At( unsigned int ) const;
const T* At( ON__INT64 ) const;
const T* At( ON__UINT64 ) const;
T* Last();
const T* Last() const; // returns nullptr if count = 0
// array operations ////////////////////////////////////////////////////
T& AppendNew(); // Most efficient way to add a new class
// to the array. Increases count by 1.
void Append( const T& ); // Append copy of element.
// Increments count by 1.
void Append( int, const T*); // Append copy of an array T[count]
void Insert( int, const T& ); // Insert copy of element. Uses
// memmove() to perform any
// necessary moving.
// Increases count by 1.
void Remove(); // Removes last element. Decrements
// count by 1. Does not change capacity.
void Remove( int ); // Removes element. Uses memmove() to
// perform any necessary shifting.
// Decrements count by 1. Does not change
// capacity
void Empty(); // Sets count to 0, leaves capacity untouched.
void Reverse(); // reverse order
void Swap(int,int); // swap elements i and j
//////////
// Search( p, compare ) does a SLOW search of the array starting
// at array[0] and returns the index "i" of the first element
// that satisfies compare(p,&array[i])==0. If the search is not
// successful, then Search() returns -1. Search() is only suitable
// for performing infrequent searches of small arrays. Sort the
// array and use BinarySearch() for performing efficient searches.
int Search( const T*, int (*)(const T*,const T*) ) const;
//////////
// BinarySearch( p, compare ) does a fast search of a sorted array
// and returns the smallest index "i" of the element that satisfies
// 0==compare(p,&array[i]).
//
// BinarySearch( p, compare, count ) does a fast search of the first
// count element sorted array and returns the smallest index "i" of
// the element that satisfies 0==compare(p,&array[i]). The version
// that takes a "count" is useful when elements are being appended
// during a calculation and the appended elements are not sorted.
//
// If the search is successful,
// BinarySearch() returns the index of the element (>=0).
// If the search is not successful, BinarySearch() returns -1.
// Use QuickSort( compare ) or, in rare cases and after meaningful
// performance testing using optimzed release builds,
// HeapSort( compare ) to sort the array.
// See Also: ON_CompareIncreasing<T> and ON_CompareDeccreasing<T>
int BinarySearch( const T*, int (*)(const T*,const T*) ) const;
int BinarySearch( const T*, int (*)(const T*,const T*), int ) const;
int InsertInSortedList(const T&, int (*)(const T*, const T*));
int InsertInSortedList(const T&, int (*)(const T*, const T*), int);
//////////
// Sorts the array using the heap sort algorithm.
// See Also: ON_CompareIncreasing<T> and ON_CompareDeccreasing<T>
// QuickSort() is generally the better choice.
virtual
bool HeapSort( int (*)(const T*,const T*) );
//////////
// Sorts the array using the heap sort algorithm.
virtual
bool QuickSort( int (*)(const T*,const T*) );
/*
Description:
Sort() fills in the index[] array so that
array[index[i]] <= array[index[i+1]].
The array is not modified.
Parameters:
sort_algorithm - [in]
ON::sort_algorithm::quick_sort (best in general) or ON::sort_algorithm::heap_sort
Use ON::sort_algorithm::heap_sort only if you have done extensive testing with
optimized release builds and are confident heap sort is
significantly faster.
index - [out] an array of length Count() that is returned with
some permutation of (0,1,...,Count()-1).
compare - [in] compare function compare(a,b) should return
<0 if a<b, 0, if a==b, and >0 if a>b.
Returns:
true if successful
*/
bool Sort(
ON::sort_algorithm sort_algorithm,
int* /* index[] */ ,
int (*)(const T*,const T*)
) const;
/*
Description:
Sort() fills in the index[] array so that
array[index[i]] <= array[index[i+1]].
The array is not modified.
Parameters:
sort_algorithm - [in]
ON::sort_algorithm::quick_sort (best in general) or ON::sort_algorithm::heap_sort
Use ON::sort_algorithm::heap_sort only if you have done extensive testing with
optimized release builds and are confident heap sort is
significantly faster.
index - [out] an array of length Count() that is returned with
some permutation of (0,1,...,Count()-1).
compare - [in] compare function compare(a,b,p) should return
<0 if a<b, 0, if a==b, and >0 if a>b.
p - [in] pointer passed as third argument to compare.
Returns:
true if successful
*/
bool Sort(
ON::sort_algorithm sort_algorithm,
int*, // index[]
int (*)(const T*,const T*,void*), // int compare(const T*,const T*,void* p)
void* // p
) const;
//////////
// Permutes the array so that output[i] = input[index[i]].
// The index[] array should be a permutation of (0,...,Count()-1).
bool Permute( const int* /*index[]*/ );
//////////
// Destroys all elements and fills them with values
// set by the default constructor.
// Count and capacity are not changed.
void Zero();
// memory management /////////////////////////////////////////////////
T* Reserve( size_t ); // increase capacity to at least the requested value
void Shrink(); // remove unused capacity
void Destroy(); // onfree any memory and set count and capacity to zero
// low level memory management ///////////////////////////////////////
// By default, ON_ClassArray<> uses onrealloc() to manage
// the dynamic array memory. If you want to use something
// besides onrealloc() to manage the array memory, then override
// Realloc(). The T* Realloc(ptr, capacity) should do the following:
//
// 1) If ptr and capacity are zero, return nullptr.
// 2) If ptr is nullptr, an capacity > 0, allocate a memory block of
// capacity*sizeof(T) bytes and return a pointer to this block.
// If the allocation request fails, return nullptr.
// 3) If ptr is not nullptr and capacity is 0, free the memory block
// pointed to by ptr and return nullptr.
// 4) If ptr is not nullptr and capacity > 0, then reallocate the memory
// block and return a pointer to the reallocated block. If the
// reallocation request fails, return nullptr.
//
// NOTE WELL:
// Microsoft's VC 6.0 realloc() contains a bug that can cause
// crashes and should be avoided. See MSDN Knowledge Base article
// ID Q225099 for more information.
virtual
T* Realloc(T*,int); // (re)allocated capacity*sizeof(T) bytes
T* Array(); // The Array() function return the
const T* Array() const; // m_a pointer value.
void SetCount( int ); // If value is <= Capacity(), then
// sets count to specified value.
T* SetCapacity( size_t ); // Shrink/grows capacity. If value
// is < current Count(), then count
// is reduced to value.
int NewCapacity() const; // When the dynamic array needs to grow,
// this calculates the new value for m_capacity.
T* KeepArray(); // returns pointer to array and zeros
// out this class. Caller is responsible
// for calling destructor on each element
// and then using onfree() to release array
// memory. E.g.,
//
// for (int i=capacity;i>=0;i--) {
// array[i].~T();
// }
// onfree(array);
/*
Description:
Do not use this version of SetArray(). Use the one that takes
a pointer, count and capacity: SetArray(pointer,count,capacity)
*/
void SetArray(T*);
/*
Description:
Expert user tool to set the memory used by the dynamic array.
Parameters:
T* pointer - [in]
int count - [in] 0 <= count <= capacity
int capacity - [in]
m_a is set to pointer, m_count is set to count, and m_capacity
is set to capacity. It is critical that the pointer be one
returned by onmalloc(sz), where sz >= capacity*sizeof(T[0]),
and that the in-place operator new has been used to initialize
each element of the array.
*/
void SetArray(T*, int, int);
protected:
// implementation //////////////////////////////////////////////////////
void Move( int /* dest index*/, int /* src index */, int /* element count*/ );
void ConstructDefaultElement(T*);
void DestroyElement(T&);
T* m_a; // pointer to array memory
int m_count; // 0 <= m_count <= m_capacity
int m_capacity; // actual length of m_a[]
};
#if defined(ON_DLL_TEMPLATE)
ON_DLL_TEMPLATE template class ON_CLASS ON_ClassArray<ON_String>;
ON_DLL_TEMPLATE template class ON_CLASS ON_ClassArray<ON_wString>;
#endif
/*
Description:
ON_Object array is used to store lists of classes that are
derived from ON_Object. It differs from ON_ClassArray in
that the virtual ON_Object::MemoryRelocate function is called
when growing the dynamic array requires changing the location
of the memory buffer used to store the elements in the array.
*/
template <class T> class ON_ObjectArray : public ON_ClassArray<T>
{
public:
ON_ObjectArray();
~ON_ObjectArray(); // override for struct member deallocation, etc.
ON_ObjectArray( size_t ); // size_t parameter = initial capacity
ON_ObjectArray( const ON_ObjectArray<T>& );
ON_ObjectArray<T>& operator=( const ON_ObjectArray<T>& );
#if defined(ON_HAS_RVALUEREF)
// Clone constructor
ON_ObjectArray( ON_ObjectArray<T>&& );
// Clone Assignment operator
ON_ObjectArray<T>& operator=( ON_ObjectArray<T>&& );
#endif
ON__UINT32 DataCRC(ON__UINT32 current_remainder) const;
// virtual ON_ClassArray<T> override that
// calls MemoryRelocate on each element after
// the reallocation.
T* Realloc(T*,int);
// virtual ON_ClassArray<T> override that
// calls MemoryRelocate on each element after
// the heap sort.
// QuickSort() is generally the better choice.
bool HeapSort( int (*)(const T*,const T*) );
// virtual ON_ClassArray<T> override that
// calls MemoryRelocate on each element after
// the quick sort.
bool QuickSort( int (*)(const T*,const T*) );
};
class ON_CLASS ON_UuidPair
{
public:
/*
Description:
Compares m_uuid[0] and ignores m_uuid[1]
*/
static
int CompareFirstUuid(const class ON_UuidPair*,const class ON_UuidPair*);
/*
Description:
Compares m_uuid[1] and ignores m_uuid[0]
*/
static
int CompareSecondUuid(const class ON_UuidPair*,const class ON_UuidPair*);
/*
Description:
Compares m_uuid[0] then m_uuid[1].
*/
static
int Compare(const class ON_UuidPair*,const class ON_UuidPair*);
ON_UuidPair();
ON_UUID m_uuid[2];
};
#if defined(ON_DLL_TEMPLATE)
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_UUID>;
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_UuidIndex>;
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_UuidPtr>;
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_UuidPair>;
ON_DLL_TEMPLATE template class ON_CLASS ON_ClassArray<ON_SimpleArray<int> >;
#endif
/*
Description:
The ON_UuidList class provides a tool to efficiently
maintain a list of uuids and determine if a uuid is
in the list. This class is based on the premise that
there are no duplicate uuids in the list.
*/
class ON_CLASS ON_UuidList : private ON_SimpleArray<ON_UUID>
{
public:
ON_UuidList();
ON_UuidList(int capacity);
~ON_UuidList();
ON_UuidList(const ON_UuidList& src);
ON_UuidList& operator=(const ON_UuidList& src);
bool operator==(const ON_UuidList& other) const;
bool operator!=(const ON_UuidList& other) const;
/*
Description:
Fast uuid compare. Not necessarily the same
as ON_UuidCompare().
*/
static
int CompareUuid( const ON_UUID* a, const ON_UUID* b );
/*
Returns:
Number of active uuids in the list.
*/
int Count() const;
/*
Returns:
Array of uuids in the list. Sorted with
respect to ON_UuidList::CompareUuid().
Remarks:
Calling AddUuid() may grow the dynamic array
and make the pointer invalid.
*/
const ON_UUID* Array() const;
/*
Description:
Provides an efficient way to empty a list so that it
can be used again.
*/
void Empty();
/*
Description:
Destroy list. If list will be reused, Empty() is more
efficient.
*/
void Destroy();
void Reserve(size_t capacity);
/*
Description:
Makes the uuid list as efficient as possible in both search
speed and memory usage. Use Compact() when a uuid list
will be in use but is not likely to be modified. A list
that has been compacted can still be modified.
*/
void Compact();
/*
Description:
Adds a uuid to the list.
Parameters:
uuid - [in] id to add.
bCheckForDupicates - [in] if true, then the uuid
is not added if it is already in the list.
If you are certain that the uuid is not in the
list and you are going to have a large list of uuids,
then setting bCheckForDupicates=false will
speed up the addition of uuids.
Returns:
True if uuid was added. False if uuid was not added
because it is already in the collection.
*/
bool AddUuid(ON_UUID uuid, bool bCheckForDupicates=true);
/*
Description:
Removes a uuid from the list.
Parameters:
uuid - [in] id to remove
Returns:
True if uuid was in the list and was removed.
False if uuid was not in the list.
*/
bool RemoveUuid(ON_UUID uuid);
/*
Description:
Determine if a uuid is in the list.
Returns:
True if uuid is in the list.
*/
bool FindUuid(ON_UUID uuid) const;
/*
Description:
Saves the uuid list in an archive.
Parameters:
archive - [in] archive to write to.
Returns:
true if write was successful.
*/
bool Write(
class ON_BinaryArchive& archive
) const;
/*
Description:
Saves the uuid list in an archive.
Parameters:
archive - [in] archive to write to.
bSortBeforeWrite - [in]
True if ids should be sorted before the write
so future lookups will be fast. False if
the current state of the sorted/unsorted bits
should be preserved.
Returns:
true if write was successful.
*/
bool Write(
class ON_BinaryArchive& archive,
bool bSortBeforeWrite
) const;
/*
Description:
Read the uuid list from an archive.
Parameters:
archive - [in] archive to read from.
Returns:
true if the read was successful.
*/
bool Read(
class ON_BinaryArchive& archive
);
/*
Description:
Read the uuid list from an archive.
Parameters:
archive - [in]
archive to read from.
bool bSortAfterRead - [in]
True if ids should be sorted after the read
so future lookups will be fast. False if
the state of the sorted/unsorted bits that
existed at write time should be preserved.
Returns:
true if the read was successful.
*/
bool Read(
class ON_BinaryArchive& archive,
bool bSortAferRead
);