PPL  0.12.1
checked.defs.hh
Go to the documentation of this file.
00001 /* Abstract checked arithmetic function container.
00002    Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it>
00003    Copyright (C) 2010-2012 BUGSENG srl (http://bugseng.com)
00004 
00005 This file is part of the Parma Polyhedra Library (PPL).
00006 
00007 The PPL is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU General Public License as published by the
00009 Free Software Foundation; either version 3 of the License, or (at your
00010 option) any later version.
00011 
00012 The PPL is distributed in the hope that it will be useful, but WITHOUT
00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with this program; if not, write to the Free Software Foundation,
00019 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA.
00020 
00021 For the most up-to-date information see the Parma Polyhedra Library
00022 site: http://bugseng.com/products/ppl/ . */
00023 
00024 #ifndef PPL_checked_defs_hh
00025 #define PPL_checked_defs_hh 1
00026 
00027 #include <cassert>
00028 #include <iostream>
00029 #include <gmpxx.h>
00030 #include "mp_std_bits.defs.hh"
00031 #include "Temp.defs.hh"
00032 #include "Rounding_Dir.defs.hh"
00033 #include "Numeric_Format.defs.hh"
00034 #include "Float.defs.hh"
00035 
00036 namespace Parma_Polyhedra_Library {
00037 
00038 namespace Checked {
00039 
00040 
00041 // It is a pity that function partial specialization is not permitted
00042 // by C++.  To (partly) overcome this limitation, we use class
00043 // encapsulated functions and partial specialization of containing
00044 // classes.
00045 
00046 #define PPL_FUNCTION_CLASS(name) name ## _function_struct
00047 
00048 #define PPL_DECLARE_FUN1_0_0(name, ret_type, qual, type)                \
00049   template <typename Policy, typename type>                             \
00050   struct PPL_FUNCTION_CLASS(name);                                      \
00051   template <typename Policy, typename type>                             \
00052   inline ret_type PPL_U(name)(PPL_U(qual) PPL_U(type)& arg) {           \
00053     return PPL_FUNCTION_CLASS(name)<Policy, PPL_U(type)>::function(arg); \
00054   }
00055 
00056 #define PPL_DECLARE_FUN1_0_1(name, ret_type, qual, type, after1)        \
00057   template <typename Policy, typename type>                             \
00058   struct PPL_FUNCTION_CLASS(name);                                      \
00059   template <typename Policy, typename type>                             \
00060   inline ret_type PPL_U(name)(PPL_U(qual) PPL_U(type)& arg, PPL_U(after1) a1) { \
00061     return                                                              \
00062       PPL_FUNCTION_CLASS(name)<Policy, PPL_U(type)>::function(arg, a1); \
00063   }
00064 
00065 #define PPL_DECLARE_FUN1_0_2(name, ret_type, qual, type, after1, after2) \
00066   template <typename Policy, typename type>                             \
00067   struct PPL_FUNCTION_CLASS(name);                                      \
00068   template <typename Policy, typename type>                             \
00069   inline ret_type PPL_U(name)(PPL_U(qual) PPL_U(type)& arg, PPL_U(after1) a1, \
00070                        PPL_U(after2) a2) {                              \
00071     return                                                              \
00072       PPL_FUNCTION_CLASS(name)<Policy, PPL_U(type)>::function(arg,      \
00073                                                               a1, a2);  \
00074   }
00075 
00076 #define PPL_DECLARE_FUN1_0_3(name, ret_type, qual, type,                \
00077                              after1, after2, after3)                    \
00078   template <typename Policy, typename type>                             \
00079   struct PPL_FUNCTION_CLASS(name);                                      \
00080   template <typename Policy, typename type>                             \
00081   inline ret_type PPL_U(name)(PPL_U(qual) PPL_U(type)& arg,             \
00082                        PPL_U(after1) a1, PPL_U(after2) a2,              \
00083                        PPL_U(after3) a3) {                              \
00084     return                                                              \
00085       PPL_FUNCTION_CLASS(name)<Policy, PPL_U(type)>::function(arg,      \
00086                                                               a1, a2,   \
00087                                                               a3);      \
00088   }
00089 
00090 #define PPL_DECLARE_FUN1_1_1(name, ret_type, before1, qual, type, after1) \
00091   template <typename Policy, typename type>                             \
00092   struct PPL_FUNCTION_CLASS(name);                                      \
00093   template <typename Policy, typename type>                             \
00094   inline ret_type PPL_U(name)(PPL_U(before1) b1, PPL_U(qual) PPL_U(type)& arg, \
00095                        PPL_U(after1) a1) {                              \
00096     return                                                              \
00097       PPL_FUNCTION_CLASS(name)<Policy, PPL_U(type)>::function(b1, arg,  \
00098                                                               a1);      \
00099   }
00100 
00101 #define PPL_DECLARE_FUN1_1_2(name, ret_type, before1, qual, type,       \
00102                              after1, after2)                            \
00103   template <typename Policy, typename type>                             \
00104   struct PPL_FUNCTION_CLASS(name);                                      \
00105   template <typename Policy, typename type>                             \
00106   inline ret_type PPL_U(name)(PPL_U(before1) b1, PPL_U(qual) PPL_U(type)& arg, \
00107                        PPL_U(after1) a1, PPL_U(after2) a2) {            \
00108     return                                                              \
00109       PPL_FUNCTION_CLASS(name)<Policy, PPL_U(type)>::function(b1, arg,  \
00110                                                               a1, a2);  \
00111   }
00112 
00113 #define PPL_DECLARE_FUN1_2_2(name, ret_type, before1, before2, qual, type, \
00114                              after1, after2)                            \
00115   template <typename Policy, typename type>                             \
00116   struct PPL_FUNCTION_CLASS(name);                                      \
00117   template <typename Policy, typename type>                             \
00118   inline ret_type PPL_U(name)(PPL_U(before1) b1, PPL_U(before2) b2,     \
00119                        PPL_U(qual) PPL_U(type)& arg,                    \
00120                        PPL_U(after1) a1, PPL_U(after2) a2) {            \
00121     return                                                              \
00122       PPL_FUNCTION_CLASS(name)<Policy, PPL_U(type)>::function(b1, b2,   \
00123                                                               arg,      \
00124                                                               a1, a2);  \
00125   }
00126 
00127 #define PPL_DECLARE_FUN2_0_0(name, ret_type, qual1, type1, qual2, type2) \
00128   template <typename Policy1, typename Policy2,                         \
00129             typename type1, typename type2>                             \
00130   struct PPL_FUNCTION_CLASS(name);                                      \
00131   template <typename Policy1, typename Policy2,                         \
00132             typename type1, typename type2>                             \
00133   inline ret_type PPL_U(name)(PPL_U(qual1) PPL_U(type1)& arg1,          \
00134                        PPL_U(qual2) PPL_U(type2)& arg2) {               \
00135     return PPL_FUNCTION_CLASS(name)<Policy1, Policy2,                   \
00136       type1, PPL_U(type2)>::function(arg1, arg2);                       \
00137   }
00138 
00139 #define PPL_DECLARE_FUN2_0_1(name, ret_type, qual1, type1,      \
00140                              qual2, type2, after1)              \
00141   template <typename Policy1, typename Policy2,                 \
00142             typename type1, typename type2>                     \
00143   struct PPL_FUNCTION_CLASS(name);                              \
00144   template <typename Policy1, typename Policy2,                 \
00145             typename type1, typename type2>                     \
00146   inline ret_type PPL_U(name)(PPL_U(qual1) PPL_U(type1)& arg1,  \
00147                        PPL_U(qual2) PPL_U(type2)& arg2,         \
00148                        PPL_U(after1) a1) {                      \
00149     return PPL_FUNCTION_CLASS(name)<Policy1, Policy2,           \
00150       type1, PPL_U(type2)>::function(arg1, arg2, a1);           \
00151   }
00152 
00153 #define PPL_DECLARE_FUN2_0_2(name, ret_type, qual1, type1, qual2, type2, \
00154                              after1, after2)                            \
00155   template <typename Policy1, typename Policy2,                         \
00156             typename type1, typename type2>                             \
00157   struct PPL_FUNCTION_CLASS(name);                                      \
00158   template <typename Policy1, typename Policy2,                         \
00159             typename type1, typename type2>                             \
00160   inline ret_type PPL_U(name)(PPL_U(qual1) PPL_U(type1)& arg1,          \
00161                        PPL_U(qual2) PPL_U(type2)& arg2,                 \
00162                        PPL_U(after1) a1, PPL_U(after2) a2) {            \
00163     return PPL_FUNCTION_CLASS(name)<Policy1, Policy2,                   \
00164       type1, PPL_U(type2)>::function(arg1, arg2, a1, a2);               \
00165   }
00166 
00167 #define PPL_DECLARE_FUN3_0_1(name, ret_type, qual1, type1,              \
00168                              qual2, type2, qual3, type3, after1)        \
00169   template <typename Policy1, typename Policy2, typename Policy3,       \
00170             typename type1, typename type2, typename type3>             \
00171   struct PPL_FUNCTION_CLASS(name);                                      \
00172   template <typename Policy1, typename Policy2, typename Policy3,       \
00173             typename type1, typename type2, typename type3>             \
00174   inline ret_type PPL_U(name)(PPL_U(qual1) PPL_U(type1)& arg1,          \
00175                        PPL_U(qual2) PPL_U(type2)& arg2,                 \
00176                        PPL_U(qual3) PPL_U(type3)& arg3,                 \
00177                        PPL_U(after1) a1) {                              \
00178     return PPL_FUNCTION_CLASS(name)<Policy1, Policy2, Policy3,          \
00179       type1, type2, PPL_U(type3)>                                       \
00180       ::function(arg1, arg2, arg3, a1);                                 \
00181   }
00182 
00183 #define PPL_DECLARE_FUN5_0_1(name, ret_type,                            \
00184                              qual1, type1, qual2, type2, qual3, type3,  \
00185                              qual4, type4, qual5, type5,                \
00186                              after1)                                    \
00187   template <typename Policy1, typename Policy2, typename Policy3,       \
00188             typename Policy4,typename Policy5,                          \
00189             typename type1, typename type2, typename type3,             \
00190             typename type4, typename type5>                             \
00191   struct PPL_FUNCTION_CLASS(name);                                      \
00192   template <typename Policy1, typename Policy2, typename Policy3,       \
00193             typename Policy4,typename Policy5,                          \
00194             typename type1, typename type2, typename type3,             \
00195             typename type4, typename type5>                             \
00196   inline ret_type PPL_U(name)(PPL_U(qual1) PPL_U(type1)& arg1, PPL_U(qual2) \
00197                        PPL_U(type2)& arg2,                              \
00198                        PPL_U(qual3) PPL_U(type3)& arg3, PPL_U(qual4)    \
00199                        PPL_U(type4)& arg4,                              \
00200                        PPL_U(qual5) PPL_U(type5)& arg5,                 \
00201                        PPL_U(after1) a1) {                              \
00202     return PPL_FUNCTION_CLASS(name)<Policy1, Policy2, Policy3,          \
00203       Policy4, Policy5,                                                 \
00204       type1, type2,                                                     \
00205       type3, type4,                                                     \
00206       PPL_U(type5)>                                                     \
00207       ::function(arg1, arg2, arg3, arg4, arg5, a1);                     \
00208   }
00209 
00210 #define PPL_SPECIALIZE_FUN1_0_0(name, func, ret_type, qual, type)       \
00211   template <typename Policy>                                            \
00212   struct PPL_FUNCTION_CLASS(name)<Policy, PPL_U(type)> {                \
00213     static inline ret_type function(PPL_U(qual) PPL_U(type)& arg) {     \
00214       return PPL_U(func)<Policy>(arg);                                  \
00215     }                                                                   \
00216   };
00217 
00218 #define PPL_SPECIALIZE_FUN1_0_1(name, func, ret_type, qual, type, after1) \
00219   template <typename Policy>                                            \
00220   struct PPL_FUNCTION_CLASS(name)<Policy, PPL_U(type)> {                \
00221     static inline ret_type function(PPL_U(qual) PPL_U(type)& arg,       \
00222                                     PPL_U(after1) a1) {                 \
00223       return PPL_U(func)<Policy>(arg, a1);                              \
00224     }                                                                   \
00225   };
00226 
00227 #define PPL_SPECIALIZE_FUN1_0_2(name, func, ret_type, qual, type,       \
00228                                 after1, after2)                         \
00229   template <typename Policy>                                            \
00230   struct PPL_FUNCTION_CLASS(name)<Policy, PPL_U(type)> {                \
00231     static inline ret_type function(PPL_U(qual) PPL_U(type)& arg,       \
00232                                     PPL_U(after1) a1, PPL_U(after2) a2) \
00233     {                                                                   \
00234       return PPL_U(func)<Policy>(arg, a1, a2);                          \
00235     }                                                                   \
00236   };
00237 
00238 #define PPL_SPECIALIZE_FUN1_0_3(name, func, ret_type, qual, type,       \
00239                                 after1, after2, after3)                 \
00240   template <typename Policy>                                            \
00241   struct PPL_FUNCTION_CLASS(name)<Policy, PPL_U(type)> {                \
00242     static inline ret_type function(PPL_U(qual) PPL_U(type)& arg,       \
00243                                     PPL_U(after1) a1, PPL_U(after2) a2, \
00244                                     PPL_U(after3) a3) {                 \
00245       return PPL_U(func)<Policy>(arg, a1, a2, a3);                      \
00246     }                                                                   \
00247   };
00248 
00249 #define PPL_SPECIALIZE_FUN1_1_1(name, func, ret_type, before1,          \
00250                                 qual, type, after1)                     \
00251   template <typename Policy>                                            \
00252   struct PPL_FUNCTION_CLASS(name)<Policy, PPL_U(type)> {                \
00253     static inline ret_type function(PPL_U(before1) b1, PPL_U(qual)      \
00254                                     PPL_U(type)& arg,                   \
00255                                     PPL_U(after1) a1) {                 \
00256       return PPL_U(func)<Policy>(b1, arg, a1);                          \
00257     }                                                                   \
00258   };
00259 
00260 #define PPL_SPECIALIZE_FUN1_1_2(name, func, ret_type, before1,          \
00261                                 qual, type, after1, after2)             \
00262   template <typename Policy>                                            \
00263   struct PPL_FUNCTION_CLASS(name)<Policy, PPL_U(type)> {                \
00264     static inline ret_type function(PPL_U(before1) b1, PPL_U(qual)      \
00265                                     PPL_U(type)& arg,                   \
00266                                     PPL_U(after1) a1, PPL_U(after2) a2) \
00267     {                                                                   \
00268       return PPL_U(func)<Policy>(b1, arg, a1, a2);                      \
00269     }                                                                   \
00270   };
00271 
00272 #define PPL_SPECIALIZE_FUN1_2_2(name, func, ret_type, before1, before2, \
00273                                 qual, type, after1, after2)             \
00274   template <typename Policy>                                            \
00275   struct PPL_FUNCTION_CLASS(name)<Policy, PPL_U(type)> {                \
00276     static inline ret_type function(PPL_U(before1) b1, PPL_U(before2) b2, \
00277                                     PPL_U(qual) PPL_U(type)& arg,       \
00278                                     PPL_U(after1) a1, PPL_U(after2) a2) \
00279     {                                                                   \
00280       return PPL_U(func)<Policy>(b1, b2, arg, a1, a2);                  \
00281     }                                                                   \
00282   };
00283 
00284 #define PPL_SPECIALIZE_FUN2_0_0(name, func, ret_type, qual1, type1,     \
00285                                 qual2, type2)                           \
00286   template <typename Policy1, typename Policy2>                         \
00287   struct PPL_FUNCTION_CLASS(name)<Policy1, Policy2, type1,              \
00288                                   PPL_U(type2)> {                       \
00289     static inline ret_type function(PPL_U(qual1) PPL_U(type1)& arg1,    \
00290                                     PPL_U(qual2) PPL_U(type2) &arg2) {  \
00291       return PPL_U(func)<Policy1, Policy2>(arg1, arg2);                 \
00292     }                                                                   \
00293   };
00294 
00295 #define PPL_SPECIALIZE_FUN2_0_1(name, func, ret_type, qual1, type1,     \
00296                                 qual2, type2, after1)                   \
00297   template <typename Policy1, typename Policy2>                         \
00298   struct PPL_FUNCTION_CLASS(name)<Policy1, Policy2, type1,              \
00299                                   PPL_U(type2)> {                       \
00300     static inline ret_type function(PPL_U(qual1) PPL_U(type1)& arg1,    \
00301                                     PPL_U(qual2) PPL_U(type2) &arg2,    \
00302                                     PPL_U(after1) a1) {                 \
00303       return PPL_U(func)<Policy1, Policy2>(arg1, arg2, a1);             \
00304     }                                                                   \
00305   };
00306 
00307 #define PPL_SPECIALIZE_FUN2_0_2(name, func, ret_type, qual1, type1,     \
00308                                 qual2, type2, after1, after2)           \
00309   template <typename Policy1, typename Policy2>                         \
00310   struct PPL_FUNCTION_CLASS(name)<Policy1, Policy2, type1,              \
00311                                   PPL_U(type2)> {                       \
00312     static inline ret_type function(PPL_U(qual1) PPL_U(type1)& arg1,    \
00313                                     PPL_U(qual2) PPL_U(type2) &arg2,    \
00314                                     PPL_U(after1) a1, PPL_U(after2) a2) \
00315     {                                                                   \
00316       return PPL_U(func)<Policy1, Policy2>(arg1, arg2, a1, a2);         \
00317     }                                                                   \
00318   };
00319 
00320 #define PPL_SPECIALIZE_FUN3_0_1(name, func, ret_type, qual1, type1,     \
00321                                 qual2, type2, qual3, type3, after1)     \
00322   template <typename Policy1, typename Policy2, typename Policy3>       \
00323   struct PPL_FUNCTION_CLASS(name) <Policy1, Policy2, Policy3,           \
00324                                    type1, type2,                        \
00325                                    PPL_U(type3)> {                      \
00326     static inline Result function(PPL_U(qual1) PPL_U(type1)& arg1,      \
00327                                   PPL_U(qual2) PPL_U(type2) &arg2,      \
00328                                   PPL_U(qual3) PPL_U(type3) &arg3,      \
00329                                   PPL_U(after1) a1) {                   \
00330       return PPL_U(func)<Policy1, Policy2, Policy3>(arg1, arg2, arg3,   \
00331                                                     a1);                \
00332     }                                                                   \
00333   };
00334 
00335 #define PPL_SPECIALIZE_FUN5_0_1(name, func, ret_type,                   \
00336                                 qual1, type1, qual2, type2,             \
00337                                 qual3, type3,                           \
00338                                 qual4, type4, qual5, type5, after1)     \
00339   template <typename Policy1, typename Policy2, typename Policy3,       \
00340             typename Policy4, typename Policy5>                         \
00341   struct PPL_FUNCTION_CLASS(name) <Policy1, Policy2, Policy3, Policy4,  \
00342                                    Policy5,                             \
00343                                    type1, type2,                        \
00344                                    type3, type4,                        \
00345                                    PPL_U(type5)> {                      \
00346     static inline Result                                                \
00347       function(PPL_U(qual1) PPL_U(type1)& arg1, PPL_U(qual2)            \
00348                PPL_U(type2) &arg2,                                      \
00349                PPL_U(qual3) PPL_U(type3) &arg3, PPL_U(qual4)            \
00350                PPL_U(type4) &arg4,                                      \
00351                PPL_U(qual5) PPL_U(type5) &arg5, PPL_U(after1) a1) {     \
00352       return PPL_U(func)<Policy1, Policy2, Policy3, Policy4,            \
00353         Policy5>(arg1, arg2, arg3, arg4, arg5, a1);                     \
00354     }                                                                   \
00355   };
00356 
00357 // The `nonconst' macro helps readability of the sequel.
00358 #ifdef nonconst
00359 #define PPL_SAVED_nonconst nonconst
00360 #undef nonconst
00361 #endif
00362 #define nonconst
00363 
00364 #define PPL_SPECIALIZE_COPY(func, Type)                                 \
00365   PPL_SPECIALIZE_FUN2_0_0(copy, func, void, nonconst, Type, const, Type)
00366 #define PPL_SPECIALIZE_SGN(func, From)                                  \
00367   PPL_SPECIALIZE_FUN1_0_0(sgn, func, Result_Relation, const, From)
00368 #define PPL_SPECIALIZE_CMP(func, Type1, Type2)                          \
00369   PPL_SPECIALIZE_FUN2_0_0(cmp, func, Result_Relation, const, Type1, const, Type2)
00370 #define PPL_SPECIALIZE_CLASSIFY(func, Type)                             \
00371   PPL_SPECIALIZE_FUN1_0_3(classify, func, Result, const, Type, bool, bool, bool)
00372 #define PPL_SPECIALIZE_IS_NAN(func, Type)                       \
00373   PPL_SPECIALIZE_FUN1_0_0(is_nan, func, bool, const, Type)
00374 #define PPL_SPECIALIZE_IS_MINF(func, Type)                      \
00375   PPL_SPECIALIZE_FUN1_0_0(is_minf, func, bool, const, Type)
00376 #define PPL_SPECIALIZE_IS_PINF(func, Type)                      \
00377   PPL_SPECIALIZE_FUN1_0_0(is_pinf, func, bool, const, Type)
00378 #define PPL_SPECIALIZE_IS_INT(func, Type)                       \
00379   PPL_SPECIALIZE_FUN1_0_0(is_int, func, bool, const, Type)
00380 #define PPL_SPECIALIZE_ASSIGN_SPECIAL(func, Type)                       \
00381   PPL_SPECIALIZE_FUN1_0_2(assign_special, func, Result,                 \
00382                           nonconst, Type, Result_Class, Rounding_Dir)
00383 #define PPL_SPECIALIZE_CONSTRUCT_SPECIAL(func, Type)                    \
00384   PPL_SPECIALIZE_FUN1_0_2(construct_special, func, Result, nonconst,    \
00385                           Type, Result_Class, Rounding_Dir)
00386 #define PPL_SPECIALIZE_CONSTRUCT(func, To, From)                        \
00387   PPL_SPECIALIZE_FUN2_0_1(construct, func, Result, nonconst, To,        \
00388                           const, From, Rounding_Dir)
00389 #define PPL_SPECIALIZE_ASSIGN(func, To, From)                   \
00390   PPL_SPECIALIZE_FUN2_0_1(assign, func, Result, nonconst, To,   \
00391                           const, From, Rounding_Dir)
00392 #define PPL_SPECIALIZE_FLOOR(func, To, From)                    \
00393   PPL_SPECIALIZE_FUN2_0_1(floor, func, Result, nonconst, To,    \
00394                           const, From, Rounding_Dir)
00395 #define PPL_SPECIALIZE_CEIL(func, To, From)                     \
00396   PPL_SPECIALIZE_FUN2_0_1(ceil, func, Result, nonconst, To,     \
00397                           const, From, Rounding_Dir)
00398 #define PPL_SPECIALIZE_TRUNC(func, To, From)                    \
00399   PPL_SPECIALIZE_FUN2_0_1(trunc, func, Result, nonconst, To,    \
00400                           const, From, Rounding_Dir)
00401 #define PPL_SPECIALIZE_NEG(func, To, From)                      \
00402   PPL_SPECIALIZE_FUN2_0_1(neg, func, Result, nonconst, To,      \
00403                           const, From, Rounding_Dir)
00404 #define PPL_SPECIALIZE_ABS(func, To, From)                      \
00405   PPL_SPECIALIZE_FUN2_0_1(abs, func, Result, nonconst, To,      \
00406                           const, From, Rounding_Dir)
00407 #define PPL_SPECIALIZE_SQRT(func, To, From)                     \
00408   PPL_SPECIALIZE_FUN2_0_1(sqrt, func, Result, nonconst, To,     \
00409                           const, From, Rounding_Dir)
00410 #define PPL_SPECIALIZE_ADD(func, To, From1, From2)                      \
00411   PPL_SPECIALIZE_FUN3_0_1(add, func, Result, nonconst, To,              \
00412                           const, From1, const, From2, Rounding_Dir)
00413 #define PPL_SPECIALIZE_SUB(func, To, From1, From2)                      \
00414   PPL_SPECIALIZE_FUN3_0_1(sub, func, Result, nonconst, To,              \
00415                           const, From1, const, From2, Rounding_Dir)
00416 #define PPL_SPECIALIZE_MUL(func, To, From1, From2)                      \
00417   PPL_SPECIALIZE_FUN3_0_1(mul, func, Result, nonconst, To,              \
00418                           const, From1, const, From2, Rounding_Dir)
00419 #define PPL_SPECIALIZE_DIV(func, To, From1, From2)                      \
00420   PPL_SPECIALIZE_FUN3_0_1(div, func, Result, nonconst, To,              \
00421                           const, From1, const, From2, Rounding_Dir)
00422 #define PPL_SPECIALIZE_REM(func, To, From1, From2)                      \
00423   PPL_SPECIALIZE_FUN3_0_1(rem, func, Result, nonconst, To,              \
00424                           const, From1, const, From2, Rounding_Dir)
00425 #define PPL_SPECIALIZE_IDIV(func, To, From1, From2)                     \
00426   PPL_SPECIALIZE_FUN3_0_1(idiv, func, Result, nonconst, To,             \
00427                           const, From1, const, From2, Rounding_Dir)
00428 #define PPL_SPECIALIZE_ADD_2EXP(func, To, From)                         \
00429   PPL_SPECIALIZE_FUN2_0_2(add_2exp, func, Result, nonconst, To,         \
00430                           const, From, unsigned int, Rounding_Dir)
00431 #define PPL_SPECIALIZE_SUB_2EXP(func, To, From)                         \
00432   PPL_SPECIALIZE_FUN2_0_2(sub_2exp, func, Result, nonconst, To,         \
00433                           const, From, unsigned int, Rounding_Dir)
00434 #define PPL_SPECIALIZE_MUL_2EXP(func, To, From)                         \
00435   PPL_SPECIALIZE_FUN2_0_2(mul_2exp, func, Result, nonconst, To,         \
00436                           const, From, unsigned int, Rounding_Dir)
00437 #define PPL_SPECIALIZE_DIV_2EXP(func, To, From)                         \
00438   PPL_SPECIALIZE_FUN2_0_2(div_2exp, func, Result, nonconst, To,         \
00439                           const, From, unsigned int, Rounding_Dir)
00440 #define PPL_SPECIALIZE_SMOD_2EXP(func, To, From)                        \
00441   PPL_SPECIALIZE_FUN2_0_2(smod_2exp, func, Result, nonconst, To,        \
00442                           const, From, unsigned int, Rounding_Dir)
00443 #define PPL_SPECIALIZE_UMOD_2EXP(func, To, From)                        \
00444   PPL_SPECIALIZE_FUN2_0_2(umod_2exp, func, Result, nonconst, To,        \
00445                           const, From, unsigned int, Rounding_Dir)
00446 #define PPL_SPECIALIZE_ADD_MUL(func, To, From1, From2)                  \
00447   PPL_SPECIALIZE_FUN3_0_1(add_mul, func, Result, nonconst, To,          \
00448                           const, From1, const, From2, Rounding_Dir)
00449 #define PPL_SPECIALIZE_SUB_MUL(func, To, From1, From2)                  \
00450   PPL_SPECIALIZE_FUN3_0_1(sub_mul, func, Result, nonconst, To,          \
00451                           const, From1, const, From2, Rounding_Dir)
00452 #define PPL_SPECIALIZE_GCD(func, To, From1, From2)                      \
00453   PPL_SPECIALIZE_FUN3_0_1(gcd, func, Result, nonconst, To,              \
00454                           const, From1, const, From2, Rounding_Dir)
00455 #define PPL_SPECIALIZE_GCDEXT(func, To1, From1, From2, To2, To3)        \
00456   PPL_SPECIALIZE_FUN5_0_1(gcdext, func, Result, nonconst, To1,          \
00457                           nonconst, To2, nonconst, To3,                 \
00458                           const, From1, const, From2, Rounding_Dir)
00459 #define PPL_SPECIALIZE_LCM(func, To, From1, From2)                      \
00460   PPL_SPECIALIZE_FUN3_0_1(lcm, func, Result, nonconst, To,              \
00461                           const, From1, const, From2, Rounding_Dir)
00462 #define PPL_SPECIALIZE_INPUT(func, Type)                        \
00463   PPL_SPECIALIZE_FUN1_0_2(input, func, Result, nonconst, Type,  \
00464                           std::istream&, Rounding_Dir)
00465 #define PPL_SPECIALIZE_OUTPUT(func, Type)                       \
00466   PPL_SPECIALIZE_FUN1_1_2(output, func, Result, std::ostream&,  \
00467                           const, Type,                          \
00468                           const Numeric_Format&, Rounding_Dir)
00469 
00470 
00471 PPL_DECLARE_FUN2_0_0(copy,
00472                      void, nonconst, Type1, const, Type2)
00473 PPL_DECLARE_FUN1_0_0(sgn,
00474                      Result_Relation, const, From)
00475 PPL_DECLARE_FUN2_0_0(cmp,
00476                      Result_Relation, const, Type1, const, Type2)
00477 PPL_DECLARE_FUN1_0_3(classify,
00478                      Result, const, Type, bool, bool, bool)
00479 PPL_DECLARE_FUN1_0_0(is_nan,
00480                      bool, const, Type)
00481 PPL_DECLARE_FUN1_0_0(is_minf,
00482                      bool, const, Type)
00483 PPL_DECLARE_FUN1_0_0(is_pinf,
00484                      bool, const, Type)
00485 PPL_DECLARE_FUN1_0_0(is_int,
00486                      bool, const, Type)
00487 PPL_DECLARE_FUN1_0_2(assign_special,
00488                      Result, nonconst, Type, Result_Class, Rounding_Dir)
00489 PPL_DECLARE_FUN1_0_2(construct_special,
00490                      Result, nonconst, Type, Result_Class, Rounding_Dir)
00491 PPL_DECLARE_FUN2_0_1(construct,
00492                      Result, nonconst, To, const, From, Rounding_Dir)
00493 PPL_DECLARE_FUN2_0_1(assign,
00494                      Result, nonconst, To, const, From, Rounding_Dir)
00495 PPL_DECLARE_FUN2_0_1(floor,
00496                      Result, nonconst, To, const, From, Rounding_Dir)
00497 PPL_DECLARE_FUN2_0_1(ceil,
00498                      Result, nonconst, To, const, From, Rounding_Dir)
00499 PPL_DECLARE_FUN2_0_1(trunc,
00500                      Result, nonconst, To, const, From, Rounding_Dir)
00501 PPL_DECLARE_FUN2_0_1(neg,
00502                      Result, nonconst, To, const, From, Rounding_Dir)
00503 PPL_DECLARE_FUN2_0_1(abs,
00504                      Result, nonconst, To, const, From, Rounding_Dir)
00505 PPL_DECLARE_FUN2_0_1(sqrt,
00506                      Result, nonconst, To, const, From, Rounding_Dir)
00507 PPL_DECLARE_FUN3_0_1(add,
00508                      Result, nonconst, To,
00509                      const, From1, const, From2, Rounding_Dir)
00510 PPL_DECLARE_FUN3_0_1(sub,
00511                      Result, nonconst, To,
00512                      const, From1, const, From2, Rounding_Dir)
00513 PPL_DECLARE_FUN3_0_1(mul,
00514                      Result, nonconst, To,
00515                      const, From1, const, From2, Rounding_Dir)
00516 PPL_DECLARE_FUN3_0_1(div,
00517                      Result, nonconst, To,
00518                      const, From1, const, From2, Rounding_Dir)
00519 PPL_DECLARE_FUN3_0_1(rem,
00520                      Result, nonconst, To,
00521                      const, From1, const, From2, Rounding_Dir)
00522 PPL_DECLARE_FUN3_0_1(idiv,
00523                      Result, nonconst, To,
00524                      const, From1, const, From2, Rounding_Dir)
00525 PPL_DECLARE_FUN2_0_2(add_2exp,
00526                      Result, nonconst, To,
00527                      const, From, unsigned int, Rounding_Dir)
00528 PPL_DECLARE_FUN2_0_2(sub_2exp,
00529                      Result, nonconst, To,
00530                      const, From, unsigned int, Rounding_Dir)
00531 PPL_DECLARE_FUN2_0_2(mul_2exp,
00532                      Result, nonconst, To,
00533                      const, From, unsigned int, Rounding_Dir)
00534 PPL_DECLARE_FUN2_0_2(div_2exp,
00535                      Result, nonconst, To,
00536                      const, From, unsigned int, Rounding_Dir)
00537 PPL_DECLARE_FUN2_0_2(smod_2exp,
00538                      Result, nonconst, To,
00539                      const, From, unsigned int, Rounding_Dir)
00540 PPL_DECLARE_FUN2_0_2(umod_2exp,
00541                      Result, nonconst, To,
00542                      const, From, unsigned int, Rounding_Dir)
00543 PPL_DECLARE_FUN3_0_1(add_mul,
00544                      Result, nonconst, To,
00545                      const, From1, const, From2, Rounding_Dir)
00546 PPL_DECLARE_FUN3_0_1(sub_mul,
00547                      Result, nonconst, To,
00548                      const, From1, const, From2, Rounding_Dir)
00549 PPL_DECLARE_FUN3_0_1(gcd,
00550                      Result, nonconst, To,
00551                      const, From1, const, From2, Rounding_Dir)
00552 PPL_DECLARE_FUN5_0_1(gcdext,
00553                      Result, nonconst, To1, nonconst, To2, nonconst, To3,
00554                      const, From1, const, From2, Rounding_Dir)
00555 PPL_DECLARE_FUN3_0_1(lcm,
00556                      Result, nonconst, To,
00557                      const, From1, const, From2, Rounding_Dir)
00558 PPL_DECLARE_FUN1_0_2(input,
00559                      Result, nonconst, Type, std::istream&, Rounding_Dir)
00560 PPL_DECLARE_FUN1_1_2(output,
00561                      Result, std::ostream&, const, Type,
00562                      const Numeric_Format&, Rounding_Dir)
00563 
00564 #undef PPL_DECLARE_FUN1_0_0
00565 #undef PPL_DECLARE_FUN1_0_1
00566 #undef PPL_DECLARE_FUN1_0_2
00567 #undef PPL_DECLARE_FUN1_0_3
00568 #undef PPL_DECLARE_FUN1_1_1
00569 #undef PPL_DECLARE_FUN1_1_2
00570 #undef PPL_DECLARE_FUN1_2_2
00571 #undef PPL_DECLARE_FUN2_0_0
00572 #undef PPL_DECLARE_FUN2_0_1
00573 #undef PPL_DECLARE_FUN2_0_2
00574 #undef PPL_DECLARE_FUN3_0_1
00575 #undef PPL_DECLARE_FUN5_0_1
00576 
00577 template <typename Policy, typename To>
00578 Result round(To& to, Result r, Rounding_Dir dir);
00579 
00580 Result input_mpq(mpq_class& to, std::istream& is);
00581 
00582 } // namespace Checked
00583 
00584 struct Minus_Infinity {
00585   static const Result_Class vclass = VC_MINUS_INFINITY;
00586 };
00587 struct Plus_Infinity {
00588   static const Result_Class vclass = VC_PLUS_INFINITY;
00589 };
00590 struct Not_A_Number {
00591   static const Result_Class vclass = VC_NAN;
00592 };
00593 
00594 template <typename T>
00595 struct Is_Special : public False { };
00596 
00597 template <>
00598 struct Is_Special<Minus_Infinity> : public True {};
00599 
00600 template <>
00601 struct Is_Special<Plus_Infinity> : public True {};
00602 
00603 template <>
00604 struct Is_Special<Not_A_Number> : public True {};
00605 
00606 extern Minus_Infinity MINUS_INFINITY;
00607 extern Plus_Infinity PLUS_INFINITY;
00608 extern Not_A_Number NOT_A_NUMBER;
00609 
00610 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00611 
00612 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00613 template <typename T>
00614 struct Checked_Number_Transparent_Policy {
00616   const_bool_nodef(check_overflow, false);
00617 
00619   const_bool_nodef(check_inf_add_inf, false);
00620 
00622   const_bool_nodef(check_inf_sub_inf, false);
00623 
00625   const_bool_nodef(check_inf_mul_zero, false);
00626 
00628   const_bool_nodef(check_div_zero, false);
00629 
00631   const_bool_nodef(check_inf_div_inf, false);
00632 
00634   const_bool_nodef(check_inf_mod, false);
00635 
00637   const_bool_nodef(check_sqrt_neg, false);
00638 
00640   const_bool_nodef(has_nan, std::numeric_limits<T>::has_quiet_NaN);
00641 
00643   const_bool_nodef(has_infinity, std::numeric_limits<T>::has_infinity);
00644 
00649   const_bool_nodef(convertible, true);
00650 
00652   const_bool_nodef(fpu_check_inexact, false);
00653 
00655   const_bool_nodef(fpu_check_nan_result, false);
00656 
00661   static const Rounding_Dir ROUND_DEFAULT_CONSTRUCTOR = ROUND_NATIVE;
00662 
00667   static const Rounding_Dir ROUND_DEFAULT_OPERATOR = ROUND_NATIVE;
00668 
00673   static const Rounding_Dir ROUND_DEFAULT_INPUT = ROUND_NATIVE;
00674 
00679   static const Rounding_Dir ROUND_DEFAULT_OUTPUT = ROUND_NATIVE;
00680 
00685   static const Rounding_Dir ROUND_DEFAULT_FUNCTION = ROUND_NATIVE;
00686 
00691   static void handle_result(Result r);
00692 };
00693 
00694 } // namespace Parma_Polyhedra_Library
00695 
00696 #define CHECK_P(cond, check) ((cond) ? (check) : (assert(!(check)), false))
00697 
00698 #include "checked.inlines.hh"
00699 #include "checked_int.inlines.hh"
00700 #include "checked_float.inlines.hh"
00701 #include "checked_mpz.inlines.hh"
00702 #include "checked_mpq.inlines.hh"
00703 #include "checked_ext.inlines.hh"
00704 
00705 #undef nonconst
00706 #ifdef PPL_SAVED_nonconst
00707 #define nonconst PPL_SAVED_nonconst
00708 #undef PPL_SAVED_nonconst
00709 #endif
00710 
00711 #undef PPL_FUNCTION_CLASS
00712 #undef PPL_NAN
00713 
00714 #endif // !defined(PPL_checked_defs_hh)