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