7#include "../utility/utility.hpp"
8#include "../macros.hpp"
13#if HI_PROCESSOR == HI_CPU_X64
17#if HI_OPERATING_SYSTEM == HI_OS_WINDOWS
19#pragma intrinsic(_mul128)
24hi_warning_ignore_msvc(4702);
28template<
typename T,
typename U>
29inline bool convert_overflow(T x, U *r)
31 static_assert(std::is_integral_v<U>,
"convert_overflow() requires integral return type.");
33 std::is_integral_v<T> || std::is_floating_point_v<T>,
"convert_overflow() requires float or integral argument type.");
35 if constexpr (std::is_integral_v<T>) {
37 *r =
static_cast<U
>(x);
46inline bool add_overflow(T lhs, T rhs, T *r)
48 static_assert(std::is_integral_v<T>,
"add_overflow() requires integral arguments.");
50#if HI_COMPILER == HI_CC_GCC or HI_COMPILER == HI_CC_CLANG
55 if constexpr (std::is_unsigned_v<T>) {
62 hilet
lhs_ =
static_cast<std::make_unsigned_t<T>
>(lhs);
63 hilet
rhs_ =
static_cast<std::make_unsigned_t<T>
>(rhs);
65 *r =
static_cast<T
>(
r_);
66 return ((lhs ^ *r) & (rhs ^ *r)) < 0;
71inline bool sub_overflow(T lhs, T rhs, T *r)
73 static_assert(std::is_integral_v<T>,
"sub_overflow() requires integral arguments.");
75#if HI_COMPILER == HI_CC_GCC or HI_COMPILER == HI_CC_CLANG
80 if constexpr (std::is_unsigned_v<T>) {
87 hilet
lhs_ =
static_cast<std::make_unsigned_t<T>
>(lhs);
88 hilet
rhs_ =
static_cast<std::make_unsigned_t<T>
>(rhs);
90 *r =
static_cast<T
>(
r_);
91 return ((lhs ^ rhs) & (
~rhs ^ *r)) < 0;
101 static_assert(std::is_integral_v<T>,
"mul_overflow() requires integral arguments.");
103#if HI_COMPILER == HI_CC_GCC or HI_COMPILER == HI_CC_CLANG
106#elif HI_COMPILER == HI_CC_MSVC
107 if constexpr (std::is_signed_v<T>
and sizeof(T) ==
sizeof(
long long)) {
113 return (
hi ^ (*r >> 63)) != 0;
115 }
else if constexpr (std::is_unsigned_v<T>
and sizeof(T) ==
sizeof(
unsigned long long)) {
116 unsigned long long hi = 0;
122 if constexpr (
sizeof(T) <= (
sizeof(make_intmax_t<T>) / 2)) {
124 hilet
lhs_ =
static_cast<make_intmax_t<T>
>(lhs);
125 hilet
rhs_ =
static_cast<make_intmax_t<T>
>(rhs);
127 *r =
static_cast<T
>(
r_);
131 hi_not_implemented();
DOXYGEN BUG.
Definition algorithm.hpp:16
bool mul_overflow(T lhs, T rhs, T *r) noexcept
Multiply with overflow detection.
Definition int_overflow.hpp:99
geometry/margins.hpp
Definition lookahead_iterator.hpp:5
constexpr Out narrow_cast(In const &rhs) noexcept
Cast numeric values without loss of precision.
Definition cast.hpp:377