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 {
73   static const Type plus_infinity = C_Integer<Type>::max;
74   static const Type minus_infinity = ((C_Integer<Type>::min >= 0)
75                                       ? (C_Integer<Type>::max - 1)
76                                       : C_Integer<Type>::min);
77   static const Type not_a_number
78   = ((C_Integer<Type>::min >= 0)
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
82   = (C_Integer<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
87   = (C_Integer<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
set_neg_overflow_int(To & to,Rounding_Dir dir)95 set_neg_overflow_int(To& to, Rounding_Dir dir) {
96   if (round_up(dir)) {
97     to = Extended_Int<Policy, To>::min;
98     return V_LT_INF;
99   }
100   else {
101     if (Policy::has_infinity) {
102       to = Extended_Int<Policy, To>::minus_infinity;
103       return V_GT_MINUS_INFINITY;
104     }
105     return V_GT_MINUS_INFINITY | V_UNREPRESENTABLE;
106   }
107 }
108 
109 template <typename Policy, typename To>
110 inline Result
set_pos_overflow_int(To & to,Rounding_Dir dir)111 set_pos_overflow_int(To& to, Rounding_Dir dir) {
112   if (round_down(dir)) {
113     to = Extended_Int<Policy, To>::max;
114     return V_GT_SUP;
115   }
116   else {
117     if (Policy::has_infinity) {
118       to = Extended_Int<Policy, To>::plus_infinity;
119       return V_LT_PLUS_INFINITY;
120     }
121     return V_LT_PLUS_INFINITY | V_UNREPRESENTABLE;
122   }
123 }
124 
125 template <typename Policy, typename To>
126 inline Result
round_lt_int_no_overflow(To & to,Rounding_Dir dir)127 round_lt_int_no_overflow(To& to, Rounding_Dir dir) {
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
round_gt_int_no_overflow(To & to,Rounding_Dir dir)137 round_gt_int_no_overflow(To& to, Rounding_Dir dir) {
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
round_lt_int(To & to,Rounding_Dir dir)147 round_lt_int(To& to, Rounding_Dir dir) {
148   if (round_down(dir)) {
149     if (to == Extended_Int<Policy, To>::min) {
150       if (Policy::has_infinity) {
151         to = Extended_Int<Policy, To>::minus_infinity;
152         return V_GT_MINUS_INFINITY;
153       }
154       return V_GT_MINUS_INFINITY | V_UNREPRESENTABLE;
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
round_gt_int(To & to,Rounding_Dir dir)166 round_gt_int(To& to, Rounding_Dir dir) {
167   if (round_up(dir)) {
168     if (to == Extended_Int<Policy, To>::max) {
169       if (Policy::has_infinity) {
170         to = Extended_Int<Policy, To>::plus_infinity;
171         return V_LT_PLUS_INFINITY;
172       }
173       return V_LT_PLUS_INFINITY | V_UNREPRESENTABLE;
174     }
175     else {
176       ++to;
177       return V_LT;
178     }
179   }
180   return V_GT;
181 }
182 
PPL_SPECIALIZE_COPY(copy_generic,char)183 PPL_SPECIALIZE_COPY(copy_generic, char)
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)
200       && v == Extended_Int<Policy, Type>::not_a_number) {
201     return V_NAN;
202   }
203   if (!inf && !sign) {
204     return V_LGE;
205   }
206   if (Policy::has_infinity) {
207     if (v == Extended_Int<Policy, Type>::minus_infinity) {
208       return inf ? V_EQ_MINUS_INFINITY : V_LT;
209     }
210     if (v == Extended_Int<Policy, Type>::plus_infinity) {
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 
PPL_SPECIALIZE_CLASSIFY(classify_int,char)226 PPL_SPECIALIZE_CLASSIFY(classify_int, char)
227 PPL_SPECIALIZE_CLASSIFY(classify_int, signed char)
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
240 is_nan_int(const Type v) {
241   return Policy::has_nan && v == Extended_Int<Policy, Type>::not_a_number;
242 }
243 
PPL_SPECIALIZE_IS_NAN(is_nan_int,char)244 PPL_SPECIALIZE_IS_NAN(is_nan_int, char)
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
258 is_minf_int(const Type v) {
259   return Policy::has_infinity
260     && v == Extended_Int<Policy, Type>::minus_infinity;
261 }
262 
PPL_SPECIALIZE_IS_MINF(is_minf_int,char)263 PPL_SPECIALIZE_IS_MINF(is_minf_int, char)
264 PPL_SPECIALIZE_IS_MINF(is_minf_int, signed char)
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
277 is_pinf_int(const Type v) {
278   return Policy::has_infinity
279     && v == Extended_Int<Policy, Type>::plus_infinity;
280 }
281 
PPL_SPECIALIZE_IS_PINF(is_pinf_int,char)282 PPL_SPECIALIZE_IS_PINF(is_pinf_int, char)
283 PPL_SPECIALIZE_IS_PINF(is_pinf_int, signed char)
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
296 is_int_int(const Type v) {
297   return !is_nan<Policy>(v);
298 }
299 
PPL_SPECIALIZE_IS_INT(is_int_int,char)300 PPL_SPECIALIZE_IS_INT(is_int_int, char)
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
314 assign_special_int(Type& v, Result_Class c, Rounding_Dir dir) {
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) {
319       v = Extended_Int<Policy, Type>::not_a_number;
320       return V_NAN;
321     }
322     return V_NAN | V_UNREPRESENTABLE;
323   case VC_MINUS_INFINITY:
324     if (Policy::has_infinity) {
325       v = Extended_Int<Policy, Type>::minus_infinity;
326       return V_EQ_MINUS_INFINITY;
327     }
328     if (round_up(dir)) {
329       v = Extended_Int<Policy, Type>::min;
330       return V_LT_INF;
331     }
332     return V_EQ_MINUS_INFINITY | V_UNREPRESENTABLE;
333   case VC_PLUS_INFINITY:
334     if (Policy::has_infinity) {
335       v = Extended_Int<Policy, Type>::plus_infinity;
336       return V_EQ_PLUS_INFINITY;
337     }
338     if (round_down(dir)) {
339       v = Extended_Int<Policy, Type>::max;
340       return V_GT_SUP;
341     }
342     return V_EQ_PLUS_INFINITY | V_UNREPRESENTABLE;
343   default:
344     PPL_UNREACHABLE;
345     return V_NAN | V_UNREPRESENTABLE;
346   }
347 }
348 
PPL_SPECIALIZE_ASSIGN_SPECIAL(assign_special_int,char)349 PPL_SPECIALIZE_ASSIGN_SPECIAL(assign_special_int, char)
350 PPL_SPECIALIZE_ASSIGN_SPECIAL(assign_special_int, signed char)
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
363 assign_signed_int_signed_int(To& to, const From from, Rounding_Dir dir) {
364   if (sizeof(To) < sizeof(From)
365       || (sizeof(To) == sizeof(From)
366       && (Extended_Int<To_Policy, To>::min > Extended_Int<From_Policy, From>::min
367       || Extended_Int<To_Policy, To>::max < Extended_Int<From_Policy, From>::max))) {
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
assign_signed_int_unsigned_int(To & to,const From from,Rounding_Dir dir)385 assign_signed_int_unsigned_int(To& to, const From from, Rounding_Dir dir) {
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
assign_unsigned_int_signed_int(To & to,const From from,Rounding_Dir dir)398 assign_unsigned_int_signed_int(To& to, const From from, Rounding_Dir dir) {
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
assign_unsigned_int_unsigned_int(To & to,const From from,Rounding_Dir dir)414 assign_unsigned_int_unsigned_int(To& to, const From from, Rounding_Dir dir) {
415   if (sizeof(To) < sizeof(From)
416       || (sizeof(To) == sizeof(From)
417       && Extended_Int<To_Policy, To>::max < Extended_Int<From_Policy, From>::max)) {
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
PPL_ASSIGN_SIGNED(signed char)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
459 PPL_ASSIGN_UNSIGNED(char)
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,
557               lt(from, Extended_Int<To_Policy, To>::min))) {
558     return set_neg_overflow_int<To_Policy>(to, dir);
559   }
560   if (CHECK_P(To_Policy::check_overflow,
561               !le(from, Extended_Int<To_Policy, To>::max))) {
562     return set_pos_overflow_int<To_Policy>(to, dir);
563   }
564 #else
565   if (CHECK_P(To_Policy::check_overflow,
566              (from < Extended_Int<To_Policy, To>::min))) {
567     return set_neg_overflow_int<To_Policy>(to, dir);
568   }
569   if (CHECK_P(To_Policy::check_overflow,
570              (from > Extended_Int<To_Policy, To>::max))) {
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 
PPL_SPECIALIZE_ASSIGN(assign_int_float,char,float)596 PPL_SPECIALIZE_ASSIGN(assign_int_float, char, float)
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();
649       if (PPL_LT_SILENT(v, (Extended_Int<To_Policy, To>::min))) {
650         return set_neg_overflow_int<To_Policy>(to, dir);
651       }
652       if (PPL_GT_SILENT(v, (Extended_Int<To_Policy, To>::max))) {
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
PPL_SPECIALIZE_ASSIGN(assign_signed_int_mpz,char,mpz_class)684 PPL_SPECIALIZE_ASSIGN(assign_signed_int_mpz, char, mpz_class)
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();
705       if (PPL_GT_SILENT(v, (Extended_Int<To_Policy, To>::max))) {
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
PPL_SPECIALIZE_ASSIGN(assign_unsigned_int_mpz,char,mpz_class)729 PPL_SPECIALIZE_ASSIGN(assign_unsigned_int_mpz, char, mpz_class)
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
neg_int_larger(Type & to,const Type x,Rounding_Dir dir)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
add_int_larger(Type & to,const Type x,const Type y,Rounding_Dir dir)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
sub_int_larger(Type & to,const Type x,const Type y,Rounding_Dir dir)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
mul_int_larger(Type & to,const Type x,const Type y,Rounding_Dir dir)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
neg_signed_int(Type & to,const Type from,Rounding_Dir dir)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,
1004               (from < -Extended_Int<To_Policy, Type>::max))) {
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
neg_unsigned_int(Type & to,const Type from,Rounding_Dir dir)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
add_signed_int(Type & to,const Type x,const Type y,Rounding_Dir dir)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
add_unsigned_int(Type & to,const Type x,const Type y,Rounding_Dir dir)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,
1053               (x > Extended_Int<To_Policy, Type>::max - y))) {
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
sub_signed_int(Type & to,const Type x,const Type y,Rounding_Dir dir)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
sub_unsigned_int(Type & to,const Type x,const Type y,Rounding_Dir dir)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,
1089               (x < Extended_Int<To_Policy, Type>::min + y))) {
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
mul_signed_int(Type & to,const Type x,const Type y,Rounding_Dir dir)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
mul_unsigned_int(Type & to,const Type x,const Type y,Rounding_Dir dir)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
div_signed_int(Type & to,const Type x,const Type y,Rounding_Dir dir)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
div_unsigned_int(Type & to,const Type x,const Type y,Rounding_Dir dir)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
idiv_signed_int(Type & to,const Type x,const Type y,Rounding_Dir dir)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
idiv_unsigned_int(Type & to,const Type x,const Type y,Rounding_Dir)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
rem_signed_int(Type & to,const Type x,const Type y,Rounding_Dir)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
rem_unsigned_int(Type & to,const Type x,const Type y,Rounding_Dir)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
div_2exp_unsigned_int(Type & to,const Type x,unsigned int exp,Rounding_Dir dir)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
div_2exp_signed_int(Type & to,const Type x,unsigned int exp,Rounding_Dir dir)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
add_2exp_unsigned_int(Type & to,const Type x,unsigned int exp,Rounding_Dir dir)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
add_2exp_signed_int(Type & to,const Type x,unsigned int exp,Rounding_Dir dir)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
sub_2exp_unsigned_int(Type & to,const Type x,unsigned int exp,Rounding_Dir dir)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
sub_2exp_signed_int(Type & to,const Type x,unsigned int exp,Rounding_Dir dir)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
mul_2exp_unsigned_int(Type & to,const Type x,unsigned int exp,Rounding_Dir dir)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
mul_2exp_signed_int(Type & to,const Type x,unsigned int exp,Rounding_Dir dir)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));
1446     if (PPL_LT_SILENT(n, (Extended_Int<To_Policy, Type>::min))) {
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
smod_2exp_unsigned_int(Type & to,const Type x,unsigned int exp,Rounding_Dir dir)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
smod_2exp_signed_int(Type & to,const Type x,unsigned int exp,Rounding_Dir)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
umod_2exp_unsigned_int(Type & to,const Type x,unsigned int exp,Rounding_Dir)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
umod_2exp_signed_int(Type & to,const Type x,unsigned int exp,Rounding_Dir dir)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
isqrt_rem(Type & q,Type & r,const Type from)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
sqrt_unsigned_int(Type & to,const Type from,Rounding_Dir dir)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
sqrt_signed_int(Type & to,const Type from,Rounding_Dir dir)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
add_mul_int(Type & to,const Type x,const Type y,Rounding_Dir dir)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
sub_mul_int(Type & to,const Type x,const Type y,Rounding_Dir dir)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
output_char(std::ostream & os,Type & from,const Numeric_Format &,Rounding_Dir)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
output_int(std::ostream & os,Type & from,const Numeric_Format &,Rounding_Dir)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
1638 PPL_SPECIALIZE_FLOOR(assign_signed_int_signed_int, char, char)
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
1646 PPL_SPECIALIZE_FLOOR(assign_unsigned_int_unsigned_int, char, char)
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
1655 PPL_SPECIALIZE_CEIL(assign_signed_int_signed_int, char, char)
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
1663 PPL_SPECIALIZE_CEIL(assign_unsigned_int_unsigned_int, char, char)
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
1672 PPL_SPECIALIZE_TRUNC(assign_signed_int_signed_int, char, char)
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
1680 PPL_SPECIALIZE_TRUNC(assign_unsigned_int_unsigned_int, char, char)
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
1689 PPL_SPECIALIZE_NEG(neg_signed_int, char, char)
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
1697 PPL_SPECIALIZE_NEG(neg_unsigned_int, char, char)
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
1808 PPL_SPECIALIZE_ADD_2EXP(add_2exp_signed_int, char, char)
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
1816 PPL_SPECIALIZE_ADD_2EXP(add_2exp_unsigned_int, char, char)
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
1825 PPL_SPECIALIZE_SUB_2EXP(sub_2exp_signed_int, char, char)
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
1833 PPL_SPECIALIZE_SUB_2EXP(sub_2exp_unsigned_int, char, char)
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
1842 PPL_SPECIALIZE_MUL_2EXP(mul_2exp_signed_int, char, char)
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
1850 PPL_SPECIALIZE_MUL_2EXP(mul_2exp_unsigned_int, char, char)
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
1859 PPL_SPECIALIZE_DIV_2EXP(div_2exp_signed_int, char, char)
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
1867 PPL_SPECIALIZE_DIV_2EXP(div_2exp_unsigned_int, char, char)
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
1876 PPL_SPECIALIZE_SMOD_2EXP(smod_2exp_signed_int, char, char)
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
1884 PPL_SPECIALIZE_SMOD_2EXP(smod_2exp_unsigned_int, char, char)
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
1893 PPL_SPECIALIZE_UMOD_2EXP(umod_2exp_signed_int, char, char)
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
1901 PPL_SPECIALIZE_UMOD_2EXP(umod_2exp_unsigned_int, char, char)
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
1910 PPL_SPECIALIZE_SQRT(sqrt_signed_int, char, char)
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
1918 PPL_SPECIALIZE_SQRT(sqrt_unsigned_int, char, char)
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
1935 PPL_SPECIALIZE_ABS(assign_unsigned_int_unsigned_int, char, char)
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 
1955 PPL_SPECIALIZE_GCDEXT(gcdext_exact,
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 
2001 PPL_SPECIALIZE_SGN(sgn_generic, char)
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 
2049 PPL_SPECIALIZE_INPUT(input_generic, char)
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 
2061 PPL_SPECIALIZE_OUTPUT(output_char, char)
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)
2078