basix_doc 0.1
|
00001 00002 /****************************************************************************** 00003 * MODULE : basix.hpp 00004 * DESCRIPTION: Basic inclusions, definitions and routines 00005 * COPYRIGHT : (C) 2003 Joris van der Hoeven 00006 ******************************************************************************* 00007 * This software falls under the GNU general public license and comes WITHOUT 00008 * ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details. 00009 * If you don't have this file, write to the Free Software Foundation, Inc., 00010 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00011 ******************************************************************************/ 00012 00014 00015 #ifndef __MMX_BASIX_HPP 00016 #define __MMX_BASIX_HPP 00017 #include <basix/fast_new.hpp> 00018 #include <cmath> 00019 00020 #ifdef BASIX_HAVE_STDINT_H 00021 #include <stdint.h> 00022 #else 00023 #define uintptr_t unsigned long int 00024 #endif 00025 00026 #if __GLIBC__ >= 2 && defined(__THROW) 00027 extern "C" double hypot (double, double) __THROW __attribute__ ((const)); 00028 #else 00029 extern "C" double hypot (double, double) __attribute__ ((const)); 00030 #endif 00031 00032 namespace mmx { 00033 00034 #define LESSGTR <> 00035 #define STMPL template<> 00036 00038 enum print_format { 00039 blank, 00040 stroke, 00041 indent, 00042 unindent, 00043 lf, 00044 hrule, 00045 flush_now 00046 }; 00047 00048 extern int mmx_argc; 00049 extern char** mmx_argv; 00050 void noop (); 00051 00052 /****************************************************************************** 00053 * Indirect data structures prototypes 00054 ******************************************************************************/ 00055 00057 #define INDIRECT_PROTO(T,R) \ 00058 MMX_ALLOCATORS \ 00059 protected: \ 00060 R* rep; \ 00061 public: \ 00062 inline T (R* rep2); \ 00063 inline T (const R* rep2, bool with_inc); \ 00064 inline T (const T& x); \ 00065 inline ~T (); \ 00066 inline T& operator= (const T& x); \ 00067 inline const R* operator-> () const; \ 00068 inline void secure (); 00069 00072 #define INDIRECT_PROTO_1(T,R,X) \ 00073 MMX_ALLOCATORS \ 00074 protected: \ 00075 R<X >* rep; \ 00076 public: \ 00077 inline T (R<X >* rep2); \ 00078 inline T (const R<X >* rep2, bool with_inc); \ 00079 inline T (const T& x); \ 00080 inline ~T (); \ 00081 inline T& operator= (const T& x); \ 00082 inline const R<X >* operator-> () const; \ 00083 inline R<X >* operator-> (); \ 00084 inline void secure (); \ 00085 typedef X value_type; 00086 00089 #define INDIRECT_PROTO_2(T,R,X,Y) \ 00090 MMX_ALLOCATORS \ 00091 protected: \ 00092 R<X,Y >* rep; \ 00093 public: \ 00094 inline T (R<X,Y >* rep2); \ 00095 inline T (const R<X,Y >* rep2, bool inc); \ 00096 inline T (const T& x); \ 00097 inline ~T (); \ 00098 inline T& operator= (const T& x); \ 00099 inline const R<X,Y >* operator-> () const; \ 00100 inline void secure (); 00101 00104 #define INDIRECT_PROTO_3(T,R,X,Y,Z) \ 00105 MMX_ALLOCATORS \ 00106 protected: \ 00107 R<X,Y,Z >* rep; \ 00108 public: \ 00109 inline T (R<X,Y,Z >* rep2); \ 00110 inline T (const R<X,Y,Z >* rep2, bool inc); \ 00111 inline T (const T& x); \ 00112 inline ~T (); \ 00113 inline T& operator= (const T& x); \ 00114 inline const R<X,Y,Z >* operator-> () const; \ 00115 inline void secure (); 00116 00119 #define INDIRECT_PROTO_4(T,R,W,X,Y,Z) \ 00120 MMX_ALLOCATORS \ 00121 protected: \ 00122 R<W,X,Y,Z >* rep; \ 00123 public: \ 00124 inline T (R<W,X,Y,Z >* rep2); \ 00125 inline T (const R<W,X,Y,Z >* rep2, bool inc); \ 00126 inline T (const T& x); \ 00127 inline ~T (); \ 00128 inline T& operator= (const T& x); \ 00129 inline const R<W,X,Y,Z >* operator-> () const;\ 00130 inline void secure (); 00131 00132 /****************************************************************************** 00133 * Indirect data structures with reference counting 00134 ******************************************************************************/ 00135 00136 struct rep_struct { 00137 MMX_ALLOCATORS 00138 int ref_count; 00139 inline rep_struct (): ref_count (1) {} 00140 virtual inline ~rep_struct () {} 00141 }; 00142 00143 #define REP_STRUCT :public rep_struct 00144 #define REP_STRUCT_1(X) :public rep_struct, public format<X > 00145 #define REP_STRUCT_2(X,Y) :public rep_struct, public encapsulate1<format<X > >, public encapsulate2<format<Y> > 00146 #define INC_COUNT(x) { (x)->ref_count++; } 00147 #define DEC_COUNT(x) { if (0==--((x)->ref_count)) delete (x); } 00148 #define INC_NULL_COUNT(x) { if ((x)!=NULL) (x)->ref_count++; } 00149 #define DEC_NULL_COUNT(x) { \ 00150 if ((x)!=NULL && 0==--((x)->ref_count)) delete (x); } 00151 00152 template<typename C> C copy (const C& x) { 00153 assert (false); // object should really be copied before access 00154 return x; } 00155 template<typename C> inline nat hard_hash (const C& x) { 00156 return exact_hash (x); } 00157 template<typename C> inline nat as_hash (const C* p) { 00158 return ((nat) ((uintptr_t) ((void*) p))) >> 3; } 00159 template<typename C> inline bool hard_eq (const C& x, const C& y) { 00160 return exact_eq (x, y); } 00161 template<typename C> inline bool hard_neq (const C& x, const C& y) { 00162 return exact_neq (x, y); } 00163 template<typename C> inline bool hard_less (const C& x, const C& y) { 00164 return ((void*) inside (x)) < ((void*) inside (y)); } 00165 template<typename C> inline bool hard_gtr (const C& x, const C& y) { 00166 return ((void*) inside (x)) > ((void*) inside (y)); } 00167 00168 #define INDIRECT_IMPL(T,R) \ 00169 inline T::T (R* rep2): rep(rep2) {} \ 00170 inline T::T (const R* rep2, bool with_inc): \ 00171 rep((R*) (void*) rep2) { (void) with_inc; INC_COUNT (rep); } \ 00172 inline T::T (const T& x): rep(x.rep) { INC_COUNT (rep); } \ 00173 inline T::~T () { DEC_COUNT (rep); } \ 00174 inline const R* T::operator -> () const { return rep; } \ 00175 inline T& T::operator = (const T& x) { \ 00176 INC_COUNT (x.rep); DEC_COUNT (rep); \ 00177 rep=x.rep; return *this; } \ 00178 inline void T::secure () { \ 00179 if (rep->ref_count>1) *this= copy (*this); } \ 00180 inline R* inside (const T& x) { \ 00181 return const_cast<R*> (x.operator -> ()); } \ 00182 STMPL inline nat hard_hash (const T& x) { \ 00183 return as_hash (x.operator -> ()); } \ 00184 STMPL inline bool hard_eq (const T& x, const T& y) { \ 00185 return (x.operator -> ()) == (y.operator -> ()); } \ 00186 STMPL inline bool hard_neq (const T& x, const T& y) { \ 00187 return (x.operator -> ()) != (y.operator -> ()); } 00188 00189 #define INDIRECT_NULL_IMPL(T,R) \ 00190 inline T::T (R* rep2): rep(rep2) {} \ 00191 inline T::T (const R* rep2, bool with_inc): \ 00192 rep((R*) (void*) rep2) { (void) with_inc; INC_NULL_COUNT (rep); } \ 00193 inline T::T (const T& x): rep(x.rep) { INC_NULL_COUNT (rep); } \ 00194 inline T::~T () { DEC_NULL_COUNT (rep); } \ 00195 inline const R* T::operator -> () const { return rep; } \ 00196 inline T& T::operator = (const T& x) { \ 00197 INC_NULL_COUNT (x.rep); DEC_NULL_COUNT (rep); \ 00198 rep=x.rep; return *this; } \ 00199 inline void T::secure () { \ 00200 if (rep->ref_count>1) *this= copy (*this); } \ 00201 inline R* inside (const T& x) { \ 00202 return const_cast<R*> (x.operator -> ()); } \ 00203 STMPL inline nat hard_hash (const T& x) { \ 00204 return as_hash (x.operator -> ()); } \ 00205 STMPL inline bool hard_eq (const T& x, const T& y) { \ 00206 return (x.operator -> ()) == (y.operator -> ()); } \ 00207 STMPL inline bool hard_neq (const T& x, const T& y) { \ 00208 return (x.operator -> ()) != (y.operator -> ()); } 00209 00210 #define INDIRECT_IMPL_1(T,R,XX,X) \ 00211 template<XX> inline T<X >::T (R<X >* rep2): rep(rep2) {} \ 00212 template<XX> inline T<X >::T (const R<X >* rep2, bool with_inc): \ 00213 rep((R<X >*) (void*) rep2) { (void) with_inc; INC_COUNT (rep); } \ 00214 template<XX> inline T<X >::T (const T<X >& x): rep(x.rep) { \ 00215 INC_COUNT (rep); } \ 00216 template<XX> inline T<X >::~T () { DEC_COUNT (rep); } \ 00217 template<XX> inline const R<X >* T<X >::operator -> () const { \ 00218 return rep; } \ 00219 template<XX> inline R<X >* T<X >::operator -> () { \ 00220 return rep; } \ 00221 template<XX> inline T<X >& \ 00222 T<X >::operator = (const T<X >& x) { \ 00223 INC_COUNT (x.rep); DEC_COUNT (rep); \ 00224 rep=x.rep; return *this; } \ 00225 template<XX> inline void T<X >::secure () { \ 00226 if (rep->ref_count>1) *this= copy (*this); } \ 00227 template<XX> R<X >* inside (const T<X >& x) { \ 00228 return const_cast<R<X >*> (x.operator -> ()); } \ 00229 template<XX> inline nat hard_hash (const T<X >& x) { \ 00230 return as_hash (x.operator -> ()); } \ 00231 template<XX> inline bool hard_eq (const T<X >& x, const T<X >& y) { \ 00232 return (x.operator -> ()) == (y.operator -> ()); } \ 00233 template<XX> inline bool hard_neq (const T<X >& x, const T<X >& y) { \ 00234 return (x.operator -> ()) != (y.operator -> ()); } 00235 00236 #define INDIRECT_NULL_IMPL_1(T,R,XX,X) \ 00237 template<XX> inline T<X >::T (R<X >* rep2): rep(rep2) {} \ 00238 template<XX> inline T<X >::T (const R<X >* rep2, bool with_inc): \ 00239 rep((R<X >*) (void*) rep2) { (void) with_inc; INC_NULL_COUNT (rep); } \ 00240 template<XX> inline T<X >::T (const T<X >& x): rep(x.rep) { \ 00241 INC_NULL_COUNT (rep); } \ 00242 template<XX> inline T<X >::~T () { DEC_NULL_COUNT (rep); } \ 00243 template<XX> inline const R<X >* T<X >::operator -> () const { \ 00244 return rep; } \ 00245 template<XX> inline R<X >* T<X >::operator -> () { \ 00246 return rep; } \ 00247 template<XX> inline T<X >& \ 00248 T<X >::operator = (const T<X >& x) { \ 00249 INC_NULL_COUNT (x.rep); DEC_NULL_COUNT (rep); \ 00250 rep=x.rep; return *this; } \ 00251 template<XX> inline void T<X >::secure () { \ 00252 if (rep->ref_count>1) *this= copy (*this); } \ 00253 template<XX> R<X >* inside (const T<X >& x) { \ 00254 return const_cast<R<X >*> (x.operator -> ()); } \ 00255 template<XX> inline nat hard_hash (const T<X >& x) { \ 00256 return as_hash (x.operator -> ()); } \ 00257 template<XX> inline bool hard_eq (const T<X >& x, const T<X >& y) { \ 00258 return (x.operator -> ()) == (y.operator -> ()); } \ 00259 template<XX> inline bool hard_neq (const T<X >& x, const T<X >& y) { \ 00260 return (x.operator -> ()) != (y.operator -> ()); } 00261 00262 #define INDIRECT_IMPL_2(T,R,XX,X,YY,Y) \ 00263 template<XX,YY> inline T<X,Y >::T (R<X,Y >* rep2): rep(rep2) {} \ 00264 template<XX,YY> inline T<X,Y >::T (const R<X,Y >* rep2, bool inc): \ 00265 rep((R<X,Y >*) (void*) rep2) { (void) inc; INC_COUNT (rep); } \ 00266 template<XX,YY> inline T<X,Y >::T (const T<X,Y >& x): rep(x.rep) { \ 00267 INC_COUNT (rep); } \ 00268 template<XX,YY> inline T<X,Y >::~T () { DEC_COUNT (rep); } \ 00269 template<XX,YY> inline const R<X,Y >* T<X,Y >::operator -> () const { \ 00270 return rep; } \ 00271 template<XX,YY> inline T<X,Y >& \ 00272 T<X,Y >::operator = (const T<X,Y >& x) { \ 00273 INC_COUNT (x.rep); DEC_COUNT (rep); \ 00274 rep=x.rep; return *this; } \ 00275 template<XX,YY> inline void T<X,Y >::secure () { \ 00276 if (rep->ref_count>1) *this= copy (*this); } \ 00277 template<XX,YY> R<X,Y >* inside (const T<X,Y >& x) { \ 00278 return const_cast<R<X,Y >*> (x.operator -> ()); } \ 00279 template<XX,YY> inline nat hard_hash (const T<X,Y >& x) { \ 00280 return as_hash (x.operator -> ()); } \ 00281 template<XX,YY> inline bool hard_eq (const T<X,Y >& x, const T<X,Y >& y) { \ 00282 return (x.operator -> ()) == (y.operator -> ()); } \ 00283 template<XX,YY> inline bool hard_neq (const T<X,Y >& x, const T<X,Y >& y) { \ 00284 return (x.operator -> ()) != (y.operator -> ()); } 00285 00286 #define INDIRECT_IMPL_3(T,R,XX,X,YY,Y,ZZ,Z) \ 00287 template<XX,YY,ZZ> inline T<X,Y,Z >::T (R<X,Y,Z >* rep2): \ 00288 rep(rep2) {} \ 00289 template<XX,YY,ZZ> inline \ 00290 T<X,Y,Z >::T (const R<X,Y,Z >* rep2, bool inc): \ 00291 rep((R<X,Y,Z >*) (void*) rep2) { (void) inc; INC_COUNT (rep); } \ 00292 template<XX,YY,ZZ> inline T<X,Y,Z >::T (const T<X,Y,Z >& x): \ 00293 rep(x.rep) { INC_COUNT (rep); } \ 00294 template<XX,YY,ZZ> inline T<X,Y,Z >::~T () { DEC_COUNT (rep); } \ 00295 template<XX,YY,ZZ> inline const R<X,Y,Z >* \ 00296 T<X,Y,Z >::operator -> () const { \ 00297 return rep; } \ 00298 template<XX,YY,ZZ> inline T<X,Y,Z >& \ 00299 T<X,Y,Z >::operator = (const T<X,Y,Z >& x) { \ 00300 INC_COUNT (x.rep); DEC_COUNT (rep); \ 00301 rep=x.rep; return *this; } \ 00302 template<XX,YY,ZZ> inline void T<X,Y,Z >::secure () { \ 00303 if (rep->ref_count>1) *this= copy (*this); } \ 00304 template<XX,YY,ZZ> R<X,Y,Z >* inside (const T<X,Y,Z >& x) { \ 00305 return const_cast<R<X,Y,Z >*> (x.operator -> ()); } \ 00306 template<XX,YY,ZZ> inline nat hard_hash (const T<X,Y,Z>& x) { \ 00307 return as_hash (x.operator -> ()); } \ 00308 template<XX,YY,ZZ> inline bool \ 00309 hard_eq (const T<X,Y,Z >& x, const T<X,Y,Z >& y) { \ 00310 return (x.operator -> ()) == (y.operator -> ()); } \ 00311 template<XX,YY,ZZ> inline bool \ 00312 hard_neq (const T<X,Y,Z >& x, const T<X,Y,Z >& y) { \ 00313 return (x.operator -> ()) != (y.operator -> ()); } 00314 00315 #define INDIRECT_IMPL_4(T,R,WW,W,XX,X,YY,Y,ZZ,Z) \ 00316 template<WW,XX,YY,ZZ> inline T<W,X,Y,Z >::T (R<W,X,Y,Z >* rep2): \ 00317 rep(rep2) {} \ 00318 template<WW,XX,YY,ZZ> inline \ 00319 T<W,X,Y,Z >::T (const R<W,X,Y,Z >* rep2, bool inc): \ 00320 rep((R<W,X,Y,Z >*) (void*) rep2) { (void) inc; INC_COUNT (rep); } \ 00321 template<WW,XX,YY,ZZ> inline T<W,X,Y,Z >::T (const T<W,X,Y,Z >& x): \ 00322 rep(x.rep) { INC_COUNT (rep); } \ 00323 template<WW,XX,YY,ZZ> inline T<W,X,Y,Z >::~T () { DEC_COUNT (rep); } \ 00324 template<WW,XX,YY,ZZ> inline const R<W,X,Y,Z >* \ 00325 T<W,X,Y,Z >::operator -> () const { \ 00326 return rep; } \ 00327 template<WW,XX,YY,ZZ> inline T<W,X,Y,Z >& \ 00328 T<W,X,Y,Z >::operator = (const T<W,X,Y,Z >& x) { \ 00329 INC_COUNT (x.rep); DEC_COUNT (rep); \ 00330 rep=x.rep; return *this; } \ 00331 template<WW,XX,YY,ZZ> inline void T<W,X,Y,Z >::secure () { \ 00332 if (rep->ref_count>1) *this= copy (*this); } \ 00333 template<WW,XX,YY,ZZ> R<W,X,Y,Z >* inside (const T<W,X,Y,Z >& x) { \ 00334 return const_cast<R<W,X,Y,Z >*> (x.operator -> ()); } \ 00335 template<WW,XX,YY,ZZ> inline nat hard_hash (const T<W,X,Y,Z>& x) { \ 00336 return as_hash (x.operator -> ()); } \ 00337 template<WW,XX,YY,ZZ> inline bool \ 00338 hard_eq (const T<W,X,Y,Z >& x, const T<W,X,Y,Z >& y) { \ 00339 return (x.operator -> ()) == (y.operator -> ()); } \ 00340 template<WW,XX,YY,ZZ> inline bool \ 00341 hard_neq (const T<W,X,Y,Z >& x, const T<W,X,Y,Z >& y) { \ 00342 return (x.operator -> ()) != (y.operator -> ()); } 00343 00344 /****************************************************************************** 00345 * Use the following classes instead of templating over values 00346 ******************************************************************************/ 00347 00348 template<typename C, C x> 00349 struct fixed_value { 00350 typedef C val_type; 00351 static const C val= x; 00352 static inline C dyn_val () { return val; } 00353 }; 00354 00355 template<typename C, typename V> 00356 struct variable_value { 00357 typedef C val_type; 00358 static C val; 00359 static inline C dyn_val () { return val; } 00360 }; 00361 00362 template<typename C, typename V> 00363 struct local_value { 00364 C old_value; 00365 inline local_value (const C& new_value) { 00366 old_value= variable_value<C,V>::val; 00367 variable_value<C,V>::val= new_value; } 00368 inline ~local_value () { 00369 variable_value<C,V>::val= old_value; } 00370 }; 00371 00372 /****************************************************************************** 00373 * Forward definitions of some classes 00374 ******************************************************************************/ 00375 00376 class string; 00377 struct vector_naive; 00378 template<typename C> struct vector_variant_helper { typedef vector_naive VV; }; 00379 template<typename C, typename V=typename vector_variant_helper<C>::VV> 00380 class vector; 00381 template<typename F, typename V, typename W=V> struct implementation; 00382 00383 #define DEFINE_VARIANT(L,R) \ 00384 struct L: public R {}; \ 00385 template<typename FF, typename MM> \ 00386 struct implementation<FF,MM,L >: \ 00387 public implementation<FF,MM,R > {}; 00388 00389 #define DEFINE_VARIANT_1(XX,X,L,R) \ 00390 template<XX> struct L: public R {}; \ 00391 template<typename FF, typename MM, XX> \ 00392 struct implementation<FF,MM,L<X> >: \ 00393 public implementation<FF,MM,R > {}; 00394 00395 /****************************************************************************** 00396 * Helper class for thresholds 00397 ******************************************************************************/ 00398 00399 template<nat n> struct uniform_threshold {}; 00400 00401 template<typename C, typename Th> 00402 struct threshold_helper { 00403 typedef fixed_value<nat,2> impl; 00404 }; 00405 00406 template<typename C, nat n> 00407 struct threshold_helper<C,uniform_threshold<n> > { 00408 typedef fixed_value<nat,n> impl; 00409 }; 00410 00411 #define Threshold(C,Th) threshold_helper<C,Th >::impl::val 00412 00413 // Threshold with one parameter 00414 00415 template<typename C, typename Th> 00416 struct threshold_helper_1 { 00417 static inline nat val (nat d) { 00418 return 2; } 00419 }; 00420 00421 template<typename C, nat n> 00422 struct threshold_helper_1<C,uniform_threshold<n> > { 00423 static inline nat val (nat d) { 00424 return n; } 00425 }; 00426 00427 #define Threshold_1(C,Th,d) threshold_helper_1<C,Th>::val(d) 00428 00429 } // namespace mmx 00430 #endif // __MMX_BASIX_HPP