1 /* Specializations of std::numeric_limits for "checked" types.
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_numeric_limits_hh
25 #define PPL_checked_numeric_limits_hh 1
26 
27 #include "Checked_Number_defs.hh"
28 #include "checked_int_inlines.hh"
29 #include <limits>
30 
31 namespace std {
32 
33 using namespace Parma_Polyhedra_Library;
34 
35 #define PPL_SPECIALIZE_LIMITS_INT(T)                                    \
36   /*! \brief Partial specialization of std::numeric_limits. */          \
37   template <typename Policy>                                            \
38   class numeric_limits<Checked_Number<PPL_U(T), Policy> >              \
39     : public numeric_limits<PPL_U(T)> {                                 \
40   private:                                                              \
41     typedef Checked_Number<PPL_U(T), Policy> Type;                      \
42                                                                         \
43   public:                                                               \
44     static const bool has_infinity = Policy::has_infinity;              \
45     static const bool has_quiet_NaN =  Policy::has_nan;                 \
46                                                                         \
47     static Type min() {                                                 \
48       Type v;                                                           \
49       v.raw_value() = Checked::Extended_Int<Policy, PPL_U(T)>::min;     \
50       return v;                                                         \
51     }                                                                   \
52                                                                         \
53     static Type max() {                                                 \
54       Type v;                                                           \
55       v.raw_value() = Checked::Extended_Int<Policy, PPL_U(T)>::max;     \
56       return v;                                                         \
57     }                                                                   \
58                                                                         \
59     static Type infinity() {                                            \
60       Type v;                                                           \
61       Checked::assign_special<Policy>(v.raw_value(), VC_PLUS_INFINITY,  \
62                                       ROUND_IGNORE);                    \
63       return v;                                                         \
64     }                                                                   \
65                                                                         \
66     static Type quiet_NaN() {                                           \
67       Type v;                                                           \
68       Checked::assign_special<Policy>(v.raw_value(), VC_NAN,            \
69                                       ROUND_IGNORE);                    \
70       return v;                                                         \
71     }                                                                   \
72   };
73 
74 PPL_SPECIALIZE_LIMITS_INT(char)
75 
76 PPL_SPECIALIZE_LIMITS_INT(signed char)
77 PPL_SPECIALIZE_LIMITS_INT(signed short)
78 PPL_SPECIALIZE_LIMITS_INT(signed int)
79 PPL_SPECIALIZE_LIMITS_INT(signed long)
80 PPL_SPECIALIZE_LIMITS_INT(signed long long)
81 
82 PPL_SPECIALIZE_LIMITS_INT(unsigned char)
83 PPL_SPECIALIZE_LIMITS_INT(unsigned short)
84 PPL_SPECIALIZE_LIMITS_INT(unsigned int)
85 PPL_SPECIALIZE_LIMITS_INT(unsigned long)
86 PPL_SPECIALIZE_LIMITS_INT(unsigned long long)
87 
88 #undef PPL_SPECIALIZE_LIMITS_INT
89 
90 #define PPL_SPECIALIZE_LIMITS_FLOAT(T)                                  \
91   /*! \brief Partial specialization of std::numeric_limits. */          \
92   template <typename Policy>                                            \
93   struct numeric_limits<Checked_Number<PPL_U(T), Policy> >              \
94     : public numeric_limits<PPL_U(T)> {                                 \
95 };
96 
97 #if PPL_SUPPORTED_FLOAT
98 PPL_SPECIALIZE_LIMITS_FLOAT(float)
99 #endif
100 #if PPL_SUPPORTED_DOUBLE
101 PPL_SPECIALIZE_LIMITS_FLOAT(double)
102 #endif
103 #if PPL_SUPPORTED_LONG_DOUBLE
104 PPL_SPECIALIZE_LIMITS_FLOAT(long double)
105 #endif
106 
107 #undef PPL_SPECIALIZE_LIMITS_FLOAT
108 
109 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
110 //! Partial specialization of std::numeric_limits.
111 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
112 template <typename Policy>
113 class
114 numeric_limits<Checked_Number<mpz_class, Policy> >
115   : public numeric_limits<mpz_class> {
116 private:
117   typedef Checked_Number<mpz_class, Policy> Type;
118 
119 public:
120   static const bool has_infinity = Policy::has_infinity;
121   static const bool has_quiet_NaN =  Policy::has_nan;
122 
infinity()123   static Type infinity() {
124     Type v;
125     Checked::assign_special<Policy>(v.raw_value(), VC_PLUS_INFINITY,
126                                     ROUND_IGNORE);
127     return v;
128   }
129 
quiet_NaN()130   static Type quiet_NaN() {
131     Type v;
132     Checked::assign_special<Policy>(v.raw_value(), VC_NAN, ROUND_IGNORE);
133     return v;
134   }
135 };
136 
137 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
138 //! Partial specialization of std::numeric_limits.
139 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
140 template <typename Policy>
141 class
142 numeric_limits<Checked_Number<mpq_class, Policy> >
143 : public numeric_limits<mpq_class> {
144 private:
145   typedef Checked_Number<mpq_class, Policy> Type;
146 
147 public:
148   static const bool has_infinity = Policy::has_infinity;
149   static const bool has_quiet_NaN =  Policy::has_nan;
150 
infinity()151   static Type infinity() {
152     Type v;
153     Checked::assign_special<Policy>(v.raw_value(), VC_PLUS_INFINITY,
154                                     ROUND_IGNORE);
155     return v;
156   }
157 
quiet_NaN()158   static Type quiet_NaN() {
159     Type v;
160     Checked::assign_special<Policy>(v.raw_value(), VC_NAN, ROUND_IGNORE);
161     return v;
162   }
163 };
164 
165 } // namespace std
166 
167 #endif // !defined(PPL_checked_numeric_limits_hh)
168