basix_doc 0.1
/Users/mourrain/Devel/mmx/basix/include/basix/basix.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines