1 /* Checked_Number class declaration. 2 Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it> 3 Copyright (C) 2010-2016 BUGSENG srl (http://bugseng.com) 4 5 This file is part of the Parma Polyhedra Library (PPL). 6 7 The PPL is free software; you can redistribute it and/or modify it 8 under the terms of the GNU General Public License as published by the 9 Free Software Foundation; either version 3 of the License, or (at your 10 option) any later version. 11 12 The PPL is distributed in the hope that it will be useful, but WITHOUT 13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software Foundation, 19 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA. 20 21 For the most up-to-date information see the Parma Polyhedra Library 22 site: http://bugseng.com/products/ppl/ . */ 23 24 #ifndef PPL_Checked_Number_defs_hh 25 #define PPL_Checked_Number_defs_hh 1 26 27 #include "Checked_Number_types.hh" 28 #include "checked_defs.hh" 29 #include "meta_programming.hh" 30 #include "Slow_Copy.hh" 31 #include <iosfwd> 32 33 namespace Parma_Polyhedra_Library { 34 35 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 36 /*! \ingroup PPL_CXX_interface */ 37 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 38 struct Extended_Number_Policy { 39 const_bool_nodef(check_overflow, true); 40 const_bool_nodef(check_inf_add_inf, false); 41 const_bool_nodef(check_inf_sub_inf, false); 42 const_bool_nodef(check_inf_mul_zero, false); 43 const_bool_nodef(check_div_zero, false); 44 const_bool_nodef(check_inf_div_inf, false); 45 const_bool_nodef(check_inf_mod, false); 46 const_bool_nodef(check_sqrt_neg, false); 47 const_bool_nodef(has_nan, true); 48 const_bool_nodef(has_infinity, true); 49 50 // `convertible' is intentionally not defined: the compile time 51 // error on conversions is the expected behavior. 52 53 const_bool_nodef(fpu_check_inexact, true); 54 const_bool_nodef(fpu_check_nan_result, true); 55 56 // ROUND_DEFAULT_CONSTRUCTOR is intentionally not defined. 57 // ROUND_DEFAULT_OPERATOR is intentionally not defined. 58 // ROUND_DEFAULT_FUNCTION is intentionally not defined. 59 // ROUND_DEFAULT_INPUT is intentionally not defined. 60 // ROUND_DEFAULT_OUTPUT is intentionally not defined. 61 62 static void handle_result(Result r); 63 }; 64 65 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 66 //! A policy checking for overflows. 67 /*! \ingroup PPL_CXX_interface */ 68 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 69 template <typename T> 70 struct Check_Overflow_Policy { 71 const_bool_nodef(check_overflow, true); 72 const_bool_nodef(check_inf_add_inf, false); 73 const_bool_nodef(check_inf_sub_inf, false); 74 const_bool_nodef(check_inf_mul_zero, false); 75 const_bool_nodef(check_div_zero, false); 76 const_bool_nodef(check_inf_div_inf, false); 77 const_bool_nodef(check_inf_mod, false); 78 const_bool_nodef(check_sqrt_neg, false); 79 const_bool_nodef(has_nan, std::numeric_limits<T>::has_quiet_NaN); 80 const_bool_nodef(has_infinity, std::numeric_limits<T>::has_infinity); 81 const_bool_nodef(convertible, true); 82 const_bool_nodef(fpu_check_inexact, true); 83 const_bool_nodef(fpu_check_nan_result, true); 84 }; 85 86 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 87 /*! \ingroup PPL_CXX_interface */ 88 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 89 template <typename T, typename Enable = void> 90 struct Native_Checked_From_Wrapper; 91 92 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 93 /*! \ingroup PPL_CXX_interface */ 94 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 95 template <typename T> 96 struct Native_Checked_From_Wrapper<T, typename Enable_If<Is_Native<T>::value>::type> { 97 typedef Checked_Number_Transparent_Policy<T> Policy; raw_valueParma_Polyhedra_Library::Native_Checked_From_Wrapper98 static const T& raw_value(const T& v) { 99 return v; 100 } 101 }; 102 103 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 104 /*! \ingroup PPL_CXX_interface */ 105 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 106 template <typename T, typename P> 107 struct Native_Checked_From_Wrapper<Checked_Number<T, P> > { 108 typedef P Policy; raw_valueParma_Polyhedra_Library::Native_Checked_From_Wrapper109 static const T& raw_value(const Checked_Number<T, P>& v) { 110 return v.raw_value(); 111 } 112 }; 113 114 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 115 /*! \ingroup PPL_CXX_interface */ 116 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 117 template <typename T, typename Enable = void> 118 struct Native_Checked_To_Wrapper; 119 120 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 121 /*! \ingroup PPL_CXX_interface */ 122 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 123 template <typename T> 124 struct Native_Checked_To_Wrapper<T, typename Enable_If<Is_Native<T>::value>::type> { 125 typedef Check_Overflow_Policy<T> Policy; raw_valueParma_Polyhedra_Library::Native_Checked_To_Wrapper126 static T& raw_value(T& v) { 127 return v; 128 } 129 }; 130 131 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 132 /*! \ingroup PPL_CXX_interface */ 133 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 134 template <typename T, typename P> 135 struct Native_Checked_To_Wrapper<Checked_Number<T, P> > { 136 typedef P Policy; raw_valueParma_Polyhedra_Library::Native_Checked_To_Wrapper137 static T& raw_value(Checked_Number<T, P>& v) { 138 return v.raw_value(); 139 } 140 }; 141 142 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 143 /*! \ingroup PPL_CXX_interface */ 144 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 145 template <typename T> 146 struct Is_Checked : public False { }; 147 148 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 149 /*! \ingroup PPL_CXX_interface */ 150 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 151 template <typename T, typename P> 152 struct Is_Checked<Checked_Number<T, P> > : public True { }; 153 154 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 155 /*! \ingroup PPL_CXX_interface */ 156 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 157 template <typename T> 158 struct Is_Native_Or_Checked 159 : public Bool<Is_Native<T>::value || Is_Checked<T>::value> { }; 160 161 //! A wrapper for numeric types implementing a given policy. 162 /*! \ingroup PPL_CXX_interface 163 The wrapper and related functions implement an interface which is common 164 to all kinds of coefficient types, therefore allowing for a uniform 165 coding style. This class also implements the policy encoded by the 166 second template parameter. The default policy is to perform the detection 167 of overflow errors. 168 */ 169 template <typename T, typename Policy> 170 class Checked_Number { 171 public: 172 173 //! \name Constructors 174 //@{ 175 176 //! Default constructor. 177 Checked_Number(); 178 179 //! Copy constructor. 180 Checked_Number(const Checked_Number& y); 181 182 //! Direct initialization from a Checked_Number and rounding mode. 183 template <typename From, typename From_Policy> 184 Checked_Number(const Checked_Number<From, From_Policy>& y, Rounding_Dir dir); 185 186 //! Direct initialization from a plain char and rounding mode. 187 Checked_Number(char y, Rounding_Dir dir); 188 189 //! Direct initialization from a signed char and rounding mode. 190 Checked_Number(signed char y, Rounding_Dir dir); 191 192 //! Direct initialization from a signed short and rounding mode. 193 Checked_Number(signed short y, Rounding_Dir dir); 194 195 //! Direct initialization from a signed int and rounding mode. 196 Checked_Number(signed int y, Rounding_Dir dir); 197 198 //! Direct initialization from a signed long and rounding mode. 199 Checked_Number(signed long y, Rounding_Dir dir); 200 201 //! Direct initialization from a signed long long and rounding mode. 202 Checked_Number(signed long long y, Rounding_Dir dir); 203 204 //! Direct initialization from an unsigned char and rounding mode. 205 Checked_Number(unsigned char y, Rounding_Dir dir); 206 207 //! Direct initialization from an unsigned short and rounding mode. 208 Checked_Number(unsigned short y, Rounding_Dir dir); 209 210 //! Direct initialization from an unsigned int and rounding mode. 211 Checked_Number(unsigned int y, Rounding_Dir dir); 212 213 //! Direct initialization from an unsigned long and rounding mode. 214 Checked_Number(unsigned long y, Rounding_Dir dir); 215 216 //! Direct initialization from an unsigned long long and rounding mode. 217 Checked_Number(unsigned long long y, Rounding_Dir dir); 218 219 #if PPL_SUPPORTED_FLOAT 220 //! Direct initialization from a float and rounding mode. 221 Checked_Number(float y, Rounding_Dir dir); 222 #endif 223 224 #if PPL_SUPPORTED_DOUBLE 225 //! Direct initialization from a double and rounding mode. 226 Checked_Number(double y, Rounding_Dir dir); 227 #endif 228 229 #if PPL_SUPPORTED_LONG_DOUBLE 230 //! Direct initialization from a long double and rounding mode. 231 Checked_Number(long double y, Rounding_Dir dir); 232 #endif 233 234 //! Direct initialization from a rational and rounding mode. 235 Checked_Number(const mpq_class& y, Rounding_Dir dir); 236 237 //! Direct initialization from an unbounded integer and rounding mode. 238 Checked_Number(const mpz_class& y, Rounding_Dir dir); 239 240 //! Direct initialization from a C string and rounding mode. 241 Checked_Number(const char* y, Rounding_Dir dir); 242 243 //! Direct initialization from special and rounding mode. 244 template <typename From> 245 Checked_Number(const From&, Rounding_Dir dir, 246 typename Enable_If<Is_Special<From>::value, bool>::type 247 ignored = false); 248 249 //! Direct initialization from a Checked_Number, default rounding mode. 250 template <typename From, typename From_Policy> 251 explicit Checked_Number(const Checked_Number<From, From_Policy>& y); 252 253 //! Direct initialization from a plain char, default rounding mode. 254 Checked_Number(char y); 255 256 //! Direct initialization from a signed char, default rounding mode. 257 Checked_Number(signed char y); 258 259 //! Direct initialization from a signed short, default rounding mode. 260 Checked_Number(signed short y); 261 262 //! Direct initialization from a signed int, default rounding mode. 263 Checked_Number(signed int y); 264 265 //! Direct initialization from a signed long, default rounding mode. 266 Checked_Number(signed long y); 267 268 //! Direct initialization from a signed long long, default rounding mode. 269 Checked_Number(signed long long y); 270 271 //! Direct initialization from an unsigned char, default rounding mode. 272 Checked_Number(unsigned char y); 273 274 //! Direct initialization from an unsigned short, default rounding mode. 275 Checked_Number(unsigned short y); 276 277 //! Direct initialization from an unsigned int, default rounding mode. 278 Checked_Number(unsigned int y); 279 280 //! Direct initialization from an unsigned long, default rounding mode. 281 Checked_Number(unsigned long y); 282 283 //! Direct initialization from an unsigned long long, default rounding mode. 284 Checked_Number(unsigned long long y); 285 286 //! Direct initialization from a float, default rounding mode. 287 Checked_Number(float y); 288 289 //! Direct initialization from a double, default rounding mode. 290 Checked_Number(double y); 291 292 //! Direct initialization from a long double, default rounding mode. 293 Checked_Number(long double y); 294 295 //! Direct initialization from a rational, default rounding mode. 296 Checked_Number(const mpq_class& y); 297 298 //! Direct initialization from an unbounded integer, default rounding mode. 299 Checked_Number(const mpz_class& y); 300 301 //! Direct initialization from a C string, default rounding mode. 302 Checked_Number(const char* y); 303 304 //! Direct initialization from special, default rounding mode 305 template <typename From> 306 Checked_Number(const From&, typename Enable_If<Is_Special<From>::value, bool>::type ignored = false); 307 308 309 //@} // Constructors 310 311 //! \name Accessors and Conversions 312 //@{ 313 314 //! Conversion operator: returns a copy of the underlying numeric value. 315 operator T() const; 316 317 //! Returns a reference to the underlying numeric value. 318 T& raw_value(); 319 320 //! Returns a const reference to the underlying numeric value. 321 const T& raw_value() const; 322 323 //@} // Accessors and Conversions 324 325 //! Checks if all the invariants are satisfied. 326 bool OK() const; 327 328 //! Classifies *this. 329 /*! 330 Returns the appropriate Result characterizing: 331 - whether \p *this is NaN, 332 if \p nan is <CODE>true</CODE>; 333 - whether \p *this is a (positive or negative) infinity, 334 if \p inf is <CODE>true</CODE>; 335 - the sign of \p *this, 336 if \p sign is <CODE>true</CODE>. 337 */ 338 Result classify(bool nan = true, bool inf = true, bool sign = true) const; 339 340 //! \name Assignment Operators 341 //@{ 342 343 //! Assignment operator. 344 Checked_Number& operator=(const Checked_Number& y); 345 346 //! Assignment operator. 347 template <typename From> 348 Checked_Number& operator=(const From& y); 349 350 //! Add and assign operator. 351 template <typename From_Policy> 352 Checked_Number& operator+=(const Checked_Number<T, From_Policy>& y); 353 354 //! Add and assign operator. 355 Checked_Number& operator+=(const T& y); 356 357 //! Add and assign operator. 358 template <typename From> 359 typename Enable_If<Is_Native_Or_Checked<From>::value, 360 Checked_Number<T, Policy>&>::type 361 operator+=(const From& y); 362 363 //! Subtract and assign operator. 364 template <typename From_Policy> 365 Checked_Number& operator-=(const Checked_Number<T, From_Policy>& y); 366 367 //! Subtract and assign operator. 368 Checked_Number& operator-=(const T& y); 369 370 //! Subtract and assign operator. 371 template <typename From> 372 typename Enable_If<Is_Native_Or_Checked<From>::value, 373 Checked_Number<T, Policy>&>::type 374 operator-=(const From& y); 375 376 //! Multiply and assign operator. 377 template <typename From_Policy> 378 Checked_Number& operator*=(const Checked_Number<T, From_Policy>& y); 379 380 //! Multiply and assign operator. 381 Checked_Number& operator*=(const T& y); 382 383 //! Multiply and assign operator. 384 template <typename From> 385 typename Enable_If<Is_Native_Or_Checked<From>::value, 386 Checked_Number<T, Policy>&>::type 387 operator*=(const From& y); 388 389 //! Divide and assign operator. 390 template <typename From_Policy> 391 Checked_Number& operator/=(const Checked_Number<T, From_Policy>& y); 392 393 //! Divide and assign operator. 394 Checked_Number& operator/=(const T& y); 395 396 //! Divide and assign operator. 397 template <typename From> 398 typename Enable_If<Is_Native_Or_Checked<From>::value, 399 Checked_Number<T, Policy>&>::type 400 operator/=(const From& y); 401 402 //! Compute remainder and assign operator. 403 template <typename From_Policy> 404 Checked_Number& operator%=(const Checked_Number<T, From_Policy>& y); 405 406 //! Compute remainder and assign operator. 407 Checked_Number& operator%=(const T& y); 408 409 //! Compute remainder and assign operator. 410 template <typename From> 411 typename Enable_If<Is_Native_Or_Checked<From>::value, 412 Checked_Number<T, Policy>& >::type 413 operator%=(const From& y); 414 415 //@} // Assignment Operators 416 417 418 //! \name Increment and Decrement Operators 419 //@{ 420 421 //! Pre-increment operator. 422 Checked_Number& operator++(); 423 424 //! Post-increment operator. 425 Checked_Number operator++(int); 426 427 //! Pre-decrement operator. 428 Checked_Number& operator--(); 429 430 //! Post-decrement operator. 431 Checked_Number operator--(int); 432 433 //@} // Increment and Decrement Operators 434 435 private: 436 //! The underlying numeric value. 437 T v; 438 }; 439 440 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 441 /*! \ingroup PPL_CXX_interface */ 442 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 443 template <typename T, typename P> 444 struct Slow_Copy<Checked_Number<T, P> > : public Bool<Slow_Copy<T>::value> {}; 445 446 /*! \relates Checked_Number */ 447 template <typename T> 448 typename Enable_If<Is_Native_Or_Checked<T>::value, bool>::type 449 is_not_a_number(const T& x); 450 451 /*! \relates Checked_Number */ 452 template <typename T> 453 typename Enable_If<Is_Native_Or_Checked<T>::value, bool>::type 454 is_minus_infinity(const T& x); 455 456 /*! \relates Checked_Number */ 457 template <typename T> 458 typename Enable_If<Is_Native_Or_Checked<T>::value, bool>::type 459 is_plus_infinity(const T& x); 460 461 /*! \relates Checked_Number */ 462 template <typename T> 463 typename Enable_If<Is_Native_Or_Checked<T>::value, int>::type 464 infinity_sign(const T& x); 465 466 /*! \relates Checked_Number */ 467 template <typename T> 468 typename Enable_If<Is_Native_Or_Checked<T>::value, bool>::type 469 is_integer(const T& x); 470 471 /*! \relates Checked_Number */ 472 template <typename To, typename From> 473 typename Enable_If<Is_Native_Or_Checked<To>::value && Is_Special<From>::value, Result>::type 474 construct(To& to, const From& x, Rounding_Dir dir); 475 476 /*! \relates Checked_Number */ 477 template <typename To, typename From> 478 typename Enable_If<Is_Native_Or_Checked<To>::value && Is_Special<From>::value, Result>::type 479 assign_r(To& to, const From& x, Rounding_Dir dir); 480 481 /*! \relates Checked_Number */ 482 template <typename To> 483 typename Enable_If<Is_Native_Or_Checked<To>::value, Result>::type 484 assign_r(To& to, const char* x, Rounding_Dir dir); 485 486 /*! \relates Checked_Number */ 487 template <typename To, typename To_Policy> 488 typename Enable_If<Is_Native_Or_Checked<To>::value, Result>::type 489 assign_r(To& to, char* x, Rounding_Dir dir); 490 491 #define PPL_DECLARE_FUNC1_A(name) \ 492 template <typename To, typename From> \ 493 typename Enable_If<Is_Native_Or_Checked<To>::value \ 494 && Is_Native_Or_Checked<From>::value, \ 495 Result>::type \ 496 PPL_U(name)(To& to, const From& x, Rounding_Dir dir); 497 498 PPL_DECLARE_FUNC1_A(assign_r) 499 PPL_DECLARE_FUNC1_A(floor_assign_r) 500 PPL_DECLARE_FUNC1_A(ceil_assign_r) 501 PPL_DECLARE_FUNC1_A(trunc_assign_r) 502 PPL_DECLARE_FUNC1_A(neg_assign_r) 503 PPL_DECLARE_FUNC1_A(abs_assign_r) 504 PPL_DECLARE_FUNC1_A(sqrt_assign_r) 505 506 #undef PPL_DECLARE_FUNC1_A 507 508 #define PPL_DECLARE_FUNC1_B(name) \ 509 template <typename To, typename From> \ 510 typename Enable_If<Is_Native_Or_Checked<To>::value \ 511 && Is_Native_Or_Checked<From>::value, \ 512 Result>::type \ 513 PPL_U(name)(To& to, const From& x, unsigned int exp, Rounding_Dir dir); 514 515 PPL_DECLARE_FUNC1_B(add_2exp_assign_r) 516 PPL_DECLARE_FUNC1_B(sub_2exp_assign_r) 517 PPL_DECLARE_FUNC1_B(mul_2exp_assign_r) 518 PPL_DECLARE_FUNC1_B(div_2exp_assign_r) 519 PPL_DECLARE_FUNC1_B(smod_2exp_assign_r) 520 PPL_DECLARE_FUNC1_B(umod_2exp_assign_r) 521 522 #undef PPL_DECLARE_FUNC1_B 523 524 #define PPL_DECLARE_FUNC2(name) \ 525 template <typename To, typename From1, typename From2> \ 526 typename Enable_If<Is_Native_Or_Checked<To>::value \ 527 && Is_Native_Or_Checked<From1>::value \ 528 && Is_Native_Or_Checked<From2>::value, \ 529 Result>::type \ 530 PPL_U(name)(To& to, const From1& x, const From2& y, Rounding_Dir dir); 531 532 PPL_DECLARE_FUNC2(add_assign_r) 533 PPL_DECLARE_FUNC2(sub_assign_r) 534 PPL_DECLARE_FUNC2(mul_assign_r) 535 PPL_DECLARE_FUNC2(div_assign_r) 536 PPL_DECLARE_FUNC2(idiv_assign_r) 537 PPL_DECLARE_FUNC2(rem_assign_r) 538 PPL_DECLARE_FUNC2(gcd_assign_r) 539 PPL_DECLARE_FUNC2(lcm_assign_r) 540 PPL_DECLARE_FUNC2(add_mul_assign_r) 541 PPL_DECLARE_FUNC2(sub_mul_assign_r) 542 543 #undef PPL_DECLARE_FUNC2 544 545 #define PPL_DECLARE_FUNC4(name) \ 546 template <typename To1, typename To2, typename To3, \ 547 typename From1, typename From2> \ 548 typename Enable_If<Is_Native_Or_Checked<To1>::value \ 549 && Is_Native_Or_Checked<To2>::value \ 550 && Is_Native_Or_Checked<To3>::value \ 551 && Is_Native_Or_Checked<From1>::value \ 552 && Is_Native_Or_Checked<From2>::value, \ 553 Result>::type \ 554 PPL_U(name)(To1& to, To2& s, To3& t, \ 555 const From1& x, const From2& y, \ 556 Rounding_Dir dir); 557 558 PPL_DECLARE_FUNC4(gcdext_assign_r) 559 560 #undef PPL_DECLARE_FUNC4 561 562 //! \name Accessor Functions 563 //@{ 564 565 //@} // Accessor Functions 566 567 //! \name Memory Size Inspection Functions 568 //@{ 569 570 //! Returns the total size in bytes of the memory occupied by \p x. 571 /*! \relates Checked_Number */ 572 template <typename T, typename Policy> 573 memory_size_type 574 total_memory_in_bytes(const Checked_Number<T, Policy>& x); 575 576 //! Returns the size in bytes of the memory managed by \p x. 577 /*! \relates Checked_Number */ 578 template <typename T, typename Policy> 579 memory_size_type 580 external_memory_in_bytes(const Checked_Number<T, Policy>& x); 581 582 //@} // Memory Size Inspection Functions 583 584 //! \name Arithmetic Operators 585 //@{ 586 587 //! Unary plus operator. 588 /*! \relates Checked_Number */ 589 template <typename T, typename Policy> 590 Checked_Number<T, Policy> 591 operator+(const Checked_Number<T, Policy>& x); 592 593 //! Unary minus operator. 594 /*! \relates Checked_Number */ 595 template <typename T, typename Policy> 596 Checked_Number<T, Policy> 597 operator-(const Checked_Number<T, Policy>& x); 598 599 //! Assigns to \p x largest integral value not greater than \p x. 600 /*! \relates Checked_Number */ 601 template <typename T, typename Policy> 602 void 603 floor_assign(Checked_Number<T, Policy>& x); 604 605 //! Assigns to \p x largest integral value not greater than \p y. 606 /*! \relates Checked_Number */ 607 template <typename T, typename Policy> 608 void 609 floor_assign(Checked_Number<T, Policy>& x, const Checked_Number<T, Policy>& y); 610 611 //! Assigns to \p x smallest integral value not less than \p x. 612 /*! \relates Checked_Number */ 613 template <typename T, typename Policy> 614 void 615 ceil_assign(Checked_Number<T, Policy>& x); 616 617 //! Assigns to \p x smallest integral value not less than \p y. 618 /*! \relates Checked_Number */ 619 template <typename T, typename Policy> 620 void 621 ceil_assign(Checked_Number<T, Policy>& x, const Checked_Number<T, Policy>& y); 622 623 //! Round \p x to the nearest integer not larger in absolute value. 624 /*! \relates Checked_Number */ 625 template <typename T, typename Policy> 626 void 627 trunc_assign(Checked_Number<T, Policy>& x); 628 629 //! Assigns to \p x the value of \p y rounded to the nearest integer not larger in absolute value. 630 /*! \relates Checked_Number */ 631 template <typename T, typename Policy> 632 void 633 trunc_assign(Checked_Number<T, Policy>& x, const Checked_Number<T, Policy>& y); 634 635 //! Assigns to \p x its negation. 636 /*! \relates Checked_Number */ 637 template <typename T, typename Policy> 638 void 639 neg_assign(Checked_Number<T, Policy>& x); 640 641 //! Assigns to \p x the negation of \p y. 642 /*! \relates Checked_Number */ 643 template <typename T, typename Policy> 644 void 645 neg_assign(Checked_Number<T, Policy>& x, const Checked_Number<T, Policy>& y); 646 647 //! Assigns to \p x its absolute value. 648 /*! \relates Checked_Number */ 649 template <typename T, typename Policy> 650 void 651 abs_assign(Checked_Number<T, Policy>& x); 652 653 //! Assigns to \p x the absolute value of \p y. 654 /*! \relates Checked_Number */ 655 template <typename T, typename Policy> 656 void 657 abs_assign(Checked_Number<T, Policy>& x, const Checked_Number<T, Policy>& y); 658 659 //! Assigns to \p x the value <CODE>x + y * z</CODE>. 660 /*! \relates Checked_Number */ 661 template <typename T, typename Policy> 662 void 663 add_mul_assign(Checked_Number<T, Policy>& x, 664 const Checked_Number<T, Policy>& y, 665 const Checked_Number<T, Policy>& z); 666 667 //! Assigns to \p x the value <CODE>x - y * z</CODE>. 668 /*! \relates Checked_Number */ 669 template <typename T, typename Policy> 670 void 671 sub_mul_assign(Checked_Number<T, Policy>& x, 672 const Checked_Number<T, Policy>& y, 673 const Checked_Number<T, Policy>& z); 674 675 //! Assigns to \p x the greatest common divisor of \p y and \p z. 676 /*! \relates Checked_Number */ 677 template <typename T, typename Policy> 678 void 679 gcd_assign(Checked_Number<T, Policy>& x, 680 const Checked_Number<T, Policy>& y, 681 const Checked_Number<T, Policy>& z); 682 683 /*! \brief 684 Assigns to \p x the greatest common divisor of \p y and \p z, 685 setting \p s and \p t such that s*y + t*z = x = gcd(y, z). 686 */ 687 /*! \relates Checked_Number */ 688 template <typename T, typename Policy> 689 void 690 gcdext_assign(Checked_Number<T, Policy>& x, 691 Checked_Number<T, Policy>& s, 692 Checked_Number<T, Policy>& t, 693 const Checked_Number<T, Policy>& y, 694 const Checked_Number<T, Policy>& z); 695 696 //! Assigns to \p x the least common multiple of \p y and \p z. 697 /*! \relates Checked_Number */ 698 template <typename T, typename Policy> 699 void 700 lcm_assign(Checked_Number<T, Policy>& x, 701 const Checked_Number<T, Policy>& y, 702 const Checked_Number<T, Policy>& z); 703 704 //! Assigns to \p x the value \f$ y \cdot 2^\mathtt{exp} \f$. 705 /*! \relates Checked_Number */ 706 template <typename T, typename Policy> 707 void 708 mul_2exp_assign(Checked_Number<T, Policy>& x, 709 const Checked_Number<T, Policy>& y, 710 unsigned int exp); 711 712 //! Assigns to \p x the value \f$ y / 2^\mathtt{exp} \f$. 713 /*! \relates Checked_Number */ 714 template <typename T, typename Policy> 715 void 716 div_2exp_assign(Checked_Number<T, Policy>& x, 717 const Checked_Number<T, Policy>& y, 718 unsigned int exp); 719 720 /*! \brief 721 If \p z divides \p y, assigns to \p x the quotient of the integer 722 division of \p y and \p z. 723 724 \relates Checked_Number 725 The behavior is undefined if \p z does not divide \p y. 726 */ 727 template <typename T, typename Policy> 728 void 729 exact_div_assign(Checked_Number<T, Policy>& x, 730 const Checked_Number<T, Policy>& y, 731 const Checked_Number<T, Policy>& z); 732 733 //! Assigns to \p x the integer square root of \p y. 734 /*! \relates Checked_Number */ 735 template <typename T, typename Policy> 736 void sqrt_assign(Checked_Number<T, Policy>& x, 737 const Checked_Number<T, Policy>& y); 738 739 //@} // Arithmetic Operators 740 741 742 //! \name Relational Operators and Comparison Functions 743 //@{ 744 745 //! Equality operator. 746 /*! \relates Checked_Number */ 747 template <typename T1, typename T2> 748 inline 749 typename Enable_If<Is_Native_Or_Checked<T1>::value 750 && Is_Native_Or_Checked<T2>::value 751 && (Is_Checked<T1>::value || Is_Checked<T2>::value), 752 bool>::type 753 operator==(const T1& x, const T2& y); 754 755 /*! \relates Checked_Number */ 756 template <typename T1, typename T2> 757 inline typename Enable_If<Is_Native_Or_Checked<T1>::value 758 && Is_Native_Or_Checked<T2>::value, 759 bool>::type 760 equal(const T1& x, const T2& y); 761 762 //! Disequality operator. 763 /*! \relates Checked_Number */ 764 template <typename T1, typename T2> 765 inline 766 typename Enable_If<Is_Native_Or_Checked<T1>::value 767 && Is_Native_Or_Checked<T2>::value 768 && (Is_Checked<T1>::value || Is_Checked<T2>::value), 769 bool>::type 770 operator!=(const T1& x, const T2& y); 771 772 /*! \relates Checked_Number */ 773 template <typename T1, typename T2> 774 inline typename Enable_If<Is_Native_Or_Checked<T1>::value 775 && Is_Native_Or_Checked<T2>::value, 776 bool>::type 777 not_equal(const T1& x, const T2& y); 778 779 //! Greater than or equal to operator. 780 /*! \relates Checked_Number */ 781 template <typename T1, typename T2> 782 inline 783 typename Enable_If<Is_Native_Or_Checked<T1>::value 784 && Is_Native_Or_Checked<T2>::value 785 && (Is_Checked<T1>::value || Is_Checked<T2>::value), 786 bool>::type 787 operator>=(const T1& x, const T2& y); 788 789 /*! \relates Checked_Number */ 790 template <typename T1, typename T2> 791 inline typename Enable_If<Is_Native_Or_Checked<T1>::value 792 && Is_Native_Or_Checked<T2>::value, 793 bool>::type 794 greater_or_equal(const T1& x, const T2& y); 795 796 //! Greater than operator. 797 /*! \relates Checked_Number */ 798 template <typename T1, typename T2> 799 inline 800 typename Enable_If<Is_Native_Or_Checked<T1>::value 801 && Is_Native_Or_Checked<T2>::value 802 && (Is_Checked<T1>::value || Is_Checked<T2>::value), 803 bool>::type 804 operator>(const T1& x, const T2& y); 805 806 /*! \relates Checked_Number */ 807 template <typename T1, typename T2> 808 inline typename Enable_If<Is_Native_Or_Checked<T1>::value 809 && Is_Native_Or_Checked<T2>::value, 810 bool>::type 811 greater_than(const T1& x, const T2& y); 812 813 //! Less than or equal to operator. 814 /*! \relates Checked_Number */ 815 template <typename T1, typename T2> 816 inline 817 typename Enable_If<Is_Native_Or_Checked<T1>::value 818 && Is_Native_Or_Checked<T2>::value 819 && (Is_Checked<T1>::value || Is_Checked<T2>::value), 820 bool>::type 821 operator<=(const T1& x, const T2& y); 822 823 /*! \relates Checked_Number */ 824 template <typename T1, typename T2> 825 inline typename Enable_If<Is_Native_Or_Checked<T1>::value 826 && Is_Native_Or_Checked<T2>::value, 827 bool>::type 828 less_or_equal(const T1& x, const T2& y); 829 830 //! Less than operator. 831 /*! \relates Checked_Number */ 832 template <typename T1, typename T2> 833 inline 834 typename Enable_If<Is_Native_Or_Checked<T1>::value 835 && Is_Native_Or_Checked<T2>::value 836 && (Is_Checked<T1>::value || Is_Checked<T2>::value), 837 bool>::type 838 operator<(const T1& x, const T2& y); 839 840 /*! \relates Checked_Number */ 841 template <typename T1, typename T2> 842 inline typename Enable_If<Is_Native_Or_Checked<T1>::value 843 && Is_Native_Or_Checked<T2>::value, 844 bool>::type 845 less_than(const T1& x, const T2& y); 846 847 /*! \brief 848 Returns \f$-1\f$, \f$0\f$ or \f$1\f$ depending on whether the value 849 of \p x is negative, zero or positive, respectively. 850 851 \relates Checked_Number 852 */ 853 template <typename From> 854 inline typename Enable_If<Is_Native_Or_Checked<From>::value, int>::type \ 855 sgn(const From& x); 856 857 /*! \brief 858 Returns a negative, zero or positive value depending on whether 859 \p x is lower than, equal to or greater than \p y, respectively. 860 861 \relates Checked_Number 862 */ 863 template <typename From1, typename From2> 864 inline typename Enable_If<Is_Native_Or_Checked<From1>::value 865 && Is_Native_Or_Checked<From2>::value, 866 int>::type 867 cmp(const From1& x, const From2& y); 868 869 //@} // Relational Operators and Comparison Functions 870 871 //! \name Input-Output Operators 872 //@{ 873 874 /*! \relates Checked_Number */ 875 template <typename T> 876 typename Enable_If<Is_Native_Or_Checked<T>::value, Result>::type 877 output(std::ostream& os, 878 const T& x, 879 const Numeric_Format& format, 880 Rounding_Dir dir); 881 882 //! Output operator. 883 /*! \relates Checked_Number */ 884 template <typename T, typename Policy> 885 std::ostream& 886 operator<<(std::ostream& os, const Checked_Number<T, Policy>& x); 887 888 //! Ascii dump for native or checked. 889 /*! \relates Checked_Number */ 890 template <typename T> 891 typename Enable_If<Is_Native_Or_Checked<T>::value, void>::type 892 ascii_dump(std::ostream& s, const T& t); 893 894 //! Input function. 895 /*! 896 \relates Checked_Number 897 898 \param is 899 Input stream to read from; 900 901 \param x 902 Number (possibly extended) to assign to in case of successful reading; 903 904 \param dir 905 Rounding mode to be applied. 906 907 \return 908 Result of the input operation. Success, success with imprecision, 909 overflow, parsing error: all possibilities are taken into account, 910 checked for, and properly reported. 911 912 This function attempts reading a (possibly extended) number from the given 913 stream \p is, possibly rounding as specified by \p dir, assigning the result 914 to \p x upon success, and returning the appropriate Result. 915 916 The input syntax allows the specification of: 917 - plain base-10 integer numbers as <CODE>34976098</CODE>, 918 <CODE>-77</CODE> and <CODE>+13</CODE>; 919 - base-10 integer numbers in scientific notation as <CODE>15e2</CODE> 920 and <CODE>15*^2</CODE> (both meaning \f$15 \cdot 10^2 = 1500\f$), 921 <CODE>9200e-2</CODE> and <CODE>-18*^+11111111111111111</CODE>; 922 - base-10 rational numbers in fraction notation as 923 <CODE>15/3</CODE> and <CODE>15/-3</CODE>; 924 - base-10 rational numbers in fraction/scientific notation as 925 <CODE>15/30e-1</CODE> (meaning \f$5\f$) and <CODE>15*^-3/29e2</CODE> 926 (meaning \f$3/580000\f$); 927 - base-10 rational numbers in floating point notation as 928 <CODE>71.3</CODE> (meaning \f$713/10\f$) and 929 <CODE>-0.123456</CODE> (meaning \f$-1929/15625\f$); 930 - base-10 rational numbers in floating point scientific notation as 931 <CODE>2.2e-1</CODE> (meaning \f$11/50\f$) and <CODE>-2.20001*^+3</CODE> 932 (meaning \f$-220001/100\f$); 933 - integers and rationals (in fractional, floating point and scientific 934 notations) specified by using Mathematica-style bases, in the range 935 from 2 to 36, as 936 <CODE>2^^11</CODE> (meaning \f$3\f$), 937 <CODE>36^^z</CODE> (meaning \f$35\f$), 938 <CODE>36^^xyz</CODE> (meaning \f$44027\f$), 939 <CODE>2^^11.1</CODE> (meaning \f$7/2\f$), 940 <CODE>10^^2e3</CODE> (meaning \f$2000\f$), 941 <CODE>8^^2e3</CODE> (meaning \f$1024\f$), 942 <CODE>8^^2.1e3</CODE> (meaning \f$1088\f$), 943 <CODE>8^^20402543.120347e7</CODE> (meaning \f$9073863231288\f$), 944 <CODE>8^^2.1</CODE> (meaning \f$17/8\f$); 945 note that the base and the exponent are always written as plain 946 base-10 integer numbers; also, when an ambiguity may arise, the 947 character <CODE>e</CODE> is interpreted as a digit, so that 948 <CODE>16^^1e2</CODE> (meaning \f$482\f$) is different from 949 <CODE>16^^1*^2</CODE> (meaning \f$256\f$); 950 - the C-style hexadecimal prefix <CODE>0x</CODE> is interpreted as 951 the Mathematica-style prefix <CODE>16^^</CODE>; 952 - the C-style binary exponent indicator <CODE>p</CODE> can only be used 953 when base 16 has been specified; if used, the exponent will be 954 applied to base 2 (instead of base 16, as is the case when the 955 indicator <CODE>e</CODE> is used); 956 - special values like <CODE>inf</CODE> and <CODE>+inf</CODE> 957 (meaning \f$+\infty\f$), <CODE>-inf</CODE> (meaning \f$-\infty\f$), 958 and <CODE>nan</CODE> (meaning "not a number"). 959 960 The rationale behind the accepted syntax can be summarized as follows: 961 - if the syntax is accepted by Mathematica, then this function 962 accepts it with the same semantics; 963 - if the syntax is acceptable as standard C++ integer or floating point 964 literal (except for octal notation and type suffixes, which are not 965 supported), then this function accepts it with the same semantics; 966 - natural extensions of the above are accepted with the natural 967 extensions of the semantics; 968 - special values are accepted. 969 970 Valid syntax is more formally and completely specified by the 971 following grammar, with the additional provisos that everything is 972 <EM>case insensitive</EM>, that the syntactic category 973 <CODE>BDIGIT</CODE> is further restricted by the current base 974 and that for all bases above 14, any <CODE>e</CODE> is always 975 interpreted as a digit and never as a delimiter for the exponent part 976 (if such a delimiter is desired, it has to be written as <CODE>*^</CODE>). 977 978 \code 979 number : NAN INF : 'inf' 980 | SIGN INF ; 981 | INF 982 | num NAN : 'nan' 983 | num DIV num ; 984 ; 985 SIGN : '-' 986 num : u_num | '+' 987 | SIGN u_num ; 988 989 u_num : u_num1 EXP : 'e' 990 | HEX u_num1 | 'p' 991 | base BASE u_num1 | '*^' 992 ; ; 993 POINT : '.' 994 u_num1 : mantissa ; 995 | mantissa EXP exponent 996 ; DIV : '/' 997 ; 998 mantissa: bdigits 999 | POINT bdigits MINUS : '-' 1000 | bdigits POINT ; 1001 | bdigits POINT bdigits 1002 ; PLUS : '+' 1003 ; 1004 exponent: SIGN digits 1005 | digits HEX : '0x' 1006 ; ; 1007 1008 bdigits : BDIGIT BASE : '^^' 1009 | bdigits BDIGIT ; 1010 ; 1011 DIGIT : '0' .. '9' 1012 digits : DIGIT ; 1013 | digits DIGIT 1014 ; BDIGIT : '0' .. '9' 1015 | 'a' .. 'z' 1016 ; 1017 \endcode 1018 */ 1019 template <typename T> 1020 typename Enable_If<Is_Native_Or_Checked<T>::value, Result>::type 1021 input(T& x, std::istream& is, Rounding_Dir dir); 1022 1023 //! Input operator. 1024 /*! \relates Checked_Number */ 1025 template <typename T, typename Policy> 1026 std::istream& 1027 operator>>(std::istream& is, Checked_Number<T, Policy>& x); 1028 1029 //! Ascii load for native or checked. 1030 /*! \relates Checked_Number */ 1031 template <typename T> 1032 typename Enable_If<Is_Native_Or_Checked<T>::value, bool>::type 1033 ascii_load(std::ostream& s, T& t); 1034 1035 //@} // Input-Output Operators 1036 1037 void throw_result_exception(Result r); 1038 1039 template <typename T> 1040 T 1041 plus_infinity(); 1042 1043 template <typename T> 1044 T 1045 minus_infinity(); 1046 1047 template <typename T> 1048 T 1049 not_a_number(); 1050 1051 //! Swaps \p x with \p y. 1052 /*! \relates Checked_Number */ 1053 template <typename T, typename Policy> 1054 void swap(Checked_Number<T, Policy>& x, Checked_Number<T, Policy>& y); 1055 1056 template <typename T, typename Policy> 1057 struct FPU_Related<Checked_Number<T, Policy> > : public FPU_Related<T> {}; 1058 1059 template <typename T> 1060 void maybe_reset_fpu_inexact(); 1061 1062 template <typename T> 1063 int maybe_check_fpu_inexact(); 1064 1065 } // namespace Parma_Polyhedra_Library 1066 1067 #include "Checked_Number_inlines.hh" 1068 #include "Checked_Number_templates.hh" 1069 1070 #endif // !defined(PPL_Checked_Number_defs_hh) 1071