00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef __MMX_TYPE_PROPS_HPP
00014 #define __MMX_TYPE_PROPS_HPP
00015 #include <basix/exception.hpp>
00017 namespace mmx {
00018
00019
00020
00021
00022
00023 template<typename Op, typename C>
00024 struct unary_return_type_helper {
00025 typedef C RET;
00026 };
00027
00028 template<typename Op, typename C1, typename C2>
00029 struct binary_return_type_helper {
00030 typedef C1 RET;
00031 };
00032
00033 template<typename Op, typename C1, typename C2, typename C3>
00034 struct ternary_return_type_helper {
00035 typedef C1 RET;
00036 };
00037
00038 #define UNARY_RETURN_TYPE(TMPL,op,C,Ret) \
00039 TMPL \
00040 struct unary_return_type_helper<op,C > { \
00041 typedef Ret RET; \
00042 };
00043
00044 #define BINARY_RETURN_TYPE(TMPL,op,C1,C2,Ret) \
00045 TMPL \
00046 struct binary_return_type_helper<op,C1,C2 > { \
00047 typedef Ret RET; \
00048 };
00049
00050 #define TERNARY_RETURN_TYPE(TMPL,op,C1,C2,C3,Ret) \
00051 TMPL \
00052 struct ternary_return_type_helper<op,C1,C2,C3 > { \
00053 typedef Ret RET; \
00054 };
00055
00056 #define Unary_return_type(Op,C) \
00057 typename unary_return_type_helper<Op,C>::RET
00058 #define Binary_return_type(Op,C1,C2) \
00059 typename binary_return_type_helper<Op,C1,C2>::RET
00060 #define Ternary_return_type(Op,C1,C2,C3) \
00061 typename ternary_return_type_helper<Op,C1,C2,C3>::RET
00062
00063 struct abs_op;
00064 struct Re_op;
00065 struct gaussian_op;
00066 struct center_op;
00067 struct radius_op;
00068 struct numerator_op;
00069 struct denominator_op;
00070 struct lift_op;
00071 struct project_op;
00072 struct reconstruct_op;
00073 struct truncate_op;
00074 struct complete_op;
00075 struct evaluate_op;
00076 template<typename C> class complex;
00077
00078 #define Abs_type(C) typename unary_return_type_helper<abs_op,C >::RET
00079 #define Real_type(C) typename unary_return_type_helper<Re_op,C >::RET
00080 #define Complex_type(C) \
00081 typename binary_return_type_helper<gaussian_op,C,C >::RET
00082 #define Center_type(C) typename unary_return_type_helper<center_op,C >::RET
00083 #define Radius_type(C) typename unary_return_type_helper<radius_op,C >::RET
00084 #define Numerator_type(C) \
00085 typename unary_return_type_helper<numerator_op,C >::RET
00086 #define Denominator_type(C) \
00087 typename unary_return_type_helper<denominator_op,C >::RET
00088 #define Lift_type(C) \
00089 typename unary_return_type_helper<lift_op,C >::RET
00090 #define Project_type(C) \
00091 typename unary_return_type_helper<project_op,C >::RET
00092 #define Reconstruct_type(C) \
00093 typename unary_return_type_helper<reconstruct_op,C >::RET
00094 #define Truncate_type(C) \
00095 typename binary_return_type_helper<truncate_op,C,nat>::RET
00096 #define Complete_type(C) \
00097 typename unary_return_type_helper<complete_op,C >::RET
00098 #define Evaluate_type(C,D) \
00099 typename binary_return_type_helper<evaluate_op,C,D>::RET
00100
00101 UNARY_RETURN_TYPE(STMPL,abs_op,generic,generic);
00102 UNARY_RETURN_TYPE(STMPL,abs_op,syntactic,syntactic);
00103 UNARY_RETURN_TYPE(STMPL,Re_op,generic,generic);
00104 UNARY_RETURN_TYPE(STMPL,Re_op,syntactic,syntactic);
00105 UNARY_RETURN_TYPE(STMPL,center_op,generic,generic);
00106 UNARY_RETURN_TYPE(STMPL,center_op,syntactic,syntactic);
00107 UNARY_RETURN_TYPE(STMPL,radius_op,generic,generic);
00108 UNARY_RETURN_TYPE(STMPL,radius_op,syntactic,syntactic);
00109 UNARY_RETURN_TYPE(STMPL,numerator_op,generic,generic);
00110 UNARY_RETURN_TYPE(STMPL,numerator_op,syntactic,syntactic);
00111 UNARY_RETURN_TYPE(STMPL,denominator_op,generic,generic);
00112 UNARY_RETURN_TYPE(STMPL,denominator_op,syntactic,syntactic);
00113 UNARY_RETURN_TYPE(STMPL,lift_op,generic,generic);
00114 UNARY_RETURN_TYPE(STMPL,lift_op,syntactic,syntactic);
00115 UNARY_RETURN_TYPE(STMPL,project_op,generic,generic);
00116 UNARY_RETURN_TYPE(STMPL,project_op,syntactic,syntactic);
00117 UNARY_RETURN_TYPE(STMPL,reconstruct_op,generic,generic);
00118 UNARY_RETURN_TYPE(STMPL,reconstruct_op,syntactic,syntactic);
00119 BINARY_RETURN_TYPE(STMPL,truncate_op,generic,nat,generic);
00120 BINARY_RETURN_TYPE(STMPL,truncate_op,syntactic,nat,syntactic);
00121 UNARY_RETURN_TYPE(STMPL,complete_op,generic,generic);
00122 UNARY_RETURN_TYPE(STMPL,complete_op,syntactic,syntactic);
00123 BINARY_RETURN_TYPE(STMPL,evaluate_op,generic,generic,generic);
00124 BINARY_RETURN_TYPE(STMPL,evaluate_op,syntactic,syntactic,syntactic);
00125
00126 template<typename C>
00127 struct unary_return_type_helper<radius_op,C> {
00128 typedef Abs_type(C) RET;
00129 };
00130
00131 template<typename C>
00132 struct binary_return_type_helper<gaussian_op,C,C> {
00133 typedef complex<C> RET;
00134 };
00135
00136
00137
00138
00139
00140 #define TYPE_TO_TYPE(name,expr) \
00141 template<typename C> \
00142 struct name##_helper { \
00143 typedef expr val; \
00144 };
00145
00146 #define STYPE_TO_TYPE(TMPL,name,C,expr) \
00147 TMPL \
00148 struct name##_helper<C > { \
00149 typedef expr val; \
00150 };
00151
00152 template<typename C>
00153 struct default_radius_type_helper {
00154 typedef Abs_type(C) val;
00155 };
00156
00157 class unknown_as_vector_type {};
00158 class unknown_as_matrix_type {};
00159
00160 TYPE_TO_TYPE(coefficient1_type,C);
00161 TYPE_TO_TYPE(coefficient2_type,C);
00162 TYPE_TO_TYPE(coefficient3_type,C);
00163 TYPE_TO_TYPE(scalar_type,C);
00164 TYPE_TO_TYPE(monomial_type,C);
00165 TYPE_TO_TYPE(as_vector_type,unknown_as_vector_type);
00166 TYPE_TO_TYPE(as_matrix_type,unknown_as_matrix_type);
00167
00168 #define Coefficient1_type(C) typename coefficient1_type_helper<C >::val
00169 #define Coefficient2_type(C) typename coefficient2_type_helper<C >::val
00170 #define Coefficient3_type(C) typename coefficient3_type_helper<C >::val
00171 #define Scalar_type(C) typename scalar_type_helper<C >::val
00172 #define Monomial_type(C) typename monomial_type_helper<C >::val
00173 #define Default_radius_type(C) typename default_radius_type_helper<C >::val
00174 #define As_vector_type(C) typename as_vector_type_helper<C >::val
00175 #define As_matrix_type(C) typename as_matrix_type_helper<C >::val
00176
00177
00178
00179
00180
00181 struct no_format {};
00182
00183 struct empty_format {
00184 inline empty_format () {}
00185 inline empty_format (const no_format&) {}
00186 template<typename C> inline empty_format (const C&) {}
00187 template<typename C,typename D> inline empty_format (const C&, const D&) {}
00188 inline empty_format rfm () const { return *this; }
00189 inline empty_format format1 () const { return empty_format (); }
00190 inline empty_format format2 () const { return empty_format (); }
00191 inline empty_format format3 () const { return empty_format (); }
00192 };
00193
00194 template<typename C>
00195 struct format: public empty_format {
00196 typedef empty_format FT;
00197 inline format () {}
00198 inline format (const no_format&) {}
00199 inline format (const FT&) {}
00200 inline format (const format<C>&): empty_format () {}
00201 inline format<C> tfm () const { return *this; }
00202 inline C sample () const { return C(); }
00203 };
00204
00205 template<typename C> inline format<C>
00206 copy (const format<C> &x) { return format<C> (x); }
00207
00208 template<typename C> inline bool
00209 operator == (const format<C>& x, const format<C>& y) { return true; }
00210
00211 template<typename C> inline bool
00212 operator != (const format<C>& x, const format<C>& y) { return false; }
00213
00214 template<typename C> inline bool
00215 exact_eq (const format<C>& x, const format<C>& y) { return true; }
00216
00217 template<typename C> inline bool
00218 exact_neq (const format<C>& x, const format<C>& y) { return false; }
00219
00220 template<typename C> inline bool
00221 hard_eq (const format<C>& x, const format<C>& y) { return true; }
00222
00223 template<typename C> inline bool
00224 hard_neq (const format<C>& x, const format<C>& y) { return false; }
00225
00226 template<typename C> inline nat
00227 hash (const format<C>& x) { return 0; }
00228
00229 template<typename C> inline nat
00230 exact_hash (const format<C>& x) { return 0; }
00231
00232 template<typename C> inline nat
00233 hard_hash (const format<C>& x) { return 0; }
00234
00235 template<typename C> inline syntactic
00236 flatten (const format<C>& x) {
00237 string name= cpp_demangle (typeid (format<C>).name ());
00238 return apply (flatten (lit (name))); }
00239
00240 template<typename C> inline format<C>
00241 get_format (const C& x) {
00242 return typename format<C>::FT (x);
00243 }
00244
00245 template<typename C> inline C
00246 get_sample (const format<C>& fm) {
00247 return fm.sample ();
00248 }
00249
00250 template<typename C> inline format<Coefficient1_type(C) >
00251 get_format1 (const format<C>& fm) {
00252 return format<Coefficient1_type(C) > (fm.format1 ());
00253 }
00254
00255 template<typename C> inline format<Coefficient2_type(C) >
00256 get_format2 (const format<C>& fm) {
00257 return format<Coefficient2_type(C) > (fm.format2 ());
00258 }
00259
00260 template<typename C>
00261 struct encapsulate1: public C {
00262 inline encapsulate1 () {}
00263 inline encapsulate1 (const C& x): C(x) {}
00264 inline C tfm1 () const { return this->tfm (); }
00265 };
00266
00267 template<typename C>
00268 struct encapsulate2: public C {
00269 inline encapsulate2 () {}
00270 inline encapsulate2 (const C& x): C(x) {}
00271 inline C tfm2 () const { return this->tfm (); }
00272 };
00273
00274
00275
00276
00277
00278 template<typename FT1>
00279 struct unary_format {
00280 FT1 fm1;
00281 inline unary_format ():
00282 fm1 () {}
00283 template<typename C> inline unary_format (const C& x):
00284 fm1 ((FT1) CF(x)) {}
00285 template<typename C> inline unary_format (const format<C>& x):
00286 fm1 ((FT1) get_format1 (x)) {}
00287 inline unary_format (const no_format& nfm):
00288 fm1 (nfm) {}
00289 inline unary_format (const unary_format<FT1>& fm):
00290 fm1 (fm.fm1) {}
00291 inline unary_format (const FT1& fm1b):
00292 fm1 (fm1b) {}
00293 inline unary_format<FT1> rfm () const { return *this; }
00294 inline FT1 format1 () const { return fm1; }
00295 };
00296
00297 template<typename FT1> struct unary_format_helper {
00298 typedef unary_format<FT1> FT; };
00299 STMPL struct unary_format_helper<empty_format> {
00300 typedef empty_format FT; };
00301
00302 #define DEFINE_UNARY_FORMAT_1(C) \
00303 template<typename T1> struct format<C<T1> >: \
00304 public unary_format_helper<typename format<T1>::FT>::FT \
00305 { \
00306 typedef typename format<T1>::FT FT1; \
00307 typedef typename unary_format_helper<FT1>::FT FT; \
00308 inline format (): FT () {} \
00309 template<typename T> inline format (const T& x): FT (x) {} \
00310 inline format (const no_format& nfm): FT (nfm) {} \
00311 inline format (const FT& x): FT (x) {} \
00312 inline format (const format<T1>& fm1): FT ((FT1) fm1) {} \
00313 inline format (const format<C<T1> >& fm): FT (fm.rfm()) {} \
00314 inline format<C<T1> > tfm () const { return *this; } \
00315 inline C<T1> sample () const { \
00316 return C<T1> (format<T1> (this->format1 ())); } \
00317 }; \
00318 template<typename T1> \
00319 struct coefficient1_type_helper<C<T1> > { \
00320 typedef T1 val; \
00321 };
00322
00323 #define DEFINE_UNARY_FORMAT_2(C) \
00324 template<typename T1, typename X2> struct format<C<T1,X2> >: \
00325 public unary_format_helper<typename format<T1>::FT>::FT \
00326 { \
00327 typedef typename format<T1>::FT FT1; \
00328 typedef typename unary_format_helper<FT1>::FT FT; \
00329 inline format (): FT () {} \
00330 template<typename T> inline format (const T& x): FT (x) {} \
00331 inline format (const no_format& nfm): FT (nfm) {} \
00332 inline format (const FT& x): FT (x) {} \
00333 inline format (const format<T1>& fm1): FT ((FT1) fm1) {} \
00334 inline format (const format<C<T1,X2> >& fm): FT (fm.rfm()) {} \
00335 inline format<C<T1,X2> > tfm () const { return *this; } \
00336 inline C<T1,X2> sample () const { \
00337 return C<T1,X2> (format<T1> (this->format1 ())); } \
00338 }; \
00339 template<typename T1, typename X2> \
00340 struct coefficient1_type_helper<C<T1,X2> > { \
00341 typedef T1 val; \
00342 };
00343
00344 #define DEFINE_UNARY_FORMAT_3(C) \
00345 template<typename T1, typename X2, typename X3> \
00346 struct format<C<T1,X2,X3> >: \
00347 public unary_format_helper<typename format<T1>::FT>::FT \
00348 { \
00349 typedef typename format<T1>::FT FT1; \
00350 typedef typename unary_format_helper<FT1>::FT FT; \
00351 inline format (): FT () {} \
00352 template<typename T> inline format (const T& x): FT (x) {} \
00353 inline format (const no_format& nfm): FT (nfm) {} \
00354 inline format (const FT& x): FT (x) {} \
00355 inline format (const format<T1>& fm1): FT ((FT1) fm1) {} \
00356 inline format (const format<C<T1,X2,X3> >& fm): FT (fm.rfm()) {} \
00357 inline format<C<T1,X2,X3> > tfm () const { return *this; } \
00358 inline C<T1,X2,X3> sample () const { \
00359 return C<T1,X2,X3> (format<T1> (this->format1 ())); } \
00360 }; \
00361 template<typename T1, typename X2, typename X3> \
00362 struct coefficient1_type_helper<C<T1,X2,X3> > { \
00363 typedef T1 val; \
00364 };
00365
00366 #define DEFINE_UNARY_FORMAT_3_bis(C) \
00367 template<typename X1, typename T2, typename X3> \
00368 struct format<C<X1,T2,X3> >: \
00369 public unary_format_helper<typename format<T2>::FT>::FT \
00370 { \
00371 typedef typename format<T2>::FT FT2; \
00372 typedef typename unary_format_helper<FT2>::FT FT; \
00373 inline format (): FT () {} \
00374 template<typename T> inline format (const T& x): FT (x) {} \
00375 inline format (const no_format& nfm): FT (nfm) {} \
00376 inline format (const FT& x): FT (x) {} \
00377 inline format (const format<T2>& fm1): FT ((FT2) fm1) {} \
00378 inline format (const format<C<X1,T2,X3> >& fm): FT (fm.rfm()) {} \
00379 inline format<C<X1,T2,X3> > tfm () const { return *this; } \
00380 inline C<X1,T2,X3> sample () const { \
00381 return C<X1,T2,X3> (format<T2> (this->format1 ())); } \
00382 }; \
00383 template<typename X1, typename T2, typename X3> \
00384 struct coefficient1_type_helper<C<X1,T2,X3> > { \
00385 typedef T2 val; \
00386 };
00387
00388 template<typename FT1, typename FT2>
00389 struct binary_format {
00390 FT1 fm1;
00391 FT2 fm2;
00392 inline binary_format ():
00393 fm1 (), fm2 () {}
00394 template<typename C> inline binary_format (const C& x):
00395 fm1 ((FT1) CF1(x)), fm2 ((FT2) CF2(x)) {}
00396 template<typename C> inline binary_format (const format<C>& x):
00397 fm1 ((FT1) get_format1 (x)), fm2 ((FT2) get_format2 (x)) {}
00398 inline binary_format (const no_format& nfm):
00399 fm1 (nfm), fm2 (nfm) {}
00400 inline binary_format (const binary_format<FT1,FT2>& fm):
00401 fm1 (fm.fm1), fm2 (fm.fm2) {}
00402 inline binary_format (const FT1& fm1b, const FT2& fm2b):
00403 fm1 (fm1b), fm2 (fm2b) {}
00404 inline binary_format<FT1,FT2> rfm () const { return *this; }
00405 inline FT1 format1 () const { return fm1; }
00406 inline FT2 format2 () const { return fm2; }
00407 };
00408
00409 template<typename FT1, typename FT2> struct binary_format_helper {
00410 typedef binary_format<FT1,FT2> FT; };
00411 STMPL struct binary_format_helper<empty_format,empty_format> {
00412 typedef empty_format FT; };
00413
00414 #define DEFINE_BINARY_FORMAT_2(C) \
00415 template<typename T1, typename T2> struct format<C<T1,T2> >: \
00416 public binary_format_helper<typename format<T1>::FT, \
00417 typename format<T2>::FT>::FT \
00418 { \
00419 typedef typename format<T1 >::FT FT1; \
00420 typedef typename format<T2 >::FT FT2; \
00421 typedef typename binary_format_helper<FT1,FT2>::FT FT; \
00422 inline format (): FT () {} \
00423 template<typename T> inline format (const T& x): FT (x) {} \
00424 inline format (const no_format& nfm): FT (nfm) {} \
00425 inline format (const FT& x): FT (x) {} \
00426 inline format (const format<T1>& fm1, const format<T2>& fm2): \
00427 FT ((FT1) fm1, (FT2) fm2) {} \
00428 inline format (const format<C<T1,T2> >& fm): FT (fm.rfm()) {} \
00429 inline format<C<T1,T2> > tfm () const { return *this; } \
00430 inline C<T1,T2> sample () const { \
00431 return C<T1,T2> (format<T1> (this->format1 ()), \
00432 format<T2> (this->format2 ())); } \
00433 }; \
00434 template<typename T1, typename T2> \
00435 struct coefficient1_type_helper<C<T1,T2> > { \
00436 typedef T1 val; \
00437 }; \
00438 template<typename T1, typename T2> \
00439 struct coefficient2_type_helper<C<T1,T2> > { \
00440 typedef T2 val; \
00441 };
00442
00443 #define DEFINE_BINARY_FORMAT_3(C) \
00444 template<typename T1, typename T2, typename X3> \
00445 struct format<C<T1,T2,X3> >: \
00446 public binary_format_helper<typename format<T1>::FT, \
00447 typename format<T2>::FT>::FT \
00448 { \
00449 typedef typename format<T1 >::FT FT1; \
00450 typedef typename format<T2 >::FT FT2; \
00451 typedef typename binary_format_helper<FT1,FT2>::FT FT; \
00452 inline format (): FT () {} \
00453 template<typename T> inline format (const T& x): FT (x) {} \
00454 inline format (const no_format& nfm): FT (nfm) {} \
00455 inline format (const FT& x): FT (x) {} \
00456 inline format (const format<T1>& fm1, const format<T2>& fm2): \
00457 FT ((FT1) fm1, (FT2) fm2) {} \
00458 inline format (const format<C<T1,T2,X3> >& fm): FT (fm.rfm()) {} \
00459 inline format<C<T1,T2,X3> > tfm () const { return *this; } \
00460 inline C<T1,T2,X3> sample () const { \
00461 return C<T1,T2,X3> (format<T1> (this->format1 ()), \
00462 format<T2> (this->format2 ())); } \
00463 }; \
00464 template<typename T1, typename T2, typename X3> \
00465 struct coefficient1_type_helper<C<T1,T2,X3> > { \
00466 typedef T1 val; \
00467 }; \
00468 template<typename T1, typename T2, typename X3> \
00469 struct coefficient2_type_helper<C<T1,T2,X3> > { \
00470 typedef T2 val; \
00471 };
00472
00473 template<typename FT1, typename FT2, typename FT3>
00474 struct ternary_format {
00475 FT1 fm1;
00476 FT2 fm2;
00477 FT3 fm3;
00478 inline ternary_format ():
00479 fm1 (), fm2 (), fm3 () {}
00480 template<typename C> inline ternary_format (const C& x):
00481 fm1 ((FT1) CF1(x)), fm2 ((FT2) CF2(x)), fm3 ((FT3) CF3(x)) {}
00482 template<typename C> inline ternary_format (const format<C>& x):
00483 fm1 ((FT1) get_format1 (x)), fm2 ((FT2) get_format2 (x)),
00484 fm3 ((FT3) get_format3 (x)) {}
00485 inline ternary_format (const no_format& nfm):
00486 fm1 (nfm), fm2 (nfm), fm3 (nfm) {}
00487 inline ternary_format (const ternary_format<FT1,FT2,FT3>& fm):
00488 fm1 (fm.fm1), fm2 (fm.fm2), fm3 (fm.fm3) {}
00489 inline ternary_format (const FT1& fm1b, const FT2& fm2b, const FT3& fm3b):
00490 fm1 (fm1b), fm2 (fm2b), fm3 (fm3b) {}
00491 inline ternary_format<FT1,FT2,FT3> rfm () const { return *this; }
00492 inline FT1 format1 () const { return fm1; }
00493 inline FT2 format2 () const { return fm2; }
00494 inline FT2 format3 () const { return fm3; }
00495 };
00496
00497 template<typename FT1, typename FT2, typename FT3>
00498 struct ternary_format_helper {
00499 typedef ternary_format<FT1,FT2,FT3> FT; };
00500 STMPL struct ternary_format_helper<empty_format,empty_format,empty_format> {
00501 typedef empty_format FT; };
00502
00503 #define DEFINE_TERNARY_FORMAT_3(C) \
00504 template<typename T1, typename T2, typename T3> \
00505 struct format<C<T1,T2,T3> >: \
00506 public ternary_format_helper<typename format<T1>::FT, \
00507 typename format<T2>::FT, \
00508 typename format<T3>::FT>::FT \
00509 { \
00510 typedef typename format<T1 >::FT FT1; \
00511 typedef typename format<T2 >::FT FT2; \
00512 typedef typename format<T3 >::FT FT3; \
00513 typedef typename ternary_format_helper<FT1,FT2,FT3>::FT FT; \
00514 inline format (): FT () {} \
00515 template<typename T> inline format (const T& x): FT (x) {} \
00516 inline format (const no_format& nfm): FT (nfm) {} \
00517 inline format (const FT& x): FT (x) {} \
00518 inline format (const format<T1>& fm1, \
00519 const format<T1>& fm2, \
00520 const format<T2>& fm3): \
00521 FT ((FT1) fm1, (FT2) fm2, (FT3) fm3) {} \
00522 inline format (const format<C<T1,T2,T3> >& fm): \
00523 FT (fm.rfm()) {} \
00524 inline format<C<T1,T2,T3> > tfm () const { return *this; } \
00525 inline C<T1,T2,T3> sample () const { \
00526 return C<T1,T2,T3> (format<T1> (this->format1 ()), \
00527 format<T2> (this->format2 ()), \
00528 format<T3> (this->format3 ())); } \
00529 }; \
00530 template<typename T1, typename T2, typename T3> \
00531 struct coefficient1_type_helper<C<T1,T2,T3> > { \
00532 typedef T1 val; \
00533 }; \
00534 template<typename T1, typename T2, typename T3> \
00535 struct coefficient2_type_helper<C<T1,T2,T3> > { \
00536 typedef T2 val; \
00537 }; \
00538 template<typename T1, typename T2, typename T3> \
00539 struct coefficient3_type_helper<C<T1,T2,T3> > { \
00540 typedef T3 val; \
00541 };
00542
00543
00544
00545
00546
00547 template<typename FT, typename F, typename T>
00548 struct promote_scalar_helper {
00549 static inline Scalar_type(T) op (const F& x, const T& y) {
00550 return promote (x, CF(y));
00551 }
00552 };
00553
00554 template<typename F, typename T>
00555 struct promote_scalar_helper<empty_format,F,T> {
00556 static inline Scalar_type(T) op (const F& x, const T&) {
00557 return promote (x, Scalar_type(T) ());
00558 }
00559 };
00560
00561 template<typename F, typename T> inline Scalar_type(T)
00562 promote_scalar (const F& x, const T& y) {
00563 return promote_scalar_helper<typename format<T>::FT,F,T>::op (x, y);
00564 }
00565
00566 template<typename T> inline Scalar_type(T)
00567 zero_scalar (const T& y) {
00568 return promote_scalar ((int) 0, y);
00569 }
00570
00571 template<typename FT, typename T>
00572 struct formatted_new_helper {
00573 static inline T* op (nat l, const format<T>& fm) {
00574 return mmx_new<T> (l, get_sample (fm));
00575 }
00576 };
00577
00578 template<typename T>
00579 struct formatted_new_helper<empty_format,T> {
00580 static inline T* op (nat l, const format<T>& fm) {
00581 (void) fm;
00582 return mmx_new<T> (l);
00583 }
00584 };
00585
00586 template<typename T> inline T*
00587 mmx_formatted_new (nat l, const format<T>& fm) {
00588 typedef typename format<T>::FT FT;
00589 return formatted_new_helper<FT,T>::op (l, fm);
00590 }
00591
00592
00593
00594
00595
00596 template<typename Op, typename FT, typename R, typename C>
00597 struct format_unary_map_helper {
00598 static inline format<R> op (const format<C>& fm) {
00599 return get_format (Op::op (get_sample (fm))); }
00600 };
00601
00602 template<typename Op, typename FT, typename C>
00603 struct format_unary_map_helper<Op,FT,C,C> {
00604 static inline format<C> op (const format<C>& fm) {
00605 return fm; }
00606 };
00607
00608 template<typename Op, typename R, typename C>
00609 struct format_unary_map_helper<Op,empty_format,R,C> {
00610 static inline format<R> op (const format<C>&) {
00611 return format<R> (); }
00612 };
00613
00614 template<typename Op, typename C>
00615 struct format_unary_map_helper<Op,empty_format,C,C> {
00616 static inline format<C> op (const format<C>& fm) {
00617 return fm; }
00618 };
00619
00620 template<typename Op, typename C>
00621 format<Unary_return_type(Op,C) >
00622 unary_map (const format<C>& fm) {
00623 typedef Unary_return_type(Op,C) R;
00624 typedef typename format<R>::FT FT;
00625 return format_unary_map_helper<Op,FT,R,C>::op (fm);
00626 }
00627
00628 template<typename Op, typename FT, typename R, typename C1, typename C2>
00629 struct format_binary_map_scalar_helper {
00630 static inline format<R> op (const format<C1>& fm1, const C2& x) {
00631 return get_format (Op::op (get_sample (fm1), x)); }
00632 };
00633
00634 template<typename Op, typename FT, typename C1, typename C2>
00635 struct format_binary_map_scalar_helper<Op,FT,C1,C1,C2> {
00636 static inline format<C1> op (const format<C1>& fm1, const C2&) {
00637 return fm1; }
00638 };
00639
00640 template<typename Op, typename R, typename C1, typename C2>
00641 struct format_binary_map_scalar_helper<Op,empty_format,R,C1,C2> {
00642 static inline format<R> op (const format<C1>&, const C2&) {
00643 return format<R> (); }
00644 };
00645
00646 template<typename Op, typename C1, typename C2>
00647 struct format_binary_map_scalar_helper<Op,empty_format,C1,C1,C2> {
00648 static inline format<C1> op (const format<C1>& fm1, const C2&) {
00649 return fm1; }
00650 };
00651
00652 template<typename Op, typename C1, typename C2>
00653 format<Binary_return_type(Op,C1,C2) >
00654 binary_map_scalar (const format<C1>& fm, const C2& x) {
00655 typedef Binary_return_type(Op,C1,C2) R;
00656 typedef typename format<R>::FT FT;
00657 return format_binary_map_scalar_helper<Op,FT,R,C1,C2>::op (fm, x);
00658 }
00659
00660 template<typename Op, typename FT, typename R, typename C1, typename C2>
00661 struct format_binary_map_helper {
00662 static inline format<R> op (const format<C1>& fm1, const format<C2>& fm2) {
00663 return get_format (Op::op (get_sample (fm1), get_sample (fm2))); }
00664 };
00665
00666 template<typename Op, typename FT, typename C1, typename C2>
00667 struct format_binary_map_helper<Op,FT,C1,C1,C2> {
00668 static inline format<C1> op (const format<C1>& fm1, const format<C2>&) {
00669 return fm1; }
00670 };
00671
00672 template<typename Op, typename R, typename C1, typename C2>
00673 struct format_binary_map_helper<Op,empty_format,R,C1,C2> {
00674 static inline format<R> op (const format<C1>&, const format<C2>&) {
00675 return format<R> (); }
00676 };
00677
00678 template<typename Op, typename C1, typename C2>
00679 struct format_binary_map_helper<Op,empty_format,C1,C1,C2> {
00680 static inline format<C1> op (const format<C1>& fm1, const format<C2>&) {
00681 return fm1; }
00682 };
00683
00684 template<typename Op, typename C1, typename C2>
00685 format<Binary_return_type(Op,C1,C2) >
00686 binary_map (const format<C1>& fm1, const format<C2>& fm2) {
00687 typedef Binary_return_type(Op,C1,C2) R;
00688 typedef typename format<R>::FT FT;
00689 return format_binary_map_helper<Op,FT,R,C1,C2>::op (fm1, fm2);
00690 }
00691
00692
00693
00694
00695
00696 template<typename T,typename F>
00697 struct as_helper {
00698 static inline T cv (const F& x) { return x; }
00699 };
00700
00701 #ifndef WITH_AS
00702 #define WITH_AS
00703 template<typename T,typename F> inline T
00704 as (const F& x) {
00705 return as_helper<T,F>::cv (x);
00706 }
00707 #endif
00708
00709 template<typename T,typename F> inline void
00710 set_as (T& r, const F& x) {
00711 r= as_helper<T,F>::cv (x);
00712 }
00713
00714 template<typename T,typename F> inline T
00715 outplace_set_as (const F& x) {
00716 T r;
00717 set_as (r, x);
00718 return r;
00719 }
00720
00721 template<typename T,typename F> inline T
00722 promote (const F& x, const T& y) {
00723 T r= y;
00724 set_as (r, x);
00725 return r;
00726 }
00727
00728 template<typename T,typename F> inline T
00729 promote (const F& x, const format<T>& fm) {
00730 return promote (x, get_sample (fm));
00731 }
00732
00733 template<typename FT,typename T,typename F>
00734 struct format_as_helper {
00735 static inline format<T> cv (const format<F>& fm) {
00736 return get_format (as<T> (get_sample (fm))); }
00737 };
00738
00739 template<typename FT,typename T>
00740 struct format_as_helper<FT,T,T> {
00741 static inline format<T> cv (const format<T>& fm) {
00742 return fm; }
00743 };
00744
00745 template<typename T,typename F>
00746 struct format_as_helper<empty_format,T,F> {
00747 static inline format<T> cv (const format<F>&) {
00748 return format<T> (); }
00749 };
00750
00751 template<typename T>
00752 struct format_as_helper<empty_format,T,T> {
00753 static inline format<T> cv (const format<T>& fm) {
00754 return fm; }
00755 };
00756
00757 template<typename T,typename F>
00758 struct as_helper<format<T>,format<F> > {
00759 static inline format<T> cv (const format<F>& fm) {
00760 typedef typename format<T>::FT FT;
00761 return format_as_helper<FT,T,F>::cv (fm); }
00762 };
00763
00764 template<typename C>
00765 struct vector_as_helper {
00766 static inline generic abstract (const C& x) {
00767 (void) x; ERROR ("invalid abstraction"); }
00768 static inline C concrete (const generic& x) {
00769 (void) x; ERROR ("invalid concretization"); }
00770 };
00771
00772 template<typename T>
00773 struct fast_helper {
00774 typedef T fast_type;
00775 static inline fast_type dd (const T& x) { return x; }
00776 static inline T uu (const fast_type& x) { return x; }
00777 };
00778
00779 #define Fast_type(T) typename fast_helper<T>::fast_type
00780
00781 template<typename T> Fast_type(T)
00782 fast (const T& x) {
00783 return fast_helper<T>::dd (x);
00784 }
00785
00786 template<typename T> T
00787 slow (const Fast_type(T)& x) {
00788 return fast_helper<T>::uu (x);
00789 }
00790
00791 template<typename T, typename F> T
00792 slow_as (const F& x) {
00793 return fast_helper<T>::uu (x);
00794 }
00795
00796 template<typename T> inline format<Fast_type(T) >
00797 fast (const format<T>& fm) {
00798 return get_format (fast (get_sample (fm)));
00799 }
00800
00801 template<typename T> inline format<T>
00802 slow (const format<Fast_type(T) >& fm) {
00803 return get_format (slow<T> (get_sample (fm)));
00804 }
00805
00806 template<typename T, typename F> inline format<T>
00807 slow_as (const format<F>& fm) {
00808 return get_format (slow_as<T,F> (get_sample (fm)));
00809 }
00810
00811
00812
00813
00814
00815 template<typename C>
00816 struct unary_return_type_helper<lift_op,C> {
00817 typedef C RET;
00818 };
00819
00820 template<typename C>
00821 struct lift_helper {
00822 template<typename R> static inline void
00823 set_op (R& y, const C& x) { set_as (y, x); }
00824 static inline Lift_type(C)
00825 op (const C& x) { return as<Lift_type(C)> (x); }
00826 };
00827
00828 template<typename C> inline Lift_type(C)
00829 lift (const C& x) { return lift_helper<C>::op (x); }
00830
00831 template<typename C,typename R> inline void
00832 set_lift (R& y, const C& x) { lift_helper<C>::set_op (y, x); }
00833
00834 template<typename C> inline format<Lift_type(C) >
00835 lift (const format<C>& fm) { return get_format (lift (get_sample (fm))); }
00836
00837
00838 template<typename C>
00839 struct project_helper {
00840 template<typename R> static inline void
00841 set_op (R& y, const C& x);
00842 static inline Project_type(C)
00843 op (const C& x);
00844 };
00845
00846 template<typename C> inline Project_type(C)
00847 project (const C& x) { return project_helper<C>::op (x); }
00848
00849 template<typename C,typename R> inline void
00850 set_project (R& y, const C& x) { project_helper<C>::set_op (y, x); }
00851
00852 template<typename C> inline format<Project_type(C) >
00853 project (const format<C>& fm) { return get_format (project (get_sample (fm)));}
00854
00855
00856
00857
00858
00859 template<typename T> inline void set_zero (T& x) { set_as (x, (int) 0); }
00860 template<typename T> inline void set_one (T& x) { set_as (x, (int) 1); }
00861 template<typename T> inline void set_true (T& x) { set_as (x, true); }
00862 template<typename T> inline void set_false (T& x) { set_as (x, false); }
00863
00864 template<typename T> inline void set_default (T& x) {
00865 x= get_sample (get_format (x)); }
00866 template<typename T> inline void set_pi (T& x) {
00867 x= promote (4, x) * atan (promote (1, x)); }
00868 template<typename T> inline void set_nan (T& x) {
00869 x= promote (1, x) / promote (0, x); }
00870 template<typename T> inline void set_imaginary (T& x) {
00871 x= times_i (promote (1, x)); }
00872 template<typename T> inline void set_accuracy (T& x) {
00873 x= decexp2 (promote (1, x), precision (x) - 1); }
00874 template<typename T> inline void set_infinity (T& x) {
00875 x= times_infinity (promote (1, x)); }
00876 template<typename T> void set_smallest (T& x) {
00877 x= next_above (promote (0, x)); }
00878 template<typename T> void set_largest (T& x) {
00879 set_infinity (x); x= next_below (x); }
00880 template<typename T> inline void set_maximal (T& x) {
00881 set_infinity (x); }
00882 template<typename T> inline void set_minimal (T& x) {
00883 set_maximal (x); x= -x; }
00884
00885 inline void set_default (bool& x) { x= false; }
00886
00887 template<typename C> inline C
00888 zero_cst () { C r; set_zero (r); return r; }
00889 template<typename C> inline C
00890 one_cst () { C r; set_one (r); return r; }
00891 template<typename C> inline C
00892 default_cst () { C r; set_default (r); return r; }
00893 template<typename C> inline C
00894 pi_cst () { C r; set_pi (r); return r; }
00895 template<typename C> inline C
00896 log2_cst () { C r; set_log2 (r); return r; }
00897 template<typename C> inline C
00898 euler_cst () { C r; set_euler (r); return r; }
00899 template<typename C> inline C
00900 catalan_cst () { C r; set_catalan (r); return r; }
00901 template<typename C> inline C
00902 imaginary_cst () { C r; set_imaginary (r); return r; }
00903 template<typename C> inline C
00904 nan_cst () { C r; set_nan (r); return r; }
00905 template<typename C> inline C
00906 fuzz_cst () { C r; set_fuzz (r); return r; }
00907 template<typename C> inline C
00908 smallest_cst () { C r; set_smallest (r); return r; }
00909 template<typename C> inline C
00910 largest_cst () { C r; set_largest (r); return r; }
00911 template<typename C> inline C
00912 accuracy_cst () { C r; set_accuracy (r); return r; }
00913 template<typename C> inline C
00914 infinity_cst () { C r; set_infinity (r); return r; }
00915 template<typename C> inline C
00916 maximal_cst () { C r; set_maximal (r); return r; }
00917 template<typename C> inline C
00918 minimal_cst () { C r; set_minimal (r); return r; }
00919
00920 template<typename C> inline C
00921 default_cst (const format<C>& fm) {
00922 C r= get_sample (fm); set_default (r); return r; }
00923 template<typename C> inline C
00924 pi_cst (const format<C>& fm) {
00925 C r= promote (0, fm); set_pi (r); return r; }
00926 template<typename C> inline C
00927 log2_cst (const format<C>& fm) {
00928 C r= promote (0, fm); set_log2 (r); return r; }
00929 template<typename C> inline C
00930 euler_cst (const format<C>& fm) {
00931 C r= promote (0, fm); set_euler (r); return r; }
00932 template<typename C> inline C
00933 catalan_cst (const format<C>& fm) {
00934 C r= promote (0, fm); set_catalan (r); return r; }
00935 template<typename C> inline C
00936 imaginary_cst (const format<C>& fm) {
00937 C r= promote (0, fm); set_imaginary (r); return r; }
00938 template<typename C> inline C
00939 nan_cst (const format<C>& fm) {
00940 C r= promote (0, fm); set_nan (r); return r; }
00941 template<typename C> inline C
00942 fuzz_cst (const format<C>& fm) {
00943 C r= promote (0, fm); set_fuzz (r); return r; }
00944 template<typename C> inline C
00945 smallest_cst (const format<C>& fm) {
00946 C r= promote (0, fm); set_smallest (r); return r; }
00947 template<typename C> inline C
00948 largest_cst (const format<C>& fm) {
00949 C r= promote (0, fm); set_largest (r); return r; }
00950 template<typename C> inline C
00951 accuracy_cst (const format<C>& fm) {
00952 C r= promote (0, fm); set_accuracy (r); return r; }
00953 template<typename C> inline C
00954 infinity_cst (const format<C>& fm) {
00955 C r= promote (0, fm); set_infinity (r); return r; }
00956 template<typename C> inline C
00957 maximal_cst (const format<C>& fm) {
00958 C r= promote (0, fm); set_maximal (r); return r; }
00959 template<typename C> inline C
00960 minimal_cst (const format<C>& fm) {
00961 C r= promote (0, fm); set_minimal (r); return r; }
00962
00963 #define Default(C) default_cst<C>()
00964 #define Pi(C) pi_cst<C>()
00965 #define Log2(C) log2_cst<C>()
00966 #define Euler(C) euler_cst<C>()
00967 #define Catalan(C) catalan_cst<C>()
00968 #define Imaginary(C) imaginary_cst<C>()
00969 #define Nan(C) nan_cst<C>()
00970 #define Fuzz(C) fuzz_cst<C>()
00971 #define Smallest(C) smallest_cst<C>()
00972 #define Largest(C) largest_cst<C>()
00973 #define Accuracy(C) accuracy_cst<C>()
00974 #define Infinity(C) infinity_cst<C>()
00975 #define Maximal(C) maximal_cst<C>()
00976 #define Minimal(C) minimal_cst<C>()
00977
00978
00979
00980
00981
00982 template<typename C>
00983 struct inspector {
00984 static inline nat length (const C& c) { (void) c; return 0; }
00985 static inline generic access (const C& c, nat i) {
00986 (void) c; (void) i;
00987 VERIFY (false, "out of range");
00988 return generic (); }
00989 };
00990
00991
00992
00993
00994
00995 template<typename M> void
00996 raw_write (M& m, const char* p, nat n) {
00997 for (nat i=0; i<n; i++) m << p[i];
00998 }
00999
01000 template<typename M> void
01001 raw_read (M& m, const char* p, nat n) {
01002 for (nat i=0; i<n; i++) {
01003 VERIFY (busy (m), "read failed");
01004 m >> p[i];
01005 }
01006 }
01007
01008 template<typename M> void
01009 raw_write_length (M& m, nat l) {
01010 if (l < (nat) 255) m << ((char) l);
01011 else {
01012 m << ((char) 255);
01013 raw_write (m, (const char*) ((const void*) (&l)), sizeof (nat));
01014 }
01015 }
01016
01017 template<typename M> void
01018 raw_read_length (M& m, nat& l) {
01019 char c;
01020 m >> c;
01021 if (c != ((char) 255)) l= (nat) ((uchar) c);
01022 else raw_read (m, (char*) ((void)* (&l)), sizeof (nat));
01023 }
01024
01025
01026
01027
01028
01029 enum mmx_rounding {
01030 MMX_ROUND_NEAR,
01031 MMX_ROUND_ZERO,
01032 MMX_ROUND_UP,
01033 MMX_ROUND_DOWN
01034 };
01035
01036 struct rounded_none_up;
01037 struct rounded_none_down;
01038 template<typename V> struct rounded_operations;
01039
01040 template<typename C>
01041 struct rounding_helper {
01042 typedef int rounding_mode;
01043 template<mmx_rounding Mode, typename K= nat> struct translate {
01044 static const rounding_mode val= -1; };
01045 static inline rounding_mode get_rounding () { return -1; }
01046 static inline void set_rounding (rounding_mode r) { (void) r; }
01047 static const bool exact_type = true;
01048 typedef rounded_operations<rounded_none_up> UV;
01049 typedef rounded_operations<rounded_none_down> DV;
01050 };
01051
01052 template<typename C, mmx_rounding Mode>
01053 struct with_rounding {
01054 typedef rounding_helper<C> H;
01055 typedef typename H::rounding_mode R;
01056 R old;
01057 inline with_rounding () {
01058 old= H::get_rounding ();
01059 H::set_rounding (H::template translate<Mode>::val); }
01060 inline ~with_rounding () {
01061 H::set_rounding (old); }
01062 };
01063
01064 #define Round_up(C) typename rounding_helper<C>::UV
01065 #define Round_down(C) typename rounding_helper<C>::DV
01066
01067 inline double next_above (const double& x);
01068 inline double rounding_error (const double& x);
01069 template<typename C> inline Abs_type(C) rounding_error (const C& x) {
01070 return promote (0, abs (x)); }
01071 template<typename C> inline Abs_type(C) additive_error (const C& x) {
01072 return rounding_error (x); }
01073 template<typename C> inline Abs_type(C) multiplicative_error (const C& x) {
01074 return rounding_error (x); }
01075 template<typename C> inline Abs_type(C) elementary_error (const C& x) {
01076 return rounding_error (x); }
01077
01078
01079
01080
01081
01082 template<typename B,typename C,typename R>
01083 struct make_ball_helper {
01084 static inline B val (const C& c, const R& r) { return c; }
01085 };
01086
01087 template<typename B,typename C,typename R> B
01088 make_ball (const C& c, const R& r) {
01089 return make_ball_helper<B,C,R>::val (c, r);
01090 }
01091
01092 template<typename C> inline C center (const C& x) { return x; }
01093 template<typename C> inline Abs_type(C) radius (const C& x) { return 0; }
01094
01095 template<typename C> inline Abs_type(C)
01096 abs_down (const C& x) { return abs (x); }
01097 template<typename C> inline Abs_type(C)
01098 abs_up (const C& x) { return abs (x); }
01099 template<typename C> inline Abs_type(C)
01100 bnd_down (const C& x) { return as<Abs_type(C) > (x); }
01101 template<typename C> inline Abs_type(C)
01102 bnd_up (const C& x) { return as<Abs_type(C) > (x); }
01103
01104 template<typename B,typename C>
01105 struct make_interval_helper {
01106 static inline B val (const C& l, const C& r) { return decexp2 (l+r, 1); }
01107 };
01108
01109 template<typename B,typename C> B
01110 make_interval (const C& l, const C& r) {
01111 return make_interval_helper<B,C>::val (l, r);
01112 }
01113
01114 template<typename C> inline C lower (const C& x) { return x; }
01115 template<typename C> inline C upper (const C& x) { return x; }
01116
01117
01118
01119
01120
01121 template<typename C> struct projective_helper {
01122 static const bool val= false; };
01123
01124 #define Projective(C) projective_helper<C>::val
01125
01126 }
01127 #endif // __MMX_TYPE_PROPS_HPP