|
71 | 71 | #pragma warning(disable: 4127 4355 4514 4623 4626 4820 4866 4868 5027 5045 4582 4583) |
72 | 72 | #endif |
73 | 73 |
|
74 | | -#if (!defined(__APPLE__) && (!defined(_LIBCPP_VERSION) || _LIBCPP_VERSION >= 15000)) |
| 74 | +#if !( \ |
| 75 | + defined(__APPLE__) /* macOS */ \ |
| 76 | + || (defined(_LIBCPP_VERSION) && _LIBCPP_VERSION < 15000) /* libc++ < 15.0 */ \ |
| 77 | + || (defined(__MSVCRT_VERSION__) && !defined( _UCRT)) /* msvcrt */ \ |
| 78 | + ) |
75 | 79 | #define ICECREAM_UCHAR_HEADER |
76 | 80 | #include <uchar.h> |
77 | 81 | #endif |
@@ -4081,6 +4085,25 @@ namespace detail { |
4081 | 4085 |
|
4082 | 4086 | // -------------------------------------------------- Range classes |
4083 | 4087 |
|
| 4088 | + // Check if a value of type From fits in type To. Uses SFINAE to avoid tautological |
| 4089 | + // comparison warnings when From type have the same size or is shorter than To type. |
| 4090 | + template<typename To, typename From> |
| 4091 | + auto fits_in(From v) -> typename std::enable_if< |
| 4092 | + (sizeof(From) > sizeof(To)), bool |
| 4093 | + >::type |
| 4094 | + { |
| 4095 | + return v >= std::numeric_limits<To>::lowest() |
| 4096 | + && v <= std::numeric_limits<To>::max(); |
| 4097 | + } |
| 4098 | + |
| 4099 | + template<typename To, typename From> |
| 4100 | + auto fits_in(From) -> typename std::enable_if< |
| 4101 | + (sizeof(From) <= sizeof(To)), bool |
| 4102 | + >::type |
| 4103 | + { |
| 4104 | + return true; |
| 4105 | + } |
| 4106 | + |
4084 | 4107 | // Direct representation of a slicing string. |
4085 | 4108 | struct Slice |
4086 | 4109 | { |
@@ -4141,10 +4164,7 @@ namespace detail { |
4141 | 4164 | ) |
4142 | 4165 |
|
4143 | 4166 | // or if there is an overflow to convert from long to ptrdiff |
4144 | | - || ( |
4145 | | - lnum > std::numeric_limits<ptrdiff_t>::max() |
4146 | | - || lnum < std::numeric_limits<ptrdiff_t>::lowest() |
4147 | | - ) |
| 4167 | + || !fits_in<ptrdiff_t>(lnum) |
4148 | 4168 | ) { |
4149 | 4169 | return {}; |
4150 | 4170 | } |
|
0 commit comments