00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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 reset_indent,
00044 cr,
00045 lf,
00046 hrule,
00047 flush_now,
00048
00049 black_foreground,
00050 red_foreground,
00051 green_foreground,
00052 yellow_foreground,
00053 blue_foreground,
00054 magenta_foreground,
00055 cyan_foreground,
00056 white_foreground,
00057
00058 black_background,
00059 red_background,
00060 green_background,
00061 yellow_background,
00062 blue_background,
00063 magenta_background,
00064 cyan_background,
00065 white_background,
00066
00067 bold,
00068 underline,
00069 blink,
00070
00071 reset_attributes
00072 };
00073
00074 extern int mmx_argc;
00075 extern char** mmx_argv;
00076 void noop ();
00077
00078
00079
00080
00081
00083 #define INDIRECT_PROTO(T,R) \
00084 MMX_ALLOCATORS \
00085 protected: \
00086 R* rep; \
00087 public: \
00088 inline T (R* rep2); \
00089 inline T (const R* rep2, bool with_inc); \
00090 inline T (const T& x); \
00091 inline ~T (); \
00092 inline T& operator= (const T& x); \
00093 inline const R* operator-> () const; \
00094 inline void secure ();
00095
00098 #define INDIRECT_PROTO_1(T,R,X) \
00099 MMX_ALLOCATORS \
00100 protected: \
00101 R<X >* rep; \
00102 public: \
00103 inline T (R<X >* rep2); \
00104 inline T (const R<X >* rep2, bool with_inc); \
00105 inline T (const T& x); \
00106 inline ~T (); \
00107 inline T& operator= (const T& x); \
00108 inline const R<X >* operator-> () const; \
00109 inline R<X >* operator-> (); \
00110 inline void secure (); \
00111 typedef X value_type;
00112
00115 #define INDIRECT_PROTO_2(T,R,X,Y) \
00116 MMX_ALLOCATORS \
00117 protected: \
00118 R<X,Y >* rep; \
00119 public: \
00120 inline T (R<X,Y >* rep2); \
00121 inline T (const R<X,Y >* rep2, bool inc); \
00122 inline T (const T& x); \
00123 inline ~T (); \
00124 inline T& operator= (const T& x); \
00125 inline const R<X,Y >* operator-> () const; \
00126 inline void secure ();
00127
00130 #define INDIRECT_PROTO_3(T,R,X,Y,Z) \
00131 MMX_ALLOCATORS \
00132 protected: \
00133 R<X,Y,Z >* rep; \
00134 public: \
00135 inline T (R<X,Y,Z >* rep2); \
00136 inline T (const R<X,Y,Z >* rep2, bool inc); \
00137 inline T (const T& x); \
00138 inline ~T (); \
00139 inline T& operator= (const T& x); \
00140 inline const R<X,Y,Z >* operator-> () const; \
00141 inline void secure ();
00142
00145 #define INDIRECT_PROTO_4(T,R,W,X,Y,Z) \
00146 MMX_ALLOCATORS \
00147 protected: \
00148 R<W,X,Y,Z >* rep; \
00149 public: \
00150 inline T (R<W,X,Y,Z >* rep2); \
00151 inline T (const R<W,X,Y,Z >* rep2, bool inc); \
00152 inline T (const T& x); \
00153 inline ~T (); \
00154 inline T& operator= (const T& x); \
00155 inline const R<W,X,Y,Z >* operator-> () const;\
00156 inline void secure ();
00157
00158
00159
00160
00161
00162 struct rep_struct {
00163 MMX_ALLOCATORS
00164 int ref_count;
00165 inline rep_struct (): ref_count (1) {}
00166 virtual inline ~rep_struct () {}
00167 };
00168
00169 #define REP_STRUCT :public rep_struct
00170 #define REP_STRUCT_1(X) :public rep_struct, public format<X >
00171 #define REP_STRUCT_2(X,Y) :public rep_struct, public encapsulate1<format<X > >, public encapsulate2<format<Y> >
00172 #define INC_COUNT(x) { (x)->ref_count++; }
00173 #define DEC_COUNT(x) { if (0==--((x)->ref_count)) delete (x); }
00174 #define INC_NULL_COUNT(x) { if ((x)!=NULL) (x)->ref_count++; }
00175 #define DEC_NULL_COUNT(x) { \
00176 if ((x)!=NULL && 0==--((x)->ref_count)) delete (x); }
00177
00178 template<typename C> C copy (const C& x) {
00179 assert (false);
00180 return x; }
00181
00182 template<typename C> inline nat as_hash (const C* p) {
00183 return ((nat) ((uintptr_t) ((void*) p))) >> 3; }
00184 inline nat hash (char c) { return (nat) c; }
00185 inline nat hash (signed char c) { return (nat) c; }
00186 inline nat hash (unsigned char c) { return (nat) c; }
00187 inline nat hash (short int c) { return (nat) c; }
00188 inline nat hash (short unsigned int c) { return (nat) c; }
00189 inline nat hash (int c) { return (nat) c; }
00190 inline nat hash (unsigned int c) { return (nat) c; }
00191 inline nat hash (long int c) { return (nat) c; }
00192 inline nat hash (long unsigned int c) { return (nat) c; }
00193 inline nat hash (long long int c) {
00194 nat h = (nat) ((c >> (4 * sizeof (long int))) >> (4 * sizeof (long int)));
00195 return (h<<1) ^ (h<<5) ^ (h>>27) ^ ((nat) c); }
00196 inline nat hash (long long unsigned int c) {
00197 nat h = (nat) ((c >> (4 * sizeof (long int))) >> (4 * sizeof (long int)));
00198 return (h<<1) ^ (h<<5) ^ (h>>27) ^ ((nat) c); }
00199 inline nat hash (const float& x) {
00200 return (*((nat*) ((void*) &x))) & 0xffffffff; }
00201 inline nat hash (const double& x) {
00202 union { nat n; double d; } u;
00203 u.d= x; return u.n; }
00204 template<typename C> inline nat hash (C* p) { return as_hash (p); }
00205
00206 inline nat exact_hash (char c) { return (nat) c; }
00207 inline nat exact_hash (signed char c) { return (nat) c; }
00208 inline nat exact_hash (unsigned char c) { return (nat) c; }
00209 inline nat exact_hash (short int c) { return (nat) c; }
00210 inline nat exact_hash (short unsigned int c) { return (nat) c; }
00211 inline nat exact_hash (int c) { return (nat) c; }
00212 inline nat exact_hash (unsigned int c) { return (nat) c; }
00213 inline nat exact_hash (long int c) { return (nat) c; }
00214 inline nat exact_hash (long unsigned int c) { return (nat) c; }
00215 inline nat exact_hash (long long int c) {
00216 nat h = (nat) ((c >> (4 * sizeof (long int))) >> (4 * sizeof (long int)));
00217 return (h<<1) ^ (h<<5) ^ (h>>27) ^ ((nat) c); }
00218 inline nat exact_hash (long long unsigned int c) {
00219 nat h = (nat) ((c >> (4 * sizeof (long int))) >> (4 * sizeof (long int)));
00220 return (h<<1) ^ (h<<5) ^ (h>>27) ^ ((nat) c); }
00221 inline nat exact_hash (const float& x) {
00222 return (*((nat*) ((void*) &x))) & 0xffffffff; }
00223 inline nat exact_hash (const double& x) {
00224 union { nat n; double d; } u;
00225 u.d= x; return u.n; }
00226 template<typename C> inline nat exact_hash (C* p) { return as_hash (p); }
00227
00228 inline bool exact_eq (char c1, char c2) { return c1 == c2; }
00229 inline bool exact_eq (signed char c1, signed char c2) { return c1 == c2; }
00230 inline bool exact_eq (unsigned char c1, unsigned char c2) { return c1 == c2; }
00231 inline bool exact_eq (short int c1, short int c2) { return c1 == c2; }
00232 inline bool exact_eq (short unsigned int c1, short unsigned int c2) {
00233 return c1 == c2; }
00234 inline bool exact_eq (int c1, int c2) { return c1 == c2; }
00235 inline bool exact_eq (unsigned int c1, unsigned int c2) { return c1 == c2; }
00236 inline bool exact_eq (long int c1, long int c2) { return c1 == c2; }
00237 inline bool exact_eq (long unsigned int c1, long unsigned int c2) {
00238 return c1 == c2; }
00239 inline bool exact_eq (long long int c1, long long int c2) { return c1 == c2; }
00240 inline bool exact_eq (long long unsigned int c1, long long unsigned int c2) {
00241 return c1 == c2; }
00242
00243 inline bool exact_eq (float x, float y) { return x == y; }
00244 inline bool exact_eq (double x, double y) { return x == y; }
00245 template<typename C> inline bool exact_eq (C* p1, C* p2) { return p1 == p2; }
00246
00247 inline bool exact_neq (char c1, char c2) { return c1 != c2; }
00248 inline bool exact_neq (signed char c1, signed char c2) { return c1 != c2; }
00249 inline bool exact_neq (unsigned char c1, unsigned char c2) { return c1 != c2; }
00250 inline bool exact_neq (short int c1, short int c2) { return c1 != c2; }
00251 inline bool exact_neq (short unsigned int c1, short unsigned int c2) {
00252 return c1 != c2; }
00253 inline bool exact_neq (int c1, int c2) { return c1 != c2; }
00254 inline bool exact_neq (unsigned int c1, unsigned int c2) { return c1 != c2; }
00255 inline bool exact_neq (long int c1, long int c2) { return c1 != c2; }
00256 inline bool exact_neq (long unsigned int c1, long unsigned int c2) {
00257 return c1 != c2; }
00258 inline bool exact_neq (long long int c1, long long int c2) { return c1 != c2; }
00259 inline bool exact_neq (long long unsigned int c1, long long unsigned int c2) {
00260 return c1 != c2; }
00261
00262 inline bool exact_neq (float x, float y) { return x != y; }
00263 inline bool exact_neq (double x, double y) { return x != y; }
00264 template<typename C> inline bool exact_neq (C* p1, C* p2) { return p1 != p2; }
00265
00266
00267 template<typename C> inline nat hard_hash (const C& x) {
00268 return exact_hash (x); }
00269 template<typename C> inline bool hard_eq (const C& x, const C& y) {
00270 return exact_eq (x, y); }
00271 template<typename C> inline bool hard_neq (const C& x, const C& y) {
00272 return exact_neq (x, y); }
00273 template<typename C> inline bool hard_less (const C& x, const C& y) {
00274 return ((void*) inside (x)) < ((void*) inside (y)); }
00275 template<typename C> inline bool hard_gtr (const C& x, const C& y) {
00276 return ((void*) inside (x)) > ((void*) inside (y)); }
00277
00278 #define INDIRECT_IMPL(T,R) \
00279 inline T::T (R* rep2): rep(rep2) {} \
00280 inline T::T (const R* rep2, bool with_inc): \
00281 rep((R*) (void*) rep2) { (void) with_inc; INC_COUNT (rep); } \
00282 inline T::T (const T& x): rep(x.rep) { INC_COUNT (rep); } \
00283 inline T::~T () { DEC_COUNT (rep); } \
00284 inline const R* T::operator -> () const { return rep; } \
00285 inline T& T::operator = (const T& x) { \
00286 INC_COUNT (x.rep); DEC_COUNT (rep); \
00287 rep=x.rep; return *this; } \
00288 inline void T::secure () { \
00289 if (rep->ref_count>1) *this= copy (*this); } \
00290 inline R* inside (const T& x) { \
00291 return const_cast<R*> (x.operator -> ()); } \
00292 STMPL inline nat hard_hash (const T& x) { \
00293 return as_hash (x.operator -> ()); } \
00294 STMPL inline bool hard_eq (const T& x, const T& y) { \
00295 return (x.operator -> ()) == (y.operator -> ()); } \
00296 STMPL inline bool hard_neq (const T& x, const T& y) { \
00297 return (x.operator -> ()) != (y.operator -> ()); }
00298
00299 #define INDIRECT_NULL_IMPL(T,R) \
00300 inline T::T (R* rep2): rep(rep2) {} \
00301 inline T::T (const R* rep2, bool with_inc): \
00302 rep((R*) (void*) rep2) { (void) with_inc; INC_NULL_COUNT (rep); } \
00303 inline T::T (const T& x): rep(x.rep) { INC_NULL_COUNT (rep); } \
00304 inline T::~T () { DEC_NULL_COUNT (rep); } \
00305 inline const R* T::operator -> () const { return rep; } \
00306 inline T& T::operator = (const T& x) { \
00307 INC_NULL_COUNT (x.rep); DEC_NULL_COUNT (rep); \
00308 rep=x.rep; return *this; } \
00309 inline void T::secure () { \
00310 if (rep->ref_count>1) *this= copy (*this); } \
00311 inline R* inside (const T& x) { \
00312 return const_cast<R*> (x.operator -> ()); } \
00313 STMPL inline nat hard_hash (const T& x) { \
00314 return as_hash (x.operator -> ()); } \
00315 STMPL inline bool hard_eq (const T& x, const T& y) { \
00316 return (x.operator -> ()) == (y.operator -> ()); } \
00317 STMPL inline bool hard_neq (const T& x, const T& y) { \
00318 return (x.operator -> ()) != (y.operator -> ()); }
00319
00320 #define INDIRECT_IMPL_1(T,R,XX,X) \
00321 template<XX> inline T<X >::T (R<X >* rep2): rep(rep2) {} \
00322 template<XX> inline T<X >::T (const R<X >* rep2, bool with_inc): \
00323 rep((R<X >*) (void*) rep2) { (void) with_inc; INC_COUNT (rep); } \
00324 template<XX> inline T<X >::T (const T<X >& x): rep(x.rep) { \
00325 INC_COUNT (rep); } \
00326 template<XX> inline T<X >::~T () { DEC_COUNT (rep); } \
00327 template<XX> inline const R<X >* T<X >::operator -> () const { \
00328 return rep; } \
00329 template<XX> inline R<X >* T<X >::operator -> () { \
00330 return rep; } \
00331 template<XX> inline T<X >& \
00332 T<X >::operator = (const T<X >& x) { \
00333 INC_COUNT (x.rep); DEC_COUNT (rep); \
00334 rep=x.rep; return *this; } \
00335 template<XX> inline void T<X >::secure () { \
00336 if (rep->ref_count>1) *this= copy (*this); } \
00337 template<XX> R<X >* inside (const T<X >& x) { \
00338 return const_cast<R<X >*> (x.operator -> ()); } \
00339 template<XX> inline nat hard_hash (const T<X >& x) { \
00340 return as_hash (x.operator -> ()); } \
00341 template<XX> inline bool hard_eq (const T<X >& x, const T<X >& y) { \
00342 return (x.operator -> ()) == (y.operator -> ()); } \
00343 template<XX> inline bool hard_neq (const T<X >& x, const T<X >& y) { \
00344 return (x.operator -> ()) != (y.operator -> ()); }
00345
00346 #define INDIRECT_NULL_IMPL_1(T,R,XX,X) \
00347 template<XX> inline T<X >::T (R<X >* rep2): rep(rep2) {} \
00348 template<XX> inline T<X >::T (const R<X >* rep2, bool with_inc): \
00349 rep((R<X >*) (void*) rep2) { (void) with_inc; INC_NULL_COUNT (rep); } \
00350 template<XX> inline T<X >::T (const T<X >& x): rep(x.rep) { \
00351 INC_NULL_COUNT (rep); } \
00352 template<XX> inline T<X >::~T () { DEC_NULL_COUNT (rep); } \
00353 template<XX> inline const R<X >* T<X >::operator -> () const { \
00354 return rep; } \
00355 template<XX> inline R<X >* T<X >::operator -> () { \
00356 return rep; } \
00357 template<XX> inline T<X >& \
00358 T<X >::operator = (const T<X >& x) { \
00359 INC_NULL_COUNT (x.rep); DEC_NULL_COUNT (rep); \
00360 rep=x.rep; return *this; } \
00361 template<XX> inline void T<X >::secure () { \
00362 if (rep->ref_count>1) *this= copy (*this); } \
00363 template<XX> R<X >* inside (const T<X >& x) { \
00364 return const_cast<R<X >*> (x.operator -> ()); } \
00365 template<XX> inline nat hard_hash (const T<X >& x) { \
00366 return as_hash (x.operator -> ()); } \
00367 template<XX> inline bool hard_eq (const T<X >& x, const T<X >& y) { \
00368 return (x.operator -> ()) == (y.operator -> ()); } \
00369 template<XX> inline bool hard_neq (const T<X >& x, const T<X >& y) { \
00370 return (x.operator -> ()) != (y.operator -> ()); }
00371
00372 #define INDIRECT_IMPL_2(T,R,XX,X,YY,Y) \
00373 template<XX,YY> inline T<X,Y >::T (R<X,Y >* rep2): rep(rep2) {} \
00374 template<XX,YY> inline T<X,Y >::T (const R<X,Y >* rep2, bool inc): \
00375 rep((R<X,Y >*) (void*) rep2) { (void) inc; INC_COUNT (rep); } \
00376 template<XX,YY> inline T<X,Y >::T (const T<X,Y >& x): rep(x.rep) { \
00377 INC_COUNT (rep); } \
00378 template<XX,YY> inline T<X,Y >::~T () { DEC_COUNT (rep); } \
00379 template<XX,YY> inline const R<X,Y >* T<X,Y >::operator -> () const { \
00380 return rep; } \
00381 template<XX,YY> inline T<X,Y >& \
00382 T<X,Y >::operator = (const T<X,Y >& x) { \
00383 INC_COUNT (x.rep); DEC_COUNT (rep); \
00384 rep=x.rep; return *this; } \
00385 template<XX,YY> inline void T<X,Y >::secure () { \
00386 if (rep->ref_count>1) *this= copy (*this); } \
00387 template<XX,YY> R<X,Y >* inside (const T<X,Y >& x) { \
00388 return const_cast<R<X,Y >*> (x.operator -> ()); } \
00389 template<XX,YY> inline nat hard_hash (const T<X,Y >& x) { \
00390 return as_hash (x.operator -> ()); } \
00391 template<XX,YY> inline bool hard_eq (const T<X,Y >& x, const T<X,Y >& y) { \
00392 return (x.operator -> ()) == (y.operator -> ()); } \
00393 template<XX,YY> inline bool hard_neq (const T<X,Y >& x, const T<X,Y >& y) { \
00394 return (x.operator -> ()) != (y.operator -> ()); }
00395
00396 #define INDIRECT_IMPL_3(T,R,XX,X,YY,Y,ZZ,Z) \
00397 template<XX,YY,ZZ> inline T<X,Y,Z >::T (R<X,Y,Z >* rep2): \
00398 rep(rep2) {} \
00399 template<XX,YY,ZZ> inline \
00400 T<X,Y,Z >::T (const R<X,Y,Z >* rep2, bool inc): \
00401 rep((R<X,Y,Z >*) (void*) rep2) { (void) inc; INC_COUNT (rep); } \
00402 template<XX,YY,ZZ> inline T<X,Y,Z >::T (const T<X,Y,Z >& x): \
00403 rep(x.rep) { INC_COUNT (rep); } \
00404 template<XX,YY,ZZ> inline T<X,Y,Z >::~T () { DEC_COUNT (rep); } \
00405 template<XX,YY,ZZ> inline const R<X,Y,Z >* \
00406 T<X,Y,Z >::operator -> () const { \
00407 return rep; } \
00408 template<XX,YY,ZZ> inline T<X,Y,Z >& \
00409 T<X,Y,Z >::operator = (const T<X,Y,Z >& x) { \
00410 INC_COUNT (x.rep); DEC_COUNT (rep); \
00411 rep=x.rep; return *this; } \
00412 template<XX,YY,ZZ> inline void T<X,Y,Z >::secure () { \
00413 if (rep->ref_count>1) *this= copy (*this); } \
00414 template<XX,YY,ZZ> R<X,Y,Z >* inside (const T<X,Y,Z >& x) { \
00415 return const_cast<R<X,Y,Z >*> (x.operator -> ()); } \
00416 template<XX,YY,ZZ> inline nat hard_hash (const T<X,Y,Z>& x) { \
00417 return as_hash (x.operator -> ()); } \
00418 template<XX,YY,ZZ> inline bool \
00419 hard_eq (const T<X,Y,Z >& x, const T<X,Y,Z >& y) { \
00420 return (x.operator -> ()) == (y.operator -> ()); } \
00421 template<XX,YY,ZZ> inline bool \
00422 hard_neq (const T<X,Y,Z >& x, const T<X,Y,Z >& y) { \
00423 return (x.operator -> ()) != (y.operator -> ()); }
00424
00425 #define INDIRECT_IMPL_4(T,R,WW,W,XX,X,YY,Y,ZZ,Z) \
00426 template<WW,XX,YY,ZZ> inline T<W,X,Y,Z >::T (R<W,X,Y,Z >* rep2): \
00427 rep(rep2) {} \
00428 template<WW,XX,YY,ZZ> inline \
00429 T<W,X,Y,Z >::T (const R<W,X,Y,Z >* rep2, bool inc): \
00430 rep((R<W,X,Y,Z >*) (void*) rep2) { (void) inc; INC_COUNT (rep); } \
00431 template<WW,XX,YY,ZZ> inline T<W,X,Y,Z >::T (const T<W,X,Y,Z >& x): \
00432 rep(x.rep) { INC_COUNT (rep); } \
00433 template<WW,XX,YY,ZZ> inline T<W,X,Y,Z >::~T () { DEC_COUNT (rep); } \
00434 template<WW,XX,YY,ZZ> inline const R<W,X,Y,Z >* \
00435 T<W,X,Y,Z >::operator -> () const { \
00436 return rep; } \
00437 template<WW,XX,YY,ZZ> inline T<W,X,Y,Z >& \
00438 T<W,X,Y,Z >::operator = (const T<W,X,Y,Z >& x) { \
00439 INC_COUNT (x.rep); DEC_COUNT (rep); \
00440 rep=x.rep; return *this; } \
00441 template<WW,XX,YY,ZZ> inline void T<W,X,Y,Z >::secure () { \
00442 if (rep->ref_count>1) *this= copy (*this); } \
00443 template<WW,XX,YY,ZZ> R<W,X,Y,Z >* inside (const T<W,X,Y,Z >& x) { \
00444 return const_cast<R<W,X,Y,Z >*> (x.operator -> ()); } \
00445 template<WW,XX,YY,ZZ> inline nat hard_hash (const T<W,X,Y,Z>& x) { \
00446 return as_hash (x.operator -> ()); } \
00447 template<WW,XX,YY,ZZ> inline bool \
00448 hard_eq (const T<W,X,Y,Z >& x, const T<W,X,Y,Z >& y) { \
00449 return (x.operator -> ()) == (y.operator -> ()); } \
00450 template<WW,XX,YY,ZZ> inline bool \
00451 hard_neq (const T<W,X,Y,Z >& x, const T<W,X,Y,Z >& y) { \
00452 return (x.operator -> ()) != (y.operator -> ()); }
00453
00454
00455
00456
00457
00458 template<typename C, C x>
00459 struct fixed_value {
00460 typedef C val_type;
00461 static const C val= x;
00462 static inline C dyn_val () { return val; }
00463 };
00464
00465 template<typename C, typename V>
00466 struct variable_value {
00467 typedef C val_type;
00468 static C val;
00469 static inline C dyn_val () { return val; }
00470 };
00471
00472 template<typename C, typename V>
00473 struct local_value {
00474 C old_value;
00475 inline local_value (const C& new_value) {
00476 old_value= variable_value<C,V>::val;
00477 variable_value<C,V>::val= new_value; }
00478 inline ~local_value () {
00479 variable_value<C,V>::val= old_value; }
00480 };
00481
00482
00483
00484
00485
00486 class string;
00487 struct vector_naive;
00488 template<typename C> struct vector_variant_helper { typedef vector_naive VV; };
00489 template<typename C, typename V=typename vector_variant_helper<C>::VV>
00490 class vector;
00491 template<typename F, typename V, typename W=V> struct implementation;
00492
00493 #define DEFINE_VARIANT(L,R) \
00494 struct L: public R {}; \
00495 template<typename FF, typename MM> \
00496 struct implementation<FF,MM,L >: \
00497 public implementation<FF,MM,R > {};
00498
00499 #define DEFINE_VARIANT_1(XX,X,L,R) \
00500 template<XX> struct L: public R {}; \
00501 template<typename FF, typename MM, XX> \
00502 struct implementation<FF,MM,L<X> >: \
00503 public implementation<FF,MM,R > {};
00504
00505
00506
00507
00508
00509 template<nat n> struct uniform_threshold {};
00510
00511 template<typename C, typename Th>
00512 struct threshold_helper {
00513 typedef fixed_value<nat,2> impl;
00514 };
00515
00516 template<typename C, nat n>
00517 struct threshold_helper<C,uniform_threshold<n> > {
00518 typedef fixed_value<nat,n> impl;
00519 };
00520
00521 #define Threshold(C,Th) threshold_helper<C,Th >::impl::val
00522
00523
00524
00525 template<typename C, typename Th>
00526 struct threshold_helper_1 {
00527 static inline nat val (nat d) {
00528 return 2; }
00529 };
00530
00531 template<typename C, nat n>
00532 struct threshold_helper_1<C,uniform_threshold<n> > {
00533 static inline nat val (nat d) {
00534 return n; }
00535 };
00536
00537 #define Threshold_1(C,Th,d) threshold_helper_1<C,Th>::val(d)
00538
00539 }
00540 #endif // __MMX_BASIX_HPP