PPL  1.2
checked_defs.hh
Go to the documentation of this file.
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 
472  void, nonconst, Type1, const, Type2)
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,
489 PPL_DECLARE_FUN1_0_2(construct_special,
490  Result, nonconst, Type, Result_Class, Rounding_Dir)
492  Result, nonconst, To, const, From, Rounding_Dir)
494  Result, nonconst, To, const, From, Rounding_Dir)
496  Result, nonconst, To, const, From, Rounding_Dir)
498  Result, nonconst, To, const, From, Rounding_Dir)
500  Result, nonconst, To, const, From, Rounding_Dir)
502  Result, nonconst, To, const, From, Rounding_Dir)
504  Result, nonconst, To, const, From, Rounding_Dir)
506  Result, nonconst, To, const, From, Rounding_Dir)
508  Result, nonconst, To,
509  const, From1, const, From2, Rounding_Dir)
511  Result, nonconst, To,
512  const, From1, const, From2, Rounding_Dir)
514  Result, nonconst, To,
515  const, From1, const, From2, Rounding_Dir)
517  Result, nonconst, To,
518  const, From1, const, From2, Rounding_Dir)
520  Result, nonconst, To,
521  const, From1, const, From2, Rounding_Dir)
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)
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)
556  Result, nonconst, To,
557  const, From1, const, From2, Rounding_Dir)
559  Result, nonconst, Type, std::istream&, Rounding_Dir)
560 PPL_DECLARE_FUN1_1_2(output,
561  Result, std::ostream&, const, Type,
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 
588 };
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 
611 
612 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
613 
614 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
615 template <typename T>
618  const_bool_nodef(check_overflow, false);
619 
621  const_bool_nodef(check_inf_add_inf, false);
622 
624  const_bool_nodef(check_inf_sub_inf, false);
625 
627  const_bool_nodef(check_inf_mul_zero, false);
628 
630  const_bool_nodef(check_div_zero, false);
631 
633  const_bool_nodef(check_inf_div_inf, false);
634 
636  const_bool_nodef(check_inf_mod, false);
637 
639  const_bool_nodef(check_sqrt_neg, false);
640 
642  const_bool_nodef(has_nan, std::numeric_limits<T>::has_quiet_NaN);
643 
645  const_bool_nodef(has_infinity, std::numeric_limits<T>::has_infinity);
646 
651  const_bool_nodef(convertible, true);
652 
655 
657  const_bool_nodef(fpu_check_nan_result, false);
658 
664 
670 
676 
682 
688 
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)
From bool PPL_DECLARE_FUN1_0_0(is_nan, bool, const, Type) PPL_DECLARE_FUN1_0_0(is_minf
Rounding_Dir
Rounding directions for arithmetic computations.
std::string float_mpq_to_string(mpq_class &q)
Definition: checked.cc:514
static const Result_Class vclass
Not_A_Number NOT_A_NUMBER
Definition: checked.cc:32
Result
Possible outcomes of a checked arithmetic computation.
Definition: Result_defs.hh:76
From bool Type Type Rounding_Dir To
The standard C++ namespace.
int fpu_check_inexact()
Queries the inexact computation status.
Negative infinity result class.
Definition: Result_defs.hh:34
Not a number result class.
Definition: Result_defs.hh:40
static const Rounding_Dir ROUND_DEFAULT_OUTPUT
For output functions, by default use the same rounding used by the underlying type.
static const Rounding_Dir ROUND_DEFAULT_INPUT
For input functions, by default use the same rounding used by the underlying type.
Result assign(Boundary_Type to_type, To &to, To_Info &to_info, Boundary_Type type, const T &x, const Info &info, bool should_shrink=false)
From bool Type Type Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir unsigned Rounding_Dir unsigned Rounding_Dir unsigned Rounding_Dir Rounding_Dir To2
PPL_DECLARE_FUN2_0_0(copy, void, nonconst, Type1, const, Type2) PPL_DECLARE_FUN1_0_0(sgn
Positive infinity result class.
Definition: Result_defs.hh:37
A class holding a constant called value that evaluates to true.
From bool Type Type Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir unsigned Rounding_Dir unsigned Rounding_Dir unsigned Rounding_Dir Rounding_Dir Rounding_Dir std::istream Rounding_Dir To Result round(To &to, Result r, Rounding_Dir dir)
From bool Type Type Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir unsigned Rounding_Dir unsigned Rounding_Dir unsigned Rounding_Dir Rounding_Dir To1
static const Rounding_Dir ROUND_DEFAULT_FUNCTION
For all other functions, by default use the same rounding used by the underlying type.
From bool Type Type Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir From1
static const Result_Class vclass
Plus_Infinity PLUS_INFINITY
Definition: checked.cc:31
The entire library is confined to this namespace.
Definition: version.hh:61
From bool Type Type Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir unsigned Rounding_Dir unsigned Rounding_Dir unsigned Rounding_Dir Rounding_Dir Rounding_Dir std::istream Rounding_Dir PPL_DECLARE_FUN1_1_2(output, Result, std::ostream &, const, Type, const Numeric_Format &, Rounding_Dir) template< typename Policy
static void handle_result(Result r)
Handles r: called by all constructors, operators and functions that do not return a Result value...
Minus_Infinity MINUS_INFINITY
Definition: checked.cc:30
int cmp(const GMP_Integer &x, const GMP_Integer &y)
const_bool_nodef(check_overflow, false)
Do not check for overflowed result.
From bool Type Type Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir From2
From bool Type Type Rounding_Dir From
Result input_mpq(mpq_class &to, std::istream &is)
Definition: checked.cc:429
int sgn(Boundary_Type type, const T &x, const Info &info)
static const Rounding_Dir ROUND_DEFAULT_OPERATOR
For overloaded operators (operator+(), operator-(), ...), by default use the same rounding used by th...
#define PPL_DECLARE_FUN1_0_3(name, ret_type, qual, type, after1, after2, after3)
Definition: checked_defs.hh:76
From bool Type Type PPL_DECLARE_FUN1_0_2(assign_special, Result, nonconst, Type, Result_Class, Rounding_Dir) PPL_DECLARE_FUN1_0_2(construct_special
static const Rounding_Dir ROUND_DEFAULT_CONSTRUCTOR
For constructors, by default use the same rounding used by underlying type.
Enable_If< Is_Native_Or_Checked< To >::value &&Is_Special< From >::value, Result >::type construct(To &to, const From &, Rounding_Dir dir)
A class holding a constant called value that evaluates to false.
static const Result_Class vclass
From bool Type Type Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir PPL_DECLARE_FUN3_0_1(add, Result, nonconst, To, const, From1, const, From2, Rounding_Dir) PPL_DECLARE_FUN3_0_1(sub
From bool Type Type Rounding_Dir PPL_DECLARE_FUN2_0_1(construct, Result, nonconst, To, const, From, Rounding_Dir) PPL_DECLARE_FUN2_0_1(assign
#define PPL_DECLARE_FUN5_0_1(name, ret_type, qual1, type1, qual2, type2, qual3, type3, qual4, type4, qual5, type5, after1)
From bool Type Type Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir unsigned Rounding_Dir unsigned Rounding_Dir unsigned Rounding_Dir Rounding_Dir To3
From bool Type Type Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir PPL_DECLARE_FUN2_0_2(add_2exp, Result, nonconst, To, const, From, unsigned int, Rounding_Dir) PPL_DECLARE_FUN2_0_2(sub_2exp