1 /* Abstract checked arithmetic function container.
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_defs_hh
25 #define PPL_checked_defs_hh 1
26 
27 #include "mp_std_bits_defs.hh"
28 #include "Temp_defs.hh"
29 #include "Rounding_Dir_defs.hh"
30 #include "Numeric_Format_defs.hh"
31 #include "Float_defs.hh"
32 #include <cassert>
33 #include <iostream>
34 #include <gmpxx.h>
35 
36 namespace Parma_Polyhedra_Library {
37 
38 namespace Checked {
39 
40 
41 // It is a pity that function partial specialization is not permitted
42 // by C++.  To (partly) overcome this limitation, we use class
43 // encapsulated functions and partial specialization of containing
44 // classes.
45 
46 #define PPL_FUNCTION_CLASS(name) name ## _function_struct
47 
48 #define PPL_DECLARE_FUN1_0_0(name, ret_type, qual, type)                \
49   template <typename Policy, typename type>                             \
50   struct PPL_FUNCTION_CLASS(name);                                      \
51   template <typename Policy, typename type>                             \
52   inline ret_type PPL_U(name)(PPL_U(qual) PPL_U(type)& arg) {           \
53     return PPL_FUNCTION_CLASS(name)<Policy, PPL_U(type)>::function(arg); \
54   }
55 
56 #define PPL_DECLARE_FUN1_0_1(name, ret_type, qual, type, after1)        \
57   template <typename Policy, typename type>                             \
58   struct PPL_FUNCTION_CLASS(name);                                      \
59   template <typename Policy, typename type>                             \
60   inline ret_type PPL_U(name)(PPL_U(qual) PPL_U(type)& arg, PPL_U(after1) a1) { \
61     return                                                              \
62       PPL_FUNCTION_CLASS(name)<Policy, PPL_U(type)>::function(arg, a1); \
63   }
64 
65 #define PPL_DECLARE_FUN1_0_2(name, ret_type, qual, type, after1, after2) \
66   template <typename Policy, typename type>                             \
67   struct PPL_FUNCTION_CLASS(name);                                      \
68   template <typename Policy, typename type>                             \
69   inline ret_type PPL_U(name)(PPL_U(qual) PPL_U(type)& arg, PPL_U(after1) a1, \
70                        PPL_U(after2) a2) {                              \
71     return                                                              \
72       PPL_FUNCTION_CLASS(name)<Policy, PPL_U(type)>::function(arg,      \
73                                                               a1, a2);  \
74   }
75 
76 #define PPL_DECLARE_FUN1_0_3(name, ret_type, qual, type,                \
77                              after1, after2, after3)                    \
78   template <typename Policy, typename type>                             \
79   struct PPL_FUNCTION_CLASS(name);                                      \
80   template <typename Policy, typename type>                             \
81   inline ret_type PPL_U(name)(PPL_U(qual) PPL_U(type)& arg,             \
82                        PPL_U(after1) a1, PPL_U(after2) a2,              \
83                        PPL_U(after3) a3) {                              \
84     return                                                              \
85       PPL_FUNCTION_CLASS(name)<Policy, PPL_U(type)>::function(arg,      \
86                                                               a1, a2,   \
87                                                               a3);      \
88   }
89 
90 #define PPL_DECLARE_FUN1_1_1(name, ret_type, before1, qual, type, after1) \
91   template <typename Policy, typename type>                             \
92   struct PPL_FUNCTION_CLASS(name);                                      \
93   template <typename Policy, typename type>                             \
94   inline ret_type PPL_U(name)(PPL_U(before1) b1, PPL_U(qual) PPL_U(type)& arg, \
95                        PPL_U(after1) a1) {                              \
96     return                                                              \
97       PPL_FUNCTION_CLASS(name)<Policy, PPL_U(type)>::function(b1, arg,  \
98                                                               a1);      \
99   }
100 
101 #define PPL_DECLARE_FUN1_1_2(name, ret_type, before1, qual, type,       \
102                              after1, after2)                            \
103   template <typename Policy, typename type>                             \
104   struct PPL_FUNCTION_CLASS(name);                                      \
105   template <typename Policy, typename type>                             \
106   inline ret_type PPL_U(name)(PPL_U(before1) b1, PPL_U(qual) PPL_U(type)& arg, \
107                        PPL_U(after1) a1, PPL_U(after2) a2) {            \
108     return                                                              \
109       PPL_FUNCTION_CLASS(name)<Policy, PPL_U(type)>::function(b1, arg,  \
110                                                               a1, a2);  \
111   }
112 
113 #define PPL_DECLARE_FUN1_2_2(name, ret_type, before1, before2, qual, type, \
114                              after1, after2)                            \
115   template <typename Policy, typename type>                             \
116   struct PPL_FUNCTION_CLASS(name);                                      \
117   template <typename Policy, typename type>                             \
118   inline ret_type PPL_U(name)(PPL_U(before1) b1, PPL_U(before2) b2,     \
119                        PPL_U(qual) PPL_U(type)& arg,                    \
120                        PPL_U(after1) a1, PPL_U(after2) a2) {            \
121     return                                                              \
122       PPL_FUNCTION_CLASS(name)<Policy, PPL_U(type)>::function(b1, b2,   \
123                                                               arg,      \
124                                                               a1, a2);  \
125   }
126 
127 #define PPL_DECLARE_FUN2_0_0(name, ret_type, qual1, type1, qual2, type2) \
128   template <typename Policy1, typename Policy2,                         \
129             typename type1, typename type2>                             \
130   struct PPL_FUNCTION_CLASS(name);                                      \
131   template <typename Policy1, typename Policy2,                         \
132             typename type1, typename type2>                             \
133   inline ret_type PPL_U(name)(PPL_U(qual1) PPL_U(type1)& arg1,          \
134                        PPL_U(qual2) PPL_U(type2)& arg2) {               \
135     return PPL_FUNCTION_CLASS(name)<Policy1, Policy2,                   \
136       type1, PPL_U(type2)>::function(arg1, arg2);                       \
137   }
138 
139 #define PPL_DECLARE_FUN2_0_1(name, ret_type, qual1, type1,      \
140                              qual2, type2, after1)              \
141   template <typename Policy1, typename Policy2,                 \
142             typename type1, typename type2>                     \
143   struct PPL_FUNCTION_CLASS(name);                              \
144   template <typename Policy1, typename Policy2,                 \
145             typename type1, typename type2>                     \
146   inline ret_type PPL_U(name)(PPL_U(qual1) PPL_U(type1)& arg1,  \
147                        PPL_U(qual2) PPL_U(type2)& arg2,         \
148                        PPL_U(after1) a1) {                      \
149     return PPL_FUNCTION_CLASS(name)<Policy1, Policy2,           \
150       type1, PPL_U(type2)>::function(arg1, arg2, a1);           \
151   }
152 
153 #define PPL_DECLARE_FUN2_0_2(name, ret_type, qual1, type1, qual2, type2, \
154                              after1, after2)                            \
155   template <typename Policy1, typename Policy2,                         \
156             typename type1, typename type2>                             \
157   struct PPL_FUNCTION_CLASS(name);                                      \
158   template <typename Policy1, typename Policy2,                         \
159             typename type1, typename type2>                             \
160   inline ret_type PPL_U(name)(PPL_U(qual1) PPL_U(type1)& arg1,          \
161                        PPL_U(qual2) PPL_U(type2)& arg2,                 \
162                        PPL_U(after1) a1, PPL_U(after2) a2) {            \
163     return PPL_FUNCTION_CLASS(name)<Policy1, Policy2,                   \
164       type1, PPL_U(type2)>::function(arg1, arg2, a1, a2);               \
165   }
166 
167 #define PPL_DECLARE_FUN3_0_1(name, ret_type, qual1, type1,              \
168                              qual2, type2, qual3, type3, after1)        \
169   template <typename Policy1, typename Policy2, typename Policy3,       \
170             typename type1, typename type2, typename type3>             \
171   struct PPL_FUNCTION_CLASS(name);                                      \
172   template <typename Policy1, typename Policy2, typename Policy3,       \
173             typename type1, typename type2, typename type3>             \
174   inline ret_type PPL_U(name)(PPL_U(qual1) PPL_U(type1)& arg1,          \
175                        PPL_U(qual2) PPL_U(type2)& arg2,                 \
176                        PPL_U(qual3) PPL_U(type3)& arg3,                 \
177                        PPL_U(after1) a1) {                              \
178     return PPL_FUNCTION_CLASS(name)<Policy1, Policy2, Policy3,          \
179       type1, type2, PPL_U(type3)>                                       \
180       ::function(arg1, arg2, arg3, a1);                                 \
181   }
182 
183 #define PPL_DECLARE_FUN5_0_1(name, ret_type,                            \
184                              qual1, type1, qual2, type2, qual3, type3,  \
185                              qual4, type4, qual5, type5,                \
186                              after1)                                    \
187   template <typename Policy1, typename Policy2, typename Policy3,       \
188             typename Policy4,typename Policy5,                          \
189             typename type1, typename type2, typename type3,             \
190             typename type4, typename type5>                             \
191   struct PPL_FUNCTION_CLASS(name);                                      \
192   template <typename Policy1, typename Policy2, typename Policy3,       \
193             typename Policy4,typename Policy5,                          \
194             typename type1, typename type2, typename type3,             \
195             typename type4, typename type5>                             \
196   inline ret_type PPL_U(name)(PPL_U(qual1) PPL_U(type1)& arg1, PPL_U(qual2) \
197                        PPL_U(type2)& arg2,                              \
198                        PPL_U(qual3) PPL_U(type3)& arg3, PPL_U(qual4)    \
199                        PPL_U(type4)& arg4,                              \
200                        PPL_U(qual5) PPL_U(type5)& arg5,                 \
201                        PPL_U(after1) a1) {                              \
202     return PPL_FUNCTION_CLASS(name)<Policy1, Policy2, Policy3,          \
203       Policy4, Policy5,                                                 \
204       type1, type2,                                                     \
205       type3, type4,                                                     \
206       PPL_U(type5)>                                                     \
207       ::function(arg1, arg2, arg3, arg4, arg5, a1);                     \
208   }
209 
210 #define PPL_SPECIALIZE_FUN1_0_0(name, func, ret_type, qual, type)       \
211   template <typename Policy>                                            \
212   struct PPL_FUNCTION_CLASS(name)<Policy, PPL_U(type)> {                \
213     static inline ret_type function(PPL_U(qual) PPL_U(type)& arg) {     \
214       return PPL_U(func)<Policy>(arg);                                  \
215     }                                                                   \
216   };
217 
218 #define PPL_SPECIALIZE_FUN1_0_1(name, func, ret_type, qual, type, after1) \
219   template <typename Policy>                                            \
220   struct PPL_FUNCTION_CLASS(name)<Policy, PPL_U(type)> {                \
221     static inline ret_type function(PPL_U(qual) PPL_U(type)& arg,       \
222                                     PPL_U(after1) a1) {                 \
223       return PPL_U(func)<Policy>(arg, a1);                              \
224     }                                                                   \
225   };
226 
227 #define PPL_SPECIALIZE_FUN1_0_2(name, func, ret_type, qual, type,       \
228                                 after1, after2)                         \
229   template <typename Policy>                                            \
230   struct PPL_FUNCTION_CLASS(name)<Policy, PPL_U(type)> {                \
231     static inline ret_type function(PPL_U(qual) PPL_U(type)& arg,       \
232                                     PPL_U(after1) a1, PPL_U(after2) a2) \
233     {                                                                   \
234       return PPL_U(func)<Policy>(arg, a1, a2);                          \
235     }                                                                   \
236   };
237 
238 #define PPL_SPECIALIZE_FUN1_0_3(name, func, ret_type, qual, type,       \
239                                 after1, after2, after3)                 \
240   template <typename Policy>                                            \
241   struct PPL_FUNCTION_CLASS(name)<Policy, PPL_U(type)> {                \
242     static inline ret_type function(PPL_U(qual) PPL_U(type)& arg,       \
243                                     PPL_U(after1) a1, PPL_U(after2) a2, \
244                                     PPL_U(after3) a3) {                 \
245       return PPL_U(func)<Policy>(arg, a1, a2, a3);                      \
246     }                                                                   \
247   };
248 
249 #define PPL_SPECIALIZE_FUN1_1_1(name, func, ret_type, before1,          \
250                                 qual, type, after1)                     \
251   template <typename Policy>                                            \
252   struct PPL_FUNCTION_CLASS(name)<Policy, PPL_U(type)> {                \
253     static inline ret_type function(PPL_U(before1) b1, PPL_U(qual)      \
254                                     PPL_U(type)& arg,                   \
255                                     PPL_U(after1) a1) {                 \
256       return PPL_U(func)<Policy>(b1, arg, a1);                          \
257     }                                                                   \
258   };
259 
260 #define PPL_SPECIALIZE_FUN1_1_2(name, func, ret_type, before1,          \
261                                 qual, type, after1, after2)             \
262   template <typename Policy>                                            \
263   struct PPL_FUNCTION_CLASS(name)<Policy, PPL_U(type)> {                \
264     static inline ret_type function(PPL_U(before1) b1, PPL_U(qual)      \
265                                     PPL_U(type)& arg,                   \
266                                     PPL_U(after1) a1, PPL_U(after2) a2) \
267     {                                                                   \
268       return PPL_U(func)<Policy>(b1, arg, a1, a2);                      \
269     }                                                                   \
270   };
271 
272 #define PPL_SPECIALIZE_FUN1_2_2(name, func, ret_type, before1, before2, \
273                                 qual, type, after1, after2)             \
274   template <typename Policy>                                            \
275   struct PPL_FUNCTION_CLASS(name)<Policy, PPL_U(type)> {                \
276     static inline ret_type function(PPL_U(before1) b1, PPL_U(before2) b2, \
277                                     PPL_U(qual) PPL_U(type)& arg,       \
278                                     PPL_U(after1) a1, PPL_U(after2) a2) \
279     {                                                                   \
280       return PPL_U(func)<Policy>(b1, b2, arg, a1, a2);                  \
281     }                                                                   \
282   };
283 
284 #define PPL_SPECIALIZE_FUN2_0_0(name, func, ret_type, qual1, type1,     \
285                                 qual2, type2)                           \
286   template <typename Policy1, typename Policy2>                         \
287   struct PPL_FUNCTION_CLASS(name)<Policy1, Policy2, type1,              \
288                                   PPL_U(type2)> {                       \
289     static inline ret_type function(PPL_U(qual1) PPL_U(type1)& arg1,    \
290                                     PPL_U(qual2) PPL_U(type2) &arg2) {  \
291       return PPL_U(func)<Policy1, Policy2>(arg1, arg2);                 \
292     }                                                                   \
293   };
294 
295 #define PPL_SPECIALIZE_FUN2_0_1(name, func, ret_type, qual1, type1,     \
296                                 qual2, type2, after1)                   \
297   template <typename Policy1, typename Policy2>                         \
298   struct PPL_FUNCTION_CLASS(name)<Policy1, Policy2, type1,              \
299                                   PPL_U(type2)> {                       \
300     static inline ret_type function(PPL_U(qual1) PPL_U(type1)& arg1,    \
301                                     PPL_U(qual2) PPL_U(type2) &arg2,    \
302                                     PPL_U(after1) a1) {                 \
303       return PPL_U(func)<Policy1, Policy2>(arg1, arg2, a1);             \
304     }                                                                   \
305   };
306 
307 #define PPL_SPECIALIZE_FUN2_0_2(name, func, ret_type, qual1, type1,     \
308                                 qual2, type2, after1, after2)           \
309   template <typename Policy1, typename Policy2>                         \
310   struct PPL_FUNCTION_CLASS(name)<Policy1, Policy2, type1,              \
311                                   PPL_U(type2)> {                       \
312     static inline ret_type function(PPL_U(qual1) PPL_U(type1)& arg1,    \
313                                     PPL_U(qual2) PPL_U(type2) &arg2,    \
314                                     PPL_U(after1) a1, PPL_U(after2) a2) \
315     {                                                                   \
316       return PPL_U(func)<Policy1, Policy2>(arg1, arg2, a1, a2);         \
317     }                                                                   \
318   };
319 
320 #define PPL_SPECIALIZE_FUN3_0_1(name, func, ret_type, qual1, type1,     \
321                                 qual2, type2, qual3, type3, after1)     \
322   template <typename Policy1, typename Policy2, typename Policy3>       \
323   struct PPL_FUNCTION_CLASS(name) <Policy1, Policy2, Policy3,           \
324                                    type1, type2,                        \
325                                    PPL_U(type3)> {                      \
326     static inline Result function(PPL_U(qual1) PPL_U(type1)& arg1,      \
327                                   PPL_U(qual2) PPL_U(type2) &arg2,      \
328                                   PPL_U(qual3) PPL_U(type3) &arg3,      \
329                                   PPL_U(after1) a1) {                   \
330       return PPL_U(func)<Policy1, Policy2, Policy3>(arg1, arg2, arg3,   \
331                                                     a1);                \
332     }                                                                   \
333   };
334 
335 #define PPL_SPECIALIZE_FUN5_0_1(name, func, ret_type,                   \
336                                 qual1, type1, qual2, type2,             \
337                                 qual3, type3,                           \
338                                 qual4, type4, qual5, type5, after1)     \
339   template <typename Policy1, typename Policy2, typename Policy3,       \
340             typename Policy4, typename Policy5>                         \
341   struct PPL_FUNCTION_CLASS(name) <Policy1, Policy2, Policy3, Policy4,  \
342                                    Policy5,                             \
343                                    type1, type2,                        \
344                                    type3, type4,                        \
345                                    PPL_U(type5)> {                      \
346     static inline Result                                                \
347       function(PPL_U(qual1) PPL_U(type1)& arg1, PPL_U(qual2)            \
348                PPL_U(type2) &arg2,                                      \
349                PPL_U(qual3) PPL_U(type3) &arg3, PPL_U(qual4)            \
350                PPL_U(type4) &arg4,                                      \
351                PPL_U(qual5) PPL_U(type5) &arg5, PPL_U(after1) a1) {     \
352       return PPL_U(func)<Policy1, Policy2, Policy3, Policy4,            \
353         Policy5>(arg1, arg2, arg3, arg4, arg5, a1);                     \
354     }                                                                   \
355   };
356 
357 // The `nonconst' macro helps readability of the sequel.
358 #ifdef nonconst
359 #define PPL_SAVED_nonconst nonconst
360 #undef nonconst
361 #endif
362 #define nonconst
363 
364 #define PPL_SPECIALIZE_COPY(func, Type)                                 \
365   PPL_SPECIALIZE_FUN2_0_0(copy, func, void, nonconst, Type, const, Type)
366 #define PPL_SPECIALIZE_SGN(func, From)                                  \
367   PPL_SPECIALIZE_FUN1_0_0(sgn, func, Result_Relation, const, From)
368 #define PPL_SPECIALIZE_CMP(func, Type1, Type2)                          \
369   PPL_SPECIALIZE_FUN2_0_0(cmp, func, Result_Relation, const, Type1, const, Type2)
370 #define PPL_SPECIALIZE_CLASSIFY(func, Type)                             \
371   PPL_SPECIALIZE_FUN1_0_3(classify, func, Result, const, Type, bool, bool, bool)
372 #define PPL_SPECIALIZE_IS_NAN(func, Type)                       \
373   PPL_SPECIALIZE_FUN1_0_0(is_nan, func, bool, const, Type)
374 #define PPL_SPECIALIZE_IS_MINF(func, Type)                      \
375   PPL_SPECIALIZE_FUN1_0_0(is_minf, func, bool, const, Type)
376 #define PPL_SPECIALIZE_IS_PINF(func, Type)                      \
377   PPL_SPECIALIZE_FUN1_0_0(is_pinf, func, bool, const, Type)
378 #define PPL_SPECIALIZE_IS_INT(func, Type)                       \
379   PPL_SPECIALIZE_FUN1_0_0(is_int, func, bool, const, Type)
380 #define PPL_SPECIALIZE_ASSIGN_SPECIAL(func, Type)                       \
381   PPL_SPECIALIZE_FUN1_0_2(assign_special, func, Result,                 \
382                           nonconst, Type, Result_Class, Rounding_Dir)
383 #define PPL_SPECIALIZE_CONSTRUCT_SPECIAL(func, Type)                    \
384   PPL_SPECIALIZE_FUN1_0_2(construct_special, func, Result, nonconst,    \
385                           Type, Result_Class, Rounding_Dir)
386 #define PPL_SPECIALIZE_CONSTRUCT(func, To, From)                        \
387   PPL_SPECIALIZE_FUN2_0_1(construct, func, Result, nonconst, To,        \
388                           const, From, Rounding_Dir)
389 #define PPL_SPECIALIZE_ASSIGN(func, To, From)                   \
390   PPL_SPECIALIZE_FUN2_0_1(assign, func, Result, nonconst, To,   \
391                           const, From, Rounding_Dir)
392 #define PPL_SPECIALIZE_FLOOR(func, To, From)                    \
393   PPL_SPECIALIZE_FUN2_0_1(floor, func, Result, nonconst, To,    \
394                           const, From, Rounding_Dir)
395 #define PPL_SPECIALIZE_CEIL(func, To, From)                     \
396   PPL_SPECIALIZE_FUN2_0_1(ceil, func, Result, nonconst, To,     \
397                           const, From, Rounding_Dir)
398 #define PPL_SPECIALIZE_TRUNC(func, To, From)                    \
399   PPL_SPECIALIZE_FUN2_0_1(trunc, func, Result, nonconst, To,    \
400                           const, From, Rounding_Dir)
401 #define PPL_SPECIALIZE_NEG(func, To, From)                      \
402   PPL_SPECIALIZE_FUN2_0_1(neg, func, Result, nonconst, To,      \
403                           const, From, Rounding_Dir)
404 #define PPL_SPECIALIZE_ABS(func, To, From)                      \
405   PPL_SPECIALIZE_FUN2_0_1(abs, func, Result, nonconst, To,      \
406                           const, From, Rounding_Dir)
407 #define PPL_SPECIALIZE_SQRT(func, To, From)                     \
408   PPL_SPECIALIZE_FUN2_0_1(sqrt, func, Result, nonconst, To,     \
409                           const, From, Rounding_Dir)
410 #define PPL_SPECIALIZE_ADD(func, To, From1, From2)                      \
411   PPL_SPECIALIZE_FUN3_0_1(add, func, Result, nonconst, To,              \
412                           const, From1, const, From2, Rounding_Dir)
413 #define PPL_SPECIALIZE_SUB(func, To, From1, From2)                      \
414   PPL_SPECIALIZE_FUN3_0_1(sub, func, Result, nonconst, To,              \
415                           const, From1, const, From2, Rounding_Dir)
416 #define PPL_SPECIALIZE_MUL(func, To, From1, From2)                      \
417   PPL_SPECIALIZE_FUN3_0_1(mul, func, Result, nonconst, To,              \
418                           const, From1, const, From2, Rounding_Dir)
419 #define PPL_SPECIALIZE_DIV(func, To, From1, From2)                      \
420   PPL_SPECIALIZE_FUN3_0_1(div, func, Result, nonconst, To,              \
421                           const, From1, const, From2, Rounding_Dir)
422 #define PPL_SPECIALIZE_REM(func, To, From1, From2)                      \
423   PPL_SPECIALIZE_FUN3_0_1(rem, func, Result, nonconst, To,              \
424                           const, From1, const, From2, Rounding_Dir)
425 #define PPL_SPECIALIZE_IDIV(func, To, From1, From2)                     \
426   PPL_SPECIALIZE_FUN3_0_1(idiv, func, Result, nonconst, To,             \
427                           const, From1, const, From2, Rounding_Dir)
428 #define PPL_SPECIALIZE_ADD_2EXP(func, To, From)                         \
429   PPL_SPECIALIZE_FUN2_0_2(add_2exp, func, Result, nonconst, To,         \
430                           const, From, unsigned int, Rounding_Dir)
431 #define PPL_SPECIALIZE_SUB_2EXP(func, To, From)                         \
432   PPL_SPECIALIZE_FUN2_0_2(sub_2exp, func, Result, nonconst, To,         \
433                           const, From, unsigned int, Rounding_Dir)
434 #define PPL_SPECIALIZE_MUL_2EXP(func, To, From)                         \
435   PPL_SPECIALIZE_FUN2_0_2(mul_2exp, func, Result, nonconst, To,         \
436                           const, From, unsigned int, Rounding_Dir)
437 #define PPL_SPECIALIZE_DIV_2EXP(func, To, From)                         \
438   PPL_SPECIALIZE_FUN2_0_2(div_2exp, func, Result, nonconst, To,         \
439                           const, From, unsigned int, Rounding_Dir)
440 #define PPL_SPECIALIZE_SMOD_2EXP(func, To, From)                        \
441   PPL_SPECIALIZE_FUN2_0_2(smod_2exp, func, Result, nonconst, To,        \
442                           const, From, unsigned int, Rounding_Dir)
443 #define PPL_SPECIALIZE_UMOD_2EXP(func, To, From)                        \
444   PPL_SPECIALIZE_FUN2_0_2(umod_2exp, func, Result, nonconst, To,        \
445                           const, From, unsigned int, Rounding_Dir)
446 #define PPL_SPECIALIZE_ADD_MUL(func, To, From1, From2)                  \
447   PPL_SPECIALIZE_FUN3_0_1(add_mul, func, Result, nonconst, To,          \
448                           const, From1, const, From2, Rounding_Dir)
449 #define PPL_SPECIALIZE_SUB_MUL(func, To, From1, From2)                  \
450   PPL_SPECIALIZE_FUN3_0_1(sub_mul, func, Result, nonconst, To,          \
451                           const, From1, const, From2, Rounding_Dir)
452 #define PPL_SPECIALIZE_GCD(func, To, From1, From2)                      \
453   PPL_SPECIALIZE_FUN3_0_1(gcd, func, Result, nonconst, To,              \
454                           const, From1, const, From2, Rounding_Dir)
455 #define PPL_SPECIALIZE_GCDEXT(func, To1, From1, From2, To2, To3)        \
456   PPL_SPECIALIZE_FUN5_0_1(gcdext, func, Result, nonconst, To1,          \
457                           nonconst, To2, nonconst, To3,                 \
458                           const, From1, const, From2, Rounding_Dir)
459 #define PPL_SPECIALIZE_LCM(func, To, From1, From2)                      \
460   PPL_SPECIALIZE_FUN3_0_1(lcm, func, Result, nonconst, To,              \
461                           const, From1, const, From2, Rounding_Dir)
462 #define PPL_SPECIALIZE_INPUT(func, Type)                        \
463   PPL_SPECIALIZE_FUN1_0_2(input, func, Result, nonconst, Type,  \
464                           std::istream&, Rounding_Dir)
465 #define PPL_SPECIALIZE_OUTPUT(func, Type)                       \
466   PPL_SPECIALIZE_FUN1_1_2(output, func, Result, std::ostream&,  \
467                           const, Type,                          \
468                           const Numeric_Format&, Rounding_Dir)
469 
470 
471 PPL_DECLARE_FUN2_0_0(copy,
472                      void, nonconst, Type1, const, Type2)
473 PPL_DECLARE_FUN1_0_0(sgn,
474                      Result_Relation, const, From)
475 PPL_DECLARE_FUN2_0_0(cmp,
476                      Result_Relation, const, Type1, const, Type2)
477 PPL_DECLARE_FUN1_0_3(classify,
478                      Result, const, Type, bool, bool, bool)
479 PPL_DECLARE_FUN1_0_0(is_nan,
480                      bool, const, Type)
481 PPL_DECLARE_FUN1_0_0(is_minf,
482                      bool, const, Type)
483 PPL_DECLARE_FUN1_0_0(is_pinf,
484                      bool, const, Type)
485 PPL_DECLARE_FUN1_0_0(is_int,
486                      bool, const, Type)
487 PPL_DECLARE_FUN1_0_2(assign_special,
488                      Result, nonconst, Type, Result_Class, Rounding_Dir)
489 PPL_DECLARE_FUN1_0_2(construct_special,
490                      Result, nonconst, Type, Result_Class, Rounding_Dir)
491 PPL_DECLARE_FUN2_0_1(construct,
492                      Result, nonconst, To, const, From, Rounding_Dir)
493 PPL_DECLARE_FUN2_0_1(assign,
494                      Result, nonconst, To, const, From, Rounding_Dir)
495 PPL_DECLARE_FUN2_0_1(floor,
496                      Result, nonconst, To, const, From, Rounding_Dir)
497 PPL_DECLARE_FUN2_0_1(ceil,
498                      Result, nonconst, To, const, From, Rounding_Dir)
499 PPL_DECLARE_FUN2_0_1(trunc,
500                      Result, nonconst, To, const, From, Rounding_Dir)
501 PPL_DECLARE_FUN2_0_1(neg,
502                      Result, nonconst, To, const, From, Rounding_Dir)
503 PPL_DECLARE_FUN2_0_1(abs,
504                      Result, nonconst, To, const, From, Rounding_Dir)
505 PPL_DECLARE_FUN2_0_1(sqrt,
506                      Result, nonconst, To, const, From, Rounding_Dir)
507 PPL_DECLARE_FUN3_0_1(add,
508                      Result, nonconst, To,
509                      const, From1, const, From2, Rounding_Dir)
510 PPL_DECLARE_FUN3_0_1(sub,
511                      Result, nonconst, To,
512                      const, From1, const, From2, Rounding_Dir)
513 PPL_DECLARE_FUN3_0_1(mul,
514                      Result, nonconst, To,
515                      const, From1, const, From2, Rounding_Dir)
516 PPL_DECLARE_FUN3_0_1(div,
517                      Result, nonconst, To,
518                      const, From1, const, From2, Rounding_Dir)
519 PPL_DECLARE_FUN3_0_1(rem,
520                      Result, nonconst, To,
521                      const, From1, const, From2, Rounding_Dir)
522 PPL_DECLARE_FUN3_0_1(idiv,
523                      Result, nonconst, To,
524                      const, From1, const, From2, Rounding_Dir)
525 PPL_DECLARE_FUN2_0_2(add_2exp,
526                      Result, nonconst, To,
527                      const, From, unsigned int, Rounding_Dir)
528 PPL_DECLARE_FUN2_0_2(sub_2exp,
529                      Result, nonconst, To,
530                      const, From, unsigned int, Rounding_Dir)
531 PPL_DECLARE_FUN2_0_2(mul_2exp,
532                      Result, nonconst, To,
533                      const, From, unsigned int, Rounding_Dir)
534 PPL_DECLARE_FUN2_0_2(div_2exp,
535                      Result, nonconst, To,
536                      const, From, unsigned int, Rounding_Dir)
537 PPL_DECLARE_FUN2_0_2(smod_2exp,
538                      Result, nonconst, To,
539                      const, From, unsigned int, Rounding_Dir)
540 PPL_DECLARE_FUN2_0_2(umod_2exp,
541                      Result, nonconst, To,
542                      const, From, unsigned int, Rounding_Dir)
543 PPL_DECLARE_FUN3_0_1(add_mul,
544                      Result, nonconst, To,
545                      const, From1, const, From2, Rounding_Dir)
546 PPL_DECLARE_FUN3_0_1(sub_mul,
547                      Result, nonconst, To,
548                      const, From1, const, From2, Rounding_Dir)
549 PPL_DECLARE_FUN3_0_1(gcd,
550                      Result, nonconst, To,
551                      const, From1, const, From2, Rounding_Dir)
552 PPL_DECLARE_FUN5_0_1(gcdext,
553                      Result, nonconst, To1, nonconst, To2, nonconst, To3,
554                      const, From1, const, From2, Rounding_Dir)
555 PPL_DECLARE_FUN3_0_1(lcm,
556                      Result, nonconst, To,
557                      const, From1, const, From2, Rounding_Dir)
558 PPL_DECLARE_FUN1_0_2(input,
559                      Result, nonconst, Type, std::istream&, Rounding_Dir)
560 PPL_DECLARE_FUN1_1_2(output,
561                      Result, std::ostream&, const, Type,
562                      const Numeric_Format&, Rounding_Dir)
563 
564 #undef PPL_DECLARE_FUN1_0_0
565 #undef PPL_DECLARE_FUN1_0_1
566 #undef PPL_DECLARE_FUN1_0_2
567 #undef PPL_DECLARE_FUN1_0_3
568 #undef PPL_DECLARE_FUN1_1_1
569 #undef PPL_DECLARE_FUN1_1_2
570 #undef PPL_DECLARE_FUN1_2_2
571 #undef PPL_DECLARE_FUN2_0_0
572 #undef PPL_DECLARE_FUN2_0_1
573 #undef PPL_DECLARE_FUN2_0_2
574 #undef PPL_DECLARE_FUN3_0_1
575 #undef PPL_DECLARE_FUN5_0_1
576 
577 template <typename Policy, typename To>
578 Result round(To& to, Result r, Rounding_Dir dir);
579 
580 Result input_mpq(mpq_class& to, std::istream& is);
581 
582 std::string float_mpq_to_string(mpq_class& q);
583 
584 } // namespace Checked
585 
586 struct Minus_Infinity {
587   static const Result_Class vclass = VC_MINUS_INFINITY;
588 };
589 struct Plus_Infinity {
590   static const Result_Class vclass = VC_PLUS_INFINITY;
591 };
592 struct Not_A_Number {
593   static const Result_Class vclass = VC_NAN;
594 };
595 
596 template <typename T>
597 struct Is_Special : public False { };
598 
599 template <>
600 struct Is_Special<Minus_Infinity> : public True {};
601 
602 template <>
603 struct Is_Special<Plus_Infinity> : public True {};
604 
605 template <>
606 struct Is_Special<Not_A_Number> : public True {};
607 
608 extern Minus_Infinity MINUS_INFINITY;
609 extern Plus_Infinity PLUS_INFINITY;
610 extern Not_A_Number NOT_A_NUMBER;
611 
612 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
613 /*! \ingroup PPL_CXX_interface */
614 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
615 template <typename T>
616 struct Checked_Number_Transparent_Policy {
617   //! Do not check for overflowed result.
618   const_bool_nodef(check_overflow, false);
619 
620   //! Do not check for attempts to add infinities with different sign.
621   const_bool_nodef(check_inf_add_inf, false);
622 
623   //! Do not check for attempts to subtract infinities with same sign.
624   const_bool_nodef(check_inf_sub_inf, false);
625 
626   //! Do not check for attempts to multiply infinities by zero.
627   const_bool_nodef(check_inf_mul_zero, false);
628 
629   //! Do not check for attempts to divide by zero.
630   const_bool_nodef(check_div_zero, false);
631 
632   //! Do not check for attempts to divide infinities.
633   const_bool_nodef(check_inf_div_inf, false);
634 
635   //! Do not check for attempts to compute remainder of infinities.
636   const_bool_nodef(check_inf_mod, false);
637 
638   //! Do not check for attempts to take the square root of a negative number.
639   const_bool_nodef(check_sqrt_neg, false);
640 
641   //! Handle not-a-number special value if \p T has it.
642   const_bool_nodef(has_nan, std::numeric_limits<T>::has_quiet_NaN);
643 
644   //! Handle infinity special values if \p T have them.
645   const_bool_nodef(has_infinity, std::numeric_limits<T>::has_infinity);
646 
647   /*! \brief
648     The checked number can always be safely converted to the
649     underlying type \p T and vice-versa.
650   */
651   const_bool_nodef(convertible, true);
652 
653   //! Do not honor requests to check for FPU inexact results.
654   const_bool_nodef(fpu_check_inexact, false);
655 
656   //! Do not make extra checks to detect FPU NaN results.
657   const_bool_nodef(fpu_check_nan_result, false);
658 
659   /*! \brief
660     For constructors, by default use the same rounding used by
661     underlying type.
662   */
663   static const Rounding_Dir ROUND_DEFAULT_CONSTRUCTOR = ROUND_NATIVE;
664 
665   /*! \brief
666     For overloaded operators (operator+(), operator-(), ...), by
667     default use the same rounding used by the underlying type.
668   */
669   static const Rounding_Dir ROUND_DEFAULT_OPERATOR = ROUND_NATIVE;
670 
671   /*! \brief
672     For input functions, by default use the same rounding used by
673     the underlying type.
674   */
675   static const Rounding_Dir ROUND_DEFAULT_INPUT = ROUND_NATIVE;
676 
677   /*! \brief
678     For output functions, by default use the same rounding used by
679     the underlying type.
680   */
681   static const Rounding_Dir ROUND_DEFAULT_OUTPUT = ROUND_NATIVE;
682 
683   /*! \brief
684     For all other functions, by default use the same rounding used by
685     the underlying type.
686   */
687   static const Rounding_Dir ROUND_DEFAULT_FUNCTION = ROUND_NATIVE;
688 
689   /*! \brief
690     Handles \p r: called by all constructors, operators and functions that
691     do not return a Result value.
692   */
693   static void handle_result(Result r);
694 };
695 
696 } // namespace Parma_Polyhedra_Library
697 
698 #define CHECK_P(cond, check) ((cond) ? (check) : (assert(!(check)), false))
699 
700 #include "checked_inlines.hh"
701 #include "checked_int_inlines.hh"
702 #include "checked_float_inlines.hh"
703 #include "checked_mpz_inlines.hh"
704 #include "checked_mpq_inlines.hh"
705 #include "checked_ext_inlines.hh"
706 
707 #undef nonconst
708 #ifdef PPL_SAVED_nonconst
709 #define nonconst PPL_SAVED_nonconst
710 #undef PPL_SAVED_nonconst
711 #endif
712 
713 #undef PPL_FUNCTION_CLASS
714 #undef PPL_NAN
715 
716 #endif // !defined(PPL_checked_defs_hh)
717