00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef PPL_Checked_Number_inlines_hh
00025 #define PPL_Checked_Number_inlines_hh 1
00026
00027 #include "globals.defs.hh"
00028 #include <stdexcept>
00029 #include <sstream>
00030
00031 namespace Parma_Polyhedra_Library {
00032
00033 #ifndef NDEBUG
00034 #define DEBUG_ROUND_NOT_NEEDED
00035 #endif
00036
00037 inline Rounding_Dir
00038 rounding_dir(Rounding_Dir dir) {
00039 if (dir == ROUND_NOT_NEEDED) {
00040 #ifdef DEBUG_ROUND_NOT_NEEDED
00041 return ROUND_CHECK;
00042 #endif
00043 }
00044 return dir;
00045 }
00046
00047 inline Result
00048 check_result(Result r, Rounding_Dir dir) {
00049 if (dir == ROUND_NOT_NEEDED) {
00050 #ifdef DEBUG_ROUND_NOT_NEEDED
00051 PPL_ASSERT(result_relation(r) == VR_EQ);
00052 #endif
00053 return r;
00054 }
00055 return r;
00056 }
00057
00058
00059 template <typename T>
00060 inline void
00061 Checked_Number_Transparent_Policy<T>::handle_result(Result) {
00062 }
00063
00064 inline void
00065 Extended_Number_Policy::handle_result(Result r) {
00066 if (result_class(r) == VC_NAN)
00067 throw_result_exception(r);
00068 }
00069
00070 template <typename T, typename Policy>
00071 inline
00072 Checked_Number<T, Policy>::Checked_Number()
00073 : v(0) {
00074 }
00075
00076 template <typename T, typename Policy>
00077 inline
00078 Checked_Number<T, Policy>::Checked_Number(const Checked_Number& y) {
00079
00080 Checked::copy<Policy, Policy>(v, y.raw_value());
00081 }
00082
00083 template <typename T, typename Policy>
00084 template <typename From, typename From_Policy>
00085 inline
00086 Checked_Number<T, Policy>
00087 ::Checked_Number(const Checked_Number<From, From_Policy>& y,
00088 Rounding_Dir dir) {
00089
00090 Policy::handle_result(check_result(Checked::assign_ext<Policy, From_Policy>
00091 (v,
00092 y.raw_value(),
00093 rounding_dir(dir)),
00094 dir)
00095 );
00096 }
00097
00098 template <typename T, typename Policy>
00099 template <typename From, typename From_Policy>
00100 inline
00101 Checked_Number<T, Policy>
00102 ::Checked_Number(const Checked_Number<From, From_Policy>& y) {
00103
00104 Rounding_Dir dir = Policy::ROUND_DEFAULT_CONSTRUCTOR;
00105 Policy::handle_result(check_result(Checked::assign_ext<Policy, From_Policy>
00106 (v,
00107 y.raw_value(),
00108 rounding_dir(dir)),
00109 dir));
00110 }
00111
00112
00113 #define PPL_DEFINE_CTOR(type) \
00114 template <typename T, typename Policy> \
00115 inline \
00116 Checked_Number<T, Policy>::Checked_Number(const type x, Rounding_Dir dir) { \
00117 Policy::handle_result \
00118 (check_result(Checked::assign_ext<Policy, Checked_Number_Transparent_Policy<type> > \
00119 (v, x, rounding_dir(dir)), \
00120 dir)); \
00121 } \
00122 template <typename T, typename Policy> \
00123 inline \
00124 Checked_Number<T, Policy>::Checked_Number(const type x) { \
00125 Rounding_Dir dir = Policy::ROUND_DEFAULT_CONSTRUCTOR; \
00126 Policy::handle_result \
00127 (check_result(Checked::assign_ext<Policy, Checked_Number_Transparent_Policy<type> > \
00128 (v, x, rounding_dir(dir)), \
00129 dir)); \
00130 }
00131
00132 #define PPL_COND_0(...)
00133 #define PPL_COND_1(...) __VA_ARGS__
00134 #define PPL_COND_(if, ...) PPL_COND_##if(__VA_ARGS__)
00135 #define PPL_COND(if, ...) PPL_COND_(if, __VA_ARGS__)
00136
00137 PPL_DEFINE_CTOR(char)
00138 PPL_DEFINE_CTOR(signed char)
00139 PPL_DEFINE_CTOR(signed short)
00140 PPL_DEFINE_CTOR(signed int)
00141 PPL_DEFINE_CTOR(signed long)
00142 PPL_DEFINE_CTOR(signed long long)
00143 PPL_DEFINE_CTOR(unsigned char)
00144 PPL_DEFINE_CTOR(unsigned short)
00145 PPL_DEFINE_CTOR(unsigned int)
00146 PPL_DEFINE_CTOR(unsigned long)
00147 PPL_DEFINE_CTOR(unsigned long long)
00148 PPL_COND(PPL_SUPPORTED_FLOAT, PPL_DEFINE_CTOR(float))
00149 PPL_COND(PPL_SUPPORTED_DOUBLE, PPL_DEFINE_CTOR(double))
00150 PPL_COND(PPL_SUPPORTED_LONG_DOUBLE, PPL_DEFINE_CTOR(long double))
00151 PPL_DEFINE_CTOR(mpq_class&)
00152 PPL_DEFINE_CTOR(mpz_class&)
00153
00154 #undef PPL_DEFINE_CTOR
00155
00156 #undef PPL_COND
00157 #undef PPL_COND_
00158 #undef PPL_COND_1
00159 #undef PPL_COND_0
00160
00161 template <typename T, typename Policy>
00162 inline
00163 Checked_Number<T, Policy>::Checked_Number(const char* x, Rounding_Dir dir) {
00164 std::istringstream s(x);
00165 Policy::handle_result(check_result(Checked::input<Policy>(v,
00166 s,
00167 rounding_dir(dir)),
00168 dir));
00169 }
00170
00171 template <typename T, typename Policy>
00172 inline
00173 Checked_Number<T, Policy>::Checked_Number(const char* x) {
00174 std::istringstream s(x);
00175 Rounding_Dir dir = Policy::ROUND_DEFAULT_CONSTRUCTOR;
00176 Policy::handle_result(check_result(Checked::input<Policy>(v,
00177 s,
00178 rounding_dir(dir)),
00179 dir));
00180 }
00181
00182 template <typename T, typename Policy>
00183 template <typename From>
00184 inline
00185 Checked_Number<T, Policy>::Checked_Number(const From&, Rounding_Dir dir, typename Enable_If<Is_Special<From>::value, bool>::type) {
00186 Policy::handle_result(check_result(Checked::assign_special<Policy>(v,
00187 From::vclass,
00188 rounding_dir(dir)),
00189 dir));
00190 }
00191
00192 template <typename T, typename Policy>
00193 template <typename From>
00194 inline
00195 Checked_Number<T, Policy>::Checked_Number(const From&, typename Enable_If<Is_Special<From>::value, bool>::type) {
00196 Rounding_Dir dir = Policy::ROUND_DEFAULT_CONSTRUCTOR;
00197 Policy::handle_result(check_result(Checked::assign_special<Policy>(v,
00198 From::vclass,
00199 rounding_dir(dir)),
00200 dir));
00201 }
00202
00203 template <typename To, typename From>
00204 inline typename Enable_If<Is_Native_Or_Checked<To>::value && Is_Special<From>::value, Result>::type
00205 assign_r(To& to, const From&, Rounding_Dir dir) {
00206 return check_result(Checked::assign_special<typename Native_Checked_To_Wrapper<To>
00207 ::Policy>(Native_Checked_To_Wrapper<To>::raw_value(to),
00208 From::vclass,
00209 rounding_dir(dir)),
00210 dir);
00211 }
00212
00213 template <typename To, typename From>
00214 inline typename Enable_If<Is_Native_Or_Checked<To>::value && Is_Special<From>::value, Result>::type
00215 construct(To& to, const From&, Rounding_Dir dir) {
00216 return check_result(Checked::construct_special<typename Native_Checked_To_Wrapper<To>
00217 ::Policy>(Native_Checked_To_Wrapper<To>::raw_value(to),
00218 From::vclass,
00219 rounding_dir(dir)),
00220 dir);
00221 }
00222
00223 template <typename T>
00224 inline typename Enable_If<Is_Native_Or_Checked<T>::value, bool>::type
00225 is_minus_infinity(const T& x) {
00226 return Checked::is_minf<typename Native_Checked_From_Wrapper<T>
00227 ::Policy>(Native_Checked_From_Wrapper<T>::raw_value(x));
00228 }
00229
00230 template <typename T>
00231 inline typename Enable_If<Is_Native_Or_Checked<T>::value, bool>::type
00232 is_plus_infinity(const T& x) {
00233 return Checked::is_pinf<typename Native_Checked_From_Wrapper<T>
00234 ::Policy>(Native_Checked_From_Wrapper<T>::raw_value(x));
00235 }
00236
00237 template <typename T>
00238 inline typename Enable_If<Is_Native_Or_Checked<T>::value, int>::type
00239 is_infinity(const T& x) {
00240 return is_minus_infinity(x) ? -1 : is_plus_infinity(x) ? 1 : 0;
00241 }
00242
00243 template <typename T>
00244 inline typename Enable_If<Is_Native_Or_Checked<T>::value, bool>::type
00245 is_not_a_number(const T& x) {
00246 return Checked::is_nan<typename Native_Checked_From_Wrapper<T>
00247 ::Policy>(Native_Checked_From_Wrapper<T>::raw_value(x));
00248 }
00249
00250 template <typename T>
00251 inline typename Enable_If<Is_Native_Or_Checked<T>::value, bool>::type
00252 is_integer(const T& x) {
00253 return Checked::is_int<typename Native_Checked_From_Wrapper<T>
00254 ::Policy>(Native_Checked_From_Wrapper<T>::raw_value(x));
00255 }
00256
00257 template <typename T, typename Policy>
00258 inline
00259 Checked_Number<T, Policy>::operator T() const {
00260 if (Policy::convertible)
00261 return v;
00262 }
00263
00264 template <typename T, typename Policy>
00265 inline T&
00266 Checked_Number<T, Policy>::raw_value() {
00267 return v;
00268 }
00269
00270 template <typename T, typename Policy>
00271 inline const T&
00272 Checked_Number<T, Policy>::raw_value() const {
00273 return v;
00274 }
00275
00277 template <typename T, typename Policy>
00278 inline const T&
00279 raw_value(const Checked_Number<T, Policy>& x) {
00280 return x.raw_value();
00281 }
00282
00284 template <typename T, typename Policy>
00285 inline T&
00286 raw_value(Checked_Number<T, Policy>& x) {
00287 return x.raw_value();
00288 }
00289
00290 template <typename T, typename Policy>
00291 inline bool
00292 Checked_Number<T, Policy>::OK() const {
00293 return true;
00294 }
00295
00296 template <typename T, typename Policy>
00297 inline Result
00298 Checked_Number<T, Policy>::classify(bool nan, bool inf, bool sign) const {
00299 return Checked::classify<Policy>(v, nan, inf, sign);
00300 }
00301
00302 template <typename T, typename Policy>
00303 inline bool
00304 is_not_a_number(const Checked_Number<T, Policy>& x) {
00305 return Checked::is_nan<Policy>(x.raw_value());
00306 }
00307
00308 template <typename T, typename Policy>
00309 inline bool
00310 is_minus_infinity(const Checked_Number<T, Policy>& x) {
00311 return Checked::is_minf<Policy>(x.raw_value());
00312 }
00313
00314 template <typename T, typename Policy>
00315 inline bool
00316 is_plus_infinity(const Checked_Number<T, Policy>& x) {
00317 return Checked::is_pinf<Policy>(x.raw_value());
00318 }
00319
00321 template <typename T, typename Policy>
00322 inline memory_size_type
00323 total_memory_in_bytes(const Checked_Number<T, Policy>& x) {
00324 return total_memory_in_bytes(x.raw_value());
00325 }
00326
00328 template <typename T, typename Policy>
00329 inline memory_size_type
00330 external_memory_in_bytes(const Checked_Number<T, Policy>& x) {
00331 return external_memory_in_bytes(x.raw_value());
00332 }
00333
00334
00336 template <typename To>
00337 inline typename Enable_If<Is_Native_Or_Checked<To>::value, Result>::type
00338 assign_r(To& to, const char* x, Rounding_Dir dir) {
00339 std::istringstream s(x);
00340 return check_result(Checked::input<typename Native_Checked_To_Wrapper<To>
00341 ::Policy>(Native_Checked_To_Wrapper<To>::raw_value(to),
00342 s,
00343 rounding_dir(dir)),
00344 dir);
00345 }
00346
00347 #define PPL_DEFINE_FUNC1_A(name, func) \
00348 template <typename To, typename From> \
00349 inline typename Enable_If<Is_Native_Or_Checked<To>::value \
00350 && Is_Native_Or_Checked<From>::value, \
00351 Result>::type \
00352 name(To& to, const From& x, Rounding_Dir dir) { \
00353 return \
00354 check_result(Checked::func<typename Native_Checked_To_Wrapper<To> \
00355 ::Policy, \
00356 typename Native_Checked_From_Wrapper<From> \
00357 ::Policy>(Native_Checked_To_Wrapper<To>::raw_value(to), \
00358 Native_Checked_From_Wrapper<From>::raw_value(x), \
00359 rounding_dir(dir)), dir); \
00360 }
00361
00362 PPL_DEFINE_FUNC1_A(construct, construct_ext)
00363 PPL_DEFINE_FUNC1_A(assign_r, assign_ext)
00364 PPL_DEFINE_FUNC1_A(floor_assign_r, floor_ext)
00365 PPL_DEFINE_FUNC1_A(ceil_assign_r, ceil_ext)
00366 PPL_DEFINE_FUNC1_A(trunc_assign_r, trunc_ext)
00367 PPL_DEFINE_FUNC1_A(neg_assign_r, neg_ext)
00368 PPL_DEFINE_FUNC1_A(abs_assign_r, abs_ext)
00369 PPL_DEFINE_FUNC1_A(sqrt_assign_r, sqrt_ext)
00370
00371 #undef PPL_DEFINE_FUNC1_A
00372
00373 #define PPL_DEFINE_FUNC1_B(name, func) \
00374 template <typename To, typename From> \
00375 inline typename Enable_If<Is_Native_Or_Checked<To>::value \
00376 && Is_Native_Or_Checked<From>::value, \
00377 Result>::type \
00378 name(To& to, const From& x, int exp, Rounding_Dir dir) { \
00379 return \
00380 check_result(Checked::func<typename Native_Checked_To_Wrapper<To> \
00381 ::Policy, \
00382 typename Native_Checked_From_Wrapper<From> \
00383 ::Policy>(Native_Checked_To_Wrapper<To>::raw_value(to), \
00384 Native_Checked_From_Wrapper<From>::raw_value(x), \
00385 exp, \
00386 rounding_dir(dir)), \
00387 dir); \
00388 }
00389
00390 PPL_DEFINE_FUNC1_B(add_2exp_assign_r, add_2exp_ext)
00391 PPL_DEFINE_FUNC1_B(sub_2exp_assign_r, sub_2exp_ext)
00392 PPL_DEFINE_FUNC1_B(mul_2exp_assign_r, mul_2exp_ext)
00393 PPL_DEFINE_FUNC1_B(div_2exp_assign_r, div_2exp_ext)
00394 PPL_DEFINE_FUNC1_B(smod_2exp_assign_r, smod_2exp_ext)
00395 PPL_DEFINE_FUNC1_B(umod_2exp_assign_r, umod_2exp_ext)
00396
00397 #undef PPL_DEFINE_FUNC1_B
00398
00399 #define PPL_DEFINE_FUNC2(name, func) \
00400 template <typename To, typename From1, typename From2> \
00401 inline typename Enable_If<Is_Native_Or_Checked<To>::value \
00402 && Is_Native_Or_Checked<From1>::value \
00403 && Is_Native_Or_Checked<From2>::value, \
00404 Result>::type \
00405 name(To& to, const From1& x, const From2& y, Rounding_Dir dir) { \
00406 return \
00407 check_result(Checked::func<typename Native_Checked_To_Wrapper<To> \
00408 ::Policy, \
00409 typename Native_Checked_From_Wrapper<From1> \
00410 ::Policy, \
00411 typename Native_Checked_From_Wrapper<From2> \
00412 ::Policy>(Native_Checked_To_Wrapper<To>::raw_value(to), \
00413 Native_Checked_From_Wrapper<From1>::raw_value(x), \
00414 Native_Checked_From_Wrapper<From2>::raw_value(y), \
00415 rounding_dir(dir)), \
00416 dir); \
00417 }
00418
00419 PPL_DEFINE_FUNC2(add_assign_r, add_ext)
00420 PPL_DEFINE_FUNC2(sub_assign_r, sub_ext)
00421 PPL_DEFINE_FUNC2(mul_assign_r, mul_ext)
00422 PPL_DEFINE_FUNC2(div_assign_r, div_ext)
00423 PPL_DEFINE_FUNC2(idiv_assign_r, idiv_ext)
00424 PPL_DEFINE_FUNC2(rem_assign_r, rem_ext)
00425 PPL_DEFINE_FUNC2(gcd_assign_r, gcd_ext)
00426 PPL_DEFINE_FUNC2(lcm_assign_r, lcm_ext)
00427 PPL_DEFINE_FUNC2(add_mul_assign_r, add_mul_ext)
00428 PPL_DEFINE_FUNC2(sub_mul_assign_r, sub_mul_ext)
00429
00430 #undef PPL_DEFINE_FUNC2
00431
00432 #define PPL_DEFINE_FUNC4(name, func) \
00433 template <typename To1, \
00434 typename To2, \
00435 typename To3, \
00436 typename From1, \
00437 typename From2> \
00438 inline typename Enable_If<Is_Native_Or_Checked<To1>::value \
00439 && Is_Native_Or_Checked<To2>::value \
00440 && Is_Native_Or_Checked<To3>::value \
00441 && Is_Native_Or_Checked<From1>::value \
00442 && Is_Native_Or_Checked<From2>::value, \
00443 Result>::type \
00444 name(To1& to, To2& s, To3& t, const From1& x, const From2& y, \
00445 Rounding_Dir dir) { \
00446 return \
00447 check_result \
00448 (Checked::func<typename Native_Checked_To_Wrapper<To1>::Policy, \
00449 typename Native_Checked_To_Wrapper<To2>::Policy, \
00450 typename Native_Checked_To_Wrapper<To3>::Policy, \
00451 typename Native_Checked_From_Wrapper<From1>::Policy, \
00452 typename Native_Checked_From_Wrapper<From2>::Policy> \
00453 (Native_Checked_To_Wrapper<To1>::raw_value(to), \
00454 Native_Checked_To_Wrapper<To2>::raw_value(s), \
00455 Native_Checked_To_Wrapper<To3>::raw_value(t), \
00456 Native_Checked_From_Wrapper<From1>::raw_value(x), \
00457 Native_Checked_From_Wrapper<From2>::raw_value(y), \
00458 rounding_dir(dir)), \
00459 dir); \
00460 }
00461
00462 PPL_DEFINE_FUNC4(gcdext_assign_r, gcdext_ext)
00463
00464 #undef PPL_DEFINE_PPL_DEFINE_FUNC4
00465
00466 #define PPL_DEFINE_INCREMENT(f, fun) \
00467 template <typename T, typename Policy> \
00468 inline Checked_Number<T, Policy>& \
00469 Checked_Number<T, Policy>::f() { \
00470 Policy::handle_result(fun(*this, *this, T(1), \
00471 Policy::ROUND_DEFAULT_OPERATOR)); \
00472 return *this; \
00473 } \
00474 template <typename T, typename Policy> \
00475 inline Checked_Number<T, Policy> \
00476 Checked_Number<T, Policy>::f(int) {\
00477 T r = v;\
00478 Policy::handle_result(fun(*this, *this, T(1), \
00479 Policy::ROUND_DEFAULT_OPERATOR)); \
00480 return r;\
00481 }
00482
00483 PPL_DEFINE_INCREMENT(operator ++, add_assign_r)
00484 PPL_DEFINE_INCREMENT(operator --, sub_assign_r)
00485
00486 #undef PPL_DEFINE_INCREMENT
00487
00488 template <typename T, typename Policy>
00489 inline Checked_Number<T, Policy>&
00490 Checked_Number<T, Policy>::operator=(const Checked_Number<T, Policy>& y) {
00491 Checked::copy<Policy, Policy>(v, y.raw_value());
00492 return *this;
00493 }
00494 template <typename T, typename Policy>
00495 template <typename From>
00496 inline Checked_Number<T, Policy>&
00497 Checked_Number<T, Policy>::operator=(const From& y) {
00498 Policy::handle_result(assign_r(*this, y, Policy::ROUND_DEFAULT_OPERATOR));
00499 return *this;
00500 }
00501
00502 #define PPL_DEFINE_BINARY_OP_ASSIGN(f, fun) \
00503 template <typename T, typename Policy> \
00504 template <typename From_Policy> \
00505 inline Checked_Number<T, Policy>& \
00506 Checked_Number<T, Policy>::f(const Checked_Number<T, From_Policy>& y) { \
00507 Policy::handle_result(fun(*this, *this, y, \
00508 Policy::ROUND_DEFAULT_OPERATOR)); \
00509 return *this; \
00510 } \
00511 template <typename T, typename Policy> \
00512 inline Checked_Number<T, Policy>& \
00513 Checked_Number<T, Policy>::f(const T& y) { \
00514 Policy::handle_result(fun(*this, *this, y, \
00515 Policy::ROUND_DEFAULT_OPERATOR)); \
00516 return *this; \
00517 } \
00518 template <typename T, typename Policy> \
00519 template <typename From> \
00520 inline typename Enable_If<Is_Native_Or_Checked<From>::value, \
00521 Checked_Number<T, Policy>& >::type \
00522 Checked_Number<T, Policy>::f(const From& y) { \
00523 Checked_Number<T, Policy> cy(y); \
00524 Policy::handle_result(fun(*this, *this, cy, \
00525 Policy::ROUND_DEFAULT_OPERATOR)); \
00526 return *this; \
00527 }
00528
00529 PPL_DEFINE_BINARY_OP_ASSIGN(operator +=, add_assign_r)
00530 PPL_DEFINE_BINARY_OP_ASSIGN(operator -=, sub_assign_r)
00531 PPL_DEFINE_BINARY_OP_ASSIGN(operator *=, mul_assign_r)
00532 PPL_DEFINE_BINARY_OP_ASSIGN(operator /=, div_assign_r)
00533 PPL_DEFINE_BINARY_OP_ASSIGN(operator %=, rem_assign_r)
00534
00535 #undef PPL_DEFINE_BINARY_OP_ASSIGN
00536
00537 #define PPL_DEFINE_BINARY_OP(f, fun) \
00538 template <typename T, typename Policy> \
00539 inline Checked_Number<T, Policy> \
00540 f(const Checked_Number<T, Policy>& x, const Checked_Number<T, Policy>& y) { \
00541 Checked_Number<T, Policy> r; \
00542 Policy::handle_result(fun(r, x, y, Policy::ROUND_DEFAULT_OPERATOR)); \
00543 return r; \
00544 } \
00545 template <typename Type, typename T, typename Policy> \
00546 inline \
00547 typename Enable_If<Is_Native<Type>::value, Checked_Number<T, Policy> >::type \
00548 f(const Type& x, const Checked_Number<T, Policy>& y) { \
00549 Checked_Number<T, Policy> r(x); \
00550 Policy::handle_result(fun(r, r, y, Policy::ROUND_DEFAULT_OPERATOR)); \
00551 return r; \
00552 } \
00553 template <typename T, typename Policy, typename Type> \
00554 inline \
00555 typename Enable_If<Is_Native<Type>::value, Checked_Number<T, Policy> >::type \
00556 f(const Checked_Number<T, Policy>& x, const Type& y) { \
00557 Checked_Number<T, Policy> r(y); \
00558 Policy::handle_result(fun(r, x, r, Policy::ROUND_DEFAULT_OPERATOR)); \
00559 return r; \
00560 }
00561
00562 PPL_DEFINE_BINARY_OP(operator +, add_assign_r)
00563 PPL_DEFINE_BINARY_OP(operator -, sub_assign_r)
00564 PPL_DEFINE_BINARY_OP(operator *, mul_assign_r)
00565 PPL_DEFINE_BINARY_OP(operator /, div_assign_r)
00566 PPL_DEFINE_BINARY_OP(operator %, rem_assign_r)
00567
00568 #undef PPL_DEFINE_BINARY_OP
00569
00570 #define PPL_DEFINE_COMPARE_OP(f, fun) \
00571 template <typename T1, typename T2> \
00572 inline \
00573 typename Enable_If<Is_Native_Or_Checked<T1>::value \
00574 && Is_Native_Or_Checked<T2>::value \
00575 && (Is_Checked<T1>::value || Is_Checked<T2>::value), \
00576 bool>::type \
00577 f(const T1& x, const T2& y) { \
00578 return Checked::fun<typename Native_Checked_From_Wrapper<T1>::Policy, \
00579 typename Native_Checked_From_Wrapper<T2>::Policy> \
00580 (Native_Checked_From_Wrapper<T1>::raw_value(x), \
00581 Native_Checked_From_Wrapper<T2>::raw_value(y)); \
00582 }
00583
00584 PPL_DEFINE_COMPARE_OP(operator ==, eq_ext)
00585 PPL_DEFINE_COMPARE_OP(operator !=, ne_ext)
00586 PPL_DEFINE_COMPARE_OP(operator >=, ge_ext)
00587 PPL_DEFINE_COMPARE_OP(operator >, gt_ext)
00588 PPL_DEFINE_COMPARE_OP(operator <=, le_ext)
00589 PPL_DEFINE_COMPARE_OP(operator <, lt_ext)
00590
00591 #undef PPL_DEFINE_COMPARE_OP
00592
00593 #define PPL_DEFINE_COMPARE(f, fun) \
00594 template <typename T1, typename T2> \
00595 inline typename Enable_If<Is_Native_Or_Checked<T1>::value \
00596 && Is_Native_Or_Checked<T2>::value, \
00597 bool>::type \
00598 f(const T1& x, const T2& y) { \
00599 return Checked::fun<typename Native_Checked_From_Wrapper<T1>::Policy, \
00600 typename Native_Checked_From_Wrapper<T2>::Policy> \
00601 (Native_Checked_From_Wrapper<T1>::raw_value(x), \
00602 Native_Checked_From_Wrapper<T2>::raw_value(y)); \
00603 }
00604
00605 PPL_DEFINE_COMPARE(equal, eq_ext)
00606 PPL_DEFINE_COMPARE(not_equal, ne_ext)
00607 PPL_DEFINE_COMPARE(greater_or_equal, ge_ext)
00608 PPL_DEFINE_COMPARE(greater_than, gt_ext)
00609 PPL_DEFINE_COMPARE(less_or_equal, le_ext)
00610 PPL_DEFINE_COMPARE(less_than, lt_ext)
00611
00612 #undef PPL_DEFINE_COMPARE
00613
00615 template <typename T, typename Policy>
00616 inline Checked_Number<T, Policy>
00617 operator+(const Checked_Number<T, Policy>& x) {
00618 return x;
00619 }
00620
00622 template <typename T, typename Policy>
00623 inline Checked_Number<T, Policy>
00624 operator-(const Checked_Number<T, Policy>& x) {
00625 Checked_Number<T, Policy> r;
00626 Policy::handle_result(neg_assign_r(r, x, Policy::ROUND_DEFAULT_OPERATOR));
00627 return r;
00628 }
00629
00630 #define PPL_DEFINE_ASSIGN_FUN2_1(f, fun) \
00631 template <typename T, typename Policy> \
00632 inline void \
00633 f(Checked_Number<T, Policy>& x) { \
00634 Policy::handle_result(fun(x, x, Policy::ROUND_DEFAULT_FUNCTION)); \
00635 }
00636
00637 #define PPL_DEFINE_ASSIGN_FUN2_2(f, fun) \
00638 template <typename T, typename Policy> \
00639 inline void \
00640 f(Checked_Number<T, Policy>& x, const Checked_Number<T, Policy>& y) { \
00641 Policy::handle_result(fun(x, y, Policy::ROUND_DEFAULT_FUNCTION)); \
00642 }
00643
00644 #define PPL_DEFINE_ASSIGN_FUN3_3(f, fun) \
00645 template <typename T, typename Policy> \
00646 inline void \
00647 f(Checked_Number<T, Policy>& x, const Checked_Number<T, Policy>& y, \
00648 const Checked_Number<T, Policy>& z) { \
00649 Policy::handle_result(fun(x, y, z, Policy::ROUND_DEFAULT_FUNCTION)); \
00650 }
00651
00652 #define PPL_DEFINE_ASSIGN_FUN5_5(f, fun) \
00653 template <typename T, typename Policy> \
00654 inline void \
00655 f(Checked_Number<T, Policy>& x, \
00656 Checked_Number<T, Policy>& s, Checked_Number<T, Policy>& t, \
00657 const Checked_Number<T, Policy>& y, \
00658 const Checked_Number<T, Policy>& z) { \
00659 Policy::handle_result(fun(x, s, t, y, z, Policy::ROUND_DEFAULT_FUNCTION)); \
00660 }
00661
00662 PPL_DEFINE_ASSIGN_FUN2_2(sqrt_assign, sqrt_assign_r)
00663
00664 PPL_DEFINE_ASSIGN_FUN2_1(floor_assign, floor_assign_r)
00665 PPL_DEFINE_ASSIGN_FUN2_2(floor_assign, floor_assign_r)
00666
00667 PPL_DEFINE_ASSIGN_FUN2_1(ceil_assign, ceil_assign_r)
00668 PPL_DEFINE_ASSIGN_FUN2_2(ceil_assign, ceil_assign_r)
00669
00670 PPL_DEFINE_ASSIGN_FUN2_1(trunc_assign, trunc_assign_r)
00671 PPL_DEFINE_ASSIGN_FUN2_2(trunc_assign, trunc_assign_r)
00672
00673 PPL_DEFINE_ASSIGN_FUN2_1(neg_assign, neg_assign_r)
00674 PPL_DEFINE_ASSIGN_FUN2_2(neg_assign, neg_assign_r)
00675
00676 PPL_DEFINE_ASSIGN_FUN2_1(abs_assign, abs_assign_r)
00677 PPL_DEFINE_ASSIGN_FUN2_2(abs_assign, abs_assign_r)
00678
00679 PPL_DEFINE_ASSIGN_FUN3_3(add_mul_assign, add_mul_assign_r)
00680
00681 PPL_DEFINE_ASSIGN_FUN3_3(sub_mul_assign, sub_mul_assign_r)
00682
00683 PPL_DEFINE_ASSIGN_FUN3_3(rem_assign, rem_assign_r)
00684
00685 PPL_DEFINE_ASSIGN_FUN3_3(gcd_assign, gcd_assign_r)
00686
00687 PPL_DEFINE_ASSIGN_FUN5_5(gcdext_assign, gcdext_assign_r)
00688
00689 PPL_DEFINE_ASSIGN_FUN3_3(lcm_assign, lcm_assign_r)
00690
00691 #undef PPL_DEFINE_ASSIGN_FUN2_1
00692 #undef PPL_DEFINE_ASSIGN_FUN2_2
00693 #undef PPL_DEFINE_ASSIGN_FUN3_2
00694 #undef PPL_DEFINE_ASSIGN_FUN3_3
00695 #undef PPL_DEFINE_ASSIGN_FUN5_5
00696
00697 #define PPL_DEFINE_ASSIGN_2EXP(f, fun) \
00698 template <typename T, typename Policy> \
00699 inline void \
00700 f(Checked_Number<T, Policy>& to, \
00701 const Checked_Number<T, Policy>& x, unsigned int exp) { \
00702 Policy::handle_result(fun(to, x, exp, Policy::ROUND_DEFAULT_FUNCTION)); \
00703 }
00704
00705 PPL_DEFINE_ASSIGN_2EXP(mul_2exp_assign, mul_2exp_assign_r)
00706 PPL_DEFINE_ASSIGN_2EXP(div_2exp_assign, div_2exp_assign_r)
00707
00708 template <typename T, typename Policy>
00709 inline void
00710 exact_div_assign(Checked_Number<T, Policy>& x,
00711 const Checked_Number<T, Policy>& y,
00712 const Checked_Number<T, Policy>& z) {
00713 Policy::handle_result(div_assign_r(x, y, z, ROUND_NOT_NEEDED));
00714 }
00715
00717 template <typename From>
00718 inline typename Enable_If<Is_Native_Or_Checked<From>::value, int>::type
00719 sgn(const From& x) {
00720 Result_Relation r = Checked::sgn_ext<typename Native_Checked_From_Wrapper<From>::Policy>(Native_Checked_From_Wrapper<From>::raw_value(x));
00721 switch (r) {
00722 case VR_LT:
00723 return -1;
00724 case VR_EQ:
00725 return 0;
00726 case VR_GT:
00727 return 1;
00728 default:
00729 throw(0);
00730 }
00731 }
00732
00734 template <typename From1, typename From2>
00735 inline typename Enable_If<Is_Native_Or_Checked<From1>::value
00736 && Is_Native_Or_Checked<From2>::value,
00737 int>::type
00738 cmp(const From1& x, const From2& y) {
00739 Result_Relation r
00740 = Checked::cmp_ext<typename Native_Checked_From_Wrapper<From1>::Policy,
00741 typename Native_Checked_From_Wrapper<From2>::Policy>
00742 (Native_Checked_From_Wrapper<From1>::raw_value(x),
00743 Native_Checked_From_Wrapper<From2>::raw_value(y));
00744 switch (r) {
00745 case VR_LT:
00746 return -1;
00747 case VR_EQ:
00748 return 0;
00749 case VR_GT:
00750 return 1;
00751 default:
00752 throw(0);
00753 }
00754 }
00755
00757 template <typename T>
00758 typename Enable_If<Is_Native_Or_Checked<T>::value, Result>::type
00759 output(std::ostream& os, const T& x,
00760 const Numeric_Format& fmt, Rounding_Dir dir) {
00761 return check_result(Checked::output_ext<typename Native_Checked_From_Wrapper<T>::Policy>
00762 (os,
00763 Native_Checked_From_Wrapper<T>::raw_value(x),
00764 fmt,
00765 rounding_dir(dir)),
00766 dir);
00767 }
00768
00770 template <typename T, typename Policy>
00771 inline std::ostream&
00772 operator<<(std::ostream& os, const Checked_Number<T, Policy>& x) {
00773 Policy::handle_result(output(os, x, Numeric_Format(), ROUND_IGNORE));
00774 return os;
00775 }
00776
00778 template <typename T>
00779 typename Enable_If<Is_Native_Or_Checked<T>::value, Result>::type
00780 input(T& x, std::istream& is, Rounding_Dir dir) {
00781 return check_result(Checked::input_ext<typename Native_Checked_To_Wrapper<T>::Policy>
00782 (Native_Checked_To_Wrapper<T>::raw_value(x),
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
00819 template <typename T, typename Policy>
00820 inline void
00821 swap(Checked_Number<T, Policy>& x, Checked_Number<T, Policy>& y) {
00822 using std::swap;
00823 swap(x.raw_value(), y.raw_value());
00824 }
00825
00826 template <typename T>
00827 inline void
00828 maybe_reset_fpu_inexact() {
00829 if (FPU_Related<T>::value)
00830 return fpu_reset_inexact();
00831 }
00832
00833 template <typename T>
00834 inline int
00835 maybe_check_fpu_inexact() {
00836 if (FPU_Related<T>::value)
00837 return fpu_check_inexact();
00838 else
00839 return 0;
00840 }
00841
00842 }
00843
00844 #endif // !defined(PPL_Checked_Number_inlines_hh)