fix: remove stdckdint.h cplusplus code to reduce size
This commit is contained in:
+1
-262
@@ -87,261 +87,7 @@ typedef unsigned __ckd_intmax __ckd_uintmax_t;
|
||||
#define ckd_sub(res, x, y) __builtin_sub_overflow((x), (y), (res))
|
||||
#define ckd_mul(res, x, y) __builtin_mul_overflow((x), (y), (res))
|
||||
|
||||
#elif (defined(__cplusplus) && \
|
||||
(__cplusplus >= 201103L || \
|
||||
(defined(_MSC_VER) && __cplusplus >= 199711L && \
|
||||
__ckd_has_include(<type_traits>) && \
|
||||
__ckd_has_include(<limits>))))
|
||||
#include <type_traits>
|
||||
#include <limits>
|
||||
|
||||
template <typename __T, typename __U, typename __V>
|
||||
inline bool ckd_add(__T *__res, __U __a, __V __b) {
|
||||
static_assert(std::is_integral<__T>::value &&
|
||||
std::is_integral<__U>::value &&
|
||||
std::is_integral<__V>::value,
|
||||
"non-integral types not allowed");
|
||||
static_assert(!std::is_same<__T, bool>::value &&
|
||||
!std::is_same<__U, bool>::value &&
|
||||
!std::is_same<__V, bool>::value,
|
||||
"checked booleans not supported");
|
||||
static_assert(!std::is_same<__T, char>::value &&
|
||||
!std::is_same<__U, char>::value &&
|
||||
!std::is_same<__V, char>::value,
|
||||
"unqualified char type is ambiguous");
|
||||
__ckd_uintmax_t __x = __a;
|
||||
__ckd_uintmax_t __y = __b;
|
||||
__ckd_uintmax_t __z = __x + __y;
|
||||
*__res = static_cast<__T>(__z);
|
||||
if (sizeof(__z) > sizeof(__U) && sizeof(__z) > sizeof(__V)) {
|
||||
if (sizeof(__z) > sizeof(__T) || std::is_signed<__T>::value) {
|
||||
return static_cast<__ckd_intmax_t>(__z) != static_cast<__T>(__z);
|
||||
} else if (!std::is_same<__T, __ckd_uintmax_t>::value) {
|
||||
return (__z != static_cast<__T>(__z) ||
|
||||
((std::is_signed<__U>::value ||
|
||||
std::is_signed<__V>::value) &&
|
||||
static_cast<__ckd_intmax_t>(__z) < 0));
|
||||
}
|
||||
}
|
||||
bool __truncated = false;
|
||||
if (sizeof(__T) < sizeof(__ckd_intmax_t)) {
|
||||
__truncated = __z != static_cast<__ckd_uintmax_t>(static_cast<__T>(__z));
|
||||
}
|
||||
switch (std::is_signed<__T>::value << 2 | //
|
||||
std::is_signed<__U>::value << 1 | //
|
||||
std::is_signed<__V>::value) {
|
||||
case 0: // u = u + u
|
||||
return __truncated | (__z < __x);
|
||||
case 1: // u = u + s
|
||||
__y ^= std::numeric_limits<__ckd_intmax_t>::min();
|
||||
return __truncated |
|
||||
(static_cast<__ckd_intmax_t>((__z ^ __x) &
|
||||
(__z ^ __y)) < 0);
|
||||
case 2: // u = s + u
|
||||
__x ^= std::numeric_limits<__ckd_intmax_t>::min();
|
||||
return __truncated |
|
||||
(static_cast<__ckd_intmax_t>((__z ^ __x) &
|
||||
(__z ^ __y)) < 0);
|
||||
case 3: // u = s + s
|
||||
return __truncated |
|
||||
(static_cast<__ckd_intmax_t>(((__z | __x) & __y) |
|
||||
((__z & __x) & ~__y)) < 0);
|
||||
case 4: // s = u + u
|
||||
return __truncated | (__z < __x) | (static_cast<__ckd_intmax_t>(__z) < 0);
|
||||
case 5: // s = u + s
|
||||
__y ^= std::numeric_limits<__ckd_intmax_t>::min();
|
||||
return __truncated | (__x + __y < __y);
|
||||
case 6: // s = s + u
|
||||
__x ^= std::numeric_limits<__ckd_intmax_t>::min();
|
||||
return __truncated | (__x + __y < __x);
|
||||
case 7: // s = s + s
|
||||
return __truncated |
|
||||
(static_cast<__ckd_intmax_t>((__z ^ __x) &
|
||||
(__z ^ __y)) < 0);
|
||||
default:
|
||||
for (;;) (void)0;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename __T, typename __U, typename __V>
|
||||
inline bool ckd_sub(__T *__res, __U __a, __V __b) {
|
||||
static_assert(std::is_integral<__T>::value &&
|
||||
std::is_integral<__U>::value &&
|
||||
std::is_integral<__V>::value,
|
||||
"non-integral types not allowed");
|
||||
static_assert(!std::is_same<__T, bool>::value &&
|
||||
!std::is_same<__U, bool>::value &&
|
||||
!std::is_same<__V, bool>::value,
|
||||
"checked booleans not supported");
|
||||
static_assert(!std::is_same<__T, char>::value &&
|
||||
!std::is_same<__U, char>::value &&
|
||||
!std::is_same<__V, char>::value,
|
||||
"unqualified char type is ambiguous");
|
||||
__ckd_uintmax_t __x = __a;
|
||||
__ckd_uintmax_t __y = __b;
|
||||
__ckd_uintmax_t __z = __x - __y;
|
||||
*__res = static_cast<__T>(__z);
|
||||
bool __truncated = false;
|
||||
if (sizeof(__T) < sizeof(__ckd_intmax_t)) {
|
||||
__truncated = __z != static_cast<__ckd_uintmax_t>(static_cast<__T>(__z));
|
||||
}
|
||||
switch (std::is_signed<__T>::value << 2 | //
|
||||
std::is_signed<__U>::value << 1 | //
|
||||
std::is_signed<__V>::value) {
|
||||
case 0: // u = u - u
|
||||
return __truncated | (__x < __y);
|
||||
case 1: // u = u - s
|
||||
__y ^= std::numeric_limits<__ckd_intmax_t>::min();
|
||||
return __truncated |
|
||||
(static_cast<__ckd_intmax_t>((__x ^ __y) &
|
||||
(__z ^ __x)) < 0);
|
||||
case 2: // u = s - u
|
||||
return __truncated | (__y > __x) | (static_cast<__ckd_intmax_t>(__x) < 0);
|
||||
case 3: // u = s - s
|
||||
return __truncated |
|
||||
(static_cast<__ckd_intmax_t>(((__z & __x) & __y) |
|
||||
((__z | __x) & ~__y)) < 0);
|
||||
case 4: // s = u - u
|
||||
return __truncated |
|
||||
((__x < __y) ^ (static_cast<__ckd_intmax_t>(__z) < 0));
|
||||
case 5: // s = u - s
|
||||
__y ^= std::numeric_limits<__ckd_intmax_t>::min();
|
||||
return __truncated | (__x >= __y);
|
||||
case 6: // s = s - u
|
||||
__x ^= std::numeric_limits<__ckd_intmax_t>::min();
|
||||
return __truncated | (__x < __y);
|
||||
case 7: // s = s - s
|
||||
return __truncated |
|
||||
(static_cast<__ckd_intmax_t>((__x ^ __y) &
|
||||
(__z ^ __x)) < 0);
|
||||
default:
|
||||
for (;;) (void)0;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename __T, typename __U, typename __V>
|
||||
inline bool ckd_mul(__T *__res, __U __a, __V __b) {
|
||||
static_assert(std::is_integral<__T>::value &&
|
||||
std::is_integral<__U>::value &&
|
||||
std::is_integral<__V>::value,
|
||||
"non-integral types not allowed");
|
||||
static_assert(!std::is_same<__T, bool>::value &&
|
||||
!std::is_same<__U, bool>::value &&
|
||||
!std::is_same<__V, bool>::value,
|
||||
"checked booleans not supported");
|
||||
static_assert(!std::is_same<__T, char>::value &&
|
||||
!std::is_same<__U, char>::value &&
|
||||
!std::is_same<__V, char>::value,
|
||||
"unqualified char type is ambiguous");
|
||||
__ckd_uintmax_t __x = __a;
|
||||
__ckd_uintmax_t __y = __b;
|
||||
if ((sizeof(__U) * 8 - std::is_signed<__U>::value) +
|
||||
(sizeof(__V) * 8 - std::is_signed<__V>::value) <=
|
||||
(sizeof(__T) * 8 - std::is_signed<__T>::value)) {
|
||||
if (sizeof(__ckd_uintmax_t) > sizeof(__T) || std::is_signed<__T>::value) {
|
||||
__ckd_intmax_t __z = __x * __y;
|
||||
return __z != (*__res = static_cast<__T>(__z));
|
||||
} else if (!std::is_same<__T, __ckd_uintmax_t>::value) {
|
||||
__ckd_uintmax_t __z = __x * __y;
|
||||
*__res = static_cast<__T>(__z);
|
||||
return (__z != static_cast<__T>(__z) ||
|
||||
((std::is_signed<__U>::value ||
|
||||
std::is_signed<__V>::value) &&
|
||||
static_cast<__ckd_intmax_t>(__z) < 0));
|
||||
}
|
||||
}
|
||||
switch (std::is_signed<__T>::value << 2 | //
|
||||
std::is_signed<__U>::value << 1 | //
|
||||
std::is_signed<__V>::value) {
|
||||
case 0: { // u = u * u
|
||||
__ckd_uintmax_t __z = __x * __y;
|
||||
int __o = __x && __z / __x != __y;
|
||||
*__res = static_cast<__T>(__z);
|
||||
return __o | (sizeof(__T) < sizeof(__z) &&
|
||||
__z != static_cast<__ckd_uintmax_t>(*__res));
|
||||
}
|
||||
case 1: { // u = u * s
|
||||
__ckd_uintmax_t __z = __x * __y;
|
||||
int __o = __x && __z / __x != __y;
|
||||
*__res = static_cast<__T>(__z);
|
||||
return (__o | ((static_cast<__ckd_intmax_t>(__y) < 0) & !!__x) |
|
||||
(sizeof(__T) < sizeof(__z) &&
|
||||
__z != static_cast<__ckd_uintmax_t>(*__res)));
|
||||
}
|
||||
case 2: { // u = s * u
|
||||
__ckd_uintmax_t __z = __x * __y;
|
||||
int __o = __x && __z / __x != __y;
|
||||
*__res = static_cast<__T>(__z);
|
||||
return (__o | ((static_cast<__ckd_intmax_t>(__x) < 0) & !!__y) |
|
||||
(sizeof(__T) < sizeof(__z) &&
|
||||
__z != static_cast<__ckd_uintmax_t>(*__res)));
|
||||
}
|
||||
case 3: { // u = s * s
|
||||
int __o = false;
|
||||
if (static_cast<__ckd_intmax_t>(__x & __y) < 0) {
|
||||
__x = 0 - __x;
|
||||
__y = 0 - __y;
|
||||
} else if (static_cast<__ckd_intmax_t>(__x ^ __y) < 0) {
|
||||
__o = __x && __y;
|
||||
}
|
||||
__ckd_uintmax_t __z = __x * __y;
|
||||
__o |= __x && __z / __x != __y;
|
||||
*__res = static_cast<__T>(__z);
|
||||
return __o | (sizeof(__T) < sizeof(__z) &&
|
||||
__z != static_cast<__ckd_uintmax_t>(*__res));
|
||||
}
|
||||
case 4: { // s = u * u
|
||||
__ckd_uintmax_t __z = __x * __y;
|
||||
int __o = __x && __z / __x != __y;
|
||||
*__res = static_cast<__T>(__z);
|
||||
return (__o | (static_cast<__ckd_intmax_t>(__z) < 0) |
|
||||
(sizeof(__T) < sizeof(__z) &&
|
||||
__z != static_cast<__ckd_uintmax_t>(*__res)));
|
||||
}
|
||||
case 5: { // s = u * s
|
||||
__ckd_uintmax_t __t = 0 - __y;
|
||||
__t = static_cast<__ckd_intmax_t>(__t) < 0 ? __y : __t;
|
||||
__ckd_uintmax_t __p = __t * __x;
|
||||
int __o = __t && __p / __t != __x;
|
||||
int __n = static_cast<__ckd_intmax_t>(__y) < 0;
|
||||
__ckd_uintmax_t __z = __n ? 0 - __p : __p;
|
||||
*__res = static_cast<__T>(__z);
|
||||
__ckd_uintmax_t __m = std::numeric_limits<__ckd_intmax_t>::max();
|
||||
return (__o | (__p > __m + __n) |
|
||||
(sizeof(__T) < sizeof(__z) &&
|
||||
__z != static_cast<__ckd_uintmax_t>(*__res)));
|
||||
}
|
||||
case 6: { // s = s * u
|
||||
__ckd_uintmax_t __t = 0 - __x;
|
||||
__t = static_cast<__ckd_intmax_t>(__t) < 0 ? __x : __t;
|
||||
__ckd_uintmax_t __p = __t * __y;
|
||||
int __o = __t && __p / __t != __y;
|
||||
int __n = static_cast<__ckd_intmax_t>(__x) < 0;
|
||||
__ckd_uintmax_t __z = __n ? 0 - __p : __p;
|
||||
*__res = static_cast<__T>(__z);
|
||||
__ckd_uintmax_t __m = std::numeric_limits<__ckd_intmax_t>::max();
|
||||
return (__o | (__p > __m + __n) |
|
||||
(sizeof(__T) < sizeof(__z) &&
|
||||
__z != static_cast<__ckd_uintmax_t>(*__res)));
|
||||
}
|
||||
case 7: { // s = s * s
|
||||
__ckd_uintmax_t __z = __x * __y;
|
||||
*__res = static_cast<__T>(__z);
|
||||
return ((((static_cast<__ckd_intmax_t>(__y) < 0) &&
|
||||
(static_cast<__ckd_intmax_t>(__x) ==
|
||||
std::numeric_limits<__ckd_intmax_t>::min())) ||
|
||||
(__y && ((static_cast<__ckd_intmax_t>(__z) /
|
||||
static_cast<__ckd_intmax_t>(__y)) !=
|
||||
static_cast<__ckd_intmax_t>(__x)))) |
|
||||
(sizeof(__T) < sizeof(__z) &&
|
||||
__z != static_cast<__ckd_uintmax_t>(*__res)));
|
||||
}
|
||||
default:
|
||||
for (;;) (void)0;
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
|
||||
#else
|
||||
|
||||
#define ckd_add(res, a, b) __ckd_expr(add, (res), (a), (b))
|
||||
#define ckd_sub(res, a, b) __ckd_expr(sub, (res), (a), (b))
|
||||
@@ -629,12 +375,5 @@ __ckd_declare_mul(__ckd_mul_sint128, signed __int128)
|
||||
__ckd_declare_mul(__ckd_mul_uint128, unsigned __int128)
|
||||
#endif
|
||||
|
||||
#else
|
||||
#pragma message "checked integer arithmetic unsupported in this environment"
|
||||
|
||||
#define ckd_add(res, x, y) (*(res) = (x) + (y), 0)
|
||||
#define ckd_sub(res, x, y) (*(res) = (x) - (y), 0)
|
||||
#define ckd_mul(res, x, y) (*(res) = (x) * (y), 0)
|
||||
|
||||
#endif /* GNU */
|
||||
#endif /* STDCKDINT_H_ */
|
||||
|
||||
Reference in New Issue
Block a user