PPL  1.2
checked_int_inlines.hh
Go to the documentation of this file.
1 /* Specialized "checked" functions for native integer numbers.
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_int_inlines_hh
25 #define PPL_checked_int_inlines_hh 1
26 
27 #include "C_Integer.hh"
28 #include <cerrno>
29 #include <cstdlib>
30 #include <climits>
31 #include <string>
32 
33 #if !PPL_HAVE_DECL_STRTOLL
34 signed long long
35 strtoll(const char* nptr, char** endptr, int base);
36 #endif
37 
38 #if !PPL_HAVE_DECL_STRTOULL
39 unsigned long long
40 strtoull(const char* nptr, char** endptr, int base);
41 #endif
42 
43 namespace Parma_Polyhedra_Library {
44 
45 namespace Checked {
46 
47 #ifndef PPL_HAVE_INT_FAST16_T
48 typedef int16_t int_fast16_t;
49 #endif
50 
51 #ifndef PPL_HAVE_INT_FAST32_T
52 typedef int32_t int_fast32_t;
53 #endif
54 
55 #ifndef PPL_HAVE_INT_FAST64_T
56 typedef int64_t int_fast64_t;
57 #endif
58 
59 #ifndef PPL_HAVE_UINT_FAST16_T
60 typedef uint16_t uint_fast16_t;
61 #endif
62 
63 #ifndef PPL_HAVE_UINT_FAST32_T
64 typedef uint32_t uint_fast32_t;
65 #endif
66 
67 #ifndef PPL_HAVE_UINT_FAST64_T
68 typedef uint64_t uint_fast64_t;
69 #endif
70 
71 template <typename Policy, typename Type>
72 struct Extended_Int {
74  static const Type minus_infinity = ((C_Integer<Type>::min >= 0)
75  ? (C_Integer<Type>::max - 1)
77  static const Type not_a_number
79  ? (C_Integer<Type>::max - 2 * (Policy::has_infinity ? 1 : 0))
80  : (C_Integer<Type>::min + (Policy::has_infinity ? 1 : 0)));
81  static const Type min
83  + ((C_Integer<Type>::min >= 0)
84  ? 0
85  : ((Policy::has_infinity ? 1 : 0) + (Policy::has_nan ? 1 : 0))));
86  static const Type max
88  - ((C_Integer<Type>::min >= 0)
89  ? (2 * (Policy::has_infinity ? 1 : 0) + (Policy::has_nan ? 1 : 0))
90  : (Policy::has_infinity ? 1 : 0)));
91 };
92 
93 template <typename Policy, typename To>
94 inline Result
96  if (round_up(dir)) {
98  return V_LT_INF;
99  }
100  else {
101  if (Policy::has_infinity) {
103  return V_GT_MINUS_INFINITY;
104  }
106  }
107 }
108 
109 template <typename Policy, typename To>
110 inline Result
112  if (round_down(dir)) {
114  return V_GT_SUP;
115  }
116  else {
117  if (Policy::has_infinity) {
119  return V_LT_PLUS_INFINITY;
120  }
122  }
123 }
124 
125 template <typename Policy, typename To>
126 inline Result
128  if (round_down(dir)) {
129  --to;
130  return V_GT;
131  }
132  return V_LT;
133 }
134 
135 template <typename Policy, typename To>
136 inline Result
138  if (round_up(dir)) {
139  ++to;
140  return V_LT;
141  }
142  return V_GT;
143 }
144 
145 template <typename Policy, typename To>
146 inline Result
148  if (round_down(dir)) {
149  if (to == Extended_Int<Policy, To>::min) {
150  if (Policy::has_infinity) {
152  return V_GT_MINUS_INFINITY;
153  }
155  }
156  else {
157  --to;
158  return V_GT;
159  }
160  }
161  return V_LT;
162 }
163 
164 template <typename Policy, typename To>
165 inline Result
167  if (round_up(dir)) {
168  if (to == Extended_Int<Policy, To>::max) {
169  if (Policy::has_infinity) {
171  return V_LT_PLUS_INFINITY;
172  }
174  }
175  else {
176  ++to;
177  return V_LT;
178  }
179  }
180  return V_GT;
181 }
182 
184 PPL_SPECIALIZE_COPY(copy_generic, signed char)
185 PPL_SPECIALIZE_COPY(copy_generic, signed short)
186 PPL_SPECIALIZE_COPY(copy_generic, signed int)
187 PPL_SPECIALIZE_COPY(copy_generic, signed long)
188 PPL_SPECIALIZE_COPY(copy_generic, signed long long)
189 PPL_SPECIALIZE_COPY(copy_generic, unsigned char)
190 PPL_SPECIALIZE_COPY(copy_generic, unsigned short)
191 PPL_SPECIALIZE_COPY(copy_generic, unsigned int)
192 PPL_SPECIALIZE_COPY(copy_generic, unsigned long)
193 PPL_SPECIALIZE_COPY(copy_generic, unsigned long long)
194 
195 template <typename Policy, typename Type>
196 inline Result
197 classify_int(const Type v, bool nan, bool inf, bool sign) {
198  if (Policy::has_nan
199  && (nan || sign)
201  return V_NAN;
202  }
203  if (!inf && !sign) {
204  return V_LGE;
205  }
206  if (Policy::has_infinity) {
208  return inf ? V_EQ_MINUS_INFINITY : V_LT;
209  }
211  return inf ? V_EQ_PLUS_INFINITY : V_GT;
212  }
213  }
214  if (sign) {
215  if (v < 0) {
216  return V_LT;
217  }
218  if (v > 0) {
219  return V_GT;
220  }
221  return V_EQ;
222  }
223  return V_LGE;
224 }
225 
228 PPL_SPECIALIZE_CLASSIFY(classify_int, signed short)
229 PPL_SPECIALIZE_CLASSIFY(classify_int, signed int)
230 PPL_SPECIALIZE_CLASSIFY(classify_int, signed long)
231 PPL_SPECIALIZE_CLASSIFY(classify_int, signed long long)
232 PPL_SPECIALIZE_CLASSIFY(classify_int, unsigned char)
233 PPL_SPECIALIZE_CLASSIFY(classify_int, unsigned short)
234 PPL_SPECIALIZE_CLASSIFY(classify_int, unsigned int)
235 PPL_SPECIALIZE_CLASSIFY(classify_int, unsigned long)
236 PPL_SPECIALIZE_CLASSIFY(classify_int, unsigned long long)
237 
238 template <typename Policy, typename Type>
239 inline bool
241  return Policy::has_nan && v == Extended_Int<Policy, Type>::not_a_number;
242 }
243 
245 PPL_SPECIALIZE_IS_NAN(is_nan_int, signed char)
246 PPL_SPECIALIZE_IS_NAN(is_nan_int, signed short)
247 PPL_SPECIALIZE_IS_NAN(is_nan_int, signed int)
248 PPL_SPECIALIZE_IS_NAN(is_nan_int, signed long)
249 PPL_SPECIALIZE_IS_NAN(is_nan_int, signed long long)
250 PPL_SPECIALIZE_IS_NAN(is_nan_int, unsigned char)
251 PPL_SPECIALIZE_IS_NAN(is_nan_int, unsigned short)
252 PPL_SPECIALIZE_IS_NAN(is_nan_int, unsigned int)
253 PPL_SPECIALIZE_IS_NAN(is_nan_int, unsigned long)
254 PPL_SPECIALIZE_IS_NAN(is_nan_int, unsigned long long)
255 
256 template <typename Policy, typename Type>
257 inline bool
259  return Policy::has_infinity
261 }
262 
265 PPL_SPECIALIZE_IS_MINF(is_minf_int, signed short)
266 PPL_SPECIALIZE_IS_MINF(is_minf_int, signed int)
267 PPL_SPECIALIZE_IS_MINF(is_minf_int, signed long)
268 PPL_SPECIALIZE_IS_MINF(is_minf_int, signed long long)
269 PPL_SPECIALIZE_IS_MINF(is_minf_int, unsigned char)
270 PPL_SPECIALIZE_IS_MINF(is_minf_int, unsigned short)
271 PPL_SPECIALIZE_IS_MINF(is_minf_int, unsigned int)
272 PPL_SPECIALIZE_IS_MINF(is_minf_int, unsigned long)
273 PPL_SPECIALIZE_IS_MINF(is_minf_int, unsigned long long)
274 
275 template <typename Policy, typename Type>
276 inline bool
278  return Policy::has_infinity
280 }
281 
284 PPL_SPECIALIZE_IS_PINF(is_pinf_int, signed short)
285 PPL_SPECIALIZE_IS_PINF(is_pinf_int, signed int)
286 PPL_SPECIALIZE_IS_PINF(is_pinf_int, signed long)
287 PPL_SPECIALIZE_IS_PINF(is_pinf_int, signed long long)
288 PPL_SPECIALIZE_IS_PINF(is_pinf_int, unsigned char)
289 PPL_SPECIALIZE_IS_PINF(is_pinf_int, unsigned short)
290 PPL_SPECIALIZE_IS_PINF(is_pinf_int, unsigned int)
291 PPL_SPECIALIZE_IS_PINF(is_pinf_int, unsigned long)
292 PPL_SPECIALIZE_IS_PINF(is_pinf_int, unsigned long long)
293 
294 template <typename Policy, typename Type>
295 inline bool
297  return !is_nan<Policy>(v);
298 }
299 
301 PPL_SPECIALIZE_IS_INT(is_int_int, signed char)
302 PPL_SPECIALIZE_IS_INT(is_int_int, signed short)
303 PPL_SPECIALIZE_IS_INT(is_int_int, signed int)
304 PPL_SPECIALIZE_IS_INT(is_int_int, signed long)
305 PPL_SPECIALIZE_IS_INT(is_int_int, signed long long)
306 PPL_SPECIALIZE_IS_INT(is_int_int, unsigned char)
307 PPL_SPECIALIZE_IS_INT(is_int_int, unsigned short)
308 PPL_SPECIALIZE_IS_INT(is_int_int, unsigned int)
309 PPL_SPECIALIZE_IS_INT(is_int_int, unsigned long)
310 PPL_SPECIALIZE_IS_INT(is_int_int, unsigned long long)
311 
312 template <typename Policy, typename Type>
313 inline Result
315  PPL_ASSERT(c == VC_MINUS_INFINITY || c == VC_PLUS_INFINITY || c == VC_NAN);
316  switch (c) {
317  case VC_NAN:
318  if (Policy::has_nan) {
320  return V_NAN;
321  }
322  return V_NAN | V_UNREPRESENTABLE;
323  case VC_MINUS_INFINITY:
324  if (Policy::has_infinity) {
326  return V_EQ_MINUS_INFINITY;
327  }
328  if (round_up(dir)) {
330  return V_LT_INF;
331  }
333  case VC_PLUS_INFINITY:
334  if (Policy::has_infinity) {
336  return V_EQ_PLUS_INFINITY;
337  }
338  if (round_down(dir)) {
340  return V_GT_SUP;
341  }
343  default:
344  PPL_UNREACHABLE;
345  return V_NAN | V_UNREPRESENTABLE;
346  }
347 }
348 
351 PPL_SPECIALIZE_ASSIGN_SPECIAL(assign_special_int, signed short)
352 PPL_SPECIALIZE_ASSIGN_SPECIAL(assign_special_int, signed int)
353 PPL_SPECIALIZE_ASSIGN_SPECIAL(assign_special_int, signed long)
354 PPL_SPECIALIZE_ASSIGN_SPECIAL(assign_special_int, signed long long)
355 PPL_SPECIALIZE_ASSIGN_SPECIAL(assign_special_int, unsigned char)
356 PPL_SPECIALIZE_ASSIGN_SPECIAL(assign_special_int, unsigned short)
357 PPL_SPECIALIZE_ASSIGN_SPECIAL(assign_special_int, unsigned int)
358 PPL_SPECIALIZE_ASSIGN_SPECIAL(assign_special_int, unsigned long)
359 PPL_SPECIALIZE_ASSIGN_SPECIAL(assign_special_int, unsigned long long)
360 
361 template <typename To_Policy, typename From_Policy, typename To, typename From>
362 inline Result
364  if (sizeof(To) < sizeof(From)
365  || (sizeof(To) == sizeof(From)
368  if (CHECK_P(To_Policy::check_overflow,
369  PPL_LT_SILENT(from,
370  static_cast<From>(Extended_Int<To_Policy, To>::min)))) {
371  return set_neg_overflow_int<To_Policy>(to, dir);
372  }
373  if (CHECK_P(To_Policy::check_overflow,
374  PPL_GT_SILENT(from,
375  static_cast<From>(Extended_Int<To_Policy, To>::max)))) {
376  return set_pos_overflow_int<To_Policy>(to, dir);
377  }
378  }
379  to = static_cast<To>(from);
380  return V_EQ;
381 }
382 
383 template <typename To_Policy, typename From_Policy, typename To, typename From>
384 inline Result
386  if (sizeof(To) <= sizeof(From)) {
387  if (CHECK_P(To_Policy::check_overflow,
388  from > static_cast<From>(Extended_Int<To_Policy, To>::max))) {
389  return set_pos_overflow_int<To_Policy>(to, dir);
390  }
391  }
392  to = static_cast<To>(from);
393  return V_EQ;
394 }
395 
396 template <typename To_Policy, typename From_Policy, typename To, typename From>
397 inline Result
399  if (CHECK_P(To_Policy::check_overflow, from < 0)) {
400  return set_neg_overflow_int<To_Policy>(to, dir);
401  }
402  if (sizeof(To) < sizeof(From)) {
403  if (CHECK_P(To_Policy::check_overflow,
404  from > static_cast<From>(Extended_Int<To_Policy, To>::max))) {
405  return set_pos_overflow_int<To_Policy>(to, dir);
406  }
407  }
408  to = static_cast<To>(from);
409  return V_EQ;
410 }
411 
412 template <typename To_Policy, typename From_Policy, typename To, typename From>
413 inline Result
415  if (sizeof(To) < sizeof(From)
416  || (sizeof(To) == sizeof(From)
418  if (CHECK_P(To_Policy::check_overflow,
419  PPL_GT_SILENT(from,
420  static_cast<From>(Extended_Int<To_Policy, To>::max)))) {
421  return set_pos_overflow_int<To_Policy>(to, dir);
422  }
423  }
424  to = static_cast<To>(from);
425  return V_EQ;
426 }
427 
428 
429 #define PPL_ASSIGN2_SIGNED_SIGNED(Smaller, Larger) \
430 PPL_SPECIALIZE_ASSIGN(assign_signed_int_signed_int, Smaller, Larger) \
431 PPL_SPECIALIZE_ASSIGN(assign_signed_int_signed_int, Larger, Smaller)
432 
433 #define PPL_ASSIGN2_UNSIGNED_UNSIGNED(Smaller, Larger) \
434 PPL_SPECIALIZE_ASSIGN(assign_unsigned_int_unsigned_int, Smaller, Larger) \
435 PPL_SPECIALIZE_ASSIGN(assign_unsigned_int_unsigned_int, Larger, Smaller)
436 
437 #define PPL_ASSIGN2_UNSIGNED_SIGNED(Smaller, Larger) \
438 PPL_SPECIALIZE_ASSIGN(assign_unsigned_int_signed_int, Smaller, Larger) \
439 PPL_SPECIALIZE_ASSIGN(assign_signed_int_unsigned_int, Larger, Smaller)
440 
441 #define PPL_ASSIGN2_SIGNED_UNSIGNED(Smaller, Larger) \
442 PPL_SPECIALIZE_ASSIGN(assign_signed_int_unsigned_int, Smaller, Larger) \
443 PPL_SPECIALIZE_ASSIGN(assign_unsigned_int_signed_int, Larger, Smaller)
444 
445 #define PPL_ASSIGN_SIGNED(Type) \
446 PPL_SPECIALIZE_ASSIGN(assign_signed_int_signed_int, Type, Type)
447 #define PPL_ASSIGN_UNSIGNED(Type) \
448 PPL_SPECIALIZE_ASSIGN(assign_unsigned_int_unsigned_int, Type, Type)
449 
450 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
451 PPL_ASSIGN_SIGNED(char)
452 #endif
453 PPL_ASSIGN_SIGNED(signed char)
454 PPL_ASSIGN_SIGNED(signed short)
455 PPL_ASSIGN_SIGNED(signed int)
456 PPL_ASSIGN_SIGNED(signed long)
457 PPL_ASSIGN_SIGNED(signed long long)
458 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
460 #endif
461 PPL_ASSIGN_UNSIGNED(unsigned char)
462 PPL_ASSIGN_UNSIGNED(unsigned short)
463 PPL_ASSIGN_UNSIGNED(unsigned int)
464 PPL_ASSIGN_UNSIGNED(unsigned long)
465 PPL_ASSIGN_UNSIGNED(unsigned long long)
466 
467 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
468 PPL_ASSIGN2_SIGNED_SIGNED(char, signed short)
469 PPL_ASSIGN2_SIGNED_SIGNED(char, signed int)
470 PPL_ASSIGN2_SIGNED_SIGNED(char, signed long)
471 PPL_ASSIGN2_SIGNED_SIGNED(char, signed long long)
472 #endif
473 PPL_ASSIGN2_SIGNED_SIGNED(signed char, signed short)
474 PPL_ASSIGN2_SIGNED_SIGNED(signed char, signed int)
475 PPL_ASSIGN2_SIGNED_SIGNED(signed char, signed long)
476 PPL_ASSIGN2_SIGNED_SIGNED(signed char, signed long long)
477 PPL_ASSIGN2_SIGNED_SIGNED(signed short, signed int)
478 PPL_ASSIGN2_SIGNED_SIGNED(signed short, signed long)
479 PPL_ASSIGN2_SIGNED_SIGNED(signed short, signed long long)
480 PPL_ASSIGN2_SIGNED_SIGNED(signed int, signed long)
481 PPL_ASSIGN2_SIGNED_SIGNED(signed int, signed long long)
482 PPL_ASSIGN2_SIGNED_SIGNED(signed long, signed long long)
483 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
484 PPL_ASSIGN2_UNSIGNED_UNSIGNED(char, unsigned short)
485 PPL_ASSIGN2_UNSIGNED_UNSIGNED(char, unsigned int)
486 PPL_ASSIGN2_UNSIGNED_UNSIGNED(char, unsigned long)
487 PPL_ASSIGN2_UNSIGNED_UNSIGNED(char, unsigned long long)
488 #endif
489 PPL_ASSIGN2_UNSIGNED_UNSIGNED(unsigned char, unsigned short)
490 PPL_ASSIGN2_UNSIGNED_UNSIGNED(unsigned char, unsigned int)
491 PPL_ASSIGN2_UNSIGNED_UNSIGNED(unsigned char, unsigned long)
492 PPL_ASSIGN2_UNSIGNED_UNSIGNED(unsigned char, unsigned long long)
493 PPL_ASSIGN2_UNSIGNED_UNSIGNED(unsigned short, unsigned int)
494 PPL_ASSIGN2_UNSIGNED_UNSIGNED(unsigned short, unsigned long)
495 PPL_ASSIGN2_UNSIGNED_UNSIGNED(unsigned short, unsigned long long)
496 PPL_ASSIGN2_UNSIGNED_UNSIGNED(unsigned int, unsigned long)
497 PPL_ASSIGN2_UNSIGNED_UNSIGNED(unsigned int, unsigned long long)
498 PPL_ASSIGN2_UNSIGNED_UNSIGNED(unsigned long, unsigned long long)
499 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
500 PPL_ASSIGN2_UNSIGNED_SIGNED(char, signed short)
501 PPL_ASSIGN2_UNSIGNED_SIGNED(char, signed int)
502 PPL_ASSIGN2_UNSIGNED_SIGNED(char, signed long)
503 PPL_ASSIGN2_UNSIGNED_SIGNED(char, signed long long)
504 #endif
505 PPL_ASSIGN2_UNSIGNED_SIGNED(unsigned char, signed short)
506 PPL_ASSIGN2_UNSIGNED_SIGNED(unsigned char, signed int)
507 PPL_ASSIGN2_UNSIGNED_SIGNED(unsigned char, signed long)
508 PPL_ASSIGN2_UNSIGNED_SIGNED(unsigned char, signed long long)
509 PPL_ASSIGN2_UNSIGNED_SIGNED(unsigned short, signed int)
510 PPL_ASSIGN2_UNSIGNED_SIGNED(unsigned short, signed long)
511 PPL_ASSIGN2_UNSIGNED_SIGNED(unsigned short, signed long long)
512 PPL_ASSIGN2_UNSIGNED_SIGNED(unsigned int, signed long)
513 PPL_ASSIGN2_UNSIGNED_SIGNED(unsigned int, signed long long)
514 PPL_ASSIGN2_UNSIGNED_SIGNED(unsigned long, signed long long)
515 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
516 PPL_ASSIGN2_SIGNED_UNSIGNED(char, unsigned char)
517 PPL_ASSIGN2_SIGNED_UNSIGNED(char, unsigned short)
518 PPL_ASSIGN2_SIGNED_UNSIGNED(char, unsigned int)
519 PPL_ASSIGN2_SIGNED_UNSIGNED(char, unsigned long)
520 PPL_ASSIGN2_SIGNED_UNSIGNED(char, unsigned long long)
521 #else
522 PPL_ASSIGN2_SIGNED_UNSIGNED(signed char, char)
523 #endif
524 PPL_ASSIGN2_SIGNED_UNSIGNED(signed char, unsigned char)
525 PPL_ASSIGN2_SIGNED_UNSIGNED(signed char, unsigned short)
526 PPL_ASSIGN2_SIGNED_UNSIGNED(signed char, unsigned int)
527 PPL_ASSIGN2_SIGNED_UNSIGNED(signed char, unsigned long)
528 PPL_ASSIGN2_SIGNED_UNSIGNED(signed char, unsigned long long)
529 PPL_ASSIGN2_SIGNED_UNSIGNED(signed short, unsigned short)
530 PPL_ASSIGN2_SIGNED_UNSIGNED(signed short, unsigned int)
531 PPL_ASSIGN2_SIGNED_UNSIGNED(signed short, unsigned long)
532 PPL_ASSIGN2_SIGNED_UNSIGNED(signed short, unsigned long long)
533 PPL_ASSIGN2_SIGNED_UNSIGNED(signed int, unsigned int)
534 PPL_ASSIGN2_SIGNED_UNSIGNED(signed int, unsigned long)
535 PPL_ASSIGN2_SIGNED_UNSIGNED(signed int, unsigned long long)
536 PPL_ASSIGN2_SIGNED_UNSIGNED(signed long, unsigned long)
537 PPL_ASSIGN2_SIGNED_UNSIGNED(signed long, unsigned long long)
538 PPL_ASSIGN2_SIGNED_UNSIGNED(signed long long, unsigned long long)
539 
540 template <typename To_Policy, typename From_Policy, typename To, typename From>
541 inline Result
542 assign_int_float(To& to, const From from, Rounding_Dir dir) {
543  if (is_nan<From_Policy>(from)) {
544  return assign_special<To_Policy>(to, VC_NAN, ROUND_IGNORE);
545  }
546  else if (is_minf<From_Policy>(from)) {
547  return assign_special<To_Policy>(to, VC_MINUS_INFINITY, dir);
548  }
549  else if (is_pinf<From_Policy>(from)) {
550  return assign_special<To_Policy>(to, VC_PLUS_INFINITY, dir);
551  }
552 #if 0
553  // FIXME: this is correct but it is inefficient and breaks the build
554  // for the missing definition of static const members (a problem present
555  // also in other areas of the PPL).
556  if (CHECK_P(To_Policy::check_overflow,
558  return set_neg_overflow_int<To_Policy>(to, dir);
559  }
560  if (CHECK_P(To_Policy::check_overflow,
562  return set_pos_overflow_int<To_Policy>(to, dir);
563  }
564 #else
565  if (CHECK_P(To_Policy::check_overflow,
567  return set_neg_overflow_int<To_Policy>(to, dir);
568  }
569  if (CHECK_P(To_Policy::check_overflow,
571  return set_pos_overflow_int<To_Policy>(to, dir);
572  }
573 #endif
574  if (round_not_requested(dir)) {
575  to = from;
576  return V_LGE;
577  }
578  From i_from = rint(from);
579  to = i_from;
580  if (from == i_from) {
581  return V_EQ;
582  }
583  if (round_direct(ROUND_UP)) {
584  return round_lt_int<To_Policy>(to, dir);
585  }
586  if (round_direct(ROUND_DOWN)) {
587  return round_gt_int<To_Policy>(to, dir);
588  }
589  if (from < i_from) {
590  return round_lt_int<To_Policy>(to, dir);
591  }
592  PPL_ASSERT(from > i_from);
593  return round_gt_int<To_Policy>(to, dir);
594 }
595 
597 PPL_SPECIALIZE_ASSIGN(assign_int_float, signed char, float)
598 PPL_SPECIALIZE_ASSIGN(assign_int_float, signed short, float)
599 PPL_SPECIALIZE_ASSIGN(assign_int_float, signed int, float)
600 PPL_SPECIALIZE_ASSIGN(assign_int_float, signed long, float)
601 PPL_SPECIALIZE_ASSIGN(assign_int_float, signed long long, float)
602 PPL_SPECIALIZE_ASSIGN(assign_int_float, unsigned char, float)
603 PPL_SPECIALIZE_ASSIGN(assign_int_float, unsigned short, float)
604 PPL_SPECIALIZE_ASSIGN(assign_int_float, unsigned int, float)
605 PPL_SPECIALIZE_ASSIGN(assign_int_float, unsigned long, float)
606 PPL_SPECIALIZE_ASSIGN(assign_int_float, unsigned long long, float)
607 
608 PPL_SPECIALIZE_ASSIGN(assign_int_float, char, double)
609 PPL_SPECIALIZE_ASSIGN(assign_int_float, signed char, double)
610 PPL_SPECIALIZE_ASSIGN(assign_int_float, signed short, double)
611 PPL_SPECIALIZE_ASSIGN(assign_int_float, signed int, double)
612 PPL_SPECIALIZE_ASSIGN(assign_int_float, signed long, double)
613 PPL_SPECIALIZE_ASSIGN(assign_int_float, signed long long, double)
614 PPL_SPECIALIZE_ASSIGN(assign_int_float, unsigned char, double)
615 PPL_SPECIALIZE_ASSIGN(assign_int_float, unsigned short, double)
616 PPL_SPECIALIZE_ASSIGN(assign_int_float, unsigned int, double)
617 PPL_SPECIALIZE_ASSIGN(assign_int_float, unsigned long, double)
618 PPL_SPECIALIZE_ASSIGN(assign_int_float, unsigned long long, double)
619 
620 PPL_SPECIALIZE_ASSIGN(assign_int_float, char, long double)
621 PPL_SPECIALIZE_ASSIGN(assign_int_float, signed char, long double)
622 PPL_SPECIALIZE_ASSIGN(assign_int_float, signed short, long double)
623 PPL_SPECIALIZE_ASSIGN(assign_int_float, signed int, long double)
624 PPL_SPECIALIZE_ASSIGN(assign_int_float, signed long, long double)
625 PPL_SPECIALIZE_ASSIGN(assign_int_float, signed long long, long double)
626 PPL_SPECIALIZE_ASSIGN(assign_int_float, unsigned char, long double)
627 PPL_SPECIALIZE_ASSIGN(assign_int_float, unsigned short, long double)
628 PPL_SPECIALIZE_ASSIGN(assign_int_float, unsigned int, long double)
629 PPL_SPECIALIZE_ASSIGN(assign_int_float, unsigned long, long double)
630 PPL_SPECIALIZE_ASSIGN(assign_int_float, unsigned long long, long double)
631 
632 #undef PPL_ASSIGN_SIGNED
633 #undef PPL_ASSIGN_UNSIGNED
634 #undef PPL_ASSIGN2_SIGNED_SIGNED
635 #undef PPL_ASSIGN2_UNSIGNED_UNSIGNED
636 #undef PPL_ASSIGN2_UNSIGNED_SIGNED
637 #undef PPL_ASSIGN2_SIGNED_UNSIGNED
638 
639 template <typename To_Policy, typename From_Policy, typename To>
640 inline Result
641 assign_signed_int_mpz(To& to, const mpz_class& from, Rounding_Dir dir) {
642  if (sizeof(To) <= sizeof(signed long)) {
643  if (!To_Policy::check_overflow) {
644  to = from.get_si();
645  return V_EQ;
646  }
647  if (from.fits_slong_p()) {
648  signed long v = from.get_si();
650  return set_neg_overflow_int<To_Policy>(to, dir);
651  }
653  return set_pos_overflow_int<To_Policy>(to, dir);
654  }
655  to = v;
656  return V_EQ;
657  }
658  }
659  else {
660  mpz_srcptr m = from.get_mpz_t();
661  size_t sz = mpz_size(m);
662  if (sz <= sizeof(To) / sizeof(mp_limb_t)) {
663  if (sz == 0) {
664  to = 0;
665  return V_EQ;
666  }
667  To v;
668  mpz_export(&v, 0, -1, sizeof(To), 0, 0, m);
669  if (v >= 0) {
670  if (::sgn(from) < 0) {
671  return neg<To_Policy, To_Policy>(to, v, dir);
672  }
673  to = v;
674  return V_EQ;
675  }
676  }
677  }
678  return (::sgn(from) < 0)
679  ? set_neg_overflow_int<To_Policy>(to, dir)
680  : set_pos_overflow_int<To_Policy>(to, dir);
681 }
682 
683 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
685 #endif
686 PPL_SPECIALIZE_ASSIGN(assign_signed_int_mpz, signed char, mpz_class)
687 PPL_SPECIALIZE_ASSIGN(assign_signed_int_mpz, signed short, mpz_class)
688 PPL_SPECIALIZE_ASSIGN(assign_signed_int_mpz, signed int, mpz_class)
689 PPL_SPECIALIZE_ASSIGN(assign_signed_int_mpz, signed long, mpz_class)
690 PPL_SPECIALIZE_ASSIGN(assign_signed_int_mpz, signed long long, mpz_class)
691 
692 template <typename To_Policy, typename From_Policy, typename To>
693 inline Result
694 assign_unsigned_int_mpz(To& to, const mpz_class& from, Rounding_Dir dir) {
695  if (CHECK_P(To_Policy::check_overflow, ::sgn(from) < 0)) {
696  return set_neg_overflow_int<To_Policy>(to, dir);
697  }
698  if (sizeof(To) <= sizeof(unsigned long)) {
699  if (!To_Policy::check_overflow) {
700  to = static_cast<To>(from.get_ui());
701  return V_EQ;
702  }
703  if (from.fits_ulong_p()) {
704  const unsigned long v = from.get_ui();
706  return set_pos_overflow_int<To_Policy>(to, dir);
707  }
708  to = static_cast<To>(v);
709  return V_EQ;
710  }
711  }
712  else {
713  const mpz_srcptr m = from.get_mpz_t();
714  const size_t sz = mpz_size(m);
715  if (sz <= sizeof(To) / sizeof(mp_limb_t)) {
716  if (sz == 0) {
717  to = 0;
718  }
719  else {
720  mpz_export(&to, 0, -1, sizeof(To), 0, 0, m);
721  }
722  return V_EQ;
723  }
724  }
725  return set_pos_overflow_int<To_Policy>(to, dir);
726 }
727 
728 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
730 #endif
731 PPL_SPECIALIZE_ASSIGN(assign_unsigned_int_mpz, unsigned char, mpz_class)
732 PPL_SPECIALIZE_ASSIGN(assign_unsigned_int_mpz, unsigned short, mpz_class)
733 PPL_SPECIALIZE_ASSIGN(assign_unsigned_int_mpz, unsigned int, mpz_class)
734 PPL_SPECIALIZE_ASSIGN(assign_unsigned_int_mpz, unsigned long, mpz_class)
735 PPL_SPECIALIZE_ASSIGN(assign_unsigned_int_mpz, unsigned long long, mpz_class)
736 
737 template <typename To_Policy, typename From_Policy, typename To>
738 inline Result
739 assign_int_mpq(To& to, const mpq_class& from, Rounding_Dir dir) {
740  mpz_srcptr n = from.get_num().get_mpz_t();
741  mpz_srcptr d = from.get_den().get_mpz_t();
742  PPL_DIRTY_TEMP(mpz_class, q);
743  mpz_ptr q_z = q.get_mpz_t();
744  if (round_not_requested(dir)) {
745  mpz_tdiv_q(q_z, n, d);
746  Result r = assign<To_Policy, void>(to, q, dir);
747  if (r != V_EQ) {
748  return r;
749  }
750  return V_LGE;
751  }
752  mpz_t rem;
753  int sign;
754  mpz_init(rem);
755  mpz_tdiv_qr(q_z, rem, n, d);
756  sign = mpz_sgn(rem);
757  mpz_clear(rem);
758  Result r = assign<To_Policy, void>(to, q, dir);
759  if (r != V_EQ) {
760  return r;
761  }
762  switch (sign) {
763  case -1:
764  return round_lt_int<To_Policy>(to, dir);
765  case 1:
766  return round_gt_int<To_Policy>(to, dir);
767  default:
768  return V_EQ;
769  }
770 }
771 
772 PPL_SPECIALIZE_ASSIGN(assign_int_mpq, char, mpq_class)
773 PPL_SPECIALIZE_ASSIGN(assign_int_mpq, signed char, mpq_class)
774 PPL_SPECIALIZE_ASSIGN(assign_int_mpq, signed short, mpq_class)
775 PPL_SPECIALIZE_ASSIGN(assign_int_mpq, signed int, mpq_class)
776 PPL_SPECIALIZE_ASSIGN(assign_int_mpq, signed long, mpq_class)
777 PPL_SPECIALIZE_ASSIGN(assign_int_mpq, signed long long, mpq_class)
778 PPL_SPECIALIZE_ASSIGN(assign_int_mpq, unsigned char, mpq_class)
779 PPL_SPECIALIZE_ASSIGN(assign_int_mpq, unsigned short, mpq_class)
780 PPL_SPECIALIZE_ASSIGN(assign_int_mpq, unsigned int, mpq_class)
781 PPL_SPECIALIZE_ASSIGN(assign_int_mpq, unsigned long, mpq_class)
782 PPL_SPECIALIZE_ASSIGN(assign_int_mpq, unsigned long long, mpq_class)
783 
784 #if ~0 != -1
785 #error "Only two's complement is supported"
786 #endif
787 
788 #if UCHAR_MAX == 0xff
789 #define CHAR_BITS 8
790 #else
791 #error "Unexpected max for unsigned char"
792 #endif
793 
794 #if USHRT_MAX == 0xffff
795 #define SHRT_BITS 16
796 #else
797 #error "Unexpected max for unsigned short"
798 #endif
799 
800 #if UINT_MAX == 0xffffffff
801 #define INT_BITS 32
802 #else
803 #error "Unexpected max for unsigned int"
804 #endif
805 
806 #if ULONG_MAX == 0xffffffffUL
807 #define LONG_BITS 32
808 #elif ULONG_MAX == 0xffffffffffffffffULL
809 #define LONG_BITS 64
810 #else
811 #error "Unexpected max for unsigned long"
812 #endif
813 
814 #if ULLONG_MAX == 0xffffffffffffffffULL
815 #define LONG_LONG_BITS 64
816 #else
817 #error "Unexpected max for unsigned long long"
818 #endif
819 
820 
821 template <typename T>
822 struct Larger;
823 
824 // The following may be tuned for performance on specific architectures.
825 //
826 // Current guidelines:
827 // - avoid division where possible (larger type variant for mul)
828 // - use larger type variant for types smaller than architecture bit size
829 
830 template <>
831 struct Larger<char> {
832  const_bool_nodef(use_for_neg, true);
833  const_bool_nodef(use_for_add, true);
834  const_bool_nodef(use_for_sub, true);
835  const_bool_nodef(use_for_mul, true);
836  typedef int_fast16_t type_for_neg;
837  typedef int_fast16_t type_for_add;
838  typedef int_fast16_t type_for_sub;
839  typedef int_fast16_t type_for_mul;
840 };
841 
842 template <>
843 struct Larger<signed char> {
844  const_bool_nodef(use_for_neg, true);
845  const_bool_nodef(use_for_add, true);
846  const_bool_nodef(use_for_sub, true);
847  const_bool_nodef(use_for_mul, true);
848  typedef int_fast16_t type_for_neg;
849  typedef int_fast16_t type_for_add;
850  typedef int_fast16_t type_for_sub;
851  typedef int_fast16_t type_for_mul;
852 };
853 
854 template <>
855 struct Larger<unsigned char> {
856  const_bool_nodef(use_for_neg, true);
857  const_bool_nodef(use_for_add, true);
858  const_bool_nodef(use_for_sub, true);
859  const_bool_nodef(use_for_mul, true);
860  typedef int_fast16_t type_for_neg;
861  typedef uint_fast16_t type_for_add;
862  typedef int_fast16_t type_for_sub;
863  typedef uint_fast16_t type_for_mul;
864 };
865 
866 template <>
867 struct Larger<signed short> {
868  const_bool_nodef(use_for_neg, true);
869  const_bool_nodef(use_for_add, true);
870  const_bool_nodef(use_for_sub, true);
871  const_bool_nodef(use_for_mul, true);
872  typedef int_fast32_t type_for_neg;
873  typedef int_fast32_t type_for_add;
874  typedef int_fast32_t type_for_sub;
875  typedef int_fast32_t type_for_mul;
876 };
877 
878 template <>
879 struct Larger<unsigned short> {
880  const_bool_nodef(use_for_neg, true);
881  const_bool_nodef(use_for_add, true);
882  const_bool_nodef(use_for_sub, true);
883  const_bool_nodef(use_for_mul, true);
884  typedef int_fast32_t type_for_neg;
885  typedef uint_fast32_t type_for_add;
886  typedef int_fast32_t type_for_sub;
887  typedef uint_fast32_t type_for_mul;
888 };
889 
890 template <>
891 struct Larger<signed int> {
892  const_bool_nodef(use_for_neg, (LONG_BITS == 64));
893  const_bool_nodef(use_for_add, (LONG_BITS == 64));
894  const_bool_nodef(use_for_sub, (LONG_BITS == 64));
895  const_bool_nodef(use_for_mul, true);
896  typedef int_fast64_t type_for_neg;
897  typedef int_fast64_t type_for_add;
898  typedef int_fast64_t type_for_sub;
899  typedef int_fast64_t type_for_mul;
900 };
901 
902 template <>
903 struct Larger<unsigned int> {
904  const_bool_nodef(use_for_neg, (LONG_BITS == 64));
905  const_bool_nodef(use_for_add, (LONG_BITS == 64));
906  const_bool_nodef(use_for_sub, (LONG_BITS == 64));
907  const_bool_nodef(use_for_mul, true);
908  typedef int_fast64_t type_for_neg;
909  typedef uint_fast64_t type_for_add;
910  typedef int_fast64_t type_for_sub;
911  typedef uint_fast64_t type_for_mul;
912 };
913 
914 template <>
915 struct Larger<signed long> {
916  const_bool_nodef(use_for_neg, false);
917  const_bool_nodef(use_for_add, false);
918  const_bool_nodef(use_for_sub, false);
919  const_bool_nodef(use_for_mul, (LONG_BITS == 32));
920  typedef int_fast64_t type_for_neg;
921  typedef int_fast64_t type_for_add;
922  typedef int_fast64_t type_for_sub;
923  typedef int_fast64_t type_for_mul;
924 };
925 
926 template <>
927 struct Larger<unsigned long> {
928  const_bool_nodef(use_for_neg, false);
929  const_bool_nodef(use_for_add, false);
930  const_bool_nodef(use_for_sub, false);
931  const_bool_nodef(use_for_mul, (LONG_BITS == 32));
932  typedef int_fast64_t type_for_neg;
933  typedef uint_fast64_t type_for_add;
934  typedef int_fast64_t type_for_sub;
935  typedef uint_fast64_t type_for_mul;
936 };
937 
938 template <>
939 struct Larger<signed long long> {
940  const_bool_nodef(use_for_neg, false);
941  const_bool_nodef(use_for_add, false);
942  const_bool_nodef(use_for_sub, false);
943  const_bool_nodef(use_for_mul, false);
944  typedef int_fast64_t type_for_neg;
945  typedef int_fast64_t type_for_add;
946  typedef int_fast64_t type_for_sub;
947  typedef int_fast64_t type_for_mul;
948 };
949 
950 template <>
951 struct Larger<unsigned long long> {
952  const_bool_nodef(use_for_neg, false);
953  const_bool_nodef(use_for_add, false);
954  const_bool_nodef(use_for_sub, false);
955  const_bool_nodef(use_for_mul, false);
956  typedef int_fast64_t type_for_neg;
957  typedef uint_fast64_t type_for_add;
958  typedef int_fast64_t type_for_sub;
959  typedef uint_fast64_t type_for_mul;
960 };
961 
962 template <typename To_Policy, typename From_Policy, typename Type>
963 inline Result
964 neg_int_larger(Type& to, const Type x, Rounding_Dir dir) {
965  typename Larger<Type>::type_for_neg l = x;
966  l = -l;
967  return assign<To_Policy, To_Policy>(to, l, dir);
968 }
969 
970 template <typename To_Policy, typename From1_Policy, typename From2_Policy,
971  typename Type>
972 inline Result
973 add_int_larger(Type& to, const Type x, const Type y, Rounding_Dir dir) {
974  typename Larger<Type>::type_for_add l = x;
975  l += y;
976  return assign<To_Policy, To_Policy>(to, l, dir);
977 }
978 
979 template <typename To_Policy, typename From1_Policy, typename From2_Policy,
980  typename Type>
981 inline Result
982 sub_int_larger(Type& to, const Type x, const Type y, Rounding_Dir dir) {
983  typename Larger<Type>::type_for_sub l = x;
984  l -= y;
985  return assign<To_Policy, To_Policy>(to, l, dir);
986 }
987 
988 template <typename To_Policy, typename From1_Policy, typename From2_Policy,
989  typename Type>
990 inline Result
991 mul_int_larger(Type& to, const Type x, const Type y, Rounding_Dir dir) {
992  typename Larger<Type>::type_for_mul l = x;
993  l *= y;
994  return assign<To_Policy, To_Policy>(to, l, dir);
995 }
996 
997 template <typename To_Policy, typename From_Policy, typename Type>
998 inline Result
999 neg_signed_int(Type& to, const Type from, Rounding_Dir dir) {
1000  if (To_Policy::check_overflow && Larger<Type>::use_for_neg) {
1001  return neg_int_larger<To_Policy, From_Policy>(to, from, dir);
1002  }
1003  if (CHECK_P(To_Policy::check_overflow,
1005  return set_pos_overflow_int<To_Policy>(to, dir);
1006  }
1007  to = -from;
1008  return V_EQ;
1009 }
1010 
1011 template <typename To_Policy, typename From_Policy, typename Type>
1012 inline Result
1013 neg_unsigned_int(Type& to, const Type from, Rounding_Dir dir) {
1014  if (To_Policy::check_overflow && Larger<Type>::use_for_neg) {
1015  return neg_int_larger<To_Policy, From_Policy>(to, from, dir);
1016  }
1017  if (CHECK_P(To_Policy::check_overflow, from != 0)) {
1018  return set_neg_overflow_int<To_Policy>(to, dir);
1019  }
1020  to = from;
1021  return V_EQ;
1022 }
1023 
1024 template <typename To_Policy, typename From1_Policy, typename From2_Policy,
1025  typename Type>
1026 inline Result
1027 add_signed_int(Type& to, const Type x, const Type y, Rounding_Dir dir) {
1028  if (To_Policy::check_overflow && Larger<Type>::use_for_add) {
1029  return add_int_larger<To_Policy, From1_Policy, From2_Policy>(to, x, y, dir);
1030  }
1031  if (To_Policy::check_overflow) {
1032  if (y >= 0) {
1033  if (x > Extended_Int<To_Policy, Type>::max - y) {
1034  return set_pos_overflow_int<To_Policy>(to, dir);
1035  }
1036  }
1037  else if (x < Extended_Int<To_Policy, Type>::min - y) {
1038  return set_neg_overflow_int<To_Policy>(to, dir);
1039  }
1040  }
1041  to = x + y;
1042  return V_EQ;
1043 }
1044 
1045 template <typename To_Policy, typename From1_Policy, typename From2_Policy,
1046  typename Type>
1047 inline Result
1048 add_unsigned_int(Type& to, const Type x, const Type y, Rounding_Dir dir) {
1049  if (To_Policy::check_overflow && Larger<Type>::use_for_add) {
1050  return add_int_larger<To_Policy, From1_Policy, From2_Policy>(to, x, y, dir);
1051  }
1052  if (CHECK_P(To_Policy::check_overflow,
1054  return set_pos_overflow_int<To_Policy>(to, dir);
1055  }
1056  to = x + y;
1057  return V_EQ;
1058 }
1059 
1060 template <typename To_Policy, typename From1_Policy, typename From2_Policy,
1061  typename Type>
1062 inline Result
1063 sub_signed_int(Type& to, const Type x, const Type y, Rounding_Dir dir) {
1064  if (To_Policy::check_overflow && Larger<Type>::use_for_sub) {
1065  return sub_int_larger<To_Policy, From1_Policy, From2_Policy>(to, x, y, dir);
1066  }
1067  if (To_Policy::check_overflow) {
1068  if (y >= 0) {
1069  if (x < Extended_Int<To_Policy, Type>::min + y) {
1070  return set_neg_overflow_int<To_Policy>(to, dir);
1071  }
1072  }
1073  else if (x > Extended_Int<To_Policy, Type>::max + y) {
1074  return set_pos_overflow_int<To_Policy>(to, dir);
1075  }
1076  }
1077  to = x - y;
1078  return V_EQ;
1079 }
1080 
1081 template <typename To_Policy, typename From1_Policy, typename From2_Policy,
1082  typename Type>
1083 inline Result
1084 sub_unsigned_int(Type& to, const Type x, const Type y, Rounding_Dir dir) {
1085  if (To_Policy::check_overflow && Larger<Type>::use_for_sub) {
1086  return sub_int_larger<To_Policy, From1_Policy, From2_Policy>(to, x, y, dir);
1087  }
1088  if (CHECK_P(To_Policy::check_overflow,
1090  return set_neg_overflow_int<To_Policy>(to, dir);
1091  }
1092  to = x - y;
1093  return V_EQ;
1094 }
1095 
1096 template <typename To_Policy, typename From1_Policy, typename From2_Policy,
1097  typename Type>
1098 inline Result
1099 mul_signed_int(Type& to, const Type x, const Type y, Rounding_Dir dir) {
1100  if (To_Policy::check_overflow && Larger<Type>::use_for_mul) {
1101  return mul_int_larger<To_Policy, From1_Policy, From2_Policy>(to, x, y, dir);
1102  }
1103  if (!To_Policy::check_overflow) {
1104  to = x * y;
1105  return V_EQ;
1106  }
1107  if (y == 0) {
1108  to = 0;
1109  return V_EQ;
1110  }
1111  if (y == -1) {
1112  return neg_signed_int<To_Policy, From1_Policy>(to, x, dir);
1113  }
1114  if (x >= 0) {
1115  if (y > 0) {
1116  if (x > Extended_Int<To_Policy, Type>::max / y) {
1117  return set_pos_overflow_int<To_Policy>(to, dir);
1118  }
1119  }
1120  else {
1121  if (x > Extended_Int<To_Policy, Type>::min / y) {
1122  return set_neg_overflow_int<To_Policy>(to, dir);
1123  }
1124  }
1125  }
1126  else {
1127  if (y < 0) {
1128  if (x < Extended_Int<To_Policy, Type>::max / y) {
1129  return set_pos_overflow_int<To_Policy>(to, dir);
1130  }
1131  }
1132  else {
1133  if (x < Extended_Int<To_Policy, Type>::min / y) {
1134  return set_neg_overflow_int<To_Policy>(to, dir);
1135  }
1136  }
1137  }
1138  to = x * y;
1139  return V_EQ;
1140 }
1141 
1142 template <typename To_Policy, typename From1_Policy, typename From2_Policy,
1143  typename Type>
1144 inline Result
1145 mul_unsigned_int(Type& to, const Type x, const Type y, Rounding_Dir dir) {
1146  if (To_Policy::check_overflow && Larger<Type>::use_for_mul) {
1147  return mul_int_larger<To_Policy, From1_Policy, From2_Policy>(to, x, y, dir);
1148  }
1149  if (!To_Policy::check_overflow) {
1150  to = x * y;
1151  return V_EQ;
1152  }
1153  if (y == 0) {
1154  to = 0;
1155  return V_EQ;
1156  }
1157  if (x > Extended_Int<To_Policy, Type>::max / y) {
1158  return set_pos_overflow_int<To_Policy>(to, dir);
1159  }
1160  to = x * y;
1161  return V_EQ;
1162 }
1163 
1164 template <typename To_Policy, typename From1_Policy, typename From2_Policy,
1165  typename Type>
1166 inline Result
1167 div_signed_int(Type& to, const Type x, const Type y, Rounding_Dir dir) {
1168  if (CHECK_P(To_Policy::check_div_zero, y == 0)) {
1169  return assign_nan<To_Policy>(to, V_DIV_ZERO);
1170  }
1171  if (To_Policy::check_overflow && y == -1) {
1172  return neg_signed_int<To_Policy, From1_Policy>(to, x, dir);
1173  }
1174  to = x / y;
1175  if (round_not_requested(dir)) {
1176  return V_LGE;
1177  }
1178  if (y == -1) {
1179  return V_EQ;
1180  }
1181  Type m = x % y;
1182  if (m < 0) {
1183  return round_lt_int_no_overflow<To_Policy>(to, dir);
1184  }
1185  else if (m > 0) {
1186  return round_gt_int_no_overflow<To_Policy>(to, dir);
1187  }
1188  else {
1189  return V_EQ;
1190  }
1191 }
1192 
1193 template <typename To_Policy, typename From1_Policy, typename From2_Policy,
1194  typename Type>
1195 inline Result
1196 div_unsigned_int(Type& to, const Type x, const Type y, Rounding_Dir dir) {
1197  if (CHECK_P(To_Policy::check_div_zero, y == 0)) {
1198  return assign_nan<To_Policy>(to, V_DIV_ZERO);
1199  }
1200  to = x / y;
1201  if (round_not_requested(dir)) {
1202  return V_GE;
1203  }
1204  Type m = x % y;
1205  if (m == 0) {
1206  return V_EQ;
1207  }
1208  return round_gt_int<To_Policy>(to, dir);
1209 }
1210 
1211 template <typename To_Policy, typename From1_Policy, typename From2_Policy,
1212  typename Type>
1213 inline Result
1214 idiv_signed_int(Type& to, const Type x, const Type y, Rounding_Dir dir) {
1215  if (CHECK_P(To_Policy::check_div_zero, y == 0)) {
1216  return assign_nan<To_Policy>(to, V_DIV_ZERO);
1217  }
1218  if (To_Policy::check_overflow && y == -1) {
1219  return neg_signed_int<To_Policy, From1_Policy>(to, x, dir);
1220  }
1221  to = x / y;
1222  return V_EQ;
1223 }
1224 
1225 template <typename To_Policy, typename From1_Policy, typename From2_Policy,
1226  typename Type>
1227 inline Result
1228 idiv_unsigned_int(Type& to, const Type x, const Type y, Rounding_Dir) {
1229  if (CHECK_P(To_Policy::check_div_zero, y == 0)) {
1230  return assign_nan<To_Policy>(to, V_DIV_ZERO);
1231  }
1232  to = x / y;
1233  return V_EQ;
1234 }
1235 
1236 template <typename To_Policy, typename From1_Policy, typename From2_Policy,
1237  typename Type>
1238 inline Result
1239 rem_signed_int(Type& to, const Type x, const Type y, Rounding_Dir) {
1240  if (CHECK_P(To_Policy::check_div_zero, y == 0)) {
1241  return assign_nan<To_Policy>(to, V_MOD_ZERO);
1242  }
1243  to = (y == -1) ? 0 : (x % y);
1244  return V_EQ;
1245 }
1246 
1247 template <typename To_Policy, typename From1_Policy, typename From2_Policy,
1248  typename Type>
1249 inline Result
1250 rem_unsigned_int(Type& to, const Type x, const Type y, Rounding_Dir) {
1251  if (CHECK_P(To_Policy::check_div_zero, y == 0)) {
1252  return assign_nan<To_Policy>(to, V_MOD_ZERO);
1253  }
1254  to = x % y;
1255  return V_EQ;
1256 }
1257 
1258 template <typename To_Policy, typename From_Policy, typename Type>
1259 inline Result
1260 div_2exp_unsigned_int(Type& to, const Type x, unsigned int exp,
1261  Rounding_Dir dir) {
1262  if (exp >= sizeof_to_bits(sizeof(Type))) {
1263  to = 0;
1264  if (round_not_requested(dir)) {
1265  return V_GE;
1266  }
1267  if (x == 0) {
1268  return V_EQ;
1269  }
1270  return round_gt_int_no_overflow<To_Policy>(to, dir);
1271  }
1272  to = x >> exp;
1273  if (round_not_requested(dir)) {
1274  return V_GE;
1275  }
1276  if (x & ((Type(1) << exp) - 1)) {
1277  return round_gt_int_no_overflow<To_Policy>(to, dir);
1278  }
1279  else {
1280  return V_EQ;
1281  }
1282 }
1283 
1284 template <typename To_Policy, typename From_Policy, typename Type>
1285 inline Result
1286 div_2exp_signed_int(Type& to, const Type x, unsigned int exp,
1287  Rounding_Dir dir) {
1288  if (x < 0) {
1289  if (exp >= sizeof_to_bits(sizeof(Type))) {
1290  to = 0;
1291  if (round_not_requested(dir)) {
1292  return V_LE;
1293  }
1294  return round_lt_int_no_overflow<To_Policy>(to, dir);
1295  }
1296  typedef typename C_Integer<Type>::other_type UType;
1297  UType ux = x;
1298  ux = -ux;
1299  to = ~Type(~-(ux >> exp));
1300  if (round_not_requested(dir)) {
1301  return V_LE;
1302  }
1303  if (ux & ((UType(1) << exp) -1)) {
1304  return round_lt_int_no_overflow<To_Policy>(to, dir);
1305  }
1306  return V_EQ;
1307  }
1308  else {
1309  if (exp >= sizeof_to_bits(sizeof(Type)) - 1) {
1310  to = 0;
1311  if (round_not_requested(dir)) {
1312  return V_GE;
1313  }
1314  if (x == 0) {
1315  return V_EQ;
1316  }
1317  return round_gt_int_no_overflow<To_Policy>(to, dir);
1318  }
1319  to = x >> exp;
1320  if (round_not_requested(dir)) {
1321  return V_GE;
1322  }
1323  if (x & ((Type(1) << exp) - 1)) {
1324  return round_gt_int_no_overflow<To_Policy>(to, dir);
1325  }
1326  else {
1327  return V_EQ;
1328  }
1329  }
1330 }
1331 
1332 template <typename To_Policy, typename From_Policy, typename Type>
1333 inline Result
1334 add_2exp_unsigned_int(Type& to, const Type x, unsigned int exp,
1335  Rounding_Dir dir) {
1336  if (!To_Policy::check_overflow) {
1337  to = x + (Type(1) << exp);
1338  return V_EQ;
1339  }
1340  if (exp >= sizeof_to_bits(sizeof(Type))) {
1341  return set_pos_overflow_int<To_Policy>(to, dir);
1342  }
1343  Type n = Type(1) << exp;
1344  return add_unsigned_int<To_Policy, From_Policy, void>(to, x, n, dir);
1345 }
1346 
1347 template <typename To_Policy, typename From_Policy, typename Type>
1348 inline Result
1349 add_2exp_signed_int(Type& to, const Type x, unsigned int exp,
1350  Rounding_Dir dir) {
1351  if (!To_Policy::check_overflow) {
1352  to = x + (Type(1) << exp);
1353  return V_EQ;
1354  }
1355  if (exp >= sizeof_to_bits(sizeof(Type))) {
1356  return set_pos_overflow_int<To_Policy>(to, dir);
1357  }
1358  if (exp == sizeof_to_bits(sizeof(Type)) - 1) {
1359  Type n = -2 * (Type(1) << (exp - 1));
1360  return sub_signed_int<To_Policy, From_Policy, void>(to, x, n, dir);
1361  }
1362  else {
1363  Type n = Type(1) << exp;
1364  return add_signed_int<To_Policy, From_Policy, void>(to, x, n, dir);
1365  }
1366 }
1367 
1368 template <typename To_Policy, typename From_Policy, typename Type>
1369 inline Result
1370 sub_2exp_unsigned_int(Type& to, const Type x, unsigned int exp,
1371  Rounding_Dir dir) {
1372  if (!To_Policy::check_overflow) {
1373  to = x - (Type(1) << exp);
1374  return V_EQ;
1375  }
1376  if (exp >= sizeof_to_bits(sizeof(Type))) {
1377  return set_neg_overflow_int<To_Policy>(to, dir);
1378  }
1379  Type n = Type(1) << exp;
1380  return sub_unsigned_int<To_Policy, From_Policy, void>(to, x, n, dir);
1381 }
1382 
1383 template <typename To_Policy, typename From_Policy, typename Type>
1384 inline Result
1385 sub_2exp_signed_int(Type& to, const Type x, unsigned int exp,
1386  Rounding_Dir dir) {
1387  if (!To_Policy::check_overflow) {
1388  to = x - (Type(1) << exp);
1389  return V_EQ;
1390  }
1391  if (exp >= sizeof_to_bits(sizeof(Type))) {
1392  return set_neg_overflow_int<To_Policy>(to, dir);
1393  }
1394  if (exp == sizeof_to_bits(sizeof(Type)) - 1) {
1395  Type n = -2 * (Type(1) << (exp - 1));
1396  return add_signed_int<To_Policy, From_Policy, void>(to, x, n, dir);
1397  }
1398  else {
1399  Type n = Type(1) << exp;
1400  return sub_signed_int<To_Policy, From_Policy, void>(to, x, n, dir);
1401  }
1402 }
1403 
1404 template <typename To_Policy, typename From_Policy, typename Type>
1405 inline Result
1406 mul_2exp_unsigned_int(Type& to, const Type x, unsigned int exp,
1407  Rounding_Dir dir) {
1408  if (!To_Policy::check_overflow) {
1409  to = x << exp;
1410  return V_EQ;
1411  }
1412  if (exp >= sizeof_to_bits(sizeof(Type))) {
1413  if (x == 0) {
1414  to = 0;
1415  return V_EQ;
1416  }
1417  return set_pos_overflow_int<To_Policy>(to, dir);
1418  }
1419  if (x > Extended_Int<To_Policy, Type>::max >> exp) {
1420  return set_pos_overflow_int<To_Policy>(to, dir);
1421  }
1422  to = x << exp;
1423  return V_EQ;
1424 }
1425 
1426 template <typename To_Policy, typename From_Policy, typename Type>
1427 inline Result
1428 mul_2exp_signed_int(Type& to, const Type x, unsigned int exp,
1429  Rounding_Dir dir) {
1430  if (x < 0) {
1431  if (!To_Policy::check_overflow) {
1432  to = x * (Type(1) << exp);
1433  return V_EQ;
1434  }
1435  if (exp >= sizeof_to_bits(sizeof(Type))) {
1436  return set_neg_overflow_int<To_Policy>(to, dir);
1437  }
1438  typedef typename C_Integer<Type>::other_type UType;
1439  UType mask = UType(-1) << (sizeof_to_bits(sizeof(Type)) - exp - 1);
1440  UType ux = x;
1441  if ((ux & mask) != mask) {
1442  return set_neg_overflow_int<To_Policy>(to, dir);
1443  }
1444  ux <<= exp;
1445  Type n = ~(Type(~ux));
1447  return set_neg_overflow_int<To_Policy>(to, dir);
1448  }
1449  to = n;
1450  }
1451  else {
1452  if (!To_Policy::check_overflow) {
1453  to = x << exp;
1454  return V_EQ;
1455  }
1456  if (exp >= sizeof_to_bits(sizeof(Type)) - 1) {
1457  if (x == 0) {
1458  to = 0;
1459  return V_EQ;
1460  }
1461  return set_pos_overflow_int<To_Policy>(to, dir);
1462  }
1463  if (x > Extended_Int<To_Policy, Type>::max >> exp) {
1464  return set_pos_overflow_int<To_Policy>(to, dir);
1465  }
1466  to = x << exp;
1467  }
1468  return V_EQ;
1469 }
1470 
1471 template <typename To_Policy, typename From_Policy, typename Type>
1472 inline Result
1473 smod_2exp_unsigned_int(Type& to, const Type x, unsigned int exp,
1474  Rounding_Dir dir) {
1475  if (exp > sizeof_to_bits(sizeof(Type))) {
1476  to = x;
1477  }
1478  else {
1479  Type v = (exp == sizeof_to_bits(sizeof(Type)) ? x : (x & ((Type(1) << exp) - 1)));
1480  if (v >= (Type(1) << (exp - 1))) {
1481  return set_neg_overflow_int<To_Policy>(to, dir);
1482  }
1483  else {
1484  to = v;
1485  }
1486  }
1487  return V_EQ;
1488 }
1489 
1490 template <typename To_Policy, typename From_Policy, typename Type>
1491 inline Result
1492 smod_2exp_signed_int(Type& to, const Type x, unsigned int exp,
1493  Rounding_Dir) {
1494  if (exp >= sizeof_to_bits(sizeof(Type))) {
1495  to = x;
1496  }
1497  else {
1498  Type m = Type(1) << (exp - 1);
1499  to = (x & (m - 1)) - (x & m);
1500  }
1501  return V_EQ;
1502 }
1503 
1504 template <typename To_Policy, typename From_Policy, typename Type>
1505 inline Result
1506 umod_2exp_unsigned_int(Type& to, const Type x, unsigned int exp,
1507  Rounding_Dir) {
1508  if (exp >= sizeof_to_bits(sizeof(Type))) {
1509  to = x;
1510  }
1511  else {
1512  to = x & ((Type(1) << exp) - 1);
1513  }
1514  return V_EQ;
1515 }
1516 
1517 template <typename To_Policy, typename From_Policy, typename Type>
1518 inline Result
1519 umod_2exp_signed_int(Type& to, const Type x, unsigned int exp,
1520  Rounding_Dir dir) {
1521  if (exp >= sizeof_to_bits(sizeof(Type))) {
1522  if (x < 0) {
1523  return set_pos_overflow_int<To_Policy>(to, dir);
1524  }
1525  to = x;
1526  }
1527  else {
1528  to = x & ((Type(1) << exp) - 1);
1529  }
1530  return V_EQ;
1531 }
1532 
1533 template <typename Type>
1534 inline void
1535 isqrt_rem(Type& q, Type& r, const Type from) {
1536  q = 0;
1537  r = from;
1538  Type t(1);
1539  for (t <<= sizeof_to_bits(sizeof(Type)) - 2; t != 0; t >>= 2) {
1540  Type s = q + t;
1541  if (s <= r) {
1542  r -= s;
1543  q = s + t;
1544  }
1545  q >>= 1;
1546  }
1547 }
1548 
1549 template <typename To_Policy, typename From_Policy, typename Type>
1550 inline Result
1551 sqrt_unsigned_int(Type& to, const Type from, Rounding_Dir dir) {
1552  Type rem;
1553  isqrt_rem(to, rem, from);
1554  if (round_not_requested(dir)) {
1555  return V_GE;
1556  }
1557  if (rem == 0) {
1558  return V_EQ;
1559  }
1560  return round_gt_int<To_Policy>(to, dir);
1561 }
1562 
1563 template <typename To_Policy, typename From_Policy, typename Type>
1564 inline Result
1565 sqrt_signed_int(Type& to, const Type from, Rounding_Dir dir) {
1566  if (CHECK_P(To_Policy::check_sqrt_neg, from < 0)) {
1567  return assign_nan<To_Policy>(to, V_SQRT_NEG);
1568  }
1569  return sqrt_unsigned_int<To_Policy, From_Policy>(to, from, dir);
1570 }
1571 
1572 template <typename To_Policy, typename From1_Policy, typename From2_Policy,
1573  typename Type>
1574 inline Result
1575 add_mul_int(Type& to, const Type x, const Type y, Rounding_Dir dir) {
1576  Type z;
1577  Result r = mul<To_Policy, From1_Policy, From2_Policy>(z, x, y, dir);
1578  switch (result_overflow(r)) {
1579  case 0:
1580  return add<To_Policy, To_Policy, To_Policy>(to, to, z, dir);
1581  case -1:
1582  if (to <= 0) {
1583  return set_neg_overflow_int<To_Policy>(to, dir);
1584  }
1585  return assign_nan<To_Policy>(to, V_UNKNOWN_NEG_OVERFLOW);
1586  case 1:
1587  if (to >= 0) {
1588  return set_pos_overflow_int<To_Policy>(to, dir);
1589  }
1590  return assign_nan<To_Policy>(to, V_UNKNOWN_POS_OVERFLOW);
1591  default:
1592  PPL_UNREACHABLE;
1593  return V_NAN;
1594  }
1595 }
1596 
1597 template <typename To_Policy, typename From1_Policy, typename From2_Policy,
1598  typename Type>
1599 inline Result
1600 sub_mul_int(Type& to, const Type x, const Type y, Rounding_Dir dir) {
1601  Type z;
1602  Result r = mul<To_Policy, From1_Policy, From2_Policy>(z, x, y, dir);
1603  switch (result_overflow(r)) {
1604  case 0:
1605  return sub<To_Policy, To_Policy, To_Policy>(to, to, z, dir);
1606  case -1:
1607  if (to >= 0) {
1608  return set_pos_overflow_int<To_Policy>(to, dir);
1609  }
1610  return assign_nan<To_Policy>(to, V_UNKNOWN_NEG_OVERFLOW);
1611  case 1:
1612  if (to <= 0) {
1613  return set_neg_overflow_int<To_Policy>(to, dir);
1614  }
1615  return assign_nan<To_Policy>(to, V_UNKNOWN_POS_OVERFLOW);
1616  default:
1617  PPL_UNREACHABLE;
1618  return V_NAN;
1619  }
1620 }
1621 
1622 template <typename Policy, typename Type>
1623 inline Result
1624 output_char(std::ostream& os, Type& from,
1625  const Numeric_Format&, Rounding_Dir) {
1626  os << int(from);
1627  return V_EQ;
1628 }
1629 
1630 template <typename Policy, typename Type>
1631 inline Result
1632 output_int(std::ostream& os, Type& from, const Numeric_Format&, Rounding_Dir) {
1633  os << from;
1634  return V_EQ;
1635 }
1636 
1637 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1639 #endif
1640 PPL_SPECIALIZE_FLOOR(assign_signed_int_signed_int, signed char, signed char)
1641 PPL_SPECIALIZE_FLOOR(assign_signed_int_signed_int, signed short, signed short)
1642 PPL_SPECIALIZE_FLOOR(assign_signed_int_signed_int, signed int, signed int)
1643 PPL_SPECIALIZE_FLOOR(assign_signed_int_signed_int, signed long, signed long)
1644 PPL_SPECIALIZE_FLOOR(assign_signed_int_signed_int, signed long long, signed long long)
1645 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1647 #endif
1648 PPL_SPECIALIZE_FLOOR(assign_unsigned_int_unsigned_int, unsigned char, unsigned char)
1649 PPL_SPECIALIZE_FLOOR(assign_unsigned_int_unsigned_int, unsigned short, unsigned short)
1650 PPL_SPECIALIZE_FLOOR(assign_unsigned_int_unsigned_int, unsigned int, unsigned int)
1651 PPL_SPECIALIZE_FLOOR(assign_unsigned_int_unsigned_int, unsigned long, unsigned long)
1652 PPL_SPECIALIZE_FLOOR(assign_unsigned_int_unsigned_int, unsigned long long, unsigned long long)
1653 
1654 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1656 #endif
1657 PPL_SPECIALIZE_CEIL(assign_signed_int_signed_int, signed char, signed char)
1658 PPL_SPECIALIZE_CEIL(assign_signed_int_signed_int, signed short, signed short)
1659 PPL_SPECIALIZE_CEIL(assign_signed_int_signed_int, signed int, signed int)
1660 PPL_SPECIALIZE_CEIL(assign_signed_int_signed_int, signed long, signed long)
1661 PPL_SPECIALIZE_CEIL(assign_signed_int_signed_int, signed long long, signed long long)
1662 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1664 #endif
1665 PPL_SPECIALIZE_CEIL(assign_unsigned_int_unsigned_int, unsigned char, unsigned char)
1666 PPL_SPECIALIZE_CEIL(assign_unsigned_int_unsigned_int, unsigned short, unsigned short)
1667 PPL_SPECIALIZE_CEIL(assign_unsigned_int_unsigned_int, unsigned int, unsigned int)
1668 PPL_SPECIALIZE_CEIL(assign_unsigned_int_unsigned_int, unsigned long, unsigned long)
1669 PPL_SPECIALIZE_CEIL(assign_unsigned_int_unsigned_int, unsigned long long, unsigned long long)
1670 
1671 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1673 #endif
1674 PPL_SPECIALIZE_TRUNC(assign_signed_int_signed_int, signed char, signed char)
1675 PPL_SPECIALIZE_TRUNC(assign_signed_int_signed_int, signed short, signed short)
1676 PPL_SPECIALIZE_TRUNC(assign_signed_int_signed_int, signed int, signed int)
1677 PPL_SPECIALIZE_TRUNC(assign_signed_int_signed_int, signed long, signed long)
1678 PPL_SPECIALIZE_TRUNC(assign_signed_int_signed_int, signed long long, signed long long)
1679 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1681 #endif
1682 PPL_SPECIALIZE_TRUNC(assign_unsigned_int_unsigned_int, unsigned char, unsigned char)
1683 PPL_SPECIALIZE_TRUNC(assign_unsigned_int_unsigned_int, unsigned short, unsigned short)
1684 PPL_SPECIALIZE_TRUNC(assign_unsigned_int_unsigned_int, unsigned int, unsigned int)
1685 PPL_SPECIALIZE_TRUNC(assign_unsigned_int_unsigned_int, unsigned long, unsigned long)
1686 PPL_SPECIALIZE_TRUNC(assign_unsigned_int_unsigned_int, unsigned long long, unsigned long long)
1687 
1688 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1690 #endif
1691 PPL_SPECIALIZE_NEG(neg_signed_int, signed char, signed char)
1692 PPL_SPECIALIZE_NEG(neg_signed_int, signed short, signed short)
1693 PPL_SPECIALIZE_NEG(neg_signed_int, signed int, signed int)
1694 PPL_SPECIALIZE_NEG(neg_signed_int, signed long, signed long)
1695 PPL_SPECIALIZE_NEG(neg_signed_int, signed long long, signed long long)
1696 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1698 #endif
1699 PPL_SPECIALIZE_NEG(neg_unsigned_int, unsigned char, unsigned char)
1700 PPL_SPECIALIZE_NEG(neg_unsigned_int, unsigned short, unsigned short)
1701 PPL_SPECIALIZE_NEG(neg_unsigned_int, unsigned int, unsigned int)
1702 PPL_SPECIALIZE_NEG(neg_unsigned_int, unsigned long, unsigned long)
1703 PPL_SPECIALIZE_NEG(neg_unsigned_int, unsigned long long, unsigned long long)
1704 
1705 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1706 PPL_SPECIALIZE_ADD(add_signed_int, char, char, char)
1707 #endif
1708 PPL_SPECIALIZE_ADD(add_signed_int, signed char, signed char, signed char)
1709 PPL_SPECIALIZE_ADD(add_signed_int, signed short, signed short, signed short)
1710 PPL_SPECIALIZE_ADD(add_signed_int, signed int, signed int, signed int)
1711 PPL_SPECIALIZE_ADD(add_signed_int, signed long, signed long, signed long)
1712 PPL_SPECIALIZE_ADD(add_signed_int, signed long long, signed long long, signed long long)
1713 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1714 PPL_SPECIALIZE_ADD(add_unsigned_int, char, char, char)
1715 #endif
1716 PPL_SPECIALIZE_ADD(add_unsigned_int, unsigned char, unsigned char, unsigned char)
1717 PPL_SPECIALIZE_ADD(add_unsigned_int, unsigned short, unsigned short, unsigned short)
1718 PPL_SPECIALIZE_ADD(add_unsigned_int, unsigned int, unsigned int, unsigned int)
1719 PPL_SPECIALIZE_ADD(add_unsigned_int, unsigned long, unsigned long, unsigned long)
1720 PPL_SPECIALIZE_ADD(add_unsigned_int, unsigned long long, unsigned long long, unsigned long long)
1721 
1722 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1723 PPL_SPECIALIZE_SUB(sub_signed_int, char, char, char)
1724 #endif
1725 PPL_SPECIALIZE_SUB(sub_signed_int, signed char, signed char, signed char)
1726 PPL_SPECIALIZE_SUB(sub_signed_int, signed short, signed short, signed short)
1727 PPL_SPECIALIZE_SUB(sub_signed_int, signed int, signed int, signed int)
1728 PPL_SPECIALIZE_SUB(sub_signed_int, signed long, signed long, signed long)
1729 PPL_SPECIALIZE_SUB(sub_signed_int, signed long long, signed long long, signed long long)
1730 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1731 PPL_SPECIALIZE_SUB(sub_unsigned_int, char, char, char)
1732 #endif
1733 PPL_SPECIALIZE_SUB(sub_unsigned_int, unsigned char, unsigned char, unsigned char)
1734 PPL_SPECIALIZE_SUB(sub_unsigned_int, unsigned short, unsigned short, unsigned short)
1735 PPL_SPECIALIZE_SUB(sub_unsigned_int, unsigned int, unsigned int, unsigned int)
1736 PPL_SPECIALIZE_SUB(sub_unsigned_int, unsigned long, unsigned long, unsigned long)
1737 PPL_SPECIALIZE_SUB(sub_unsigned_int, unsigned long long, unsigned long long, unsigned long long)
1738 
1739 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1740 PPL_SPECIALIZE_MUL(mul_signed_int, char, char, char)
1741 #endif
1742 PPL_SPECIALIZE_MUL(mul_signed_int, signed char, signed char, signed char)
1743 PPL_SPECIALIZE_MUL(mul_signed_int, signed short, signed short, signed short)
1744 PPL_SPECIALIZE_MUL(mul_signed_int, signed int, signed int, signed int)
1745 PPL_SPECIALIZE_MUL(mul_signed_int, signed long, signed long, signed long)
1746 PPL_SPECIALIZE_MUL(mul_signed_int, signed long long, signed long long, signed long long)
1747 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1748 PPL_SPECIALIZE_MUL(mul_unsigned_int, char, char, char)
1749 #endif
1750 PPL_SPECIALIZE_MUL(mul_unsigned_int, unsigned char, unsigned char, unsigned char)
1751 PPL_SPECIALIZE_MUL(mul_unsigned_int, unsigned short, unsigned short, unsigned short)
1752 PPL_SPECIALIZE_MUL(mul_unsigned_int, unsigned int, unsigned int, unsigned int)
1753 PPL_SPECIALIZE_MUL(mul_unsigned_int, unsigned long, unsigned long, unsigned long)
1754 PPL_SPECIALIZE_MUL(mul_unsigned_int, unsigned long long, unsigned long long, unsigned long long)
1755 
1756 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1757 PPL_SPECIALIZE_DIV(div_signed_int, char, char, char)
1758 #endif
1759 PPL_SPECIALIZE_DIV(div_signed_int, signed char, signed char, signed char)
1760 PPL_SPECIALIZE_DIV(div_signed_int, signed short, signed short, signed short)
1761 PPL_SPECIALIZE_DIV(div_signed_int, signed int, signed int, signed int)
1762 PPL_SPECIALIZE_DIV(div_signed_int, signed long, signed long, signed long)
1763 PPL_SPECIALIZE_DIV(div_signed_int, signed long long, signed long long, signed long long)
1764 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1765 PPL_SPECIALIZE_DIV(div_unsigned_int, char, char, char)
1766 #endif
1767 PPL_SPECIALIZE_DIV(div_unsigned_int, unsigned char, unsigned char, unsigned char)
1768 PPL_SPECIALIZE_DIV(div_unsigned_int, unsigned short, unsigned short, unsigned short)
1769 PPL_SPECIALIZE_DIV(div_unsigned_int, unsigned int, unsigned int, unsigned int)
1770 PPL_SPECIALIZE_DIV(div_unsigned_int, unsigned long, unsigned long, unsigned long)
1771 PPL_SPECIALIZE_DIV(div_unsigned_int, unsigned long long, unsigned long long, unsigned long long)
1772 
1773 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1774 PPL_SPECIALIZE_IDIV(idiv_signed_int, char, char, char)
1775 #endif
1776 PPL_SPECIALIZE_IDIV(idiv_signed_int, signed char, signed char, signed char)
1777 PPL_SPECIALIZE_IDIV(idiv_signed_int, signed short, signed short, signed short)
1778 PPL_SPECIALIZE_IDIV(idiv_signed_int, signed int, signed int, signed int)
1779 PPL_SPECIALIZE_IDIV(idiv_signed_int, signed long, signed long, signed long)
1780 PPL_SPECIALIZE_IDIV(idiv_signed_int, signed long long, signed long long, signed long long)
1781 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1782 PPL_SPECIALIZE_IDIV(idiv_unsigned_int, char, char, char)
1783 #endif
1784 PPL_SPECIALIZE_IDIV(idiv_unsigned_int, unsigned char, unsigned char, unsigned char)
1785 PPL_SPECIALIZE_IDIV(idiv_unsigned_int, unsigned short, unsigned short, unsigned short)
1786 PPL_SPECIALIZE_IDIV(idiv_unsigned_int, unsigned int, unsigned int, unsigned int)
1787 PPL_SPECIALIZE_IDIV(idiv_unsigned_int, unsigned long, unsigned long, unsigned long)
1788 PPL_SPECIALIZE_IDIV(idiv_unsigned_int, unsigned long long, unsigned long long, unsigned long long)
1789 
1790 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1791 PPL_SPECIALIZE_REM(rem_signed_int, char, char, char)
1792 #endif
1793 PPL_SPECIALIZE_REM(rem_signed_int, signed char, signed char, signed char)
1794 PPL_SPECIALIZE_REM(rem_signed_int, signed short, signed short, signed short)
1795 PPL_SPECIALIZE_REM(rem_signed_int, signed int, signed int, signed int)
1796 PPL_SPECIALIZE_REM(rem_signed_int, signed long, signed long, signed long)
1797 PPL_SPECIALIZE_REM(rem_signed_int, signed long long, signed long long, signed long long)
1798 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1799 PPL_SPECIALIZE_REM(rem_unsigned_int, char, char, char)
1800 #endif
1801 PPL_SPECIALIZE_REM(rem_unsigned_int, unsigned char, unsigned char, unsigned char)
1802 PPL_SPECIALIZE_REM(rem_unsigned_int, unsigned short, unsigned short, unsigned short)
1803 PPL_SPECIALIZE_REM(rem_unsigned_int, unsigned int, unsigned int, unsigned int)
1804 PPL_SPECIALIZE_REM(rem_unsigned_int, unsigned long, unsigned long, unsigned long)
1805 PPL_SPECIALIZE_REM(rem_unsigned_int, unsigned long long, unsigned long long, unsigned long long)
1806 
1807 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1809 #endif
1810 PPL_SPECIALIZE_ADD_2EXP(add_2exp_signed_int, signed char, signed char)
1811 PPL_SPECIALIZE_ADD_2EXP(add_2exp_signed_int, signed short, signed short)
1812 PPL_SPECIALIZE_ADD_2EXP(add_2exp_signed_int, signed int, signed int)
1813 PPL_SPECIALIZE_ADD_2EXP(add_2exp_signed_int, signed long, signed long)
1814 PPL_SPECIALIZE_ADD_2EXP(add_2exp_signed_int, signed long long, signed long long)
1815 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1817 #endif
1818 PPL_SPECIALIZE_ADD_2EXP(add_2exp_unsigned_int, unsigned char, unsigned char)
1819 PPL_SPECIALIZE_ADD_2EXP(add_2exp_unsigned_int, unsigned short, unsigned short)
1820 PPL_SPECIALIZE_ADD_2EXP(add_2exp_unsigned_int, unsigned int, unsigned int)
1821 PPL_SPECIALIZE_ADD_2EXP(add_2exp_unsigned_int, unsigned long, unsigned long)
1822 PPL_SPECIALIZE_ADD_2EXP(add_2exp_unsigned_int, unsigned long long, unsigned long long)
1823 
1824 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1826 #endif
1827 PPL_SPECIALIZE_SUB_2EXP(sub_2exp_signed_int, signed char, signed char)
1828 PPL_SPECIALIZE_SUB_2EXP(sub_2exp_signed_int, signed short, signed short)
1829 PPL_SPECIALIZE_SUB_2EXP(sub_2exp_signed_int, signed int, signed int)
1830 PPL_SPECIALIZE_SUB_2EXP(sub_2exp_signed_int, signed long, signed long)
1831 PPL_SPECIALIZE_SUB_2EXP(sub_2exp_signed_int, signed long long, signed long long)
1832 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1834 #endif
1835 PPL_SPECIALIZE_SUB_2EXP(sub_2exp_unsigned_int, unsigned char, unsigned char)
1836 PPL_SPECIALIZE_SUB_2EXP(sub_2exp_unsigned_int, unsigned short, unsigned short)
1837 PPL_SPECIALIZE_SUB_2EXP(sub_2exp_unsigned_int, unsigned int, unsigned int)
1838 PPL_SPECIALIZE_SUB_2EXP(sub_2exp_unsigned_int, unsigned long, unsigned long)
1839 PPL_SPECIALIZE_SUB_2EXP(sub_2exp_unsigned_int, unsigned long long, unsigned long long)
1840 
1841 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1843 #endif
1844 PPL_SPECIALIZE_MUL_2EXP(mul_2exp_signed_int, signed char, signed char)
1845 PPL_SPECIALIZE_MUL_2EXP(mul_2exp_signed_int, signed short, signed short)
1846 PPL_SPECIALIZE_MUL_2EXP(mul_2exp_signed_int, signed int, signed int)
1847 PPL_SPECIALIZE_MUL_2EXP(mul_2exp_signed_int, signed long, signed long)
1848 PPL_SPECIALIZE_MUL_2EXP(mul_2exp_signed_int, signed long long, signed long long)
1849 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1851 #endif
1852 PPL_SPECIALIZE_MUL_2EXP(mul_2exp_unsigned_int, unsigned char, unsigned char)
1853 PPL_SPECIALIZE_MUL_2EXP(mul_2exp_unsigned_int, unsigned short, unsigned short)
1854 PPL_SPECIALIZE_MUL_2EXP(mul_2exp_unsigned_int, unsigned int, unsigned int)
1855 PPL_SPECIALIZE_MUL_2EXP(mul_2exp_unsigned_int, unsigned long, unsigned long)
1856 PPL_SPECIALIZE_MUL_2EXP(mul_2exp_unsigned_int, unsigned long long, unsigned long long)
1857 
1858 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1860 #endif
1861 PPL_SPECIALIZE_DIV_2EXP(div_2exp_signed_int, signed char, signed char)
1862 PPL_SPECIALIZE_DIV_2EXP(div_2exp_signed_int, signed short, signed short)
1863 PPL_SPECIALIZE_DIV_2EXP(div_2exp_signed_int, signed int, signed int)
1864 PPL_SPECIALIZE_DIV_2EXP(div_2exp_signed_int, signed long, signed long)
1865 PPL_SPECIALIZE_DIV_2EXP(div_2exp_signed_int, signed long long, signed long long)
1866 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1868 #endif
1869 PPL_SPECIALIZE_DIV_2EXP(div_2exp_unsigned_int, unsigned char, unsigned char)
1870 PPL_SPECIALIZE_DIV_2EXP(div_2exp_unsigned_int, unsigned short, unsigned short)
1871 PPL_SPECIALIZE_DIV_2EXP(div_2exp_unsigned_int, unsigned int, unsigned int)
1872 PPL_SPECIALIZE_DIV_2EXP(div_2exp_unsigned_int, unsigned long, unsigned long)
1873 PPL_SPECIALIZE_DIV_2EXP(div_2exp_unsigned_int, unsigned long long, unsigned long long)
1874 
1875 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1877 #endif
1878 PPL_SPECIALIZE_SMOD_2EXP(smod_2exp_signed_int, signed char, signed char)
1879 PPL_SPECIALIZE_SMOD_2EXP(smod_2exp_signed_int, signed short, signed short)
1880 PPL_SPECIALIZE_SMOD_2EXP(smod_2exp_signed_int, signed int, signed int)
1881 PPL_SPECIALIZE_SMOD_2EXP(smod_2exp_signed_int, signed long, signed long)
1882 PPL_SPECIALIZE_SMOD_2EXP(smod_2exp_signed_int, signed long long, signed long long)
1883 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1885 #endif
1886 PPL_SPECIALIZE_SMOD_2EXP(smod_2exp_unsigned_int, unsigned char, unsigned char)
1887 PPL_SPECIALIZE_SMOD_2EXP(smod_2exp_unsigned_int, unsigned short, unsigned short)
1888 PPL_SPECIALIZE_SMOD_2EXP(smod_2exp_unsigned_int, unsigned int, unsigned int)
1889 PPL_SPECIALIZE_SMOD_2EXP(smod_2exp_unsigned_int, unsigned long, unsigned long)
1890 PPL_SPECIALIZE_SMOD_2EXP(smod_2exp_unsigned_int, unsigned long long, unsigned long long)
1891 
1892 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1894 #endif
1895 PPL_SPECIALIZE_UMOD_2EXP(umod_2exp_signed_int, signed char, signed char)
1896 PPL_SPECIALIZE_UMOD_2EXP(umod_2exp_signed_int, signed short, signed short)
1897 PPL_SPECIALIZE_UMOD_2EXP(umod_2exp_signed_int, signed int, signed int)
1898 PPL_SPECIALIZE_UMOD_2EXP(umod_2exp_signed_int, signed long, signed long)
1899 PPL_SPECIALIZE_UMOD_2EXP(umod_2exp_signed_int, signed long long, signed long long)
1900 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1902 #endif
1903 PPL_SPECIALIZE_UMOD_2EXP(umod_2exp_unsigned_int, unsigned char, unsigned char)
1904 PPL_SPECIALIZE_UMOD_2EXP(umod_2exp_unsigned_int, unsigned short, unsigned short)
1905 PPL_SPECIALIZE_UMOD_2EXP(umod_2exp_unsigned_int, unsigned int, unsigned int)
1906 PPL_SPECIALIZE_UMOD_2EXP(umod_2exp_unsigned_int, unsigned long, unsigned long)
1907 PPL_SPECIALIZE_UMOD_2EXP(umod_2exp_unsigned_int, unsigned long long, unsigned long long)
1908 
1909 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1911 #endif
1912 PPL_SPECIALIZE_SQRT(sqrt_signed_int, signed char, signed char)
1913 PPL_SPECIALIZE_SQRT(sqrt_signed_int, signed short, signed short)
1914 PPL_SPECIALIZE_SQRT(sqrt_signed_int, signed int, signed int)
1915 PPL_SPECIALIZE_SQRT(sqrt_signed_int, signed long, signed long)
1916 PPL_SPECIALIZE_SQRT(sqrt_signed_int, signed long long, signed long long)
1917 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1919 #endif
1920 PPL_SPECIALIZE_SQRT(sqrt_unsigned_int, unsigned char, unsigned char)
1921 PPL_SPECIALIZE_SQRT(sqrt_unsigned_int, unsigned short, unsigned short)
1922 PPL_SPECIALIZE_SQRT(sqrt_unsigned_int, unsigned int, unsigned int)
1923 PPL_SPECIALIZE_SQRT(sqrt_unsigned_int, unsigned long, unsigned long)
1924 PPL_SPECIALIZE_SQRT(sqrt_unsigned_int, unsigned long long, unsigned long long)
1925 
1926 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1927 PPL_SPECIALIZE_ABS(abs_generic, char, char)
1928 #endif
1929 PPL_SPECIALIZE_ABS(abs_generic, signed char, signed char)
1930 PPL_SPECIALIZE_ABS(abs_generic, signed short, signed short)
1931 PPL_SPECIALIZE_ABS(abs_generic, signed int, signed int)
1932 PPL_SPECIALIZE_ABS(abs_generic, signed long, signed long)
1933 PPL_SPECIALIZE_ABS(abs_generic, signed long long, signed long long)
1934 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1936 #endif
1937 PPL_SPECIALIZE_ABS(assign_unsigned_int_unsigned_int, unsigned char, unsigned char)
1938 PPL_SPECIALIZE_ABS(assign_unsigned_int_unsigned_int, unsigned short, unsigned short)
1939 PPL_SPECIALIZE_ABS(assign_unsigned_int_unsigned_int, unsigned int, unsigned int)
1940 PPL_SPECIALIZE_ABS(assign_unsigned_int_unsigned_int, unsigned long, unsigned long)
1941 PPL_SPECIALIZE_ABS(assign_unsigned_int_unsigned_int, unsigned long long, unsigned long long)
1942 
1943 PPL_SPECIALIZE_GCD(gcd_exact, char, char, char)
1944 PPL_SPECIALIZE_GCD(gcd_exact, signed char, signed char, signed char)
1945 PPL_SPECIALIZE_GCD(gcd_exact, signed short, signed short, signed short)
1946 PPL_SPECIALIZE_GCD(gcd_exact, signed int, signed int, signed int)
1947 PPL_SPECIALIZE_GCD(gcd_exact, signed long, signed long, signed long)
1948 PPL_SPECIALIZE_GCD(gcd_exact, signed long long, signed long long, signed long long)
1949 PPL_SPECIALIZE_GCD(gcd_exact, unsigned char, unsigned char, unsigned char)
1950 PPL_SPECIALIZE_GCD(gcd_exact, unsigned short, unsigned short, unsigned short)
1951 PPL_SPECIALIZE_GCD(gcd_exact, unsigned int, unsigned int, unsigned int)
1952 PPL_SPECIALIZE_GCD(gcd_exact, unsigned long, unsigned long, unsigned long)
1953 PPL_SPECIALIZE_GCD(gcd_exact, unsigned long long, unsigned long long, unsigned long long)
1954 
1956  char, char, char, char, char)
1957 PPL_SPECIALIZE_GCDEXT(gcdext_exact,
1958  signed char, signed char, signed char,
1959  signed char, signed char)
1960 PPL_SPECIALIZE_GCDEXT(gcdext_exact,
1961  signed short, signed short, signed short,
1962  signed short, signed short)
1963 PPL_SPECIALIZE_GCDEXT(gcdext_exact,
1964  signed int, signed int, signed int,
1965  signed int, signed int)
1966 PPL_SPECIALIZE_GCDEXT(gcdext_exact,
1967  signed long, signed long, signed long,
1968  signed long, signed long)
1969 PPL_SPECIALIZE_GCDEXT(gcdext_exact,
1970  signed long long, signed long long, signed long long,
1971  signed long long, signed long long)
1972 PPL_SPECIALIZE_GCDEXT(gcdext_exact,
1973  unsigned char, unsigned char, unsigned char,
1974  unsigned char, unsigned char)
1975 PPL_SPECIALIZE_GCDEXT(gcdext_exact,
1976  unsigned short, unsigned short, unsigned short,
1977  unsigned short, unsigned short)
1978 PPL_SPECIALIZE_GCDEXT(gcdext_exact,
1979  unsigned int, unsigned int, unsigned int,
1980  unsigned int, unsigned int)
1981 PPL_SPECIALIZE_GCDEXT(gcdext_exact,
1982  unsigned long, unsigned long, unsigned long,
1983  unsigned long, unsigned long)
1984 PPL_SPECIALIZE_GCDEXT(gcdext_exact,
1985  unsigned long long, unsigned long long,
1986  unsigned long long, unsigned long long,
1987  unsigned long long)
1988 
1989 PPL_SPECIALIZE_LCM(lcm_gcd_exact, char, char, char)
1990 PPL_SPECIALIZE_LCM(lcm_gcd_exact, signed char, signed char, signed char)
1991 PPL_SPECIALIZE_LCM(lcm_gcd_exact, signed short, signed short, signed short)
1992 PPL_SPECIALIZE_LCM(lcm_gcd_exact, signed int, signed int, signed int)
1993 PPL_SPECIALIZE_LCM(lcm_gcd_exact, signed long, signed long, signed long)
1994 PPL_SPECIALIZE_LCM(lcm_gcd_exact, signed long long, signed long long, signed long long)
1995 PPL_SPECIALIZE_LCM(lcm_gcd_exact, unsigned char, unsigned char, unsigned char)
1996 PPL_SPECIALIZE_LCM(lcm_gcd_exact, unsigned short, unsigned short, unsigned short)
1997 PPL_SPECIALIZE_LCM(lcm_gcd_exact, unsigned int, unsigned int, unsigned int)
1998 PPL_SPECIALIZE_LCM(lcm_gcd_exact, unsigned long, unsigned long, unsigned long)
1999 PPL_SPECIALIZE_LCM(lcm_gcd_exact, unsigned long long, unsigned long long, unsigned long long)
2000 
2002 PPL_SPECIALIZE_SGN(sgn_generic, signed char)
2003 PPL_SPECIALIZE_SGN(sgn_generic, signed short)
2004 PPL_SPECIALIZE_SGN(sgn_generic, signed int)
2005 PPL_SPECIALIZE_SGN(sgn_generic, signed long)
2006 PPL_SPECIALIZE_SGN(sgn_generic, signed long long)
2007 PPL_SPECIALIZE_SGN(sgn_generic, unsigned char)
2008 PPL_SPECIALIZE_SGN(sgn_generic, unsigned short)
2009 PPL_SPECIALIZE_SGN(sgn_generic, unsigned int)
2010 PPL_SPECIALIZE_SGN(sgn_generic, unsigned long)
2011 PPL_SPECIALIZE_SGN(sgn_generic, unsigned long long)
2012 
2013 PPL_SPECIALIZE_CMP(cmp_generic, char, char)
2014 PPL_SPECIALIZE_CMP(cmp_generic, signed char, signed char)
2015 PPL_SPECIALIZE_CMP(cmp_generic, signed short, signed short)
2016 PPL_SPECIALIZE_CMP(cmp_generic, signed int, signed int)
2017 PPL_SPECIALIZE_CMP(cmp_generic, signed long, signed long)
2018 PPL_SPECIALIZE_CMP(cmp_generic, signed long long, signed long long)
2019 PPL_SPECIALIZE_CMP(cmp_generic, unsigned char, unsigned char)
2020 PPL_SPECIALIZE_CMP(cmp_generic, unsigned short, unsigned short)
2021 PPL_SPECIALIZE_CMP(cmp_generic, unsigned int, unsigned int)
2022 PPL_SPECIALIZE_CMP(cmp_generic, unsigned long, unsigned long)
2023 PPL_SPECIALIZE_CMP(cmp_generic, unsigned long long, unsigned long long)
2024 
2025 PPL_SPECIALIZE_ADD_MUL(add_mul_int, char, char, char)
2026 PPL_SPECIALIZE_ADD_MUL(add_mul_int, signed char, signed char, signed char)
2027 PPL_SPECIALIZE_ADD_MUL(add_mul_int, signed short, signed short, signed short)
2028 PPL_SPECIALIZE_ADD_MUL(add_mul_int, signed int, signed int, signed int)
2029 PPL_SPECIALIZE_ADD_MUL(add_mul_int, signed long, signed long, signed long)
2030 PPL_SPECIALIZE_ADD_MUL(add_mul_int, signed long long, signed long long, signed long long)
2031 PPL_SPECIALIZE_ADD_MUL(add_mul_int, unsigned char, unsigned char, unsigned char)
2032 PPL_SPECIALIZE_ADD_MUL(add_mul_int, unsigned short, unsigned short, unsigned short)
2033 PPL_SPECIALIZE_ADD_MUL(add_mul_int, unsigned int, unsigned int, unsigned int)
2034 PPL_SPECIALIZE_ADD_MUL(add_mul_int, unsigned long, unsigned long, unsigned long)
2035 PPL_SPECIALIZE_ADD_MUL(add_mul_int, unsigned long long, unsigned long long, unsigned long long)
2036 
2037 PPL_SPECIALIZE_SUB_MUL(sub_mul_int, char, char, char)
2038 PPL_SPECIALIZE_SUB_MUL(sub_mul_int, signed char, signed char, signed char)
2039 PPL_SPECIALIZE_SUB_MUL(sub_mul_int, signed short, signed short, signed short)
2040 PPL_SPECIALIZE_SUB_MUL(sub_mul_int, signed int, signed int, signed int)
2041 PPL_SPECIALIZE_SUB_MUL(sub_mul_int, signed long, signed long, signed long)
2042 PPL_SPECIALIZE_SUB_MUL(sub_mul_int, signed long long, signed long long, signed long long)
2043 PPL_SPECIALIZE_SUB_MUL(sub_mul_int, unsigned char, unsigned char, unsigned char)
2044 PPL_SPECIALIZE_SUB_MUL(sub_mul_int, unsigned short, unsigned short, unsigned short)
2045 PPL_SPECIALIZE_SUB_MUL(sub_mul_int, unsigned int, unsigned int, unsigned int)
2046 PPL_SPECIALIZE_SUB_MUL(sub_mul_int, unsigned long, unsigned long, unsigned long)
2047 PPL_SPECIALIZE_SUB_MUL(sub_mul_int, unsigned long long, unsigned long long, unsigned long long)
2048 
2050 PPL_SPECIALIZE_INPUT(input_generic, signed char)
2051 PPL_SPECIALIZE_INPUT(input_generic, signed short)
2052 PPL_SPECIALIZE_INPUT(input_generic, signed int)
2053 PPL_SPECIALIZE_INPUT(input_generic, signed long)
2054 PPL_SPECIALIZE_INPUT(input_generic, signed long long)
2055 PPL_SPECIALIZE_INPUT(input_generic, unsigned char)
2056 PPL_SPECIALIZE_INPUT(input_generic, unsigned short)
2057 PPL_SPECIALIZE_INPUT(input_generic, unsigned int)
2058 PPL_SPECIALIZE_INPUT(input_generic, unsigned long)
2059 PPL_SPECIALIZE_INPUT(input_generic, unsigned long long)
2060 
2062 PPL_SPECIALIZE_OUTPUT(output_char, signed char)
2063 PPL_SPECIALIZE_OUTPUT(output_int, signed short)
2064 PPL_SPECIALIZE_OUTPUT(output_int, signed int)
2065 PPL_SPECIALIZE_OUTPUT(output_int, signed long)
2066 PPL_SPECIALIZE_OUTPUT(output_int, signed long long)
2067 PPL_SPECIALIZE_OUTPUT(output_char, unsigned char)
2068 PPL_SPECIALIZE_OUTPUT(output_int, unsigned short)
2069 PPL_SPECIALIZE_OUTPUT(output_int, unsigned int)
2070 PPL_SPECIALIZE_OUTPUT(output_int, unsigned long)
2071 PPL_SPECIALIZE_OUTPUT(output_int, unsigned long long)
2072 
2073 } // namespace Checked
2074 
2075 } // namespace Parma_Polyhedra_Library
2076 
2077 #endif // !defined(PPL_checked_int_inlines_hh)
A positive integer overflow occurred (rounding down).
Definition: Result_defs.hh:108
int result_overflow(Result r)
Result smod_2exp_unsigned_int(Type &to, const Type x, unsigned int exp, Rounding_Dir dir)
Result assign_unsigned_int_unsigned_int(To &to, const From from, Rounding_Dir dir)
#define PPL_SPECIALIZE_NEG(func, To, From)
Result sub_unsigned_int(Type &to, const Type x, const Type y, Rounding_Dir dir)
#define PPL_ASSIGN2_SIGNED_SIGNED(Smaller, Larger)
The computed result is exact.
Definition: Result_defs.hh:81
Taking the square root of a negative number.
Definition: Result_defs.hh:150
Result add_2exp_signed_int(Type &to, const Type x, unsigned int exp, Rounding_Dir dir)
#define PPL_SPECIALIZE_ADD_MUL(func, To, From1, From2)
#define PPL_SPECIALIZE_IS_MINF(func, Type)
Result output_int(std::ostream &os, Type &from, const Numeric_Format &, Rounding_Dir)
Result output_char(std::ostream &os, Type &from, const Numeric_Format &, Rounding_Dir)
Unknown result due to intermediate positive overflow.
Definition: Result_defs.hh:156
#define PPL_ASSIGN2_UNSIGNED_UNSIGNED(Smaller, Larger)
Rounding_Dir
Rounding directions for arithmetic computations.
#define PPL_SPECIALIZE_SQRT(func, To, From)
A positive integer overflow occurred (rounding up).
Definition: Result_defs.hh:111
Result add_unsigned_int(Type &to, const Type x, const Type y, Rounding_Dir dir)
void isqrt_rem(Type &q, Type &r, const Type from)
Computing a remainder modulo zero.
Definition: Result_defs.hh:147
#define PPL_SPECIALIZE_CLASSIFY(func, Type)
#define PPL_SPECIALIZE_ADD(func, To, From1, From2)
Result assign_unsigned_int_mpz(To &to, const mpz_class &from, Rounding_Dir dir)
Result add_mul_int(Type &to, const Type x, const Type y, Rounding_Dir dir)
#define PPL_ASSIGN_UNSIGNED(Type)
Result
Possible outcomes of a checked arithmetic computation.
Definition: Result_defs.hh:76
#define const_bool_nodef(name, value)
Declares a per-class constant of type bool, called name and with value value.
From bool Type Type Rounding_Dir To
#define PPL_SPECIALIZE_REM(func, To, From1, From2)
Negative infinity result class.
Definition: Result_defs.hh:34
Not a number result class.
Definition: Result_defs.hh:40
Result set_pos_overflow_int(To &to, Rounding_Dir dir)
Result add_2exp_unsigned_int(Type &to, const Type x, unsigned int exp, Rounding_Dir dir)
Result round_gt_int_no_overflow(To &to, Rounding_Dir dir)
Result round_gt_int(To &to, Rounding_Dir dir)
signed signed signed signed signed char signed signed signed signed signed int signed long long
Result gcdext_exact(To1 &to, To2 &s, To3 &t, const From1 &x, const From2 &y, Rounding_Dir dir)
Result assign_int_mpq(To &to, const mpq_class &from, Rounding_Dir dir)
Result umod_2exp_unsigned_int(Type &to, const Type x, unsigned int exp, Rounding_Dir)
#define PPL_SPECIALIZE_ABS(func, To, From)
Result mul_signed_int(Type &to, const Type x, const Type y, Rounding_Dir dir)
Result input_generic(Type &to, std::istream &is, Rounding_Dir dir)
#define PPL_SPECIALIZE_UMOD_2EXP(func, To, From)
Not a number result.
Definition: Result_defs.hh:123
PPL_SPECIALIZE_GCDEXT(gcdext_exact, char, char, char, char, char) PPL_SPECIALIZE_GCDEXT(gcdext_exact
The computed result is inexact and rounded down.
Definition: Result_defs.hh:87
#define PPL_SPECIALIZE_TRUNC(func, To, From)
#define PPL_SPECIALIZE_CMP(func, Type1, Type2)
#define PPL_SPECIALIZE_CEIL(func, To, From)
#define PPL_SPECIALIZE_DIV(func, To, From1, From2)
Result classify_int(const Type v, bool nan, bool inf, bool sign)
Enable_If<(Safe_Int_Comparison< T1, T2 >::value||Safe_Conversion< T1, T2 >::value||Safe_Conversion< T2, T1 >::value), bool >::type lt(const T1 &x, const T2 &y)
#define PPL_SPECIALIZE_IDIV(func, To, From1, From2)
#define PPL_SPECIALIZE_MUL_2EXP(func, To, From)
Result div_unsigned_int(Type &to, const Type x, const Type y, Rounding_Dir dir)
Positive infinity result class.
Definition: Result_defs.hh:37
Result assign_signed_int_unsigned_int(To &to, const From from, Rounding_Dir dir)
Result mul_2exp_unsigned_int(Type &to, const Type x, unsigned int exp, Rounding_Dir dir)
Unknown result due to intermediate negative overflow.
Definition: Result_defs.hh:153
The computed result is not representable.
Definition: Result_defs.hh:159
Result idiv_signed_int(Type &to, const Type x, const Type y, Rounding_Dir dir)
#define PPL_SPECIALIZE_SUB(func, To, From1, From2)
#define PPL_SPECIALIZE_ASSIGN_SPECIAL(func, Type)
From bool Type Type Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir unsigned int
Result neg_int_larger(Type &to, const Type x, Rounding_Dir dir)
#define sizeof_to_bits(size)
Definition: compiler.hh:80
Result add_int_larger(Type &to, const Type x, const Type y, Rounding_Dir dir)
Result round_lt_int(To &to, Rounding_Dir dir)
Result gcd_exact(To &to, const From1 &x, const From2 &y, Rounding_Dir dir)
bool round_up(Rounding_Dir dir)
#define PPL_SPECIALIZE_ADD_2EXP(func, To, From)
#define PPL_SPECIALIZE_GCD(func, To, From1, From2)
Result rem_signed_int(Type &to, const Type x, const Type y, Rounding_Dir)
Result sqrt_signed_int(Type &to, const Type from, Rounding_Dir dir)
#define PPL_SPECIALIZE_SUB_MUL(func, To, From1, From2)
Result umod_2exp_signed_int(Type &to, const Type x, unsigned int exp, Rounding_Dir dir)
Result idiv_unsigned_int(Type &to, const Type x, const Type y, Rounding_Dir)
The computed result may be inexact and rounded up.
Definition: Result_defs.hh:93
#define PPL_DIRTY_TEMP(T, id)
#define PPL_SPECIALIZE_IS_INT(func, Type)
Result assign_special_int(Type &v, Result_Class c, Rounding_Dir dir)
#define PPL_SPECIALIZE_FLOOR(func, To, From)
Result div_2exp_signed_int(Type &to, const Type x, unsigned int exp, Rounding_Dir dir)
Result mul_2exp_signed_int(Type &to, const Type x, unsigned int exp, Rounding_Dir dir)
Result sub_2exp_unsigned_int(Type &to, const Type x, unsigned int exp, Rounding_Dir dir)
unsigned long long strtoull(const char *nptr, char **endptr, int base)
Result neg_signed_int(Type &to, const Type from, Rounding_Dir dir)
Result mul_unsigned_int(Type &to, const Type x, const Type y, Rounding_Dir dir)
Result add_signed_int(Type &to, const Type x, const Type y, Rounding_Dir dir)
The entire library is confined to this namespace.
Definition: version.hh:61
#define PPL_SPECIALIZE_DIV_2EXP(func, To, From)
Enable_If< Is_Same< To_Policy, From_Policy >::value, void >::type copy_generic(Type &to, const Type &from)
bool round_direct(Rounding_Dir dir)
Result_Relation sgn_generic(const Type &x)
Result sqrt_unsigned_int(Type &to, const Type from, Rounding_Dir dir)
The computed result may be inexact and rounded down.
Definition: Result_defs.hh:96
Result assign_signed_int_signed_int(To &to, const From from, Rounding_Dir dir)
Result div_2exp_unsigned_int(Type &to, const Type x, unsigned int exp, Rounding_Dir dir)
From bool Type Type Rounding_Dir From
#define PPL_GT_SILENT(a, b)
Result smod_2exp_signed_int(Type &to, const Type x, unsigned int exp, Rounding_Dir)
Result assign_unsigned_int_signed_int(To &to, const From from, Rounding_Dir dir)
#define PPL_SPECIALIZE_IS_NAN(func, Type)
Result round_lt_int_no_overflow(To &to, Rounding_Dir dir)
#define PPL_ASSIGN2_UNSIGNED_SIGNED(Smaller, Larger)
int sgn(Boundary_Type type, const T &x, const Info &info)
Result mul_int_larger(Type &to, const Type x, const Type y, Rounding_Dir dir)
Result lcm_gcd_exact(To &to, const From1 &x, const From2 &y, Rounding_Dir dir)
Result abs_generic(To &to, const From &from, Rounding_Dir dir)
signed long long strtoll(const char *nptr, char **endptr, int base)
#define PPL_SPECIALIZE_ASSIGN(func, To, From)
#define PPL_SPECIALIZE_SUB_2EXP(func, To, From)
#define PPL_SPECIALIZE_COPY(func, Type)
A negative integer overflow occurred (rounding down).
Definition: Result_defs.hh:114
Coefficient c
Definition: PIP_Tree.cc:64
#define PPL_ASSIGN2_SIGNED_UNSIGNED(Smaller, Larger)
#define PPL_SPECIALIZE_LCM(func, To, From1, From2)
#define CHECK_P(cond, check)
Result div_signed_int(Type &to, const Type x, const Type y, Rounding_Dir dir)
Result sub_int_larger(Type &to, const Type x, const Type y, Rounding_Dir dir)
#define PPL_SPECIALIZE_OUTPUT(func, Type)
The computed result is inexact and rounded up.
Definition: Result_defs.hh:84
The computed result may be inexact.
Definition: Result_defs.hh:99
Result assign_int_float(To &to, const From from, Rounding_Dir dir)
Result set_neg_overflow_int(To &to, Rounding_Dir dir)
Result sub_signed_int(Type &to, const Type x, const Type y, Rounding_Dir dir)
#define PPL_SPECIALIZE_INPUT(func, Type)
bool round_down(Rounding_Dir dir)
Result assign_signed_int_mpz(To &to, const mpz_class &from, Rounding_Dir dir)
Result rem_unsigned_int(Type &to, const Type x, const Type y, Rounding_Dir)
#define PPL_SPECIALIZE_SMOD_2EXP(func, To, From)
#define PPL_LT_SILENT(a, b)
Performs the test a < b avoiding the warning about the comparison being always false due to limited r...
bool round_not_requested(Rounding_Dir dir)
Result_Relation cmp_generic(const Type1 &x, const Type2 &y)
#define PPL_ASSIGN_SIGNED(Type)
A negative integer overflow occurred (rounding up).
Definition: Result_defs.hh:105
Result sub_2exp_signed_int(Type &to, const Type x, unsigned int exp, Rounding_Dir dir)
#define PPL_SPECIALIZE_MUL(func, To, From1, From2)
Result neg_unsigned_int(Type &to, const Type from, Rounding_Dir dir)
Result sub_mul_int(Type &to, const Type x, const Type y, Rounding_Dir dir)
#define PPL_SPECIALIZE_IS_PINF(func, Type)
#define PPL_SPECIALIZE_SGN(func, From)
Enable_If<(Safe_Int_Comparison< T1, T2 >::value||Safe_Conversion< T1, T2 >::value||Safe_Conversion< T2, T1 >::value), bool >::type le(const T1 &x, const T2 &y)