00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef PPL_checked_defs_hh
00024 #define PPL_checked_defs_hh 1
00025
00026 #include <iostream>
00027 #include <gmpxx.h>
00028 #include "Rounding_Dir.defs.hh"
00029 #include "Numeric_Format.defs.hh"
00030
00031 namespace Parma_Polyhedra_Library {
00032
00033 namespace Checked {
00034
00035 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00037
00038 #endif // PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00039 struct Check_Overflow_Policy {
00040 static const int check_overflow = 1;
00041 static const int check_inf_add_inf = 0;
00042 static const int check_inf_sub_inf = 0;
00043 static const int check_inf_mul_zero = 0;
00044 static const int check_div_zero = 0;
00045 static const int check_inf_div_inf = 0;
00046 static const int check_inf_mod = 0;
00047 static const int check_sqrt_neg = 0;
00048 static const int handle_nan = 0;
00049 static const int handle_infinity = 0;
00050 static const int convertible = 1;
00051 static const int fpu_check_inexact = 0;
00052 static const int check_nan_args = 1;
00053 };
00054
00055
00056
00057
00058
00059
00060 #define FUNCTION_CLASS(name) name ## _function_struct
00061
00062 #define DECLARE_FUN1_0_0(name, ret_type, qual, type) \
00063 template <typename Policy, typename type> \
00064 struct FUNCTION_CLASS(name); \
00065 template <typename Policy, typename type> \
00066 inline ret_type name(qual type& arg) { \
00067 return FUNCTION_CLASS(name)<Policy, type>::function(arg); \
00068 }
00069
00070 #define DECLARE_FUN1_0_1(name, ret_type, qual, type, after1) \
00071 template <typename Policy, typename type> \
00072 struct FUNCTION_CLASS(name); \
00073 template <typename Policy, typename type> \
00074 inline ret_type name(qual type& arg, after1 a1) { \
00075 return FUNCTION_CLASS(name)<Policy, type>::function(arg, a1); \
00076 }
00077
00078 #define DECLARE_FUN1_0_2(name, ret_type, qual, type, after1, after2) \
00079 template <typename Policy, typename type> \
00080 struct FUNCTION_CLASS(name); \
00081 template <typename Policy, typename type> \
00082 inline ret_type name(qual type& arg, after1 a1, after2 a2) { \
00083 return FUNCTION_CLASS(name)<Policy, type>::function(arg, a1, a2); \
00084 }
00085
00086 #define DECLARE_FUN1_0_3(name, ret_type, qual, type, after1, after2, after3) \
00087 template <typename Policy, typename type> \
00088 struct FUNCTION_CLASS(name); \
00089 template <typename Policy, typename type> \
00090 inline ret_type name(qual type& arg, after1 a1, after2 a2, after3 a3) { \
00091 return FUNCTION_CLASS(name)<Policy, type>::function(arg, a1, a2, a3); \
00092 }
00093
00094 #define DECLARE_FUN1_1_1(name, ret_type, before1, qual, type, after1) \
00095 template <typename Policy, typename type> \
00096 struct FUNCTION_CLASS(name); \
00097 template <typename Policy, typename type> \
00098 inline ret_type name(before1 b1, qual type& arg, after1 a1) { \
00099 return FUNCTION_CLASS(name)<Policy, type>::function(b1, arg, a1); \
00100 }
00101
00102 #define DECLARE_FUN1_1_2(name, ret_type, before1, qual, type, after1, after2) \
00103 template <typename Policy, typename type> \
00104 struct FUNCTION_CLASS(name); \
00105 template <typename Policy, typename type> \
00106 inline ret_type name(before1 b1, qual type& arg, after1 a1, after2 a2) { \
00107 return FUNCTION_CLASS(name)<Policy, type>::function(b1, arg, a1, a2); \
00108 }
00109
00110 #define DECLARE_FUN1_2_2(name, ret_type, before1, before2, qual, type, after1, after2) \
00111 template <typename Policy, typename type> \
00112 struct FUNCTION_CLASS(name); \
00113 template <typename Policy, typename type> \
00114 inline ret_type name(before1 b1, before2 b2, qual type& arg, after1 a1, after2 a2) { \
00115 return FUNCTION_CLASS(name)<Policy, type>::function(b1, b2, arg, a1, a2); \
00116 }
00117
00118 #define DECLARE_FUN2_0_0(name, ret_type, qual1, type1, qual2, type2) \
00119 template <typename Policy, typename type1, typename type2> \
00120 struct FUNCTION_CLASS(name); \
00121 template <typename Policy, typename type1, typename type2> \
00122 inline ret_type name(qual1 type1& arg1, qual2 type2& arg2) { \
00123 return FUNCTION_CLASS(name)<Policy, type1, type2>::function(arg1, arg2); \
00124 }
00125
00126 #define DECLARE_FUN2_0_1(name, ret_type, qual1, type1, qual2, type2, after1) \
00127 template <typename Policy, typename type1, typename type2> \
00128 struct FUNCTION_CLASS(name); \
00129 template <typename Policy, typename type1, typename type2> \
00130 inline ret_type name(qual1 type1& arg1, qual2 type2& arg2, after1 a1) { \
00131 return FUNCTION_CLASS(name)<Policy, type1, type2>::function(arg1, arg2, a1); \
00132 }
00133
00134 #define DECLARE_FUN2_0_2(name, ret_type, qual1, type1, qual2, type2, after1, after2) \
00135 template <typename Policy, typename type1, typename type2> \
00136 struct FUNCTION_CLASS(name); \
00137 template <typename Policy, typename type1, typename type2> \
00138 inline ret_type name(qual1 type1& arg1, qual2 type2& arg2, after1 a1, after2 a2) { \
00139 return FUNCTION_CLASS(name)<Policy, type1, type2>::function(arg1, arg2, a1, a2); \
00140 }
00141
00142 #define DECLARE_FUN3_0_1(name, ret_type, qual1, type1, qual2, type2, qual3, type3, after1) \
00143 template <typename Policy, typename type1, typename type2, typename type3> \
00144 struct FUNCTION_CLASS(name); \
00145 template <typename Policy, typename type1, typename type2, typename type3> \
00146 inline ret_type name(qual1 type1& arg1, qual2 type2& arg2, qual3 type3& arg3, after1 a1) { \
00147 return FUNCTION_CLASS(name)<Policy, type1, type2, type3>::function(arg1, arg2, arg3, a1); \
00148 }
00149
00150 #define DECLARE_FUN5_0_1(name, ret_type, \
00151 qual1, type1, qual2, type2, qual3, type3, \
00152 qual4, type4, qual5, type5, \
00153 after1) \
00154 template <typename Policy, \
00155 typename type1, typename type2, typename type3, \
00156 typename type4, typename type5> \
00157 struct FUNCTION_CLASS(name); \
00158 template <typename Policy, \
00159 typename type1, typename type2, typename type3, \
00160 typename type4, typename type5> \
00161 inline ret_type name(qual1 type1& arg1, qual2 type2& arg2, \
00162 qual3 type3& arg3, qual4 type4& arg4, \
00163 qual5 type5& arg5, after1 a1) { \
00164 return FUNCTION_CLASS(name)<Policy, type1, type2, type3, type4, type5> \
00165 ::function(arg1, arg2, arg3, arg4, arg5, a1); \
00166 }
00167
00168 #define SPECIALIZE_FUN1_0_0(name, suf, ret_type, qual, type) \
00169 template <typename Policy> \
00170 struct FUNCTION_CLASS(name)<Policy, type> { \
00171 static inline ret_type function(qual type& arg) { \
00172 return name ## _ ## suf<Policy>(arg); \
00173 } \
00174 };
00175
00176 #define SPECIALIZE_FUN1_0_1(name, suf, ret_type, qual, type, after1) \
00177 template <typename Policy> \
00178 struct FUNCTION_CLASS(name)<Policy, type> { \
00179 static inline ret_type function(qual type& arg, after1 a1) { \
00180 return name ## _ ## suf<Policy>(arg, a1); \
00181 } \
00182 };
00183
00184 #define SPECIALIZE_FUN1_0_2(name, suf, ret_type, qual, type, after1, after2) \
00185 template <typename Policy> \
00186 struct FUNCTION_CLASS(name)<Policy, type> { \
00187 static inline ret_type function(qual type& arg, after1 a1, after2 a2) { \
00188 return name ## _ ## suf<Policy>(arg, a1, a2); \
00189 } \
00190 };
00191
00192 #define SPECIALIZE_FUN1_0_3(name, suf, ret_type, qual, type, after1, after2, after3) \
00193 template <typename Policy> \
00194 struct FUNCTION_CLASS(name)<Policy, type> { \
00195 static inline ret_type function(qual type& arg, after1 a1, after2 a2, after3 a3) { \
00196 return name ## _ ## suf<Policy>(arg, a1, a2, a3); \
00197 } \
00198 };
00199
00200 #define SPECIALIZE_FUN1_1_1(name, suf, ret_type, before1, qual, type, after1) \
00201 template <typename Policy> \
00202 struct FUNCTION_CLASS(name)<Policy, type> { \
00203 static inline ret_type function(before1 b1, qual type& arg, after1 a1) { \
00204 return name ## _ ## suf<Policy>(b1, arg, a1); \
00205 } \
00206 };
00207
00208 #define SPECIALIZE_FUN1_1_2(name, suf, ret_type, before1, qual, type, after1, after2) \
00209 template <typename Policy> \
00210 struct FUNCTION_CLASS(name)<Policy, type> { \
00211 static inline ret_type function(before1 b1, qual type& arg, after1 a1, after2 a2) { \
00212 return name ## _ ## suf<Policy>(b1, arg, a1, a2); \
00213 } \
00214 };
00215
00216 #define SPECIALIZE_FUN1_2_2(name, suf, ret_type, before1, before2, qual, type, after1, after2) \
00217 template <typename Policy> \
00218 struct FUNCTION_CLASS(name)<Policy, type> { \
00219 static inline ret_type function(before1 b1, before2 b2, qual type& arg, after1 a1, after2 a2) { \
00220 return name ## _ ## suf<Policy>(b1, b2, arg, a1, a2); \
00221 } \
00222 };
00223
00224 #define SPECIALIZE_FUN2_0_0(name, suf, ret_type, qual1, type1, qual2, type2) \
00225 template <typename Policy> \
00226 struct FUNCTION_CLASS(name)<Policy, type1, type2> { \
00227 static inline ret_type function(qual1 type1& arg1, qual2 type2 &arg2) { \
00228 return name ## _ ## suf<Policy>(arg1, arg2); \
00229 } \
00230 };
00231
00232 #define SPECIALIZE_FUN2_0_1(name, suf, ret_type, qual1, type1, qual2, type2, after1) \
00233 template <typename Policy> \
00234 struct FUNCTION_CLASS(name)<Policy, type1, type2> { \
00235 static inline ret_type function(qual1 type1& arg1, qual2 type2 &arg2, after1 a1) { \
00236 return name ## _ ## suf<Policy>(arg1, arg2, a1); \
00237 } \
00238 };
00239
00240 #define SPECIALIZE_FUN2_0_2(name, suf, ret_type, qual1, type1, qual2, type2, after1, after2) \
00241 template <typename Policy> \
00242 struct FUNCTION_CLASS(name)<Policy, type1, type2> { \
00243 static inline ret_type function(qual1 type1& arg1, qual2 type2 &arg2, after1 a1, after2 a2) { \
00244 return name ## _ ## suf<Policy>(arg1, arg2, a1, a2); \
00245 } \
00246 };
00247
00248 #define SPECIALIZE_FUN3_0_1(name, suf, ret_type, qual1, type1, qual2, type2, qual3, type3, after1) \
00249 template <typename Policy> \
00250 struct FUNCTION_CLASS(name) <Policy, type1, type2, type3> { \
00251 static inline Result function(qual1 type1& arg1, qual2 type2 &arg2, qual3 type3 &arg3, after1 a1) { \
00252 return name ## _ ## suf<Policy>(arg1, arg2, arg3, a1); \
00253 } \
00254 };
00255
00256 #define SPECIALIZE_FUN5_0_1(name, suf, ret_type, \
00257 qual1, type1, qual2, type2, qual3, type3, \
00258 qual4, type4, qual5, type5, after1) \
00259 template <typename Policy> \
00260 struct FUNCTION_CLASS(name) <Policy, \
00261 type1, type2, type3, type4, type5> { \
00262 static inline Result \
00263 function(qual1 type1& arg1, qual2 type2 &arg2, qual3 type3 &arg3, \
00264 qual4 type4 &arg4, qual5 type5 &arg5, after1 a1) { \
00265 return name ## _ ## suf<Policy>(arg1, arg2, arg3, arg4, arg5, a1); \
00266 } \
00267 };
00268
00269 #define nonconst
00270
00271 #define SPECIALIZE_COPY(suf, Type) \
00272 SPECIALIZE_FUN2_0_0(copy, suf, void, nonconst, Type, const, Type)
00273 #define SPECIALIZE_SGN(suf, From) \
00274 SPECIALIZE_FUN1_0_0(sgn, suf, Result, const, From)
00275 #define SPECIALIZE_CMP(suf, Type1, Type2) \
00276 SPECIALIZE_FUN2_0_0(cmp, suf, Result, const, Type1, const, Type2)
00277 #define SPECIALIZE_SET_SPECIAL(suf, Type) \
00278 SPECIALIZE_FUN1_0_1(set_special, suf, Result, nonconst, Type, Result)
00279 #define SPECIALIZE_CLASSIFY(suf, Type) \
00280 SPECIALIZE_FUN1_0_3(classify, suf, Result, const, Type, bool, bool, bool)
00281 #define SPECIALIZE_IS_NAN(suf, Type) \
00282 SPECIALIZE_FUN1_0_0(is_nan, suf, bool, const, Type)
00283 #define SPECIALIZE_IS_MINF(suf, Type) \
00284 SPECIALIZE_FUN1_0_0(is_minf, suf, bool, const, Type)
00285 #define SPECIALIZE_IS_PINF(suf, Type) \
00286 SPECIALIZE_FUN1_0_0(is_pinf, suf, bool, const, Type)
00287 #define SPECIALIZE_IS_INT(suf, Type) \
00288 SPECIALIZE_FUN1_0_0(is_int, suf, bool, const, Type)
00289 #define SPECIALIZE_CONSTRUCT(suf, To, From) \
00290 SPECIALIZE_FUN2_0_1(construct, suf, Result, nonconst, To, const, From, Rounding_Dir)
00291 #define SPECIALIZE_ASSIGN(suf, To, From) \
00292 SPECIALIZE_FUN2_0_1(assign, suf, Result, nonconst, To, const, From, Rounding_Dir)
00293 #define SPECIALIZE_NEG(suf, To, From) \
00294 SPECIALIZE_FUN2_0_1(neg, suf, Result, nonconst, To, const, From, Rounding_Dir)
00295 #define SPECIALIZE_ABS(suf, To, From) \
00296 SPECIALIZE_FUN2_0_1(abs, suf, Result, nonconst, To, const, From, Rounding_Dir)
00297 #define SPECIALIZE_SQRT(suf, To, From) \
00298 SPECIALIZE_FUN2_0_1(sqrt, suf, Result, nonconst, To, const, From, Rounding_Dir)
00299 #define SPECIALIZE_ADD(suf, To, From1, From2) \
00300 SPECIALIZE_FUN3_0_1(add, suf, Result, nonconst, To, const, From1, const, From2, Rounding_Dir)
00301 #define SPECIALIZE_SUB(suf, To, From1, From2) \
00302 SPECIALIZE_FUN3_0_1(sub, suf, Result, nonconst, To, const, From1, const, From2, Rounding_Dir)
00303 #define SPECIALIZE_MUL(suf, To, From1, From2) \
00304 SPECIALIZE_FUN3_0_1(mul, suf, Result, nonconst, To, const, From1, const, From2, Rounding_Dir)
00305 #define SPECIALIZE_DIV(suf, To, From1, From2) \
00306 SPECIALIZE_FUN3_0_1(div, suf, Result, nonconst, To, const, From1, const, From2, Rounding_Dir)
00307 #define SPECIALIZE_REM(suf, To, From1, From2) \
00308 SPECIALIZE_FUN3_0_1(rem, suf, Result, nonconst, To, const, From1, const, From2, Rounding_Dir)
00309 #define SPECIALIZE_MUL2EXP(suf, To, From) \
00310 SPECIALIZE_FUN2_0_2(mul2exp, suf, Result, nonconst, To, const, From, int, Rounding_Dir)
00311 #define SPECIALIZE_DIV2EXP(suf, To, From) \
00312 SPECIALIZE_FUN2_0_2(div2exp, suf, Result, nonconst, To, const, From, int, Rounding_Dir)
00313 #define SPECIALIZE_ADD_MUL(suf, To, From1, From2) \
00314 SPECIALIZE_FUN3_0_1(add_mul, suf, Result, nonconst, To, const, From1, const, From2, Rounding_Dir)
00315 #define SPECIALIZE_SUB_MUL(suf, To, From1, From2) \
00316 SPECIALIZE_FUN3_0_1(sub_mul, suf, Result, nonconst, To, const, From1, const, From2, Rounding_Dir)
00317 #define SPECIALIZE_GCD(suf, To, From1, From2) \
00318 SPECIALIZE_FUN3_0_1(gcd, suf, Result, nonconst, To, const, From1, const, From2, Rounding_Dir)
00319 #define SPECIALIZE_GCDEXT(suf, To1, From1, From2, To2, To3) \
00320 SPECIALIZE_FUN5_0_1(gcdext, suf, Result, nonconst, To1, \
00321 const, From1, const, From2, nonconst, To2, nonconst, To3, Rounding_Dir)
00322 #define SPECIALIZE_LCM(suf, To, From1, From2) \
00323 SPECIALIZE_FUN3_0_1(lcm, suf, Result, nonconst, To, const, From1, const, From2, Rounding_Dir)
00324 #define SPECIALIZE_INPUT(suf, Type) \
00325 SPECIALIZE_FUN1_0_2(input, suf, Result, nonconst, Type, std::istream&, Rounding_Dir)
00326 #define SPECIALIZE_OUTPUT(suf, Type) \
00327 SPECIALIZE_FUN1_1_2(output, suf, Result, std::ostream&, const, Type, const Numeric_Format&, Rounding_Dir)
00328
00329
00330 DECLARE_FUN2_0_0(copy, void, nonconst, Type1, const, Type2)
00331 DECLARE_FUN1_0_0(sgn, Result, const, From)
00332 DECLARE_FUN2_0_0(cmp, Result, const, Type1, const, Type2)
00333 DECLARE_FUN1_0_1(set_special, Result, nonconst, Type, Result)
00334 DECLARE_FUN1_0_3(classify, Result, const, Type, bool, bool, bool)
00335 DECLARE_FUN1_0_0(is_nan, bool, const, Type)
00336 DECLARE_FUN1_0_0(is_minf, bool, const, Type)
00337 DECLARE_FUN1_0_0(is_pinf, bool, const, Type)
00338 DECLARE_FUN1_0_0(is_int, bool, const, Type)
00339 DECLARE_FUN2_0_1(construct, Result, nonconst, To, const, From, Rounding_Dir)
00340 DECLARE_FUN2_0_1(assign, Result, nonconst, To, const, From, Rounding_Dir)
00341 DECLARE_FUN2_0_1(neg, Result, nonconst, To, const, From, Rounding_Dir)
00342 DECLARE_FUN2_0_1(abs, Result, nonconst, To, const, From, Rounding_Dir)
00343 DECLARE_FUN2_0_1(sqrt, Result, nonconst, To, const, From, Rounding_Dir)
00344 DECLARE_FUN3_0_1(add, Result, nonconst, To, const, From1, const, From2, Rounding_Dir)
00345 DECLARE_FUN3_0_1(sub, Result, nonconst, To, const, From1, const, From2, Rounding_Dir)
00346 DECLARE_FUN3_0_1(mul, Result, nonconst, To, const, From1, const, From2, Rounding_Dir)
00347 DECLARE_FUN3_0_1(div, Result, nonconst, To, const, From1, const, From2, Rounding_Dir)
00348 DECLARE_FUN3_0_1(rem, Result, nonconst, To, const, From1, const, From2, Rounding_Dir)
00349 DECLARE_FUN2_0_2(mul2exp, Result, nonconst, To, const, From, int, Rounding_Dir)
00350 DECLARE_FUN2_0_2(div2exp, Result, nonconst, To, const, From, int, Rounding_Dir)
00351 DECLARE_FUN3_0_1(add_mul, Result, nonconst, To, const, From1, const, From2, Rounding_Dir)
00352 DECLARE_FUN3_0_1(sub_mul, Result, nonconst, To, const, From1, const, From2, Rounding_Dir)
00353 DECLARE_FUN3_0_1(gcd, Result, nonconst, To, const, From1, const, From2, Rounding_Dir)
00354 DECLARE_FUN5_0_1(gcdext, Result, nonconst, To1, const, From1, const, From2,
00355 nonconst, To2, nonconst, To3, Rounding_Dir)
00356 DECLARE_FUN3_0_1(lcm, Result, nonconst, To, const, From1, const, From2, Rounding_Dir)
00357 DECLARE_FUN1_0_2(input, Result, nonconst, Type, std::istream&, Rounding_Dir)
00358 DECLARE_FUN1_1_2(output, Result, std::ostream&, const, Type, const Numeric_Format&, Rounding_Dir)
00359
00360 template <typename Policy, typename To>
00361 Result round(To& to, Result r, Rounding_Dir dir);
00362
00363 Result input_mpq(mpq_class& to, std::istream& is);
00364
00365 }
00366
00367 struct Minus_Infinity {
00368 };
00369
00370 struct Plus_Infinity {
00371 };
00372
00373 struct Not_A_Number {
00374 };
00375
00376 extern Minus_Infinity MINUS_INFINITY;
00377 extern Plus_Infinity PLUS_INFINITY;
00378 extern Not_A_Number NOT_A_NUMBER;
00379
00380 }
00381
00382
00383 #define CHECK_P(cond, check) ((cond) ? (check) : (assert(!(check)), false))
00384
00385 #include "checked.inlines.hh"
00386 #include "checked_int.inlines.hh"
00387 #include "checked_float.inlines.hh"
00388 #include "checked_mpz.inlines.hh"
00389 #include "checked_mpq.inlines.hh"
00390 #include "checked_ext.inlines.hh"
00391
00392 #endif // !defined(PPL_checked_defs_hh)