8#ifndef V8_BASE_NUMERICS_SAFE_CONVERSIONS_H_
9#define V8_BASE_NUMERICS_SAFE_CONVERSIONS_H_
20#if defined(__ARMEL__) && !defined(__native_client__)
22#define BASE_HAS_OPTIMIZED_SAFE_CONVERSIONS (1)
24#define BASE_HAS_OPTIMIZED_SAFE_CONVERSIONS (0)
30#if !BASE_HAS_OPTIMIZED_SAFE_CONVERSIONS
31template <
typename Dst,
typename Src>
32struct SaturateFastAsmOp {
34 static constexpr Dst
Do(Src) {
36 return CheckOnFailure::template HandleFailure<Dst>();
40#undef BASE_HAS_OPTIMIZED_SAFE_CONVERSIONS
44template <
typename Dst,
typename Src>
47 static constexpr bool Do(Src) {
49 return CheckOnFailure::template HandleFailure<bool>();
54template <
typename Dst,
typename Src>
55 requires(std::signed_integral<Dst> && std::signed_integral<Src> &&
56 !kIsTypeInRangeForNumericType<Dst, Src>)
57struct IsValueInRangeFastOp<Dst, Src> {
58 static constexpr bool is_supported =
true;
60 static constexpr bool Do(Src value) {
63 return value ==
static_cast<Dst
>(
value);
68template <
typename Dst,
typename Src>
69 requires(std::unsigned_integral<Dst> && std::signed_integral<Src> &&
70 !kIsTypeInRangeForNumericType<Dst, Src>)
72 static constexpr bool is_supported =
true;
74 static constexpr bool Do(Src value) {
83template <
typename Dst,
typename Src>
84 requires(IsNumeric<Src> && std::is_arithmetic_v<Dst> &&
85 std::numeric_limits<Dst>::lowest() < std::numeric_limits<Dst>::max())
88 const auto underlying_value =
static_cast<SrcType
>(
value);
101 requires(IsNumeric<Src> && std::is_arithmetic_v<Dst> &&
102 std::numeric_limits<Dst>::lowest() < std::numeric_limits<Dst>::max())
106 if (IsValueInRangeForNumericType<Dst>(value)) [[likely]] {
109 return CheckHandler::template HandleFailure<Dst>();
117 static constexpr T
NaN() {
118 if constexpr (std::numeric_limits<T>::has_quiet_NaN) {
119 return std::numeric_limits<T>::quiet_NaN();
124 using std::numeric_limits<T>::max;
126 if constexpr (std::numeric_limits<T>::has_infinity) {
127 return std::numeric_limits<T>::infinity();
129 return std::numeric_limits<T>::max();
132 using std::numeric_limits<T>::lowest;
134 if constexpr (std::numeric_limits<T>::has_infinity) {
135 return std::numeric_limits<T>::infinity() * -1;
137 return std::numeric_limits<T>::lowest();
142template <
typename Dst,
template <
typename>
class S,
typename Src>
148 : S<Dst>::Underflow())
158template <
typename Dst,
typename Src>
161 static constexpr Dst
Do(Src) {
163 return CheckOnFailure::template HandleFailure<Dst>();
167template <
typename Dst,
typename Src>
168 requires(std::integral<Src> && std::integral<Dst> &&
170struct SaturateFastOp<Dst, Src> {
171 static constexpr bool is_supported =
true;
172 static constexpr Dst
Do(Src value) {
177template <
typename Dst,
typename Src>
178 requires(std::integral<Src> && std::integral<Dst> &&
181 static constexpr bool is_supported =
true;
182 static constexpr Dst
Do(Src value) {
189 if (IsValueInRangeForNumericType<Dst>(value)) [[likely]] {
190 return static_cast<Dst
>(
value);
200template <
typename Dst,
201 template <
typename>
class SaturationHandler = SaturationDefaultLimits,
205 const auto underlying_value =
static_cast<SrcType
>(
value);
206 return !std::is_constant_evaluated() &&
208 std::is_same_v<SaturationHandler<Dst>,
220template <
typename Dst,
typename Src,
typename SrcType = UnderlyingType<Src>>
222 IsNumeric<Src> && std::is_arithmetic_v<Dst> &&
232 return static_cast<Dst
>(
static_cast<SrcType
>(
value));
236template <
typename Dst,
typename Src>
239template <
typename Dst,
typename Src>
240 requires(std::is_arithmetic_v<ArithmeticOrUnderlyingEnum<Dst>> &&
241 std::is_arithmetic_v<ArithmeticOrUnderlyingEnum<Src>>)
257 requires std::is_arithmetic_v<T>
265 template <
typename Src>
271 template <
typename Src>
287 template <
typename Dst>
289 constexpr operator Dst()
const {
297 template <
typename U>
298 requires std::is_arithmetic_v<U>
314#define BASE_NUMERIC_COMPARISON_OPERATORS(CLASS, NAME, OP) \
315 template <typename L, typename R> \
316 requires(internal::Is##CLASS##Op<L, R>) \
317 constexpr bool operator OP(L lhs, R rhs) { \
318 return SafeCompare<NAME, UnderlyingType<L>, UnderlyingType<R>>(lhs, rhs); \
330using internal::as_signed;
331using internal::as_unsigned;
332using internal::checked_cast;
333using internal::IsValueInRangeForNumericType;
334using internal::IsValueNegative;
335using internal::kIsTypeInRangeForNumericType;
336using internal::MakeStrictNum;
337using internal::SafeUnsignedAbs;
338using internal::saturated_cast;
339using internal::strict_cast;
358template <typename Dst =
int, typename Src>
359 requires(
std::integral<Dst> &&
std::floating_point<Src>)
365template <
typename Dst =
int,
typename Src>
366 requires(std::integral<Dst> && std::floating_point<Src>)
380template <
typename Dst =
int,
typename Src>
381 requires(std::integral<Dst> && std::floating_point<Src>)
383 const Src rounded = std::round(value);
constexpr bool IsUnderflowFlagSet() const
constexpr bool IsOverflowFlagSet() const
constexpr bool IsValid() const
constexpr bool operator!() const
constexpr StrictNumeric(Src value)
constexpr StrictNumeric()
constexpr StrictNumeric(const StrictNumeric< Src > &rhs)
constexpr bool IsValueNegative(T value)
constexpr auto kStaticDstRangeRelationToSrcRange
StrictNumeric(T) -> StrictNumeric< T >
constexpr auto as_unsigned(Src value)
UnderlyingTypeImpl< T >::type UnderlyingType
constexpr Dst saturated_cast_impl(Src value, RangeCheck constraint)
constexpr Dst strict_cast(Src value)
constexpr bool kIsNumericRangeContained
constexpr bool kIsMaxInRangeForNumericType
constexpr bool kIsNumericRangeContained< Dst, Src >
constexpr Dst checked_cast(Src value)
constexpr bool IsValueInRangeForNumericType(Src value)
constexpr Dst CommonMaxOrMin(bool is_min)
constexpr StrictNumeric< UnderlyingType< T > > MakeStrictNum(const T value)
typename std::conditional_t< std::is_enum_v< T >, std::underlying_type< T >, ArithmeticOrIntegralConstant< T > >::type ArithmeticOrUnderlyingEnum
constexpr RangeCheck DstRangeRelationToSrcRange(Src value)
constexpr bool kIsMinInRangeForNumericType
constexpr Dst saturated_cast(Src value)
Dst ClampRound(Src value)
Dst ClampFloor(Src value)
#define BASE_NUMERIC_COMPARISON_OPERATORS(CLASS, NAME, OP)
static constexpr bool Do(Src value)
static constexpr bool is_supported
static constexpr bool Do(Src)
static constexpr Dst Do(Src)
static constexpr bool is_supported
static constexpr Dst Do(Src value)
static constexpr bool is_supported
static constexpr Dst Do(Src)
static constexpr T Underflow()
static constexpr T Overflow()
std::unique_ptr< ValueMirror > value