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_Number_inlines_hh
00024 #define PPL_Checked_Number_inlines_hh 1
00025
00026 #include <stdexcept>
00027 #include <sstream>
00028
00029 namespace Parma_Polyhedra_Library {
00030
00031 inline Rounding_Dir
00032 rounding_dir(Rounding_Dir dir) {
00033 if (dir == ROUND_NOT_NEEDED) {
00034 #ifdef DEBUG_ROUND_NOT_NEEDED
00035 return ROUND_DIRECT;
00036 #else
00037 return ROUND_IGNORE;
00038 #endif
00039 }
00040 return dir;
00041 }
00042
00043 inline Result
00044 check_result(Result r, Rounding_Dir dir) {
00045 if (dir == ROUND_NOT_NEEDED && !is_special(r)) {
00046 #ifdef DEBUG_ROUND_NOT_NEEDED
00047
00048
00049 assert(r == V_EQ);
00050 #else
00051 return V_EQ;
00052 #endif
00053 }
00054 return r;
00055 }
00056
00057
00058 inline void
00059 Checked_Number_Transparent_Policy::handle_result(Result) {
00060 }
00061
00062 inline void
00063 Checked_Number_Default_Policy::handle_result(Result r) {
00064 if (is_special(r))
00065 throw_result_exception(r);
00066 }
00067
00068 inline void
00069 Extended_Number_Policy::handle_result(Result r) {
00070 if (is_special(r))
00071 throw_result_exception(r);
00072 }
00073
00074 template <typename T, typename Policy>
00075 inline
00076 Checked_Number<T, Policy>::Checked_Number()
00077 : v(0) {
00078 }
00079
00080 template <typename T, typename Policy>
00081 inline
00082 Checked_Number<T, Policy>::Checked_Number(const Checked_Number& y) {
00083
00084 Checked::copy<Policy>(v, y.raw_value());
00085 }
00086
00087 template <typename T, typename Policy>
00088 template <typename From, typename From_Policy>
00089 inline
00090 Checked_Number<T, Policy>
00091 ::Checked_Number(const Checked_Number<From, From_Policy>& y, Rounding_Dir dir) {
00092
00093 Policy::handle_result(check_result(Checked::assign_ext<Policy, From_Policy>
00094 (v,
00095 y.raw_value(),
00096 rounding_dir(dir)),
00097 dir));
00098 }
00099
00100 template <typename T, typename Policy>
00101 template <typename From, typename From_Policy>
00102 inline
00103 Checked_Number<T, Policy>
00104 ::Checked_Number(const Checked_Number<From, From_Policy>& y) {
00105
00106 Rounding_Dir dir = Policy::ROUND_DEFAULT_CONSTRUCTOR;
00107 Policy::handle_result(check_result(Checked::assign_ext<Policy, From_Policy>
00108 (v,
00109 y.raw_value(),
00110 rounding_dir(dir)),
00111 dir));
00112 }
00113
00114
00115 #define DEF_CTOR(type) \
00116 template <typename T, typename Policy> \
00117 inline \
00118 Checked_Number<T, Policy>::Checked_Number(const type x, Rounding_Dir dir) { \
00119 Policy::handle_result(check_result(Checked::assign_ext<Policy, Default_From_Policy>(v, x, rounding_dir(dir)), dir)); \
00120 } \
00121 template <typename T, typename Policy> \
00122 inline \
00123 Checked_Number<T, Policy>::Checked_Number(const type x) { \
00124 Rounding_Dir dir = Policy::ROUND_DEFAULT_CONSTRUCTOR; \
00125 Policy::handle_result(check_result(Checked::assign_ext<Policy, Default_From_Policy>(v, x, rounding_dir(dir)), dir)); \
00126 }
00127
00128 #define COND_0(...)
00129 #define COND_1(...) __VA_ARGS__
00130 #define COND_(if, ...) COND_##if(__VA_ARGS__)
00131 #define COND(if, ...) COND_(if, __VA_ARGS__)
00132
00133 DEF_CTOR(signed char)
00134 DEF_CTOR(signed short)
00135 DEF_CTOR(signed int)
00136 DEF_CTOR(signed long)
00137 DEF_CTOR(signed long long)
00138 DEF_CTOR(unsigned char)
00139 DEF_CTOR(unsigned short)
00140 DEF_CTOR(unsigned int)
00141 DEF_CTOR(unsigned long)
00142 DEF_CTOR(unsigned long long)
00143 COND(PPL_SUPPORTED_FLOAT, DEF_CTOR(float))
00144 COND(PPL_SUPPORTED_DOUBLE, DEF_CTOR(double))
00145 COND(PPL_SUPPORTED_LONG_DOUBLE, DEF_CTOR(long double))
00146 DEF_CTOR(mpq_class&)
00147 DEF_CTOR(mpz_class&)
00148
00149 #undef DEF_CTOR
00150
00151 template <typename T, typename Policy>
00152 inline
00153 Checked_Number<T, Policy>::Checked_Number(const char* x, Rounding_Dir dir) {
00154 std::istringstream s(x);
00155 Policy::handle_result(check_result(Checked::input<Policy>(v,
00156 s,
00157 rounding_dir(dir)),
00158 dir));
00159 }
00160
00161 template <typename T, typename Policy>
00162 inline
00163 Checked_Number<T, Policy>::Checked_Number(const char* x) {
00164 std::istringstream s(x);
00165 Rounding_Dir dir = Policy::ROUND_DEFAULT_CONSTRUCTOR;
00166 Policy::handle_result(check_result(Checked::input<Policy>(v,
00167 s,
00168 rounding_dir(dir)),
00169 dir));
00170 }
00171
00172 template <typename T, typename Policy>
00173 inline
00174 Checked_Number<T, Policy>::Checked_Number(const Not_A_Number& x,
00175 Rounding_Dir dir) {
00176
00177 Policy::handle_result(check_result(Checked::assign<Policy>(v,
00178 x,
00179 rounding_dir(dir)),
00180 dir));
00181 }
00182
00183 template <typename T, typename Policy>
00184 inline
00185 Checked_Number<T, Policy>::Checked_Number(const Not_A_Number& x) {
00186
00187 Rounding_Dir dir = ROUND_IGNORE;
00188 Policy::handle_result(check_result(Checked::assign<Policy>(v,
00189 x,
00190 rounding_dir(dir)),
00191 dir));
00192 }
00193
00194 template <typename T, typename Policy>
00195 inline
00196 Checked_Number<T, Policy>::Checked_Number(const Minus_Infinity& x,
00197 Rounding_Dir dir) {
00198
00199 Policy::handle_result(check_result(Checked::assign<Policy>(v,
00200 x,
00201 rounding_dir(dir)),
00202 dir));
00203 }
00204
00205 template <typename T, typename Policy>
00206 inline
00207 Checked_Number<T, Policy>::Checked_Number(const Minus_Infinity& x) {
00208
00209 Rounding_Dir dir = Policy::ROUND_DEFAULT_CONSTRUCTOR_INF;
00210 Policy::handle_result(check_result(Checked::assign<Policy>(v,
00211 x,
00212 rounding_dir(dir)),
00213 dir));
00214 }
00215
00216 template <typename T, typename Policy>
00217 inline
00218 Checked_Number<T, Policy>::Checked_Number(const Plus_Infinity& x,
00219 Rounding_Dir dir) {
00220
00221 Policy::handle_result(check_result(Checked::assign<Policy>(v,
00222 x,
00223 rounding_dir(dir)),
00224 dir));
00225 }
00226
00227 template <typename T, typename Policy>
00228 inline
00229 Checked_Number<T, Policy>::Checked_Number(const Plus_Infinity& x) {
00230
00231 Rounding_Dir dir = Policy::ROUND_DEFAULT_CONSTRUCTOR_INF;
00232 Policy::handle_result(check_result(Checked::assign<Policy>(v,
00233 x,
00234 rounding_dir(dir)),
00235 dir));
00236 }
00237
00238 template <typename T>
00239 inline bool
00240 is_minus_infinity(const T& x) {
00241 return Checked::is_minf<typename Native_Checked_From_Wrapper<T>::Policy>(Native_Checked_From_Wrapper<T>::raw_value(x));
00242 }
00243
00244 template <typename T>
00245 inline bool
00246 is_plus_infinity(const T& x) {
00247 return Checked::is_pinf<typename Native_Checked_From_Wrapper<T>::Policy>(Native_Checked_From_Wrapper<T>::raw_value(x));
00248 }
00249
00250 template <typename T>
00251 inline bool
00252 is_not_a_number(const T& x) {
00253 return Checked::is_nan<typename Native_Checked_From_Wrapper<T>::Policy>(Native_Checked_From_Wrapper<T>::raw_value(x));
00254 }
00255
00256 template <typename T>
00257 inline bool
00258 is_integer(const T& x) {
00259 return Checked::is_int<typename Native_Checked_From_Wrapper<T>::Policy>(Native_Checked_From_Wrapper<T>::raw_value(x));
00260 }
00261
00262 template <typename T, typename Policy>
00263 inline
00264 Checked_Number<T, Policy>::operator T() const {
00265 if (Policy::convertible)
00266 return v;
00267 }
00268
00269 template <typename T, typename Policy>
00270 inline T&
00271 Checked_Number<T, Policy>::raw_value() {
00272 return v;
00273 }
00274
00275 template <typename T, typename Policy>
00276 inline const T&
00277 Checked_Number<T, Policy>::raw_value() const {
00278 return v;
00279 }
00280
00282 template <typename T, typename Policy>
00283 inline const T&
00284 raw_value(const Checked_Number<T, Policy>& x) {
00285 return x.raw_value();
00286 }
00287
00289 template <typename T, typename Policy>
00290 inline T&
00291 raw_value(Checked_Number<T, Policy>& x) {
00292 return x.raw_value();
00293 }
00294
00295 template <typename T, typename Policy>
00296 inline bool
00297 Checked_Number<T, Policy>::OK() const {
00298 return true;
00299 }
00300
00301 template <typename T, typename Policy>
00302 inline Result
00303 Checked_Number<T, Policy>::classify(bool nan, bool inf, bool sign) const {
00304 return Checked::classify<Policy>(v, nan, inf, sign);
00305 }
00306
00307 template <typename T, typename Policy>
00308 inline bool
00309 is_not_a_number(const Checked_Number<T, Policy>& x) {
00310 return Checked::is_nan<Policy>(x.raw_value());
00311 }
00312
00313 template <typename T, typename Policy>
00314 inline bool
00315 is_minus_infinity(const Checked_Number<T, Policy>& x) {
00316 return Checked::is_minf<Policy>(x.raw_value());
00317 }
00318
00319 template <typename T, typename Policy>
00320 inline bool
00321 is_plus_infinity(const Checked_Number<T, Policy>& x) {
00322 return Checked::is_pinf<Policy>(x.raw_value());
00323 }
00324
00326 template <typename T, typename Policy>
00327 inline memory_size_type
00328 total_memory_in_bytes(const Checked_Number<T, Policy>& x) {
00329 return Checked::total_memory_in_bytes(x.raw_value());
00330 }
00331
00333 template <typename T, typename Policy>
00334 inline memory_size_type
00335 external_memory_in_bytes(const Checked_Number<T, Policy>& x) {
00336 return Checked::external_memory_in_bytes(x.raw_value());
00337 }
00338
00339 template <typename To>
00340 inline Result
00341 assign_r(To& to, const Minus_Infinity& x, Rounding_Dir dir) {
00342 return check_result(Checked::assign<typename Native_Checked_To_Wrapper<To>::Policy>(Native_Checked_To_Wrapper<To>::raw_value(to), x, rounding_dir(dir)), dir);
00343 }
00344 template <typename To>
00345 inline Result
00346 assign_r(To& to, const Plus_Infinity& x, Rounding_Dir dir) {
00347 return check_result(Checked::assign<typename Native_Checked_To_Wrapper<To>::Policy>(Native_Checked_To_Wrapper<To>::raw_value(to), x, rounding_dir(dir)), dir);
00348 }
00349 template <typename To>
00350 inline Result
00351 assign_r(To& to, const Not_A_Number& x, Rounding_Dir dir) {
00352 return check_result(Checked::assign<typename Native_Checked_To_Wrapper<To>::Policy>(Native_Checked_To_Wrapper<To>::raw_value(to), x, rounding_dir(dir)), dir);
00353 }
00354
00355 template <typename To>
00356 inline Result
00357 assign_r(To& to, const char* x, Rounding_Dir dir) {
00358 std::istringstream s(x);
00359 return check_result(Checked::input<typename Native_Checked_To_Wrapper<To>::Policy>(Native_Checked_To_Wrapper<To>::raw_value(to), s, rounding_dir(dir)), dir);
00360 }
00361
00362 #define FUNC1(name, func) \
00363 template <typename To, typename From> \
00364 inline Result \
00365 name(To& to, const From& x, Rounding_Dir dir) { \
00366 return check_result(Checked::func<typename Native_Checked_To_Wrapper<To>::Policy, typename Native_Checked_From_Wrapper<From>::Policy>(Native_Checked_To_Wrapper<To>::raw_value(to), Native_Checked_From_Wrapper<From>::raw_value(x), rounding_dir(dir)), dir); \
00367 }
00368
00369 FUNC1(construct, construct_ext)
00370 FUNC1(assign_r, assign_ext)
00371 FUNC1(neg_assign_r, neg_ext)
00372 FUNC1(abs_assign_r, abs_ext)
00373 FUNC1(sqrt_assign_r, sqrt_ext)
00374
00375 #undef FUNC1
00376
00377 #define FUNC1(name, func) \
00378 template <typename To, typename From> \
00379 inline Result \
00380 name(To& to, const From& x, int exp, Rounding_Dir dir) { \
00381 return check_result(Checked::func<typename Native_Checked_To_Wrapper<To>::Policy, typename Native_Checked_From_Wrapper<From>::Policy>(Native_Checked_To_Wrapper<To>::raw_value(to), Native_Checked_From_Wrapper<From>::raw_value(x), exp, rounding_dir(dir)), dir); \
00382 }
00383
00384 FUNC1(mul2exp_assign_r, mul2exp_ext)
00385 FUNC1(div2exp_assign_r, div2exp_ext)
00386
00387 #undef FUNC1
00388
00389 #define FUNC2(name, func) \
00390 template <typename To, \
00391 typename From1, \
00392 typename From2> \
00393 inline Result \
00394 name(To& to, const From1& x, const From2& y, Rounding_Dir dir) { \
00395 return check_result(Checked::func<typename Native_Checked_To_Wrapper<To>::Policy, typename Native_Checked_From_Wrapper<From1>::Policy, typename Native_Checked_From_Wrapper<From2>::Policy>(Native_Checked_To_Wrapper<To>::raw_value(to), Native_Checked_From_Wrapper<From1>::raw_value(x), Native_Checked_From_Wrapper<From2>::raw_value(y), rounding_dir(dir)), dir); \
00396 }
00397
00398 FUNC2(add_assign_r, add_ext)
00399 FUNC2(sub_assign_r, sub_ext)
00400 FUNC2(mul_assign_r, mul_ext)
00401 FUNC2(div_assign_r, div_ext)
00402 FUNC2(rem_assign_r, rem_ext)
00403 FUNC2(gcd_assign_r, gcd_ext)
00404 FUNC2(lcm_assign_r, lcm_ext)
00405 FUNC2(add_mul_assign_r, add_mul_ext)
00406 FUNC2(sub_mul_assign_r, sub_mul_ext)
00407
00408 #undef FUNC2
00409
00410 #define FUNC4(name, func) \
00411 template <typename To1, \
00412 typename From1, \
00413 typename From2, \
00414 typename To2, \
00415 typename To3> \
00416 inline Result \
00417 name(To1& to, const From1& x, const From2& y, To2& s, To3& t, \
00418 Rounding_Dir dir) { \
00419 return \
00420 check_result \
00421 (Checked::func<typename Native_Checked_To_Wrapper<To1>::Policy, \
00422 typename Native_Checked_From_Wrapper<From1>::Policy, \
00423 typename Native_Checked_From_Wrapper<From2>::Policy, \
00424 typename Native_Checked_To_Wrapper<To2>::Policy, \
00425 typename Native_Checked_To_Wrapper<To3>::Policy> \
00426 (Native_Checked_To_Wrapper<To1>::raw_value(to), \
00427 Native_Checked_From_Wrapper<From1>::raw_value(x), \
00428 Native_Checked_From_Wrapper<From2>::raw_value(y), \
00429 Native_Checked_To_Wrapper<To2>::raw_value(s), \
00430 Native_Checked_To_Wrapper<To3>::raw_value(t), \
00431 rounding_dir(dir)), \
00432 dir); \
00433 }
00434
00435 FUNC4(gcdext_assign_r, gcdext_ext)
00436
00437 #undef FUNC4
00438
00439 #define DEF_INCREMENT(f, fun) \
00440 template <typename T, typename Policy> \
00441 inline Checked_Number<T, Policy>& \
00442 Checked_Number<T, Policy>::f() { \
00443 Policy::handle_result(fun(*this, *this, T(1), \
00444 Policy::ROUND_DEFAULT_OPERATOR)); \
00445 return *this; \
00446 } \
00447 template <typename T, typename Policy> \
00448 inline Checked_Number<T, Policy> \
00449 Checked_Number<T, Policy>::f(int) {\
00450 T r = v;\
00451 Policy::handle_result(fun(*this, *this, T(1), \
00452 Policy::ROUND_DEFAULT_OPERATOR)); \
00453 return r;\
00454 }
00455
00456 DEF_INCREMENT(operator ++, add_assign_r)
00457 DEF_INCREMENT(operator --, sub_assign_r)
00458
00459 #undef DEF_INCREMENT
00460
00462 template <typename T, typename Policy>
00463 inline void
00464 swap(Checked_Number<T, Policy>& x, Checked_Number<T, Policy>& y) {
00465 std::swap(x.raw_value(), y.raw_value());
00466 }
00467
00468 template <typename T, typename Policy>
00469 inline Checked_Number<T, Policy>&
00470 Checked_Number<T, Policy>::operator=(const Checked_Number<T, Policy>& y) {
00471 Checked::copy<Policy>(v, y.raw_value());
00472 return *this;
00473 }
00474 template <typename T, typename Policy>
00475 template <typename From, typename From_Policy>
00476 inline Checked_Number<T, Policy>&
00477 Checked_Number<T, Policy>
00478 ::operator=(const Checked_Number<From, From_Policy>& y) {
00479 Policy::handle_result(assign_r(*this, y, Policy::ROUND_DEFAULT_OPERATOR));
00480 return *this;
00481 }
00482 template <typename T, typename Policy>
00483 template <typename From>
00484 inline Checked_Number<T, Policy>&
00485 Checked_Number<T, Policy>::operator=(const From& y) {
00486 Policy::handle_result(assign_r(*this, y, Policy::ROUND_DEFAULT_OPERATOR));
00487 return *this;
00488 }
00489 template <typename T, typename Policy>
00490 inline Checked_Number<T, Policy>&
00491 Checked_Number<T, Policy>::operator=(const Not_A_Number& y) {
00492 Policy::handle_result(assign_r(*this, y, ROUND_IGNORE));
00493 return *this;
00494 }
00495 template <typename T, typename Policy>
00496 inline Checked_Number<T, Policy>&
00497 Checked_Number<T, Policy>::operator=(const Minus_Infinity& y) {
00498 Policy::handle_result(assign_r(*this, y, Policy::ROUND_DEFAULT_ASSIGN_INF));
00499 return *this;
00500 }
00501 template <typename T, typename Policy>
00502 inline Checked_Number<T, Policy>&
00503 Checked_Number<T, Policy>::operator=(const Plus_Infinity& y) {
00504 Policy::handle_result(assign_r(*this, y, Policy::ROUND_DEFAULT_ASSIGN_INF));
00505 return *this;
00506 }
00507
00508 #define DEF_BINARY_OP_ASSIGN(f, fun) \
00509 template <typename T, typename Policy> \
00510 template <typename From_Policy> \
00511 inline Checked_Number<T, Policy>& \
00512 Checked_Number<T, Policy>::f(const Checked_Number<T, From_Policy>& y) { \
00513 Policy::handle_result(fun(*this, *this, y, \
00514 Policy::ROUND_DEFAULT_OPERATOR)); \
00515 return *this; \
00516 } \
00517 template <typename T, typename Policy> \
00518 inline Checked_Number<T, Policy>& \
00519 Checked_Number<T, Policy>::f(const T& y) { \
00520 Policy::handle_result(fun(*this, *this, y, \
00521 Policy::ROUND_DEFAULT_OPERATOR)); \
00522 return *this; \
00523 } \
00524 template <typename T, typename Policy> \
00525 template <typename From, typename From_Policy> \
00526 inline Checked_Number<T, Policy>& \
00527 Checked_Number<T, Policy>::f(const Checked_Number<From, From_Policy>& y) { \
00528 Checked_Number<T, Policy> cy(y); \
00529 Policy::handle_result(fun(*this, *this, cy, \
00530 Policy::ROUND_DEFAULT_OPERATOR)); \
00531 return *this; \
00532 } \
00533 template <typename T, typename Policy> \
00534 template <typename From> \
00535 inline Checked_Number<T, Policy>& \
00536 Checked_Number<T, Policy>::f(const From& y) { \
00537 Checked_Number<T, Policy> cy(y); \
00538 Policy::handle_result(fun(*this, *this, cy, \
00539 Policy::ROUND_DEFAULT_OPERATOR)); \
00540 return *this; \
00541 }
00542
00543 DEF_BINARY_OP_ASSIGN(operator +=, add_assign_r)
00544 DEF_BINARY_OP_ASSIGN(operator -=, sub_assign_r)
00545 DEF_BINARY_OP_ASSIGN(operator *=, mul_assign_r)
00546 DEF_BINARY_OP_ASSIGN(operator /=, div_assign_r)
00547 DEF_BINARY_OP_ASSIGN(operator %=, rem_assign_r)
00548
00549 #undef DEF_BINARY_OP_ASSIGN
00550
00551 #define DEF_BINARY_OP_TYPE(f, fun, Type) \
00552 template <typename T, typename Policy> \
00553 inline Checked_Number<T, Policy> \
00554 f(const Type x, const Checked_Number<T, Policy>& y) { \
00555 Checked_Number<T, Policy> r(x); \
00556 Policy::handle_result(fun(r, r, y, Policy::ROUND_DEFAULT_OPERATOR)); \
00557 return r; \
00558 } \
00559 template <typename T, typename Policy> \
00560 inline Checked_Number<T, Policy> \
00561 f(const Checked_Number<T, Policy>& x, const Type y) { \
00562 Checked_Number<T, Policy> r(y); \
00563 Policy::handle_result(fun(r, x, r, Policy::ROUND_DEFAULT_OPERATOR)); \
00564 return r; \
00565 }
00566
00567 #define DEF_BINARY_OP(f, fun) \
00568 template <typename T, typename Policy> \
00569 inline Checked_Number<T, Policy> \
00570 f(const Checked_Number<T, Policy>& x, const Checked_Number<T, Policy>& y) { \
00571 Checked_Number<T, Policy> r; \
00572 Policy::handle_result(fun(r, x, y, Policy::ROUND_DEFAULT_OPERATOR)); \
00573 return r; \
00574 } \
00575 DEF_BINARY_OP_TYPE(f, fun, signed char) \
00576 DEF_BINARY_OP_TYPE(f, fun, signed short) \
00577 DEF_BINARY_OP_TYPE(f, fun, signed int) \
00578 DEF_BINARY_OP_TYPE(f, fun, signed long) \
00579 DEF_BINARY_OP_TYPE(f, fun, signed long long) \
00580 DEF_BINARY_OP_TYPE(f, fun, unsigned char) \
00581 DEF_BINARY_OP_TYPE(f, fun, unsigned short) \
00582 DEF_BINARY_OP_TYPE(f, fun, unsigned int) \
00583 DEF_BINARY_OP_TYPE(f, fun, unsigned long) \
00584 DEF_BINARY_OP_TYPE(f, fun, unsigned long long) \
00585 COND(PPL_SUPPORTED_FLOAT, DEF_BINARY_OP_TYPE(f, fun, float)) \
00586 COND(PPL_SUPPORTED_DOUBLE, DEF_BINARY_OP_TYPE(f, fun, double)) \
00587 COND(PPL_SUPPORTED_LONG_DOUBLE, DEF_BINARY_OP_TYPE(f, fun, long double)) \
00588 DEF_BINARY_OP_TYPE(f, fun, mpz_class&) \
00589 DEF_BINARY_OP_TYPE(f, fun, mpq_class&)
00590
00591 DEF_BINARY_OP(operator +, add_assign_r)
00592 DEF_BINARY_OP(operator -, sub_assign_r)
00593 DEF_BINARY_OP(operator *, mul_assign_r)
00594 DEF_BINARY_OP(operator /, div_assign_r)
00595 DEF_BINARY_OP(operator %, rem_assign_r)
00596
00597 #undef DEF_BINARY_OP_TYPE
00598 #undef DEF_BINARY_OP
00599
00600 #define DEF_COMPARE_TYPE(f, fun, Type) \
00601 template <typename From, typename From_Policy> \
00602 inline bool \
00603 f(const Type x, const Checked_Number<From, From_Policy>& y) { \
00604 return Checked::fun<Default_From_Policy, From_Policy>(x, y.raw_value()); \
00605 } \
00606 template <typename From, typename From_Policy> \
00607 inline bool \
00608 f(const Checked_Number<From, From_Policy>& x, const Type y) { \
00609 return Checked::fun<From_Policy, Default_From_Policy>(x.raw_value(), y); \
00610 }
00611
00612 #define DEF_COMPARE(f, fun) \
00613 template <typename T1, typename Policy1, \
00614 typename T2, typename Policy2> \
00615 inline bool \
00616 f(const Checked_Number<T1, Policy1>& x, \
00617 const Checked_Number<T2, Policy2>& y) { \
00618 return Checked::fun<Policy1, Policy2>(x.raw_value(), y.raw_value()); \
00619 } \
00620 DEF_COMPARE_TYPE(f, fun, signed char) \
00621 DEF_COMPARE_TYPE(f, fun, signed short) \
00622 DEF_COMPARE_TYPE(f, fun, signed int) \
00623 DEF_COMPARE_TYPE(f, fun, signed long) \
00624 DEF_COMPARE_TYPE(f, fun, signed long long) \
00625 DEF_COMPARE_TYPE(f, fun, unsigned char) \
00626 DEF_COMPARE_TYPE(f, fun, unsigned short) \
00627 DEF_COMPARE_TYPE(f, fun, unsigned int) \
00628 DEF_COMPARE_TYPE(f, fun, unsigned long) \
00629 DEF_COMPARE_TYPE(f, fun, unsigned long long) \
00630 COND(PPL_SUPPORTED_FLOAT, DEF_COMPARE_TYPE(f, fun, float)) \
00631 COND(PPL_SUPPORTED_DOUBLE, DEF_COMPARE_TYPE(f, fun, double)) \
00632 COND(PPL_SUPPORTED_LONG_DOUBLE, DEF_COMPARE_TYPE(f, fun, long double)) \
00633 DEF_COMPARE_TYPE(f, fun, mpz_class&) \
00634 DEF_COMPARE_TYPE(f, fun, mpq_class&)
00635
00636
00637 DEF_COMPARE(operator ==, eq_ext)
00638 DEF_COMPARE(operator !=, ne_ext)
00639 DEF_COMPARE(operator >=, ge_ext)
00640 DEF_COMPARE(operator >, gt_ext)
00641 DEF_COMPARE(operator <=, le_ext)
00642 DEF_COMPARE(operator <, lt_ext)
00643
00644 #undef DEF_COMPARE_TYPE
00645 #undef DEF_COMPARE
00646
00648 template <typename T, typename Policy>
00649 inline Checked_Number<T, Policy>
00650 operator+(const Checked_Number<T, Policy>& x) {
00651 return x;
00652 }
00653
00655 template <typename T, typename Policy>
00656 inline Checked_Number<T, Policy>
00657 operator-(const Checked_Number<T, Policy>& x) {
00658 Checked_Number<T, Policy> r;
00659 Policy::handle_result(neg_assign_r(r, x, Policy::ROUND_DEFAULT_OPERATOR));
00660 return r;
00661 }
00662
00663 #define DEF_ASSIGN_FUN2_1(f, fun) \
00664 template <typename T, typename Policy> \
00665 inline void \
00666 f(Checked_Number<T, Policy>& x) { \
00667 Policy::handle_result(fun(x, x, Policy::ROUND_DEFAULT_FUNCTION)); \
00668 }
00669
00670 #define DEF_ASSIGN_FUN2_2(f, fun) \
00671 template <typename T, typename Policy> \
00672 inline void \
00673 f(Checked_Number<T, Policy>& x, const Checked_Number<T, Policy>& y) { \
00674 Policy::handle_result(fun(x, y, Policy::ROUND_DEFAULT_FUNCTION)); \
00675 }
00676
00677 #define DEF_ASSIGN_FUN3_3(f, fun) \
00678 template <typename T, typename Policy> \
00679 inline void \
00680 f(Checked_Number<T, Policy>& x, const Checked_Number<T, Policy>& y, \
00681 const Checked_Number<T, Policy>& z) { \
00682 Policy::handle_result(fun(x, y, z, Policy::ROUND_DEFAULT_FUNCTION)); \
00683 }
00684
00685 #define DEF_ASSIGN_FUN5_5(f, fun) \
00686 template <typename T, typename Policy> \
00687 inline void \
00688 f(Checked_Number<T, Policy>& x, const Checked_Number<T, Policy>& y, \
00689 const Checked_Number<T, Policy>& z, \
00690 Checked_Number<T, Policy>& s, Checked_Number<T, Policy>& t) { \
00691 Policy::handle_result(fun(x, y, z, s, t, Policy::ROUND_DEFAULT_FUNCTION)); \
00692 }
00693
00694 DEF_ASSIGN_FUN2_2(sqrt_assign, sqrt_assign_r)
00695
00696 DEF_ASSIGN_FUN2_1(neg_assign, neg_assign_r)
00697 DEF_ASSIGN_FUN2_2(neg_assign, neg_assign_r)
00698
00699 DEF_ASSIGN_FUN3_3(add_mul_assign, add_mul_assign_r)
00700
00701 DEF_ASSIGN_FUN3_3(sub_mul_assign, sub_mul_assign_r)
00702
00703 DEF_ASSIGN_FUN3_3(gcd_assign, gcd_assign_r)
00704
00705 DEF_ASSIGN_FUN5_5(gcdext_assign, gcdext_assign_r)
00706
00707 DEF_ASSIGN_FUN3_3(lcm_assign, lcm_assign_r)
00708
00709 #undef DEF_ASSIGN_FUN2_1
00710 #undef DEF_ASSIGN_FUN2_2
00711 #undef DEF_ASSIGN_FUN3_2
00712 #undef DEF_ASSIGN_FUN3_3
00713
00714 template <typename T, typename Policy>
00715 inline void
00716 exact_div_assign(Checked_Number<T, Policy>& x,
00717 const Checked_Number<T, Policy>& y,
00718 const Checked_Number<T, Policy>& z) {
00719 Policy::handle_result(div_assign_r(x, y, z, ROUND_NOT_NEEDED));
00720 }
00721
00723 template <typename T, typename Policy>
00724 inline int
00725 sgn(const Checked_Number<T, Policy>& x) {
00726 Result r = Checked::sgn_ext<Policy>(x.raw_value());
00727 switch (r) {
00728 case V_LT:
00729 return -1;
00730 case V_EQ:
00731 return 0;
00732 case V_GT:
00733 return 1;
00734 default:
00735 throw(0);
00736 }
00737 }
00738
00740 template <typename T1, typename Policy1,
00741 typename T2, typename Policy2>
00742 inline int
00743 cmp(const Checked_Number<T1, Policy1>& x,
00744 const Checked_Number<T2, Policy2>& y) {
00745 Result r = Checked::cmp_ext<Policy1, Policy2>(x.raw_value(), y.raw_value());
00746 switch (r) {
00747 case V_LT:
00748 return -1;
00749 case V_EQ:
00750 return 0;
00751 case V_GT:
00752 return 1;
00753 default:
00754 throw(0);
00755 }
00756 }
00757
00759 template <typename T, typename Policy>
00760 inline Result
00761 output(std::ostream& os, const Checked_Number<T, Policy>& x,
00762 const Numeric_Format& fmt, Rounding_Dir dir) {
00763 return check_result(Checked::output_ext<Policy>(os,
00764 x.raw_value(),
00765 fmt,
00766 rounding_dir(dir)),
00767 dir);
00768 }
00769
00771 template <typename T, typename Policy>
00772 inline std::ostream&
00773 operator<<(std::ostream& os, const Checked_Number<T, Policy>& x) {
00774 Policy::handle_result(output(os, x, Numeric_Format(), ROUND_IGNORE));
00775 return os;
00776 }
00777
00779 template <typename T, typename Policy>
00780 inline Result
00781 input(Checked_Number<T, Policy>& x, std::istream& is, Rounding_Dir dir) {
00782 return check_result(Checked::input_ext<Policy>(x.raw_value(),
00783 is,
00784 rounding_dir(dir)),
00785 dir);
00786 }
00787
00789 template <typename T, typename Policy>
00790 inline std::istream& operator>>(std::istream& is,
00791 Checked_Number<T, Policy>& x) {
00792 Result r = input(x, is, Policy::ROUND_DEFAULT_INPUT);
00793 if (r == V_CVT_STR_UNK)
00794 is.setstate(std::ios::failbit);
00795 else
00796 Policy::handle_result(r);
00797 return is;
00798 }
00799
00800 template <typename T>
00801 inline T
00802 plus_infinity() {
00803 return PLUS_INFINITY;
00804 }
00805
00806 template <typename T>
00807 inline T
00808 minus_infinity() {
00809 return MINUS_INFINITY;
00810 }
00811
00812 template <typename T>
00813 inline T
00814 not_a_number() {
00815 return NOT_A_NUMBER;
00816 }
00817
00818 }
00819
00820 #endif // !defined(PPL_Checked_Number_inlines_hh)