Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

gul_types.h

Go to the documentation of this file.
00001 /* LIBGUL - Geometry Utility Library
00002  * Copyright (C) 1998-1999 Norbert Irmer
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Library General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Library General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Library General Public
00015  * License along with this library; if not, write to the
00016  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017  * Boston, MA 02111-1307, USA.
00018  */
00019  
00020 #ifndef GUL_TYPES_H
00021 #define GUL_TYPES_H
00022 
00023 
00024 #ifdef __GNUC__
00025 
00026   /*---------------------------------------------------------------------------
00027   BTW,  "gcc -dM -E - < /dev/null" shows symbols automatically defined by gcc
00028   ----------------------------------------------------------------------------*/
00029 
00030   #ifndef alloca
00031     #define alloca __builtin_alloca
00032   #endif
00033 
00034 #endif
00035 
00036 /***********************************************************************
00037   Configuration Options
00038 ***********************************************************************/
00039 // define this only when doing memory leak debugging, very slow !
00040 // #define POOLDBG
00041 // define this only when debugging
00042 // #define RANGECHECK
00043 
00044 // at least sparc ultras require an alignment of 8 bytes, or
00045 // else writing doubles causes a bus error. in any case,
00046 // the alignment must be >= sizeof(void*)
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   // a normal function, not a template, onto which can be set a breakpoint
00087   GULAPI void gul_halt( void );
00088 #endif
00089 
00090 #if (defined(__MINGW32__)) || (defined(_MSC_VER))
00091   // still have to define this somewhere :((
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 // #if !defined(_MSC_VER) || defined(NEED_NEW_H)
00103 //  #include <new.h>
00104 // #endif
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   // 64-Bit Integer constants
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   // 64-Bit Integer constants
00126   #define LL(i) i##i64
00127 #else
00128   typedef unsigned long long uint64;
00129   typedef long long int64;
00130   #ifdef __MINGW32__
00131 //    #include <float.h>
00132 //    #define isinf(f) (!_finite((f)))
00133   #endif
00134   // 64-Bit Integer constants
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  /* rational number traits */
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; } // in multiples of 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   // i never understood for what this 'tiny' is needed in "Numerical Recipes",
00179   // but anyway here it is
00180   static float tiny() { return 1e-20f; }
00181   static float giant() { return 1.0f/tiny(); }
00182   // these constants are needed in some templates, which i also want to 
00183   // instantiate for the rational number class, and  i do not want to write
00184   //  an operator which converts floats or ints to rationals (this is too
00185   // dangerous, because of the many (unwanted) implicit conversions, 
00186   // which c++ does)
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   // IEEE functions
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   // windows runtime has no float functions !!!
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   // IEEE functions
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; } // in multiples of 4
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   // i never understood for what this 'tiny' is needed in "Numerical Recipes",
00249   // but anyway here it is
00250   static double tiny() { return 1e-40; }
00251   static double giant() { return 1.0f/tiny(); }
00252   // these constants are needed in some templates, which i also want to 
00253   // instantiate for the rational number class, and  i do not want to write
00254   //  an operator which converts floats or ints to rationals (this is too
00255   // dangerous, because of the many (unwanted) implicit conversions, 
00256   // which c++ does)
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   // IEEE functions
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 // this tolerance structure is not longer needed, since from now on only
00301 // the relative error is measured, when checking equality
00302 
00303 template< class T > struct rtl  // tolerances for comparisons - struct
00304 { 
00305   T zero_tol;
00306   T zero_tol_v2;
00307   T zero_tol_v3;
00308   T zero_tol_v4;
00309   T point_coincidence_tol;
00310   T knot_coincidence_tol;
00311   T knot_uniqueness_tol;
00312     
00313   rtl() 
00314   {
00315     // this tolerances only make sense when the values are normalized
00316     zero_tol = rtr<T>::epsilon() * (T)16;
00317     zero_tol_v2 = zero_tol / rtr<T>::root2_2();
00318     zero_tol_v3 = zero_tol / rtr<T>::root2_3();
00319     zero_tol_v4 = zero_tol / (T)2;
00320     point_coincidence_tol = rtr<T>::epsilon() * (T)16;
00321     knot_coincidence_tol = rtr<T>::epsilon() * (T)16;
00322     knot_uniqueness_tol = rtr<T>::epsilon() * (T)16; 
00323   }
00324 
00325   rtl( T zt, T pct, T kct, T kut )
00326   {
00327     zero_tol = zt;
00328     zero_tol_v2 = zero_tol / rtr<T>::root2_2();
00329     zero_tol_v3 = zero_tol / rtr<T>::root2_3();
00330     zero_tol_v4 = zero_tol / (T)2;
00331     point_coincidence_tol = pct;
00332     knot_coincidence_tol = kct;
00333     knot_uniqueness_tol = kut;
00334   }
00335 
00336   rtl( const rtl& a )
00337   {
00338     zero_tol = a.zero_tol;
00339     zero_tol_v2 = a.zero_tol_v2;
00340     zero_tol_v3 = a.zero_tol_v3;
00341     zero_tol_v4 = a.zero_tol_v4;
00342     point_coincidence_tol = a.point_coincidence_tol;
00343     knot_coincidence_tol = a.knot_coincidence_tol;
00344     knot_uniqueness_tol = a.knot_uniqueness_tol;
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                                             // give 'a' the sign of 'b':
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   Union for some dirty tricks
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   Pointer with reference counter semantic
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;     /* storage class */
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     // this only decreases the counter for constructed elements
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     // only for objects without constructors/destructors !!!!
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();  /* something went wrong */
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   // gets the number of constructed elements in the area to which it points
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   // Caution when using this ! The source p must not be changed in any way
00541   // as long the pointer uses it
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();  /* call constructors */
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();  /* call constructors */
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 );      /* call constructors */
00588     for( size_t i = 0; i < n; i++ ) ::new(p++) T();
00589   }
00590 
00591 
00592   void reset()       //! delete all elements
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   // this only decreases the counter for constructed elements
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   //  T* operator->() const { return m_rep->m_ptr; }
00644   T* get() const { return m_rep->m_ptr; }
00645   //  operator T*() const { return m_rep->m_ptr; }
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  // low level, not for classes !
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   template< class T2 > inline vec4<T>& operator=( const point<T2>& a );
00687   template< class T2 > inline vec4<T>& operator=( const point2<T2>& a );
00688   template< class T2 > inline vec4<T>& operator=( const point1<T2>& a );
00689 
00690   template< class T2 > inline vec4<T>& operator=( const hpoint<T2>& a );
00691   template< class T2 > inline vec4<T>& operator=( const hpoint2<T2>& a );
00692   template< class T2 > inline vec4<T>& operator=( const hpoint1<T2>& a );
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     creates 4x4 unit matrix                                           */
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     create 4x4 rotation matrix about x axis.
00714     the angle theta (in radians) describes the clockwise rotation, if you
00715     look along the axis towards the origin                              */
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     create 4x4 rotation matrix about y axis.
00729     the angle theta (in radians) describes the clockwise rotation, if you
00730     look along the axis towards the origin                              */
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     create 4x4 rotation matrix about z axis.
00744     the angle theta (in radians) describes the clockwise rotation, if you
00745     look along the axis towards the origin                              */
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    point types
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 template< class T > template< class T2 >
01074 inline vec4<T>& vec4<T>::operator=( const point<T2>& a )
01075 {
01076   m[0] = (T)a.x; m[1] = (T)a.y; m[2] = (T)a.z; m[3] = (T)1;
01077   return *this;
01078 }
01079 template< class T > template< class T2 >
01080 inline vec4<T>& vec4<T>::operator=( const point2<T2>& a )
01081 {
01082   m[0] = (T)a.x; m[1] = (T)a.y; m[2] = (T)0; m[3] = (T)1;
01083   return *this;
01084 }
01085 template< class T > template< class T2 >
01086 inline vec4<T>& vec4<T>::operator=( const point1<T2>& a )
01087 {
01088   m[0] = (T)a.x; m[1] = (T)0; m[2] = (T)0; m[3] = (T)1;
01089   return *this;
01090 }
01091 
01092 template< class T > template< class T2 >
01093 inline vec4<T>& vec4<T>::operator=( const hpoint<T2>& a )
01094 {
01095   m[0] = (T)a.x; m[1] = (T)a.y; m[2] = (T)a.z; m[3] = (T)a.w;
01096   return *this;
01097 }
01098 template< class T > template< class T2 >
01099 inline vec4<T>& vec4<T>::operator=( const hpoint2<T2>& a )
01100 {
01101   m[0] = (T)a.x; m[1] = (T)a.y; m[2] = (T)0; m[3] = (T)a.w;
01102   return *this;
01103 }
01104 template< class T > template< class T2 >
01105 inline vec4<T>& vec4<T>::operator=( const hpoint1<T2>& a )
01106 {
01107   m[0] = (T)a.x; m[1] = (T)0; m[2] = (T)0; m[3] = (T)a.w;
01108   return *this;
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                                         /* simple list templates */
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   // simple 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 // private:                      // don't allow simple copying
01300 //   List( const List<T>& other );
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   // simple List, bidirectional
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();  // tail remains the same
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   // caution, this emptys the input list
01397   List2( List2<T>& other )
01398   {
01399     head = NULL; tail = NULL; nElems = 0;
01400     (*this) += other;
01401   }
01402 
01403 // private:                      // don't allow simple copying
01404 //   List2( const List2<T>& other );
01405 };
01406 
01407                               /* simple stack template */
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   Balanced Binary Tree (allocates/deallocates memory for keys)
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);   // must leave parent field untouched !!!!
01477   }
01478   ~Map()
01479   {
01480     // misusing the unused parent field of the special root node as reference
01481     // counter (to have at least pointer copy semantics)
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   // same as above, but for objects which can only be passed by value
01540   // (e.g. something like "int(4)")
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; // to indicate that node isn't in the tree anymore
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 )  // deliver first element in symmetric order
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 )  // deliver last element in symmetric order
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   Balanced Binary Tree (doesn't allocates/deallocates memory for keys)
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);   // must leave parent field untouched !!!!
01692   }
01693   ~RefMap()
01694   {
01695     // misusing the unused parent field of the special root node as reference
01696     // counter (to have at least pointer copy semantics)
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; // to indicate that node isn't in the tree anymore
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 )  // deliver first element in symmetric order
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 )  // deliver last element in symmetric order
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 // base class for objects which are reserved in the pool 
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 // these structs are used for storing records in a kdtree
01848 
01849 // structure which can be used for records with any number of dimensions
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 // structure which can be used to attach additional data to records
01861 template< class T, class EP >
01862 struct kdpoint : public pool_object
01863 {
01864   EP m_P;
01865   void *m_id;  // for casting the base class to derived classes,
01866                // or for tagging additional data to a record
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   this is a hack to get the 'basic_string' class of Gnu C 2.95.2 working with
01936   PoolAlloc (in this implementation 'basic_string' doesn't uses the
01937   std::allocator !!!! ) 
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

Generated on Mon Jan 21 04:17:34 2002 for GUL 0.6 - Geometry Utility Library by doxygen1.2.13.1 written by Dimitri van Heesch, © 1997-2001