00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00015
00016
00017 #if !defined(ON_ARRAY_DEFS_INC_)
00018 #define ON_ARRAY_DEFS_INC_
00019
00020 #if defined(ON_COMPILER_MSC)
00021
00022
00023
00024 #pragma warning(push)
00025
00026
00027
00028
00029
00030
00031
00032 #pragma warning(disable:4100)
00033
00034
00035
00036
00037
00038
00039 #pragma warning(disable:4211)
00040 #endif
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00053
00055
00056
00057
00058 template <class T>
00059 T* ON_SimpleArray<T>::Realloc(T* ptr,int capacity)
00060 {
00061 return (T*)onrealloc(ptr,capacity*sizeof(T));
00062 }
00063
00064 template <class T>
00065 ON_SimpleArray<T>::ON_SimpleArray()
00066 : m_a(0),
00067 m_count(0),
00068 m_capacity(0)
00069 {}
00070
00071 template <class T>
00072 ON_SimpleArray<T>::ON_SimpleArray( int c )
00073 : m_a(0),
00074 m_count(0),
00075 m_capacity(0)
00076 {
00077 if ( c > 0 )
00078 SetCapacity( c );
00079 }
00080
00081
00082 template <class T>
00083 ON_SimpleArray<T>::ON_SimpleArray( const ON_SimpleArray<T>& src )
00084 : m_a(0),
00085 m_count(0),
00086 m_capacity(0)
00087 {
00088 *this = src;
00089 }
00090
00091 template <class T>
00092 ON_SimpleArray<T>::~ON_SimpleArray()
00093 {
00094 SetCapacity(0);
00095 }
00096
00097 template <class T>
00098 ON_SimpleArray<T>& ON_SimpleArray<T>::operator=( const ON_SimpleArray<T>& src )
00099 {
00100 if( &src != this ) {
00101 if ( src.m_count <= 0 ) {
00102 m_count = 0;
00103 }
00104 else {
00105 if ( m_capacity < src.m_count ) {
00106 SetCapacity( src.m_count );
00107 }
00108 if ( m_a ) {
00109 m_count = src.m_count;
00110 memcpy( m_a, src.m_a, m_count*sizeof(T) );
00111 }
00112 }
00113 }
00114 return *this;
00115 }
00116
00117
00118
00119 template <class T>
00120 void ON_SimpleArray<T>::EmergencyDestroy(void)
00121 {
00122 m_count = 0;
00123 m_capacity = 0;
00124 m_a = 0;
00125 }
00126
00127
00128
00129 template <class T>
00130 int ON_SimpleArray<T>::Count() const
00131 {
00132 return m_count;
00133 }
00134
00135 template <class T>
00136 unsigned int ON_SimpleArray<T>::UnsignedCount() const
00137 {
00138 return ((unsigned int)m_count);
00139 }
00140
00141 template <class T>
00142 int ON_SimpleArray<T>::Capacity() const
00143 {
00144 return m_capacity;
00145 }
00146
00147 template <class T>
00148 unsigned int ON_SimpleArray<T>::SizeOfArray() const
00149 {
00150 return ((unsigned int)(m_capacity*sizeof(T)));
00151 }
00152
00153 template <class T>
00154 unsigned int ON_SimpleArray<T>::SizeOfElement() const
00155 {
00156 return ((unsigned int)(sizeof(T)));
00157 }
00158
00159
00160 template <class T>
00161 ON__UINT32 ON_SimpleArray<T>::DataCRC(ON__UINT32 current_remainder) const
00162 {
00163 return ON_CRC32(current_remainder,m_count*sizeof(m_a[0]),m_a);
00164 }
00165
00166 template <class T>
00167 T& ON_SimpleArray<T>::operator[]( int i )
00168 {
00169 #if defined(ON_DEBUG)
00170 if ( i < 0 || i > m_capacity )
00171 {
00172 ON_ERROR("ON_SimpleArray[i]: i out of range.");
00173 }
00174 #endif
00175 return m_a[i];
00176 }
00177
00178 template <class T>
00179 T& ON_SimpleArray<T>::operator[]( unsigned int i )
00180 {
00181 #if defined(ON_DEBUG)
00182 if ( i > (unsigned int)m_capacity )
00183 {
00184 ON_ERROR("ON_SimpleArray[i]: i out of range.");
00185 }
00186 #endif
00187 return m_a[i];
00188 }
00189
00190
00191 template <class T>
00192 T& ON_SimpleArray<T>::operator[]( ON__INT64 i )
00193 {
00194 #if defined(ON_DEBUG)
00195 if ( i < 0 || i > (ON__INT64)m_capacity )
00196 {
00197 ON_ERROR("ON_SimpleArray[i]: i out of range.");
00198 }
00199 #endif
00200 return m_a[i];
00201 }
00202
00203 template <class T>
00204 T& ON_SimpleArray<T>::operator[]( ON__UINT64 i )
00205 {
00206 #if defined(ON_DEBUG)
00207 if ( i > (ON__UINT64)m_capacity )
00208 {
00209 ON_ERROR("ON_SimpleArray[i]: i out of range.");
00210 }
00211 #endif
00212 return m_a[i];
00213 }
00214
00215 template <class T>
00216 const T& ON_SimpleArray<T>::operator[](int i) const
00217 {
00218 #if defined(ON_DEBUG)
00219 if ( i < 0 || i > m_capacity )
00220 {
00221 ON_ERROR("ON_SimpleArray[i]: i out of range.");
00222 }
00223 #endif
00224 return m_a[i];
00225 }
00226
00227 template <class T>
00228 const T& ON_SimpleArray<T>::operator[](unsigned int i) const
00229 {
00230 #if defined(ON_DEBUG)
00231 if ( i > (unsigned int)m_capacity )
00232 {
00233 ON_ERROR("ON_SimpleArray[i]: i out of range.");
00234 }
00235 #endif
00236 return m_a[i];
00237 }
00238
00239
00240 template <class T>
00241 const T& ON_SimpleArray<T>::operator[](ON__INT64 i) const
00242 {
00243 #if defined(ON_DEBUG)
00244 if ( i < 0 || i > ((ON__INT64)m_capacity) )
00245 {
00246 ON_ERROR("ON_SimpleArray[i]: i out of range.");
00247 }
00248 #endif
00249 return m_a[i];
00250 }
00251
00252 template <class T>
00253 const T& ON_SimpleArray<T>::operator[](ON__UINT64 i) const
00254 {
00255 #if defined(ON_DEBUG)
00256 if ( i > (ON__UINT64)m_capacity )
00257 {
00258 ON_ERROR("ON_SimpleArray[i]: i out of range.");
00259 }
00260 #endif
00261 return m_a[i];
00262 }
00263
00264
00265 template <class T>
00266 ON_SimpleArray<T>::operator T*()
00267 {
00268 return (m_count > 0) ? m_a : 0;
00269 }
00270
00271 template <class T>
00272 ON_SimpleArray<T>::operator const T*() const
00273 {
00274 return (m_count > 0) ? m_a : 0;
00275 }
00276
00277 template <class T>
00278 T* ON_SimpleArray<T>::Array()
00279 {
00280 return m_a;
00281 }
00282
00283 template <class T>
00284 const T* ON_SimpleArray<T>::Array() const
00285 {
00286 return m_a;
00287 }
00288
00289 template <class T>
00290 T* ON_SimpleArray<T>::KeepArray()
00291 {
00292 T* p = m_a;
00293 m_a = 0;
00294 m_count = 0;
00295 m_capacity = 0;
00296 return p;
00297 }
00298
00299 template <class T>
00300 void ON_SimpleArray<T>::SetArray(T* p)
00301 {
00302 if ( m_a && m_a != p )
00303 onfree(m_a);
00304 m_a = p;
00305 }
00306
00307 template <class T>
00308 void ON_SimpleArray<T>::SetArray(T* p, int count, int capacity)
00309 {
00310 if ( m_a && m_a != p )
00311 onfree(m_a);
00312 m_a = p;
00313 m_count = count;
00314 m_capacity = capacity;
00315 }
00316
00317 template <class T>
00318 T* ON_SimpleArray<T>::First()
00319 {
00320 return (m_count > 0) ? m_a : 0;
00321 }
00322
00323 template <class T>
00324 const T* ON_SimpleArray<T>::First() const
00325 {
00326 return (m_count > 0) ? m_a : 0;
00327 }
00328
00329 template <class T>
00330 T* ON_SimpleArray<T>::At( int i )
00331 {
00332 return (i >= 0 && i < m_count) ? m_a+i : 0;
00333 }
00334
00335 template <class T>
00336 T* ON_SimpleArray<T>::At( unsigned int i )
00337 {
00338 return (i < (unsigned int)m_count) ? m_a+i : 0;
00339 }
00340
00341 template <class T>
00342 const T* ON_SimpleArray<T>::At( int i) const
00343 {
00344 return (i >= 0 && i < m_count) ? m_a+i : 0;
00345 }
00346
00347 template <class T>
00348 const T* ON_SimpleArray<T>::At( unsigned int i) const
00349 {
00350 return (i < (unsigned int)m_count) ? m_a+i : 0;
00351 }
00352
00353 template <class T>
00354 T* ON_SimpleArray<T>::At( ON__INT64 i )
00355 {
00356 return (i >= 0 && i < (ON__INT64)m_count) ? m_a+i : 0;
00357 }
00358
00359 template <class T>
00360 T* ON_SimpleArray<T>::At( ON__UINT64 i )
00361 {
00362 return (i < (ON__UINT64)m_count) ? m_a+i : 0;
00363 }
00364
00365 template <class T>
00366 const T* ON_SimpleArray<T>::At( ON__INT64 i) const
00367 {
00368 return (i >= 0 && i < (ON__INT64)m_count) ? m_a+i : 0;
00369 }
00370
00371 template <class T>
00372 const T* ON_SimpleArray<T>::At( ON__UINT64 i) const
00373 {
00374 return (i < (ON__UINT64)m_count) ? m_a+i : 0;
00375 }
00376
00377 template <class T>
00378 T* ON_SimpleArray<T>::Last()
00379 {
00380 return (m_count > 0) ? m_a+(m_count-1) : 0;
00381 }
00382
00383 template <class T>
00384 const T* ON_SimpleArray<T>::Last() const
00385 {
00386 return (m_count > 0) ? m_a+(m_count-1) : 0;
00387 }
00388
00389
00390
00391 template <class T>
00392 void ON_SimpleArray<T>::Move( int dest_i, int src_i, int ele_cnt )
00393 {
00394
00395
00396 if ( ele_cnt <= 0 || src_i < 0 || dest_i < 0 || src_i == dest_i ||
00397 src_i + ele_cnt > m_count || dest_i > m_count )
00398 return;
00399
00400 int capacity = dest_i + ele_cnt;
00401 if ( capacity > m_capacity ) {
00402 if ( capacity < 2*m_capacity )
00403 capacity = 2*m_capacity;
00404 SetCapacity( capacity );
00405 }
00406
00407 memmove( &m_a[dest_i], &m_a[src_i], ele_cnt*sizeof(T) );
00408 }
00409
00410 template <class T>
00411 T& ON_SimpleArray<T>::AppendNew()
00412 {
00413 if ( m_count == m_capacity )
00414 {
00415 int new_capacity = NewCapacity();
00416 Reserve( new_capacity );
00417 }
00418 memset( &m_a[m_count], 0, sizeof(T) );
00419 return m_a[m_count++];
00420 }
00421
00422 template <class T>
00423 void ON_SimpleArray<T>::Append( const T& x )
00424 {
00425 if ( m_count == m_capacity )
00426 {
00427 const int newcapacity = NewCapacity();
00428 if (m_a)
00429 {
00430 const int s = (int)(&x - m_a);
00431 if ( s >= 0 && s < m_capacity )
00432 {
00433
00434
00435
00436
00437 T temp;
00438 temp = x;
00439 Reserve( newcapacity );
00440 m_a[m_count++] = temp;
00441 return;
00442 }
00443 }
00444 Reserve(newcapacity);
00445 }
00446 m_a[m_count++] = x;
00447 }
00448
00449 template <class T>
00450 void ON_SimpleArray<T>::Append( int count, const T* p )
00451 {
00452 if ( count > 0 && p )
00453 {
00454 if ( count + m_count > m_capacity )
00455 {
00456 int newcapacity = NewCapacity();
00457 if ( newcapacity < count + m_count )
00458 newcapacity = count + m_count;
00459 Reserve( newcapacity );
00460 }
00461 memcpy( m_a + m_count, p, count*sizeof(T) );
00462 m_count += count;
00463 }
00464 }
00465
00466 template <class T>
00467 void ON_SimpleArray<T>::Insert( int i, const T& x )
00468 {
00469 if( i >= 0 && i <= m_count )
00470 {
00471 if ( m_count == m_capacity )
00472 {
00473 int newcapacity = NewCapacity();
00474 Reserve( newcapacity );
00475 }
00476 m_count++;
00477 Move( i+1, i, m_count-1-i );
00478 m_a[i] = x;
00479 }
00480 }
00481
00482 template <class T>
00483 void ON_SimpleArray<T>::Remove()
00484 {
00485 Remove(m_count-1);
00486 }
00487
00488 template <class T>
00489 void ON_SimpleArray<T>::Remove( int i )
00490 {
00491 if ( i >= 0 && i < m_count ) {
00492 Move( i, i+1, m_count-1-i );
00493 m_count--;
00494 memset( &m_a[m_count], 0, sizeof(T) );
00495 }
00496 }
00497
00498 template <class T>
00499 void ON_SimpleArray<T>::Empty()
00500 {
00501 if ( m_a )
00502 memset( m_a, 0, m_capacity*sizeof(T) );
00503 m_count = 0;
00504 }
00505
00506 template <class T>
00507 void ON_SimpleArray<T>::Reverse()
00508 {
00509
00510
00511
00512 T t;
00513 int i = 0;
00514 int j = m_count-1;
00515 for ( ; i < j; i++, j-- ) {
00516 t = m_a[i];
00517 m_a[i] = m_a[j];
00518 m_a[j] = t;
00519 }
00520 }
00521
00522 template <class T>
00523 void ON_SimpleArray<T>::Swap( int i, int j )
00524 {
00525 if ( i != j ) {
00526 const T t(m_a[i]);
00527 m_a[i] = m_a[j];
00528 m_a[j] = t;
00529 }
00530 }
00531
00532 template <class T>
00533 int ON_SimpleArray<T>::Search( const T& key ) const
00534 {
00535 const T* p = &key;
00536 for ( int i = 0; i < m_count; i++ ) {
00537 if (!memcmp(p,m_a+i,sizeof(T)))
00538 return i;
00539 }
00540 return -1;
00541 }
00542
00543 template <class T>
00544 int ON_SimpleArray<T>::Search( const T* key, int (*compar)(const T*,const T*) ) const
00545 {
00546 for ( int i = 0; i < m_count; i++ ) {
00547 if (!compar(key,m_a+i))
00548 return i;
00549 }
00550 return -1;
00551 }
00552
00553 template <class T>
00554 int ON_SimpleArray<T>::BinarySearch( const T* key, int (*compar)(const T*,const T*) ) const
00555 {
00556 const T* found = (key&&m_a&&m_count>0)
00557 ? (const T*)bsearch( key, m_a, m_count, sizeof(T), (int(*)(const void*,const void*))compar )
00558 : 0;
00559
00560
00561
00562 int rc;
00563 if ( 0 != found )
00564 {
00565
00566
00567 #if defined(ON_COMPILER_MSC1300)
00568 rc = ((int)(found - m_a));
00569 #elif 8 == ON_SIZEOF_POINTER
00570
00571
00572
00573 const ON__UINT64 fptr = (ON__UINT64)found;
00574 const ON__UINT64 aptr = (ON__UINT64)m_a;
00575 const ON__UINT64 sz = (ON__UINT64)sizeof(T);
00576 const ON__UINT64 i = (fptr - aptr)/sz;
00577 rc = (int)i;
00578 #else
00579
00580
00581
00582 const ON__UINT32 fptr = (ON__UINT32)found;
00583 const ON__UINT32 aptr = (ON__UINT32)m_a;
00584 const ON__UINT32 sz = (ON__UINT32)sizeof(T);
00585 const ON__UINT32 i = (fptr - aptr)/sz;
00586 rc = (int)i;
00587 #endif
00588 }
00589 else
00590 {
00591
00592 rc = -1;
00593 }
00594
00595 return rc;
00596
00597 }
00598
00599 template <class T>
00600 int ON_SimpleArray<T>::BinarySearch( const T* key, int (*compar)(const T*,const T*), int count ) const
00601 {
00602 if ( count > m_count )
00603 count = m_count;
00604 if ( count <= 0 )
00605 return -1;
00606 const T* found = (key&&m_a&&m_count>0)
00607 ? (const T*)bsearch( key, m_a, count, sizeof(T), (int(*)(const void*,const void*))compar )
00608 : 0;
00609
00610
00611
00612 int rc;
00613 if ( 0 != found )
00614 {
00615
00616
00617 #if defined(ON_COMPILER_MSC1300)
00618 rc = ((int)(found - m_a));
00619 #elif 8 == ON_SIZEOF_POINTER
00620
00621
00622
00623 const ON__UINT64 fptr = (ON__UINT64)found;
00624 const ON__UINT64 aptr = (ON__UINT64)m_a;
00625 const ON__UINT64 sz = (ON__UINT64)sizeof(T);
00626 const ON__UINT64 i = (fptr - aptr)/sz;
00627 rc = (int)i;
00628 #else
00629
00630
00631
00632 const ON__UINT32 fptr = (ON__UINT32)found;
00633 const ON__UINT32 aptr = (ON__UINT32)m_a;
00634 const ON__UINT32 sz = (ON__UINT32)sizeof(T);
00635 const ON__UINT32 i = (fptr - aptr)/sz;
00636 rc = (int)i;
00637 #endif
00638 }
00639 else
00640 {
00641
00642 rc = -1;
00643 }
00644 return rc;
00645 }
00646
00647
00648
00649 template <class T>
00650 bool ON_SimpleArray<T>::HeapSort( int (*compar)(const T*,const T*) )
00651 {
00652 bool rc = false;
00653 if ( m_a && m_count > 0 && compar ) {
00654 if ( m_count > 1 )
00655 ON_hsort( m_a, m_count, sizeof(T), (int(*)(const void*,const void*))compar );
00656 rc = true;
00657 }
00658 return rc;
00659 }
00660
00661 template <class T>
00662 bool ON_SimpleArray<T>::QuickSort( int (*compar)(const T*,const T*) )
00663 {
00664 bool rc = false;
00665 if ( m_a && m_count > 0 && compar ) {
00666 if ( m_count > 1 )
00667 ON_qsort( m_a, m_count, sizeof(T), (int(*)(const void*,const void*))compar );
00668 rc = true;
00669 }
00670 return rc;
00671 }
00672
00673 template <class T>
00674 bool ON_SimpleArray<T>::Sort( ON::sort_algorithm sa, int* index, int (*compar)(const T*,const T*) ) const
00675 {
00676 bool rc = false;
00677 if ( m_a && m_count > 0 && compar && index ) {
00678 if ( m_count > 1 )
00679 ON_Sort(sa, index, m_a, m_count, sizeof(T), (int(*)(const void*,const void*))compar );
00680 else if ( m_count == 1 )
00681 index[0] = 0;
00682 rc = true;
00683 }
00684 return rc;
00685 }
00686
00687 template <class T>
00688 bool ON_SimpleArray<T>::Sort( ON::sort_algorithm sa, int* index, int (*compar)(const T*,const T*,void*),void* p ) const
00689 {
00690 bool rc = false;
00691 if ( m_a && m_count > 0 && compar && index ) {
00692 if ( m_count > 1 )
00693 ON_Sort(sa, index, m_a, m_count, sizeof(T), (int(*)(const void*,const void*,void*))compar, p );
00694 else if ( m_count == 1 )
00695 index[0] = 0;
00696 rc = true;
00697 }
00698 return rc;
00699 }
00700
00701 template <class T>
00702 bool ON_SimpleArray<T>::Permute( const int* index )
00703 {
00704 bool rc = false;
00705 if ( m_a && m_count > 0 && index ) {
00706 int i;
00707 T* buffer = (T*)onmalloc(m_count*sizeof(buffer[0]));
00708 memcpy( buffer, m_a, m_count*sizeof(T) );
00709 for (i = 0; i < m_count; i++ )
00710 memcpy( m_a+i, buffer+index[i], sizeof(T) );
00711 onfree(buffer);
00712 rc = true;
00713 }
00714 return rc;
00715 }
00716
00717 template <class T>
00718 void ON_SimpleArray<T>::Zero()
00719 {
00720 if ( m_a && m_capacity > 0 ) {
00721 memset( m_a, 0, m_capacity*sizeof(T) );
00722 }
00723 }
00724
00725 template <class T>
00726 void ON_SimpleArray<T>::MemSet( unsigned char value )
00727 {
00728 if ( m_a && m_capacity > 0 ) {
00729 memset( m_a, value, m_capacity*sizeof(T) );
00730 }
00731 }
00732
00733
00734
00735 template <class T>
00736 void ON_SimpleArray<T>::Reserve( int newcap )
00737 {
00738 if( m_capacity < newcap )
00739 SetCapacity( newcap );
00740 }
00741
00742 template <class T>
00743 void ON_SimpleArray<T>::Shrink()
00744 {
00745 SetCapacity( m_count );
00746 }
00747
00748 template <class T>
00749 void ON_SimpleArray<T>::Destroy()
00750 {
00751 SetCapacity( 0 );
00752 }
00753
00754
00755
00756 template <class T>
00757 void ON_SimpleArray<T>::SetCount( int count )
00758 {
00759 if ( count >= 0 && count <= m_capacity )
00760 m_count = count;
00761 }
00762
00763 template <class T>
00764 void ON_SimpleArray<T>::SetCapacity( int capacity )
00765 {
00766
00767 if ( capacity != m_capacity ) {
00768 if( capacity > 0 ) {
00769 if ( m_count > capacity )
00770 m_count = capacity;
00771
00772 m_a = Realloc( m_a, capacity );
00773 if ( m_a ) {
00774 if ( capacity > m_capacity ) {
00775
00776 memset( m_a + m_capacity, 0, (capacity-m_capacity)*sizeof(T) );
00777 }
00778 m_capacity = capacity;
00779 }
00780 else {
00781
00782 m_count = m_capacity = 0;
00783 }
00784 }
00785 else if (m_a) {
00786 Realloc(m_a,0);
00787 m_a = 0;
00788 m_count = m_capacity = 0;
00789 }
00790 }
00791 }
00792
00793 template <class T>
00794 int ON_SimpleArray<T>::NewCapacity() const
00795 {
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813 const size_t cap_size = 32*sizeof(void*)*1024*1024;
00814 if (m_count*sizeof(T) <= cap_size || m_count < 8)
00815 return ((m_count <= 2) ? 4 : 2*m_count);
00816
00817
00818
00819 int delta_count = 8 + cap_size/sizeof(T);
00820 if ( delta_count > m_count )
00821 delta_count = m_count;
00822 return (m_count + delta_count);
00823 }
00824
00825 template <class T>
00826 int ON_ClassArray<T>::NewCapacity() const
00827 {
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845 const size_t cap_size = 32*sizeof(void*)*1024*1024;
00846 if (m_count*sizeof(T) <= cap_size || m_count < 8)
00847 return ((m_count <= 2) ? 4 : 2*m_count);
00848
00849
00850
00851 int delta_count = 8 + cap_size/sizeof(T);
00852 if ( delta_count > m_count )
00853 delta_count = m_count;
00854 return (m_count + delta_count);
00855 }
00856
00858
00860
00861 template <class T>
00862 ON_ObjectArray<T>::ON_ObjectArray()
00863 {
00864 }
00865
00866 template <class T>
00867 ON_ObjectArray<T>::~ON_ObjectArray()
00868 {
00869 }
00870
00871 template <class T>
00872 ON_ObjectArray<T>::ON_ObjectArray( const ON_ObjectArray<T>& src ) : ON_ClassArray<T>(src)
00873 {
00874 }
00875
00876 template <class T>
00877 ON_ObjectArray<T>& ON_ObjectArray<T>::operator=( const ON_ObjectArray<T>& src)
00878 {
00879 if( this != &src)
00880 {
00881 ON_ClassArray<T>::operator =(src);
00882 }
00883 return *this;
00884 }
00885
00886
00887 template <class T>
00888 ON_ObjectArray<T>::ON_ObjectArray( int c )
00889 : ON_ClassArray<T>(c)
00890 {
00891 }
00892
00893 template <class T>
00894 T* ON_ObjectArray<T>::Realloc(T* ptr,int capacity)
00895 {
00896 T* reptr = (T*)onrealloc(ptr,capacity*sizeof(T));
00897 if ( ptr && reptr && reptr != ptr )
00898 {
00899
00900
00901 int i;
00902 for ( i = 0; i < this->m_count; i++ )
00903 {
00904 reptr[i].MemoryRelocate();
00905 }
00906 }
00907 return reptr;
00908 }
00909
00911
00913
00914
00915
00916
00917 template <class T>
00918 T* ON_ClassArray<T>::Realloc(T* ptr,int capacity)
00919 {
00920 return (T*)onrealloc(ptr,capacity*sizeof(T));
00921 }
00922
00923 template <class T>
00924 ON__UINT32 ON_ObjectArray<T>::DataCRC(ON__UINT32 current_remainder) const
00925 {
00926
00927
00928 int i;
00929 for ( i = 0; i < this->m_count; i++ )
00930 {
00931 current_remainder = this->m_a[i].DataCRC(current_remainder);
00932 }
00933 return current_remainder;
00934 }
00935
00936 template <class T>
00937 ON_ClassArray<T>::ON_ClassArray()
00938 : m_a(0),
00939 m_count(0),
00940 m_capacity(0)
00941 {}
00942
00943 template <class T>
00944 ON_ClassArray<T>::ON_ClassArray( int c )
00945 : m_a(0),
00946 m_count(0),
00947 m_capacity(0)
00948 {
00949 if ( c > 0 )
00950 SetCapacity( c );
00951 }
00952
00953
00954 template <class T>
00955 ON_ClassArray<T>::ON_ClassArray( const ON_ClassArray<T>& src )
00956 : m_a(0),
00957 m_count(0),
00958 m_capacity(0)
00959 {
00960 *this = src;
00961 }
00962
00963 template <class T>
00964 ON_ClassArray<T>::~ON_ClassArray()
00965 {
00966 SetCapacity(0);
00967 }
00968
00969 template <class T>
00970 ON_ClassArray<T>& ON_ClassArray<T>::operator=( const ON_ClassArray<T>& src )
00971 {
00972 int i;
00973 if( &src != this ) {
00974 if ( src.m_count <= 0 ) {
00975 m_count = 0;
00976 }
00977 else {
00978 if ( m_capacity < src.m_count ) {
00979 SetCapacity( src.m_count );
00980 }
00981 if ( m_a ) {
00982 m_count = src.m_count;
00983 for ( i = 0; i < m_count; i++ ) {
00984 m_a[i] = src.m_a[i];
00985 }
00986 }
00987 }
00988 }
00989 return *this;
00990 }
00991
00992
00993
00994 template <class T>
00995 void ON_ClassArray<T>::EmergencyDestroy(void)
00996 {
00997 m_count = 0;
00998 m_capacity = 0;
00999 m_a = 0;
01000 }
01001
01002
01003
01004 template <class T>
01005 int ON_ClassArray<T>::Count() const
01006 {
01007 return m_count;
01008 }
01009
01010 template <class T>
01011 unsigned int ON_ClassArray<T>::UnsignedCount() const
01012 {
01013 return ((unsigned int)m_count);
01014 }
01015
01016 template <class T>
01017 int ON_ClassArray<T>::Capacity() const
01018 {
01019 return m_capacity;
01020 }
01021
01022 template <class T>
01023 unsigned int ON_ClassArray<T>::SizeOfArray() const
01024 {
01025 return ((unsigned int)(m_capacity*sizeof(T)));
01026 }
01027
01028 template <class T>
01029 unsigned int ON_ClassArray<T>::SizeOfElement() const
01030 {
01031 return ((unsigned int)(sizeof(T)));
01032 }
01033
01034 template <class T>
01035 T& ON_ClassArray<T>::operator[]( int i )
01036 {
01037 #if defined(ON_DEBUG)
01038 if ( i < 0 || i > m_capacity )
01039 {
01040 ON_ERROR("ON_ClassArray[i]: i out of range.");
01041 }
01042 #endif
01043 return m_a[i];
01044 }
01045
01046
01047 template <class T>
01048 T& ON_ClassArray<T>::operator[]( ON__INT64 i )
01049 {
01050 #if defined(ON_DEBUG)
01051 if ( i < 0 || i > (ON__INT64)m_capacity )
01052 {
01053 ON_ERROR("ON_ClassArray[i]: i out of range.");
01054 }
01055 #endif
01056 return m_a[i];
01057 }
01058
01059 template <class T>
01060 T& ON_ClassArray<T>::operator[]( unsigned int i )
01061 {
01062 #if defined(ON_DEBUG)
01063 if ( i > (unsigned int)m_capacity )
01064 {
01065 ON_ERROR("ON_ClassArray[i]: i out of range.");
01066 }
01067 #endif
01068 return m_a[i];
01069 }
01070
01071 template <class T>
01072 T& ON_ClassArray<T>::operator[]( ON__UINT64 i )
01073 {
01074 #if defined(ON_DEBUG)
01075 if ( i > (ON__UINT64)m_capacity )
01076 {
01077 ON_ERROR("ON_ClassArray[i]: i out of range.");
01078 }
01079 #endif
01080 return m_a[i];
01081 }
01082
01083 template <class T>
01084 const T& ON_ClassArray<T>::operator[](int i) const
01085 {
01086 #if defined(ON_DEBUG)
01087 if ( i < 0 || i > m_capacity )
01088 {
01089 ON_ERROR("ON_ClassArray[i]: i out of range.");
01090 }
01091 #endif
01092 return m_a[i];
01093 }
01094
01095 template <class T>
01096 const T& ON_ClassArray<T>::operator[](ON__INT64 i) const
01097 {
01098 #if defined(ON_DEBUG)
01099 if ( i < 0 || i > (ON__INT64)m_capacity )
01100 {
01101 ON_ERROR("ON_ClassArray[i]: i out of range.");
01102 }
01103 #endif
01104 return m_a[i];
01105 }
01106
01107 template <class T>
01108 const T& ON_ClassArray<T>::operator[](unsigned int i) const
01109 {
01110 #if defined(ON_DEBUG)
01111 if ( i > (unsigned int)m_capacity )
01112 {
01113 ON_ERROR("ON_ClassArray[i]: i out of range.");
01114 }
01115 #endif
01116 return m_a[i];
01117 }
01118
01119 template <class T>
01120 const T& ON_ClassArray<T>::operator[](ON__UINT64 i) const
01121 {
01122 #if defined(ON_DEBUG)
01123 if ( i > (ON__UINT64)m_capacity )
01124 {
01125 ON_ERROR("ON_ClassArray[i]: i out of range.");
01126 }
01127 #endif
01128 return m_a[i];
01129 }
01130
01131 template <class T>
01132 ON_ClassArray<T>::operator T*()
01133 {
01134 return (m_count > 0) ? m_a : 0;
01135 }
01136
01137 template <class T>
01138 ON_ClassArray<T>::operator const T*() const
01139 {
01140 return (m_count > 0) ? m_a : 0;
01141 }
01142
01143 template <class T>
01144 T* ON_ClassArray<T>::Array()
01145 {
01146 return m_a;
01147 }
01148
01149 template <class T>
01150 const T* ON_ClassArray<T>::Array() const
01151 {
01152 return m_a;
01153 }
01154
01155 template <class T>
01156 T* ON_ClassArray<T>::KeepArray()
01157 {
01158 T* p = m_a;
01159 m_a = 0;
01160 m_count = 0;
01161 m_capacity = 0;
01162 return p;
01163 }
01164
01165 template <class T>
01166 void ON_ClassArray<T>::SetArray(T* p)
01167 {
01168 if ( m_a && m_a != p )
01169 Destroy();
01170 m_a = p;
01171 }
01172
01173 template <class T>
01174 void ON_ClassArray<T>::SetArray(T* p, int count, int capacity)
01175 {
01176 if ( m_a && m_a != p )
01177 Destroy();
01178 m_a = p;
01179 m_count = count;
01180 m_capacity = capacity;
01181 }
01182
01183 template <class T>
01184 T* ON_ClassArray<T>::First()
01185 {
01186 return (m_count > 0) ? m_a : 0;
01187 }
01188
01189 template <class T>
01190 const T* ON_ClassArray<T>::First() const
01191 {
01192 return (m_count > 0) ? m_a : 0;
01193 }
01194
01195 template <class T>
01196 T* ON_ClassArray<T>::At( int i )
01197 {
01198 return (i >= 0 && i < m_count) ? m_a+i : 0;
01199 }
01200
01201 template <class T>
01202 T* ON_ClassArray<T>::At( unsigned int i )
01203 {
01204 return (i < (unsigned int)m_count) ? m_a+i : 0;
01205 }
01206
01207 template <class T>
01208 const T* ON_ClassArray<T>::At( int i) const
01209 {
01210 return (i >= 0 && i < m_count) ? m_a+i : 0;
01211 }
01212
01213 template <class T>
01214 const T* ON_ClassArray<T>::At( unsigned int i) const
01215 {
01216 return (i < (unsigned int)m_count) ? m_a+i : 0;
01217 }
01218
01219
01220 template <class T>
01221 T* ON_ClassArray<T>::At( ON__INT64 i )
01222 {
01223 return (i >= 0 && i < (ON__INT64)m_count) ? m_a+i : 0;
01224 }
01225
01226 template <class T>
01227 T* ON_ClassArray<T>::At( ON__UINT64 i )
01228 {
01229 return (i < (ON__UINT64)m_count) ? m_a+i : 0;
01230 }
01231
01232 template <class T>
01233 const T* ON_ClassArray<T>::At( ON__INT64 i) const
01234 {
01235 return (i >= 0 && i < (ON__INT64)m_count) ? m_a+i : 0;
01236 }
01237
01238 template <class T>
01239 const T* ON_ClassArray<T>::At( ON__UINT64 i) const
01240 {
01241 return (i < (ON__UINT64)m_count) ? m_a+i : 0;
01242 }
01243
01244
01245 template <class T>
01246 T* ON_ClassArray<T>::Last()
01247 {
01248 return (m_count > 0) ? m_a+(m_count-1) : 0;
01249 }
01250
01251 template <class T>
01252 const T* ON_ClassArray<T>::Last() const
01253 {
01254 return (m_count > 0) ? m_a+(m_count-1) : 0;
01255 }
01256
01257
01258
01259 template <class T>
01260 void ON_ClassArray<T>::Move( int dest_i, int src_i, int ele_cnt )
01261 {
01262
01263
01264
01265 if ( ele_cnt <= 0 || src_i < 0 || dest_i < 0 || src_i == dest_i ||
01266 src_i + ele_cnt > m_count || dest_i > m_count )
01267 return;
01268
01269 int capacity = dest_i + ele_cnt;
01270 if ( capacity > m_capacity ) {
01271 if ( capacity < 2*m_capacity )
01272 capacity = 2*m_capacity;
01273 SetCapacity( capacity );
01274 }
01275
01276
01277
01278
01279
01280 memmove( (void*)(&m_a[dest_i]), (const void*)(&m_a[src_i]), ele_cnt*sizeof(T) );
01281 }
01282
01283 template <class T>
01284 void ON_ClassArray<T>::ConstructDefaultElement(T* p)
01285 {
01286
01287
01288 new(p) T;
01289 }
01290
01291 template <class T>
01292 void ON_ClassArray<T>::DestroyElement(T& x)
01293 {
01294 x.~T();
01295 }
01296
01297 template <class T>
01298 T& ON_ClassArray<T>::AppendNew()
01299 {
01300 if ( m_count == m_capacity )
01301 {
01302 int newcapacity = NewCapacity();
01303 Reserve( newcapacity );
01304 }
01305 else
01306 {
01307
01308 DestroyElement(m_a[m_count]);
01309
01310 ConstructDefaultElement(&m_a[m_count]);
01311 }
01312 return m_a[m_count++];
01313 }
01314
01315 template <class T>
01316 void ON_ClassArray<T>::Append( const T& x )
01317 {
01318 if ( m_count == m_capacity )
01319 {
01320 const int newcapacity = NewCapacity();
01321 if (m_a)
01322 {
01323 const int s = (int)(&x - m_a);
01324 if ( s >= 0 && s < m_capacity )
01325 {
01326
01327
01328
01329
01330 T temp;
01331 temp = x;
01332 Reserve( newcapacity );
01333 m_a[m_count++] = temp;
01334 return;
01335 }
01336 }
01337 Reserve(newcapacity);
01338 }
01339 m_a[m_count++] = x;
01340 }
01341
01342 template <class T>
01343 void ON_ClassArray<T>::Append( int count, const T* p )
01344 {
01345 int i;
01346 if ( count > 0 && p )
01347 {
01348 if ( count + m_count > m_capacity )
01349 {
01350 int newcapacity = NewCapacity();
01351 if ( newcapacity < count + m_count )
01352 newcapacity = count + m_count;
01353 Reserve( newcapacity );
01354 }
01355 for ( i = 0; i < count; i++ ) {
01356 m_a[m_count++] = p[i];
01357 }
01358 }
01359 }
01360
01361
01362 template <class T>
01363 void ON_ClassArray<T>::Insert( int i, const T& x )
01364 {
01365 if( i >= 0 && i <= m_count )
01366 {
01367 if ( m_count == m_capacity )
01368 {
01369 int newcapacity = NewCapacity();
01370 Reserve( newcapacity );
01371 }
01372 DestroyElement( m_a[m_count] );
01373 m_count++;
01374 if ( i < m_count-1 ) {
01375 Move( i+1, i, m_count-1-i );
01376
01377
01378 memset( (void*)(&m_a[i]), 0, sizeof(T) );
01379 ConstructDefaultElement( &m_a[i] );
01380 }
01381 else {
01382 ConstructDefaultElement( &m_a[m_count-1] );
01383 }
01384 m_a[i] = x;
01385 }
01386 }
01387
01388 template <class T>
01389 void ON_ClassArray<T>::Remove( )
01390 {
01391 Remove(m_count-1);
01392 }
01393
01394 template <class T>
01395 void ON_ClassArray<T>::Remove( int i )
01396 {
01397 if ( i >= 0 && i < m_count )
01398 {
01399 DestroyElement( m_a[i] );
01400
01401
01402 memset( (void*)(&m_a[i]), 0, sizeof(T) );
01403 Move( i, i+1, m_count-1-i );
01404
01405
01406 memset( (void*)(&m_a[m_count-1]), 0, sizeof(T) );
01407 ConstructDefaultElement(&m_a[m_count-1]);
01408 m_count--;
01409 }
01410 }
01411
01412 template <class T>
01413 void ON_ClassArray<T>::Empty()
01414 {
01415 int i;
01416 for ( i = m_count-1; i >= 0; i-- ) {
01417 DestroyElement( m_a[i] );
01418
01419
01420 memset( (void*)(&m_a[i]), 0, sizeof(T) );
01421 ConstructDefaultElement( &m_a[i] );
01422 }
01423 m_count = 0;
01424 }
01425
01426 template <class T>
01427 void ON_ClassArray<T>::Reverse()
01428 {
01429
01430
01431
01432 char t[sizeof(T)];
01433 int i = 0;
01434 int j = m_count-1;
01435 for ( ; i < j; i++, j-- ) {
01436 memcpy( t, &m_a[i], sizeof(T) );
01437 memcpy( &m_a[i], &m_a[j], sizeof(T) );
01438 memcpy( &m_a[j], t, sizeof(T) );
01439 }
01440 }
01441
01442 template <class T>
01443 void ON_ClassArray<T>::Swap( int i, int j )
01444 {
01445 if ( i != j && i >= 0 && j >= 0 && i < m_count && j < m_count ) {
01446 char t[sizeof(T)];
01447 memcpy( t, &m_a[i], sizeof(T) );
01448 memcpy( &m_a[i], &m_a[j], sizeof(T) );
01449 memcpy( &m_a[j], t, sizeof(T) );
01450 }
01451 }
01452
01453 template <class T>
01454 int ON_ClassArray<T>::Search( const T* key, int (*compar)(const T*,const T*) ) const
01455 {
01456 for ( int i = 0; i < m_count; i++ )
01457 {
01458 if (!compar(key,m_a+i))
01459 return i;
01460 }
01461 return -1;
01462 }
01463
01464 template <class T>
01465 int ON_ClassArray<T>::BinarySearch( const T* key, int (*compar)(const T*,const T*) ) const
01466 {
01467 const T* found = (key&&m_a&&m_count>0) ? (const T*)bsearch( key, m_a, m_count, sizeof(T), (int(*)(const void*,const void*))compar ) : 0;
01468 #if defined(ON_COMPILER_MSC1300)
01469
01470 return found ? ((int)(found - m_a)) : -1;
01471 #else
01472
01473 return found ? ((int)((((ON__UINT64)found) - ((ON__UINT64)m_a))/sizeof(T))) : -1;
01474 #endif
01475 }
01476
01477 template <class T>
01478 int ON_ClassArray<T>::BinarySearch( const T* key, int (*compar)(const T*,const T*), int count ) const
01479 {
01480 if ( count > m_count )
01481 count = m_count;
01482 if ( count <= 0 )
01483 return -1;
01484 const T* found = (key&&m_a&&m_count>0) ? (const T*)bsearch( key, m_a, count, sizeof(T), (int(*)(const void*,const void*))compar ) : 0;
01485 #if defined(ON_COMPILER_MSC1300)
01486
01487 return found ? ((int)(found - m_a)) : -1;
01488 #else
01489
01490 return found ? ((int)((((ON__UINT64)found) - ((ON__UINT64)m_a))/sizeof(T))) : -1;
01491 #endif
01492 }
01493
01494 template <class T>
01495 bool ON_ClassArray<T>::HeapSort( int (*compar)(const T*,const T*) )
01496 {
01497 bool rc = false;
01498 if ( m_a && m_count > 0 && compar )
01499 {
01500 if ( m_count > 1 )
01501 ON_hsort( m_a, m_count, sizeof(T), (int(*)(const void*,const void*))compar );
01502 rc = true;
01503 }
01504 return rc;
01505 }
01506
01507 template <class T>
01508 bool ON_ClassArray<T>::QuickSort( int (*compar)(const T*,const T*) )
01509 {
01510 bool rc = false;
01511 if ( m_a && m_count > 0 && compar )
01512 {
01513 if ( m_count > 1 )
01514 ON_qsort( m_a, m_count, sizeof(T), (int(*)(const void*,const void*))compar );
01515 rc = true;
01516 }
01517 return rc;
01518 }
01519
01520
01521
01522 template <class T>
01523 bool ON_ObjectArray<T>::HeapSort( int (*compar)(const T*,const T*) )
01524 {
01525 bool rc = false;
01526
01527
01528 if ( this->m_a && this->m_count > 0 && compar )
01529 {
01530 if ( this->m_count > 1 )
01531 {
01532 ON_hsort( this->m_a, this->m_count, sizeof(T), (int(*)(const void*,const void*))compar );
01533
01534
01535
01536 int i;
01537 for ( i = 0; i < this->m_count; i++ )
01538 {
01539 this->m_a[i].MemoryRelocate();
01540 }
01541 }
01542 rc = true;
01543 }
01544 return rc;
01545 }
01546
01547 template <class T>
01548 bool ON_ObjectArray<T>::QuickSort( int (*compar)(const T*,const T*) )
01549 {
01550 bool rc = false;
01551
01552
01553 if ( this->m_a && this->m_count > 0 && compar )
01554 {
01555 if ( this->m_count > 1 )
01556 {
01557 ON_qsort( this->m_a, this->m_count, sizeof(T), (int(*)(const void*,const void*))compar );
01558
01559
01560
01561 int i;
01562 for ( i = 0; i < this->m_count; i++ )
01563 {
01564 this->m_a[i].MemoryRelocate();
01565 }
01566 }
01567 rc = true;
01568 }
01569 return rc;
01570 }
01571
01572
01573 template <class T>
01574 bool ON_ClassArray<T>::Sort( ON::sort_algorithm sa, int* index, int (*compar)(const T*,const T*) ) const
01575 {
01576 bool rc = false;
01577 if ( m_a && m_count > 0 && compar && index )
01578 {
01579 if ( m_count > 1 )
01580 ON_Sort(sa, index, m_a, m_count, sizeof(T), (int(*)(const void*,const void*))compar );
01581 else if ( m_count == 1 )
01582 index[0] = 0;
01583 rc = true;
01584 }
01585 return rc;
01586 }
01587
01588 template <class T>
01589 bool ON_ClassArray<T>::Sort( ON::sort_algorithm sa, int* index, int (*compar)(const T*,const T*,void*),void* p ) const
01590 {
01591 bool rc = false;
01592 if ( m_a && m_count > 0 && compar && index )
01593 {
01594 if ( m_count > 1 )
01595 ON_Sort(sa, index, m_a, m_count, sizeof(T), (int(*)(const void*,const void*,void*))compar, p );
01596 else if ( m_count == 1 )
01597 index[0] = 0;
01598 rc = true;
01599 }
01600 return rc;
01601 }
01602
01603 template <class T>
01604 bool ON_ClassArray<T>::Permute( const int* index )
01605 {
01606 bool rc = false;
01607 if ( m_a && m_count > 0 && index )
01608 {
01609 int i;
01610 T* buffer = (T*)onmalloc(m_count*sizeof(buffer[0]));
01611 memcpy( buffer, m_a, m_count*sizeof(T) );
01612 for (i = 0; i < m_count; i++ )
01613 memcpy( m_a+i, buffer+index[i], sizeof(T) );
01614 onfree(buffer);
01615 rc = true;
01616 }
01617 return rc;
01618 }
01619
01620 template <class T>
01621 void ON_ClassArray<T>::Zero()
01622 {
01623 int i;
01624 if ( m_a && m_capacity > 0 ) {
01625 for ( i = m_capacity-1; i >= 0; i-- ) {
01626 DestroyElement(m_a[i]);
01627
01628
01629 memset( (void*)(&m_a[i]), 0, sizeof(T) );
01630 ConstructDefaultElement(&m_a[i]);
01631 }
01632 }
01633 }
01634
01635
01636
01637 template <class T>
01638 void ON_ClassArray<T>::Reserve( int newcap )
01639 {
01640 if( m_capacity < newcap )
01641 SetCapacity( newcap );
01642 }
01643
01644 template <class T>
01645 void ON_ClassArray<T>::Shrink()
01646 {
01647 SetCapacity( m_count );
01648 }
01649
01650 template <class T>
01651 void ON_ClassArray<T>::Destroy()
01652 {
01653 SetCapacity( 0 );
01654 }
01655
01656
01657
01658 template <class T>
01659 void ON_ClassArray<T>::SetCount( int count )
01660 {
01661 if ( count >= 0 && count <= m_capacity )
01662 m_count = count;
01663 }
01664
01665 template <class T>
01666 void ON_ClassArray<T>::SetCapacity( int capacity )
01667 {
01668
01669 int i;
01670 if ( capacity < 1 ) {
01671 if ( m_a ) {
01672 for ( i = m_capacity-1; i >= 0; i-- ) {
01673 DestroyElement(m_a[i]);
01674 }
01675 Realloc(m_a,0);
01676 m_a = 0;
01677 }
01678 m_count = 0;
01679 m_capacity = 0;
01680 }
01681 else if ( m_capacity < capacity ) {
01682
01683 m_a = Realloc( m_a, capacity );
01684
01685 if ( 0 != m_a )
01686 {
01687
01688
01689
01690
01691 memset( (void*)(m_a + m_capacity), 0, (capacity-m_capacity)*sizeof(T) );
01692 for ( i = m_capacity; i < capacity; i++ ) {
01693 ConstructDefaultElement(&m_a[i]);
01694 }
01695 m_capacity = capacity;
01696 }
01697 else
01698 {
01699
01700 m_capacity = 0;
01701 m_count = 0;
01702 }
01703 }
01704 else if ( m_capacity > capacity ) {
01705
01706 for ( i = m_capacity-1; i >= capacity; i-- ) {
01707 DestroyElement(m_a[i]);
01708 }
01709 if ( m_count > capacity )
01710 m_count = capacity;
01711 m_capacity = capacity;
01712 m_a = Realloc( m_a, capacity );
01713 if ( 0 == m_a )
01714 {
01715
01716 m_capacity = 0;
01717 m_count = 0;
01718 }
01719 }
01720 }
01721
01725
01726 template< class T>
01727 static
01728 int ON_CompareIncreasing( const T* a, const T* b)
01729 {
01730 if( *a < *b )
01731 return -1;
01732 if( *b < *a )
01733 return 1;
01734 return 0;
01735 }
01736
01737 template< class T>
01738 static
01739 int ON_CompareDecreasing( const T* a, const T* b)
01740 {
01741 if( *b < *a )
01742 return -1;
01743 if( *a < *b )
01744 return 1;
01745 return 0;
01746 }
01747
01748 #if defined(ON_COMPILER_MSC)
01749 #pragma warning(pop)
01750 #endif
01751
01752 #endif