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