|
1 | 1 | /*-------------------------------------------------------------------------
|
2 | 2 | *
|
3 | 3 | * int.h
|
4 |
| - * Routines to perform integer math, while checking for overflows. |
| 4 | + * Overflow-aware integer math and integer comparison routines. |
5 | 5 | *
|
6 | 6 | * The routines in this file are intended to be well defined C, without
|
7 | 7 | * relying on compiler flags like -fwrapv.
|
|
22 | 22 |
|
23 | 23 |
|
24 | 24 | /*---------
|
25 |
| - * The following guidelines apply to all the routines: |
| 25 | + * The following guidelines apply to all the overflow routines: |
26 | 26 | * - If a + b overflows, return true, otherwise store the result of a + b
|
27 | 27 | * into *result. The content of *result is implementation defined in case of
|
28 | 28 | * overflow.
|
@@ -438,4 +438,75 @@ pg_mul_u64_overflow(uint64 a, uint64 b, uint64 *result)
|
438 | 438 | #endif
|
439 | 439 | }
|
440 | 440 |
|
| 441 | +/*------------------------------------------------------------------------ |
| 442 | + * |
| 443 | + * Comparison routines for integer types. |
| 444 | + * |
| 445 | + * These routines are primarily intended for use in qsort() comparator |
| 446 | + * functions and therefore return a positive integer, 0, or a negative |
| 447 | + * integer depending on whether "a" is greater than, equal to, or less |
| 448 | + * than "b", respectively. These functions are written to be as efficient |
| 449 | + * as possible without introducing overflow risks, thereby helping ensure |
| 450 | + * the comparators that use them are transitive. |
| 451 | + * |
| 452 | + * Types with fewer than 32 bits are cast to signed integers and |
| 453 | + * subtracted. Other types are compared using > and <, and the results of |
| 454 | + * those comparisons (which are either (int) 0 or (int) 1 per the C |
| 455 | + * standard) are subtracted. |
| 456 | + * |
| 457 | + * NB: If the comparator function is inlined, some compilers may produce |
| 458 | + * worse code with these helper functions than with code with the |
| 459 | + * following form: |
| 460 | + * |
| 461 | + * if (a < b) |
| 462 | + * return -1; |
| 463 | + * if (a > b) |
| 464 | + * return 1; |
| 465 | + * return 0; |
| 466 | + * |
| 467 | + *------------------------------------------------------------------------ |
| 468 | + */ |
| 469 | + |
| 470 | +static inline int |
| 471 | +pg_cmp_s16(int16 a, int16 b) |
| 472 | +{ |
| 473 | + return (int32) a - (int32) b; |
| 474 | +} |
| 475 | + |
| 476 | +static inline int |
| 477 | +pg_cmp_u16(uint16 a, uint16 b) |
| 478 | +{ |
| 479 | + return (int32) a - (int32) b; |
| 480 | +} |
| 481 | + |
| 482 | +static inline int |
| 483 | +pg_cmp_s32(int32 a, int32 b) |
| 484 | +{ |
| 485 | + return (a > b) - (a < b); |
| 486 | +} |
| 487 | + |
| 488 | +static inline int |
| 489 | +pg_cmp_u32(uint32 a, uint32 b) |
| 490 | +{ |
| 491 | + return (a > b) - (a < b); |
| 492 | +} |
| 493 | + |
| 494 | +static inline int |
| 495 | +pg_cmp_s64(int64 a, int64 b) |
| 496 | +{ |
| 497 | + return (a > b) - (a < b); |
| 498 | +} |
| 499 | + |
| 500 | +static inline int |
| 501 | +pg_cmp_u64(uint64 a, uint64 b) |
| 502 | +{ |
| 503 | + return (a > b) - (a < b); |
| 504 | +} |
| 505 | + |
| 506 | +static inline int |
| 507 | +pg_cmp_size(size_t a, size_t b) |
| 508 | +{ |
| 509 | + return (a > b) - (a < b); |
| 510 | +} |
| 511 | + |
441 | 512 | #endif /* COMMON_INT_H */
|
0 commit comments