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