00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef GUL_TYPES_H
00021 #define GUL_TYPES_H
00022
00023
00024 #ifdef __GNUC__
00025
00026
00027
00028
00029
00030 #ifndef alloca
00031 #define alloca __builtin_alloca
00032 #endif
00033
00034 #endif
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #define ALIGNMENT 8
00048 #define POOL_ALIGNMENT (ALIGNMENT > sizeof(void*) ? ALIGNMENT : sizeof(void*))
00049
00050 #ifdef KAI_BSD_HACK
00051 #include <sys/cdefs.h>
00052 #include <machine/ansi.h>
00053 #undef _BSD_WCHAR_T_
00054 #endif
00055
00056 #include <cstddef>
00057 #include <stdlib.h>
00058 #include <string.h>
00059 #include <limits.h>
00060 #include <float.h>
00061 #include <math.h>
00062
00063 #ifdef RANGECHECK
00064 #include <iostream>
00065 #endif
00066
00067 #ifdef _MSC_VER
00068 #include <malloc.h>
00069 #ifdef USEDLL
00070 #ifdef CREATE_GUL_DLL
00071 #define GULAPI __declspec(dllexport)
00072 #else
00073 #define GULAPI __declspec(dllimport)
00074 #endif
00075 #else
00076 #define GULAPI
00077 #endif
00078 #else
00079 #define GULAPI
00080 #endif
00081
00082 #ifdef _MSC_VER
00083 GULAPI void *test_gul_dll_malloc( size_t s );
00084 GULAPI void test_gul_dll_free( void *s );
00085
00086
00087 GULAPI void gul_halt( void );
00088 #endif
00089
00090 #if (defined(__MINGW32__)) || (defined(_MSC_VER))
00091
00092 GULAPI double scalbn(double,int);
00093 GULAPI int ilogb(double);
00094 GULAPI long random(void);
00095 GULAPI void srandom(long);
00096 #endif
00097
00098 #include "gul_error.h"
00099 #include "gust_pool.h"
00100 #include "gust_new.h"
00101
00102
00103
00104
00105
00106 namespace gul
00107 {
00108 #ifndef NDEBUG
00109 const bool ndebug=false;
00110 #else
00111 const bool ndebug=true;
00112 #endif
00113
00114 #ifdef _MSC_VER
00115 typedef unsigned _int64 uint64;
00116 typedef _int64 int64;
00117 #define isinf(f) (!_finite((f)))
00118
00119 #define LL(i) i##i64
00120 #else
00121 #ifdef __BORLANDC__
00122 typedef unsigned __int64 uint64;
00123 typedef __int64 int64;
00124 #define isinf(f) (!_finite((f)))
00125
00126 #define LL(i) i##i64
00127 #else
00128 typedef unsigned long long uint64;
00129 typedef long long int64;
00130 #ifdef __MINGW32__
00131
00132
00133 #endif
00134
00135 #define LL(i) i##LL
00136 #endif
00137 #endif
00138
00139 typedef unsigned long uint32;
00140 typedef long int32;
00141
00142 template< class T >
00143 inline int compare( const T& a, const T& b )
00144 {
00145 if( a < b )
00146 return -1;
00147 else if( a == b )
00148 return 0;
00149 return 1;
00150 }
00151 template< class T >
00152 inline int test( const T& a )
00153 {
00154 if( a < 0 ) return -1;
00155 else if( a == 0 ) return 0;
00156 return 1;
00157 }
00158
00159 template< class T > struct rtr
00160 {
00161 };
00162
00163 template<> struct rtr< float >
00164 {
00165 static float epsilon() { return FLT_EPSILON; }
00166 static float epsilon_inv() { return 1.0f/FLT_EPSILON; }
00167 static float zero_tol() { return 1.e-4f; }
00168 static size_t mantissa_length() { return 4; }
00169 static float maximum() { return FLT_MAX; }
00170 static float minimum() { return FLT_MIN; }
00171 static float pi() { return 3.14159265358979323846f; }
00172 static float pi_180() { return 3.14159265358979323846f/180.0f; }
00173 static float pi_180_inv() { return 180.0f/3.14159265358979323846f; }
00174 static float root2_2() { return 1.41421356237309514547f; }
00175 static float root2_3() { return 1.7320508076887719318f; }
00176 static float golden_r() { return 0.61803399f; }
00177 static float golden_c() { return 1.0f-golden_r(); }
00178
00179
00180 static float tiny() { return 1e-20f; }
00181 static float giant() { return 1.0f/tiny(); }
00182
00183
00184
00185
00186
00187 static float zero() { return 0.0f; }
00188 static float one() { return 1.0f; }
00189
00190 static float **m_BinCoeff;
00191 static int m_BinCoeff_Pmax;
00192 static void InitBinCoeff( const int Pmax );
00193 static void ExitBinCoeff();
00194 static float BinCoeff( const int p, const int k )
00195 {
00196 if( (k > p) || (k < 0) || (p < 0) ) return 0.0;
00197 if( p > m_BinCoeff_Pmax ) InitBinCoeff( p );
00198 return m_BinCoeff[p][k];
00199 }
00200 #if (!defined(__MINGW32__)) && (!defined(__BORLANDC__)) && (!defined(sun)) && \
00201 (!defined(_MSC_VER))
00202 static float floor( const float a ) { return ::floorf(a); }
00203 static float ceil( const float a ) { return ::ceilf(a); }
00204 static float fabs( const float a ) { return ::fabsf(a); }
00205 static float sqrt( const float a ) { return ::sqrtf(a); }
00206 static float sin( const float a ) { return ::sinf(a); }
00207 static float cos( const float a ) { return ::cosf(a); }
00208 static float acos( const float a ) { return ::acosf(a); }
00209
00210 static int ilogb( const float a ) { return ::ilogbf(a); }
00211 static float scalbn( const float x, int n ) { return ::scalbnf(x,n); }
00212 #else
00213
00214 static float floor( const float a ) { return (float)::floor((double)a); }
00215 static float ceil( const float a ) { return (float)::ceil((double)a); }
00216 static float fabs( const float a ) { return (float)::fabs((double)a); }
00217 static float sqrt( const float a ) { return (float)::sqrt((double)a); }
00218 static float sin( const float a ) { return (float)::sin((double)a); }
00219 static float cos( const float a ) { return (float)::cos((double)a); }
00220 static float acos( const float a ) { return (float)::acos((double)a); }
00221
00222 static int ilogb( const float a ) { return ::ilogb((double)a); }
00223 static float scalbn(const float x, int n)
00224 { return (float)::scalbn((double)x,n); }
00225 #endif
00226 static float rad( const float d ) { return d * pi_180(); }
00227 static float deg( const float r ) { return r * pi_180_inv(); }
00228 static int cmp( const float a, const float b ) { return compare<float>(a,b);}
00229
00230 static int id() { return(1); }
00231 };
00232
00233 template<> struct rtr< double >
00234 {
00235 static double epsilon() { return DBL_EPSILON; }
00236 static double epsilon_inv() { return 1.0/DBL_EPSILON; }
00237 static double zero_tol() { return 1.0e-9; }
00238 static size_t mantissa_length() { return 8; }
00239 static double maximum() { return DBL_MAX; }
00240 static double minimum() { return DBL_MIN; }
00241 static double pi() { return 3.14159265358979323846; }
00242 static double pi_180() { return 3.14159265358979323846/180.0; }
00243 static double pi_180_inv() { return 180.0/3.14159265358979323846; }
00244 static double root2_2() { return 1.41421356237309514547; }
00245 static double root2_3() { return 1.7320508076887719318; }
00246 static double golden_r() { return 0.61803399; }
00247 static double golden_c() { return 1.0-golden_r(); }
00248
00249
00250 static double tiny() { return 1e-40; }
00251 static double giant() { return 1.0f/tiny(); }
00252
00253
00254
00255
00256
00257 static float zero() { return 0.0; }
00258 static float one() { return 1.0; }
00259
00260 static double **m_BinCoeff;
00261 static int m_BinCoeff_Pmax;
00262 static void InitBinCoeff( const int Pmax );
00263 static void ExitBinCoeff();
00264 static double BinCoeff( const int p, const int k )
00265 {
00266 if( (k > p) || (k < 0) || (p < 0) ) return 0.0f;
00267 if( p > m_BinCoeff_Pmax ) InitBinCoeff( p );
00268 return m_BinCoeff[p][k];
00269 }
00270 static double floor( const double a ) { return ::floor(a); }
00271 static double ceil( const double a ) { return ::ceil(a); }
00272 static double fabs( const double a ) { return ::fabs(a); }
00273 static double sqrt( const double a ) { return ::sqrt(a); }
00274 static double sin( const double a ) { return ::sin(a); }
00275 static double cos( const double a ) { return ::cos(a); }
00276 static double acos( const double a ) { return ::acos(a); }
00277
00278 static int ilogb( const double a ) { return ::ilogb(a); }
00279 static double scalbn( const double x, int n ) { return ::scalbn(x,n); }
00280
00281 static double rad( const double d ) { return d * pi_180(); }
00282 static double deg( const double r ) { return r * pi_180_inv(); }
00283 static int cmp( const double a, const double b ){return compare<double>(a,b);}
00284
00285 static int id() { return(2); }
00286 };
00287
00288 template<> struct rtr< int >
00289 {
00290 static int id() { return(3); }
00291 };
00292
00293 template<> struct rtr< unsigned int >
00294 {
00295 static int id() { return(4); }
00296 };
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349 template< class T >
00350 inline T Max( const T& a, const T& b ) { return a > b ? a : b; }
00351 template< class T >
00352 inline T Min( const T& a, const T& b ) { return a < b ? a : b; }
00353
00354 template< class T >
00355 inline T Max( const T& a, const T& b, const T& c )
00356 { if((a > b) && (a > c)) return a;
00357 else if(b > c) return b;
00358 return c;
00359 }
00360 template< class T >
00361 inline T Min( const T& a, const T& b, const T& c )
00362 { if((a < b) && (a < c)) return a;
00363 else if(b < c) return b;
00364 return c;
00365 }
00366
00367 template< class T >
00368 inline void Swap( T& a, T& b ) { T tmp=a; a=b; b=tmp; }
00369 template< class T >
00370 inline T Square( const T& a ) { return a*a; }
00371
00372 template< class T > inline T Sign( const T& a, const T& b )
00373 { return (b < 0.0 ? -rtr<T>::fabs(a) : rtr<T>::fabs(a)); }
00374
00375
00376
00377
00378
00379
00380
00381 union ptr_int_union
00382 {
00383 void *p;
00384 int i;
00385 void set_i( int ii ) { p = 0; i = ii; }
00386 };
00387
00388
00389
00390
00391
00392 template < class T >
00393 class Ptr
00394 {
00395 template< class M >
00396 struct Ptr_rep
00397 {
00398 T *m_ptr;
00399 unsigned int m_refs;
00400 unsigned int m_type : 2;
00401 unsigned int m_size : 30;
00402 unsigned int m_nelems;
00403
00404 Ptr_rep( T *p, unsigned int i, unsigned int t, size_t s, unsigned int n) :
00405 m_ptr(p), m_refs(i), m_type(t), m_nelems(n)
00406 {
00407 #ifdef RANGECHECK
00408 if( s > 0x3fffffff )
00409 {
00410 std::cout << "Ptr: array is too big\n";
00411 std::cout.flush();
00412 gul_halt();
00413 }
00414 #endif
00415
00416 m_size = (unsigned int)s;
00417 }
00418
00419 inline ~Ptr_rep()
00420 {
00421 T *p = m_ptr;
00422
00423 if( m_type != gust::dumb )
00424 {
00425 for( unsigned int j = 0; j < m_nelems; j++ )
00426 {
00427 p->~T();
00428 p++;
00429 }
00430 }
00431 gust::release((void *)m_ptr, m_type, m_size);
00432 }
00433
00434
00435 void shrink( unsigned int n )
00436 {
00437 if( m_type != gust::dumb )
00438 for( int i = n; i < m_nelems; i++ ) m_ptr[i].~T();
00439 m_nelems = n;
00440 }
00441
00442
00443 void realloc(unsigned int n)
00444 {
00445 if( m_type == heap )
00446 {
00447 m_ptr = (T *)::realloc( m_ptr, sizeof(T)*n );
00448 m_size = sizeof(T)*n;
00449 m_nelems = n;
00450 }
00451 else if( m_size < sizeof(T)*n )
00452 throw InternalError();
00453 }
00454 };
00455
00456 Ptr_rep<T> *m_rep;
00457
00458 public:
00459 explicit Ptr( T *p = 0, unsigned int t = 0, size_t s = 0,
00460 unsigned int n = 0 )
00461 {
00462 size_t dummy;
00463
00464 if( p != 0 )
00465 {
00466 m_rep = (Ptr_rep<T> *)gust::PoolAlloc( sizeof(Ptr_rep<T>), &dummy );
00467 if( m_rep == 0 ) throw gul::AllocError();
00468
00469 ::new(m_rep) Ptr_rep<T>(p,1,t,s,n);
00470 }
00471 else
00472 m_rep = 0;
00473 }
00474
00475 Ptr( const Ptr& other )
00476 {
00477 if( other.m_rep ) other.m_rep->m_refs++;
00478 m_rep = other.m_rep;
00479 }
00480
00481 Ptr& operator=( const Ptr& other )
00482 {
00483 if( other.m_rep ) other.m_rep->m_refs++;
00484
00485 if( (m_rep != 0) && (--m_rep->m_refs == 0) )
00486 {
00487 m_rep->~Ptr_rep<T>();
00488 gust::PoolFree( m_rep, sizeof(Ptr_rep<T>) );
00489 }
00490
00491 m_rep = other.m_rep;
00492
00493 return( *this );
00494 }
00495
00496 ~Ptr()
00497 {
00498 if( (m_rep != 0) && (--m_rep->m_refs == 0) )
00499 {
00500 m_rep->~Ptr_rep<T>();
00501 gust::PoolFree( m_rep, sizeof(Ptr_rep<T>) );
00502 }
00503 }
00504
00505
00506 int nElems() const
00507 {
00508 if( m_rep != 0 )
00509 return m_rep->m_nelems;
00510 else
00511 return 0;
00512 }
00513 const Ptr_rep<T> *rep( void ) const { return m_rep; }
00514
00515 void reset( T *p, unsigned int r, unsigned int t, size_t s,
00516 unsigned int n )
00517 {
00518 size_t dummy;
00519
00520 if( m_rep == 0 )
00521 {
00522 m_rep = (Ptr_rep<T> *)gust::PoolAlloc( sizeof(Ptr_rep<T>), &dummy );
00523 if( m_rep == 0 ) throw gul::AllocError();
00524 }
00525 else
00526 {
00527 if( --(m_rep->m_refs) == 0 )
00528 {
00529 m_rep->~Ptr_rep<T>();
00530 }
00531 else
00532 {
00533 m_rep = (Ptr_rep<T> *)gust::PoolAlloc( sizeof(Ptr_rep<T>), &dummy );
00534 if( m_rep == 0 ) throw gul::AllocError();
00535 }
00536 }
00537 ::new(m_rep) Ptr_rep<T>(p,r,t,s,n);
00538 }
00539
00540
00541
00542 void use_pointer( T *p, unsigned int n )
00543 {
00544 size_t dummy;
00545
00546 if( m_rep == 0 )
00547 {
00548 m_rep = (Ptr_rep<T> *)gust::PoolAlloc( sizeof(Ptr_rep<T>), &dummy );
00549 if( m_rep == 0 ) throw gul::AllocError();
00550 }
00551 else
00552 {
00553 if( --(m_rep->m_refs) == 0 )
00554 {
00555 m_rep->~Ptr_rep<T>();
00556 }
00557 else
00558 {
00559 m_rep = (Ptr_rep<T> *)gust::PoolAlloc( sizeof(Ptr_rep<T>), &dummy );
00560 if( m_rep == 0 ) throw gul::AllocError();
00561 }
00562 }
00563 ::new(m_rep) Ptr_rep<T>(p,1,gust::dumb,0,n);
00564 }
00565
00566 void reserve_global( unsigned int n )
00567 {
00568 size_t s;
00569 T *p = (T *)gust::reserve_global( n*sizeof(T), &s );
00570
00571 reset( p, 1, gust::heap, s, n );
00572 for( size_t i = 0; i < n; i++ ) ::new(p++) T();
00573 }
00574
00575 void reserve_pool( unsigned int n )
00576 {
00577 size_t s;
00578 T *p = (T *)gust::reserve_pool( n*sizeof(T), &s );
00579
00580 reset( p, 1, gust::pool, s, n );
00581 for( size_t i = 0; i < n; i++ ) ::new(p++) T();
00582 }
00583
00584 void reserve_place( void *buf, unsigned int n )
00585 {
00586 T *p = (T *)buf;
00587 reset( p, 1, gust::place, n*sizeof(T), n );
00588 for( size_t i = 0; i < n; i++ ) ::new(p++) T();
00589 }
00590
00591
00592 void reset()
00593 {
00594 if( m_rep == 0 ) return;
00595
00596 if( --(m_rep->m_refs) == 0 )
00597 {
00598 m_rep->~Ptr_rep<T>();
00599 gust::PoolFree( m_rep, sizeof(Ptr_rep<T>) );
00600 }
00601 m_rep = 0;
00602 }
00603
00604 void shrink(unsigned int n)
00605 {
00606 if( m_rep == 0 ) throw gul::Error();
00607 m_rep->shrink(n);
00608 }
00609 T& operator*() const
00610 {
00611 #ifdef RANGECHECK
00612 if( nElems() <= 0 )
00613 {
00614 cout << "Ptr: pointer not initialized\n";
00615 cout.flush();
00616 gul_halt();
00617 }
00618 #endif
00619 return *(m_rep->m_ptr);
00620 }
00621 T& operator[](int i) const
00622 {
00623 #ifdef RANGECHECK
00624 if( (i >= nElems()) || (i < 0) )
00625 {
00626 std::cout << "Ptr: accessing elements behind array bounds\n";
00627 std::cout.flush();
00628 gul_halt();
00629 }
00630 if( m_rep && m_rep->m_size )
00631 {
00632 if( (size_t)i*sizeof(T) >= m_rep->m_size )
00633 {
00634 std::cout << "Ptr: size and element count don't match\n";
00635 std::cout.flush();
00636 gul_halt();
00637 }
00638 }
00639 #endif
00640 return (m_rep->m_ptr)[i];
00641 }
00642
00643
00644 T* get() const { return m_rep->m_ptr; }
00645
00646
00647 T* release()
00648 {
00649 if( (m_rep == 0) || (m_rep->m_refs != 1) )
00650 throw Error();
00651 T *p = m_rep->m_ptr;
00652 gust::PoolFree( m_rep, sizeof(Ptr_rep<T>) );
00653 m_rep = 0;
00654 return(p);
00655 }
00656
00657 void realloc(unsigned int n) const
00658 { if(m_rep != 0) m_rep->realloc(n); else throw InternalError(); }
00659 };
00660
00661 enum DomainDirection
00662 {
00663 u_direction,
00664 v_direction
00665 };
00666
00667 typedef int sub_range[2];
00668
00669
00670 template< class T > class point;
00671 template< class T > class point2;
00672 template< class T > class point1;
00673 template< class T > class hpoint;
00674 template< class T > class hpoint2;
00675 template< class T > class hpoint1;
00676
00677
00678 template< class T >
00679 class vec4
00680 {
00681 public:
00682 T m[4];
00683 T& operator[] (size_t i) { return m[i]; }
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694 };
00695
00696 template< class T >
00697 struct mat4x4
00698 {
00699 vec4<T> m[4];
00700 vec4<T>& operator[] (size_t i) { return m[i]; }
00701
00702
00703
00704 static mat4x4<T> identity()
00705 {
00706 mat4x4 a = { {{{(T)1,(T)0,(T)0,(T)0}},
00707 {{(T)0,(T)1,(T)0,(T)0}},
00708 {{(T)0,(T)0,(T)1,(T)0}},
00709 {{(T)0,(T)0,(T)0,(T)1}}} };
00710 return a;
00711 }
00712
00713
00714
00715
00716
00717 static mat4x4<T> rotate_x( T theta )
00718 {
00719 mat4x4 a = identity();
00720 T ct = rtr<T>::cos(theta);
00721 T st = rtr<T>::sin(theta);
00722 a[1][1] = a[2][2] = ct;
00723 a[1][2] = -st;
00724 a[2][1] = st;
00725 return a;
00726 }
00727
00728
00729
00730
00731
00732 static mat4x4<T> rotate_y( T theta )
00733 {
00734 mat4x4 a = identity();
00735 T ct = rtr<T>::cos(theta);
00736 T st = rtr<T>::sin(theta);
00737 a[0][0] = a[2][2] = ct;
00738 a[0][2] = st;
00739 a[2][0] = -st;
00740 return a;
00741 }
00742
00743
00744
00745
00746
00747 static mat4x4<T> rotate_z( T theta )
00748 {
00749 mat4x4 a = identity();
00750 T ct = rtr<T>::cos(theta);
00751 T st = rtr<T>::sin(theta);
00752 a[0][0] = a[1][1] = ct;
00753 a[0][1] = -st;
00754 a[1][0] = st;
00755 return a;
00756 }
00757 };
00758
00759 template< class T >
00760 struct bounding_box
00761 {
00762 T x1;
00763 T x2;
00764 T y1;
00765 T y2;
00766 T z1;
00767 T z2;
00768 };
00769
00770
00771
00772
00773
00774 template< class T >
00775 class point1
00776 {
00777 public:
00778 T x;
00779 static int dim() { return 1; }
00780 static bool hom() { return false; }
00781 T weight() const { return (T)1; }
00782 point1<T>() { }
00783 template< class T2 >
00784 point1<T>( const T2& ax )
00785 {
00786 x = (T)ax;
00787 }
00788 inline point1<T>& operator+= ( const point1<T>& a )
00789 {
00790 x += a.x;
00791 return *this;
00792 }
00793 inline point1<T>& operator-= ( const point1<T>& a )
00794 {
00795 x -= a.x;
00796 return *this;
00797 }
00798 inline point1<T>& operator*= ( T& a )
00799 {
00800 x *= a;
00801 return *this;
00802 }
00803 const T& operator[] ( size_t i ) const { return (&x)[i]; }
00804
00805 operator vec4<T>() const
00806 {
00807 vec4<T> v;
00808 v[0] = x; v[1] = 0; v[2] = 0; v[3] = 1;
00809 return v;
00810 }
00811 };
00812 template< class T >
00813 class point2
00814 {
00815 public:
00816 T x;
00817 T y;
00818 static int dim() { return 2; }
00819 static bool hom() { return false; }
00820 T weight() const { return rtr<T>::one(); }
00821 point2<T>() { }
00822 template< class T2 >
00823 point2<T>( const T2& ax, const T2& ay )
00824 {
00825 x = (T)ax;
00826 y = (T)ay;
00827 }
00828 template< class T2 >
00829 point2<T>& operator=( const point2<T2>& a )
00830 {
00831 x = (T)a.x;
00832 y = (T)a.y;
00833 return *this;
00834 }
00835 inline point2<T>& operator+= ( const point2<T>& a )
00836 {
00837 x += a.x; y += a.y;
00838 return *this;
00839 }
00840 inline point2<T>& operator-= ( const point2<T>& a )
00841 {
00842 x -= a.x; y -= a.y;
00843 return *this;
00844 }
00845 inline point2<T>& operator*= ( T& a )
00846 {
00847 x *= a; y *= a;
00848 return *this;
00849 }
00850 const T& operator[] ( size_t i ) const { return (&x)[i]; }
00851
00852 operator vec4<T>() const
00853 {
00854 vec4<T> v;
00855 v[0] = x; v[1] = y; v[2] = 0; v[3] = 1;
00856 return v;
00857 }
00858 };
00859 template< class T >
00860 class point
00861 {
00862 public:
00863 T x;
00864 T y;
00865 T z;
00866 static int dim() { return 3; }
00867 static bool hom() { return false; }
00868 T weight() const { return rtr<T>::one(); }
00869 point<T>() { }
00870 template< class T2 >
00871 point<T>( const T2& ax, const T2& ay, const T2& az )
00872 {
00873 x = (T)ax;
00874 y = (T)ay;
00875 z = (T)az;
00876 }
00877 template< class T2 >
00878 point<T>& operator=( const point2<T2>& a )
00879 {
00880 x = (T)a.x;
00881 y = (T)a.y;
00882 z = (T)0;
00883 return *this;
00884 }
00885 template< class T2 >
00886 point<T>& operator=( const point<T2>& a )
00887 {
00888 x = (T)a.x;
00889 y = (T)a.y;
00890 z = (T)a.z;
00891 return *this;
00892 }
00893 inline point<T>& operator+= ( const point<T>& a )
00894 {
00895 x += a.x; y += a.y; z += a.z;
00896 return *this;
00897 }
00898 inline point<T>& operator-= ( const point<T>& a )
00899 {
00900 x -= a.x; y -= a.y; z -= a.z;
00901 return *this;
00902 }
00903 inline point<T>& operator*= ( T& a )
00904 {
00905 x *= a; y *= a; z *= a;
00906 return *this;
00907 }
00908 const T& operator[] ( size_t i ) const { return (&x)[i]; }
00909
00910 operator vec4<T>() const
00911 {
00912 vec4<T> v;
00913 v[0] = x; v[1] = y; v[2] = z; v[3] = 1;
00914 return v;
00915 }
00916 };
00917
00918 template< class T >
00919 class hpoint1
00920 {
00921 public:
00922 T x;
00923 T w;
00924 static int dim() { return 2; }
00925 static bool hom() { return true; }
00926 T weight() const { return w; }
00927 hpoint1<T>() { }
00928 template< class T2 >
00929 hpoint1<T>( const T2& ax, const T2& aw )
00930 {
00931 x = (T)ax;
00932 w = (T)aw;
00933 }
00934 inline hpoint1<T>& operator+= ( const hpoint1<T>& a )
00935 {
00936 x += a.x; w += a.w;
00937 return *this;
00938 }
00939 inline hpoint1<T>& operator-= ( const hpoint1<T>& a )
00940 {
00941 x -= a.x; w -= a.w;
00942 return *this;
00943 }
00944 inline hpoint1<T>& operator*= ( T& a )
00945 {
00946 x *= a; w *= a;
00947 return *this;
00948 }
00949 const T& operator[] ( size_t i ) const { return (&x)[i]; }
00950
00951 operator vec4<T>() const
00952 {
00953 vec4<T> v;
00954 v[0] = x; v[1] = 0; v[2] = 0; v[3] = w;
00955 return v;
00956 }
00957 };
00958 template< class T >
00959 class hpoint2
00960 {
00961 public:
00962 T x;
00963 T y;
00964 T w;
00965 static int dim() { return 3; }
00966 static bool hom() { return true; }
00967 T weight() const { return w; }
00968 hpoint2<T>() { }
00969 template< class T2 >
00970 hpoint2<T>( const T2& ax, const T2& ay, const T2& aw )
00971 {
00972 x = (T)ax;
00973 y = (T)ay;
00974 w = (T)aw;
00975 }
00976 inline hpoint2<T>& operator+= ( const hpoint2<T>& a )
00977 {
00978 x += a.x; y += a.y; w += a.w;
00979 return *this;
00980 }
00981 inline hpoint2<T>& operator-= ( const hpoint2<T>& a )
00982 {
00983 x -= a.x; y -= a.y; w -= a.w;
00984 return *this;
00985 }
00986 inline hpoint2<T>& operator*= ( T& a )
00987 {
00988 x *= a; y *= a; w *= a;
00989 return *this;
00990 }
00991 const T& operator[] ( size_t i ) const { return (&x)[i]; }
00992
00993 operator vec4<T>() const
00994 {
00995 vec4<T> v;
00996 v[0] = x; v[1] = y; v[2] = 0; v[3] = w;
00997 return v;
00998 }
00999 };
01000 template< class T >
01001 class hpoint
01002 {
01003 public:
01004 T x;
01005 T y;
01006 T z;
01007 T w;
01008 static int dim() { return 4; }
01009 static bool hom() { return true; }
01010 T weight() const { return w; }
01011 hpoint<T>() { }
01012 template< class T2 >
01013 hpoint<T>( const T2& ax, const T2& ay, const T2& az, const T2& aw )
01014 {
01015 x = (T)ax;
01016 y = (T)ay;
01017 z = (T)az;
01018 w = (T)aw;
01019 }
01020 template< class T2 >
01021 hpoint<T>& operator=( const point<T2>& a )
01022 {
01023 x = (T)a.x;
01024 y = (T)a.y;
01025 z = (T)a.z;
01026 w = (T)1;
01027 return *this;
01028 }
01029 template< class T2 >
01030 hpoint<T>& operator=( const point2<T2>& a )
01031 {
01032 x = (T)a.x;
01033 y = (T)a.y;
01034 z = (T)0;
01035 w = (T)1;
01036 return *this;
01037 }
01038 template< class T2 >
01039 hpoint<T>& operator=( const hpoint2<T2>& a )
01040 {
01041 x = (T)a.x;
01042 y = (T)a.y;
01043 z = (T)0;
01044 w = (T)a.w;
01045 return *this;
01046 }
01047 inline hpoint<T>& operator+= ( const hpoint<T>& a )
01048 {
01049 x += a.x; y += a.y; z += a.z; w += a.w;
01050 return *this;
01051 }
01052 inline hpoint<T>& operator-= ( const hpoint<T>& a )
01053 {
01054 x -= a.x; y -= a.y; z -= a.z; w -= a.w;
01055 return *this;
01056 }
01057 inline hpoint<T>& operator*= ( T& a )
01058 {
01059 x *= a; y *= a; z *= a; w *= a;
01060 return *this;
01061 }
01062 const T& operator[] ( size_t i ) const { return (&x)[i]; }
01063
01064 operator vec4<T>() const
01065 {
01066 vec4<T> v;
01067 v[0] = x; v[1] = y; v[2] = z; v[3] = w;
01068 return v;
01069 }
01070 };
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112 template< class T >
01113 struct line
01114 {
01115 point<T> P1;
01116 point<T> P2;
01117 const point<T>& operator[] ( size_t i ) const { return (&P1)[i]; }
01118 };
01119 template< class T >
01120 struct line2
01121 {
01122 point2<T> P1;
01123 point2<T> P2;
01124 const point2<T>& operator[] ( size_t i ) const { return (&P1)[i]; }
01125 };
01126
01127 template< class T >
01128 struct triangle
01129 {
01130 point<T> P1;
01131 point<T> P2;
01132 point<T> P3;
01133 };
01134 template< class T >
01135 struct triangle2
01136 {
01137 point2<T> P1;
01138 point2<T> P2;
01139 point2<T> P3;
01140 };
01141 struct itriangle
01142 {
01143 int v[3];
01144 };
01145
01146 template< class EP >
01147 struct polyline
01148 {
01149 int n;
01150 Ptr<EP> P;
01151 };
01152
01153
01154 template< class T >
01155 struct knot_vec
01156 {
01157 int m;
01158 Ptr< T > U;
01159 };
01160 template< class HP >
01161 struct point_vec
01162 {
01163 int n;
01164 Ptr< HP > Pw;
01165 };
01166 template< class T, class HP >
01167 struct curve
01168 {
01169 int p;
01170 knot_vec<T> knt;
01171 point_vec<HP> cpt;
01172 };
01173
01174 template< class HP >
01175 struct point_net
01176 {
01177 int nu;
01178 int nv;
01179 Ptr< Ptr< HP > > Pw;
01180 };
01181 template< class T, class HP >
01182 struct surface
01183 {
01184 int pu;
01185 int pv;
01186 knot_vec<T> knu;
01187 knot_vec<T> knv;
01188 point_net<HP> net;
01189 };
01190
01191 template< class T > class ListNode
01192 {
01193 public:
01194 T el;
01195 ListNode *next;
01196 ListNode *prev;
01197
01198 ListNode() { }
01199 ListNode( const T& a ) : el(a) { }
01200
01201 void *operator new( size_t s )
01202 {
01203 size_t dummy;
01204 void *p = gust::PoolAlloc( s, &dummy );
01205 if( p == NULL ) throw PoolAllocError();
01206 return(p);
01207 }
01208 void operator delete( void *p, size_t s )
01209 {
01210 gust::PoolFree( p, s );
01211 }
01212 };
01213
01214 template< class T > class List
01215 {
01216 public:
01217 T *head;
01218 int nElems;
01219
01220 List() { head = NULL; nElems = 0; }
01221 ~List() { DeleteElems(); }
01222
01223 T *First(void) const { return head; }
01224 T *Last(void) const
01225 {
01226 T *n0 = 0;
01227 T *n = head;
01228 while(n) { n0 = n; n = n->next; }
01229 return n0;
01230 }
01231 bool IsEmpty(void) const { return(nElems == 0); }
01232
01233 void Append( T *node )
01234 {
01235 node->next = head;
01236 node->prev = NULL;
01237 if( head != NULL ) head->prev = node;
01238 head = node;
01239 nElems++;
01240 }
01241
01242 void Remove( T *node )
01243 {
01244 if( node->prev != NULL ) node->prev->next = node->next;
01245 if( node->next != NULL ) node->next->prev = node->prev;
01246 if( head == node ) head = node->next;
01247 nElems--;
01248 }
01249 void DeleteElems( void )
01250 {
01251 T *n = head, *nnext;
01252 while( n != NULL ) { nnext = n->next; delete n; n = nnext; }
01253 head = NULL; nElems = 0;
01254 }
01255 void ReleaseElems( void )
01256 {
01257 head = NULL; nElems = 0;
01258 }
01259
01260 List<T>& operator+=( List<T>& other )
01261 {
01262 T *olast;
01263
01264 if( &other == this ) return *this;
01265
01266 if( head )
01267 {
01268 olast = other.Last();
01269 if( olast )
01270 {
01271 olast->next = head;
01272 head->prev = olast;
01273 head = other.First();
01274 nElems += other.nElems;
01275 other.ReleaseElems();
01276 }
01277 }
01278 else
01279 {
01280 head = other.First();
01281 nElems = other.nElems;
01282 other.ReleaseElems();
01283 }
01284 return *this;
01285 }
01286 List<T>& operator=( List<T>& other )
01287 {
01288 if( this == &other ) return *this;
01289
01290 DeleteElems();
01291 return ((*this) += other);
01292 }
01293 List( List<T>& other )
01294 {
01295 head = NULL; nElems = 0;
01296 (*this) += other;
01297 }
01298
01299
01300
01301 };
01302
01303 template< class T >
01304 struct ListNodeInfo
01305 {
01306 List<T> *m_L;
01307 T *m_n;
01308
01309 ListNodeInfo( List<T> *L, T *n ) { m_L = L; m_n = n; }
01310 };
01311
01312 template< class T > class List2
01313 {
01314 public:
01315 T *tail;
01316 T *head;
01317 int nElems;
01318
01319 List2() { head = NULL; tail = NULL; nElems = 0; }
01320 ~List2() { DeleteElems(); }
01321
01322 T *First(void) const { return head; }
01323 T *Last(void) const { return tail; }
01324
01325 bool IsEmpty(void) const { return(nElems == 0); }
01326
01327 void AppendLeft( T *node )
01328 {
01329 node->next = head;
01330 node->prev = NULL;
01331 if( head != NULL ) { head->prev = node; } else { tail = node; }
01332 head = node;
01333 nElems++;
01334 }
01335 void AppendRight( T *node )
01336 {
01337 node->prev = tail;
01338 node->next = NULL;
01339 if( tail != NULL ) { tail->next = node; } else { head = node; }
01340 tail = node;
01341 nElems++;
01342 }
01343 void Remove( T *node )
01344 {
01345 if( node->prev != NULL ) node->prev->next = node->next;
01346 if( node->next != NULL ) node->next->prev = node->prev;
01347 if( head == node ) head = node->next;
01348 if( tail == node ) tail = node->prev;
01349 nElems--;
01350 }
01351 void DeleteElems( void )
01352 {
01353 T *n = head, *nnext;
01354 while( n != NULL ) { nnext = n->next; delete n; n = nnext; }
01355 head = tail = NULL; nElems = 0;
01356 }
01357 void ReleaseElems( void )
01358 {
01359 head = tail = NULL; nElems = 0;
01360 }
01361
01362 List2<T>& operator+=( List2<T>& other )
01363 {
01364 T *olast;
01365
01366 if( &other == this ) return *this;
01367
01368 if( head )
01369 {
01370 olast = other.Last();
01371 if( olast )
01372 {
01373 olast->next = head;
01374 head->prev = olast;
01375 head = other.First();
01376 nElems += other.nElems;
01377 other.ReleaseElems();
01378 }
01379 }
01380 else
01381 {
01382 head = other.First();
01383 tail = other.Last();
01384 nElems = other.nElems;
01385 other.ReleaseElems();
01386 }
01387 return *this;
01388 }
01389 List2<T>& operator=( List2<T>& other )
01390 {
01391 if( this == &other ) return *this;
01392
01393 DeleteElems();
01394 return ((*this) += other);
01395 }
01396
01397 List2( List2<T>& other )
01398 {
01399 head = NULL; tail = NULL; nElems = 0;
01400 (*this) += other;
01401 }
01402
01403
01404
01405 };
01406
01407
01408 template< class T >
01409 struct Stack
01410 {
01411 T *m_sp;
01412 Ptr<T> m_buf;
01413
01414 Stack() { m_sp = 0; }
01415 ~Stack() { }
01416
01417 void init(unsigned int maxelems)
01418 {
01419 m_buf.reserve_pool(maxelems);
01420 m_sp = &m_buf[0];
01421 }
01422 void reset() { m_sp = &m_buf[0]; }
01423 unsigned int release( T **elems )
01424 {
01425 unsigned int i = (unsigned int)(m_sp - &m_buf[0]);
01426 *elems = m_buf.release();
01427 m_sp = 0;
01428 return i;
01429 }
01430 void push( const T& el ) { *m_sp = el; m_sp++; }
01431 T pop() { m_sp--; return *m_sp; }
01432 };
01433
01434 }
01435
01436 #include "guma_sorting.h"
01437
01438 namespace gul {
01439
01440 using guma::BBTNode;
01441 using guma::PtrHeapSort;
01442 using guma::InitBBT;
01443 using guma::InsertElementIntoBBT;
01444 using guma::DeleteElementFromBBT;
01445 using guma::SearchElementInBBT;
01446 using guma::SearchSuccessorInBBT;
01447 using guma::SearchPredecessorInBBT;
01448
01449
01450
01451
01452 template< class T >
01453 struct Map
01454 {
01455 struct Node
01456 {
01457 BBTNode *m_node;
01458 Node() : m_node(0) { }
01459 Node(BBTNode *node) : m_node(node) { }
01460 BBTNode *bbtnode() { return m_node; }
01461 T *key() { return (T *)m_node->key; }
01462 bool IsEmpty() { return m_node == 0; }
01463 Node left() { return Node(m_node->left); }
01464 Node right() { return Node(m_node->right); }
01465 };
01466
01467 BBTNode *root;
01468
01469 Map()
01470 {
01471 size_t dummy;
01472
01473 root = (BBTNode *)gust::PoolAlloc( sizeof(BBTNode), &dummy );
01474 if( root == NULL ) throw PoolAllocError();
01475 (*((int *)&root->parent)) = 1;
01476 InitBBT(root);
01477 }
01478 ~Map()
01479 {
01480
01481
01482
01483 if( --(*((int *)&root->parent)) == 0 )
01484 {
01485 DeleteElems();
01486 gust::PoolFree( root, sizeof(BBTNode) );
01487 }
01488 }
01489 Map( const Map& other )
01490 {
01491 (*((int *)&other->root->parent))++;
01492 root = other->root;
01493 }
01494 Map& operator=( const Map& other )
01495 {
01496 (*((int *)&other->root->parent))++;
01497 if( --(*((int *)&root->parent)) == 0 )
01498 {
01499 DeleteElems();
01500 gust::PoolFree( root, sizeof(BBTNode) );
01501 }
01502 root = other->root;
01503 }
01504
01505 Node Head( void ) { return(Node(root->right)); }
01506 int Height( void ) { return( *((int *)(&root->left)) ); }
01507 bool IsEmpty( void ) { return root->right == 0; }
01508 bool IsRemoved( Node node )
01509 { return node.bbtnode()->parent == 0; }
01510
01511 Node NewNode()
01512 {
01513 BBTNode *node;
01514 size_t dummy;
01515
01516 node = (BBTNode *)gust::PoolAlloc( sizeof(BBTNode), &dummy );
01517 if( node == NULL ) throw PoolAllocError();
01518 node->key = gust::PoolAlloc( sizeof(T), &dummy );
01519 if( node->key == NULL ) throw PoolAllocError();
01520 ::new(node->key) T();
01521
01522 return(Node(node));
01523 }
01524 template< class T1 >
01525 Node NewNode( T1& key )
01526 {
01527 BBTNode *node;
01528 size_t dummy;
01529
01530 node = (BBTNode *)gust::PoolAlloc( sizeof(BBTNode), &dummy );
01531 if( node == NULL ) throw PoolAllocError();
01532 node->key = gust::PoolAlloc( sizeof(T), &dummy );
01533 if( node->key == NULL ) throw PoolAllocError();
01534 ::new(node->key) T(key);
01535
01536 return(Node(node));
01537 }
01538
01539
01540
01541
01542 template< class T1 >
01543 Node NewNodeV( T1 key )
01544 {
01545 BBTNode *node;
01546 size_t dummy;
01547
01548 node = (BBTNode *)gust::PoolAlloc( sizeof(BBTNode), &dummy );
01549 if( node == NULL ) throw PoolAllocError();
01550 node->key = gust::PoolAlloc( sizeof(T), &dummy );
01551 if( node->key == NULL ) throw PoolAllocError();
01552 ::new(node->key) T(key);
01553
01554 return(Node(node));
01555 }
01556 T *ReleaseKey( Node node )
01557 {
01558 T *t = 0;
01559 if( !node.IsEmpty() )
01560 {
01561 t = node.key();
01562 node.bbtnode()->key = 0;
01563 }
01564 return t;
01565 }
01566 void FreeNode( Node node )
01567 {
01568 if( !node.IsEmpty() )
01569 {
01570 if( node.key() != 0 )
01571 {
01572 node.key()->~T();
01573 gust::PoolFree( node.key(), sizeof(T) );
01574 }
01575 gust::PoolFree( node.bbtnode(), sizeof(BBTNode) );
01576 }
01577 }
01578 void do_destroy( Node node )
01579 {
01580 if( node.IsEmpty() ) return;
01581
01582 if( !node.left().IsEmpty() ) do_destroy( node.left() );
01583 if( !node.right().IsEmpty() ) do_destroy( node.right() );
01584
01585 FreeNode( node );
01586 }
01587 void DeleteElems( void )
01588 {
01589 do_destroy( Head() );
01590 InitBBT(root);
01591 }
01592 void InsertNode( Node element, Node where, int side )
01593 {
01594 InsertElementIntoBBT( element.bbtnode(), where.bbtnode(), side, root );
01595 }
01596 void RemoveNode( Node element )
01597 {
01598 BBTNode *el = element.bbtnode();
01599 DeleteElementFromBBT( el, root );
01600 el->parent = 0;
01601 }
01602 template< class K >
01603 int SearchNode( K *key, int (*compfunc)(K *, T *), Node *element )
01604 {
01605 BBTNode *el;
01606 int side = SearchElementInBBT(root, (void *)key,
01607 (int (*)(void *, void *))compfunc, &el );
01608 *element = Node(el);
01609 return side;
01610 }
01611 Node Successor( Node element )
01612 {
01613 return Node( SearchSuccessorInBBT(element.bbtnode(), root) );
01614 }
01615 Node Predecessor( Node element )
01616 {
01617 return Node( SearchPredecessorInBBT(element.bbtnode(), root) );
01618 }
01619 Node First( void )
01620 {
01621 BBTNode *node = NULL, *next = root->right;
01622
01623 while( next != NULL )
01624 {
01625 node = next;
01626 next = node->left;
01627 }
01628
01629 return( Node(node) );
01630 }
01631 Node Last( void )
01632 {
01633 BBTNode *node = NULL, *next = root->right;
01634
01635 while( next != NULL )
01636 {
01637 node = next;
01638 next = node->right;
01639 }
01640 return( Node(node) );
01641 }
01642 void do_convert_to_array( int *nEl, Node node, Ptr<T *> *A )
01643 {
01644 if( !node.IsEmpty() )
01645 {
01646 do_convert_to_array( nEl, node.left(), A );
01647 (*A)[*nEl] = node.key();
01648 (*nEl)++;
01649 do_convert_to_array( nEl, node.right(), A );
01650 }
01651 }
01652 int ConvertToArray( Ptr<T *> *retKey )
01653 {
01654 int nEl = 0, maxEl = 1 << Height();
01655
01656 (*retKey).reserve_pool( maxEl );
01657
01658 do_convert_to_array( &nEl, Head(), retKey );
01659
01660 return nEl;
01661 }
01662 };
01663
01664
01665
01666
01667 template< class T >
01668 struct RefMap
01669 {
01670 struct Node
01671 {
01672 BBTNode *m_node;
01673 Node() : m_node(0) { }
01674 Node(BBTNode *node) : m_node(node) { }
01675 BBTNode *bbtnode() { return m_node; }
01676 T *key() { return (T *)m_node->key; }
01677 bool IsEmpty() { return m_node == 0; }
01678 Node left() { return Node(m_node->left); }
01679 Node right() { return Node(m_node->right); }
01680 };
01681
01682 BBTNode *root;
01683
01684 RefMap()
01685 {
01686 size_t dummy;
01687
01688 root = (BBTNode *)gust::PoolAlloc( sizeof(BBTNode), &dummy );
01689 if( root == NULL ) throw PoolAllocError();
01690 (*((int *)&root->parent)) = 1;
01691 InitBBT(root);
01692 }
01693 ~RefMap()
01694 {
01695
01696
01697
01698 if( --(*((int *)&root->parent)) == 0 )
01699 {
01700 DeleteElems();
01701 gust::PoolFree( root, sizeof(BBTNode) );
01702 }
01703 }
01704 RefMap( const RefMap& other )
01705 {
01706 (*((int *)&other->root->parent))++;
01707 root = other->root;
01708 }
01709 RefMap& operator=( const RefMap& other )
01710 {
01711 (*((int *)&other->root->parent))++;
01712 if( --(*((int *)&root->parent)) == 0 )
01713 {
01714 DeleteElems();
01715 gust::PoolFree( root, sizeof(BBTNode) );
01716 }
01717 root = other->root;
01718 }
01719 Node Head( void ) { return(Node(root->right)); }
01720 int Height( void ) { return( *((int *)(&root->left)) ); }
01721 bool IsEmpty( void ) { return root->right == 0; }
01722 bool IsRemoved( Node node )
01723 { return node.bbtnode()->parent == 0; }
01724
01725 Node NewNode( T *key )
01726 {
01727 BBTNode *node;
01728 size_t dummy;
01729
01730 node = (BBTNode *)gust::PoolAlloc( sizeof(BBTNode), &dummy );
01731 if( node == NULL ) throw PoolAllocError();
01732 node->key = key;
01733
01734 return(Node(node));
01735 }
01736 void FreeNode( Node node )
01737 {
01738 if( !node.IsEmpty() )
01739 gust::PoolFree( node.bbtnode(), sizeof(BBTNode) );
01740 }
01741 void do_destroy( Node node )
01742 {
01743 if( node.IsEmpty() ) return;
01744
01745 if( !node.left().IsEmpty() ) do_destroy( node.left() );
01746 if( !node.right().IsEmpty() ) do_destroy( node.right() );
01747
01748 gust::PoolFree( node.bbtnode(), sizeof(BBTNode) );
01749 }
01750 void DeleteElems( void )
01751 {
01752 do_destroy( Head() );
01753 InitBBT(root);
01754 }
01755 void InsertNode( Node element, Node where, int side )
01756 {
01757 InsertElementIntoBBT( element.bbtnode(), where.bbtnode(), side, root );
01758 }
01759 void RemoveNode( Node element )
01760 {
01761 BBTNode *el = element.bbtnode();
01762 DeleteElementFromBBT( el, root );
01763 el->parent = 0;
01764 }
01765 template< class K >
01766 int SearchNode( K *key, int (*compfunc)(K *, T *), Node *element )
01767 {
01768 BBTNode *el;
01769 int side = SearchElementInBBT(root, (void *)key,
01770 (int (*)(void *, void *))compfunc, &el );
01771 *element = Node(el);
01772 return side;
01773 }
01774 Node Successor( Node element )
01775 {
01776 return Node( SearchSuccessorInBBT(element.bbtnode(), root) );
01777 }
01778 Node Predecessor( Node element )
01779 {
01780 return Node( SearchPredecessorInBBT(element.bbtnode(), root) );
01781 }
01782 Node First( void )
01783 {
01784 BBTNode *node = NULL, *next = root->right;
01785
01786 while( next != NULL )
01787 {
01788 node = next;
01789 next = node->left;
01790 }
01791 return( Node(node) );
01792 }
01793 Node Last( void )
01794 {
01795 BBTNode *node = NULL, *next = root->right;
01796
01797 while( next != NULL )
01798 {
01799 node = next;
01800 next = node->right;
01801 }
01802 return( Node(node) );
01803 }
01804 template< class U >
01805 void do_convert_to_array( int *nEl, Node node, Ptr<U> *A )
01806 {
01807 if( !node.IsEmpty() )
01808 {
01809 do_convert_to_array( nEl, node.left(), A );
01810 (*A)[*nEl] = (U)node.key();
01811 (*nEl)++;
01812 do_convert_to_array( nEl, node.right(), A );
01813 }
01814 }
01815 template< class U >
01816 int ConvertToArray( Ptr<U> *retKey )
01817 {
01818 int nEl = 0, maxEl = 1 << Height();
01819
01820 (*retKey).reserve_pool( maxEl );
01821
01822 do_convert_to_array<U>( &nEl, Head(), retKey );
01823
01824 return nEl;
01825 }
01826 };
01827
01828
01829
01830 class pool_object
01831 {
01832 public:
01833 void *operator new( size_t s )
01834 {
01835 size_t dummy;
01836 void *p = gust::PreferPoolAlloc( s, &dummy );
01837 if( p == NULL ) throw PoolAllocError();
01838 return(p);
01839 }
01840
01841 void operator delete( void *p, size_t s )
01842 {
01843 gust::PreferPoolFree( p, s );
01844 }
01845 };
01846
01847
01848
01849
01850 template< class T >
01851 class kdarray : public pool_object
01852 {
01853 public:
01854 T *m_base;
01855 kdarray() { }
01856 kdarray( T *base ) { m_base = base; }
01857 T& operator[]( size_t i) const { return m_base[i]; }
01858 };
01859
01860
01861 template< class T, class EP >
01862 struct kdpoint : public pool_object
01863 {
01864 EP m_P;
01865 void *m_id;
01866
01867 kdpoint( const EP& P, void *id ) { m_P = P; m_id = id; }
01868 const T& operator[] ( size_t i ) const { return m_P[i]; }
01869 };
01870
01871
01872 template< class T >
01873 class poolalloc
01874 {
01875 public:
01876 typedef T value_type;
01877 typedef size_t size_type;
01878 typedef ptrdiff_t difference_type;
01879 typedef T* pointer;
01880 typedef const T* const_pointer;
01881 typedef T& reference;
01882 typedef const T& const_reference;
01883
01884 pointer address( reference r ) const { return &r; }
01885 const_pointer address( const_reference r ) const { return &r; }
01886
01887 poolalloc() throw() { }
01888 template< class U > poolalloc( const poolalloc<U>& ) throw() { }
01889 ~poolalloc() throw() { }
01890
01891 inline pointer allocate( size_type n, const void *h = 0 );
01892 inline void deallocate( pointer p, size_type n );
01893
01894 void construct( pointer p, const T& val ) { new(p) T(val); }
01895 void destroy( pointer p ) { p->~T(); }
01896 size_type max_size() const throw() { return ((size_t)-1); }
01897
01898 template< class U >
01899 struct rebind { typedef poolalloc<U> other; };
01900 };
01901
01902 template< class T >
01903 inline bool operator==( const poolalloc<T>&, const poolalloc<T>& ) throw()
01904 { return true; }
01905 template< class T >
01906 inline bool operator!=( const poolalloc<T>&, const poolalloc<T>& ) throw()
01907 { return false; }
01908
01909 template<> class poolalloc<void>
01910 {
01911 public:
01912 typedef void* pointer;
01913 typedef const void* const_pointer;
01914 typedef void value_type;
01915
01916 template< class U >
01917 struct rebind { typedef poolalloc<U> other; };
01918 };
01919
01920 template< class T >
01921 inline T *poolalloc<T>::allocate( size_type n, poolalloc<void>::const_pointer h )
01922 {
01923 size_t dummy;
01924 T *p = (T *)gust::PreferPoolAlloc( n*sizeof(T), &dummy );
01925 if( p == 0 ) throw gul::AllocError();
01926 return p;
01927 }
01928 template< class T >
01929 inline void poolalloc<T>::deallocate( pointer p, size_type n )
01930 {
01931 gust::PreferPoolFree( p, n*sizeof(T) );
01932 }
01933
01934
01935
01936
01937
01938
01939
01940 class pool_bytealloc
01941 {
01942 public:
01943 static void *allocate( size_t n )
01944 {
01945 size_t dummy;
01946 void *p = gust::PreferPoolAlloc( n, &dummy );
01947 if( p == 0 ) throw gul::AllocError();
01948 return p;
01949 }
01950 static void deallocate( void *p, size_t n )
01951 {
01952 gust::PreferPoolFree( p, n );
01953 }
01954 };
01955
01956
01957
01958 }
01959
01960 #endif