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