8#ifndef V8_BASE_NUMERICS_SAFE_MATH_SHARED_IMPL_H_
9#define V8_BASE_NUMERICS_SAFE_MATH_SHARED_IMPL_H_
16#include "build/build_config.h"
19#if defined(__asmjs__) || defined(__wasm__)
21#define BASE_HAS_OPTIMIZED_SAFE_MATH (0)
23#elif !defined(__native_client__) && \
24 ((defined(__clang__) && \
25 ((__clang_major__ > 3) || \
26 (__clang_major__ == 3 && __clang_minor__ >= 4))) || \
27 (defined(__GNUC__) && __GNUC__ >= 5))
29#define BASE_HAS_OPTIMIZED_SAFE_MATH (1)
31#define BASE_HAS_OPTIMIZED_SAFE_MATH (0)
39#if !BASE_HAS_OPTIMIZED_SAFE_MATH
40template <
typename T,
typename U>
44 static constexpr bool Do(T, U,
V*) {
46 return CheckOnFailure::template HandleFailure<bool>();
50template <
typename T,
typename U>
54 static constexpr bool Do(T, U,
V*) {
56 return CheckOnFailure::template HandleFailure<bool>();
60template <
typename T,
typename U>
64 static constexpr bool Do(T, U,
V*) {
66 return CheckOnFailure::template HandleFailure<bool>();
70template <
typename T,
typename U>
74 static constexpr V Do(T, U) {
76 return CheckOnFailure::template HandleFailure<V>();
80template <
typename T,
typename U>
84 static constexpr V Do(T, U) {
86 return CheckOnFailure::template HandleFailure<V>();
90template <
typename T,
typename U>
94 static constexpr V Do(T, U) {
96 return CheckOnFailure::template HandleFailure<V>();
103 static constexpr T
Do(T) {
105 return CheckOnFailure::template HandleFailure<T>();
109#undef BASE_HAS_OPTIMIZED_SAFE_MATH
115template <
typename Numeric>
118template <
typename Numeric>
119 requires(std::integral<Numeric>)
121 using type =
typename std::make_unsigned<Numeric>::type;
124template <
typename Numeric>
125 requires(std::floating_point<Numeric>)
136 requires(std::integral<T>)
138 using UnsignedT =
typename std::make_unsigned<T>::type;
140 return static_cast<T
>(UnsignedT(0) -
static_cast<UnsignedT
>(
value));
144 requires(std::floating_point<T>)
150 requires(std::integral<T>)
156 requires(std::integral<T>)
162 requires(std::floating_point<T>)
167template <
template <
typename,
typename>
class M,
typename L,
typename R,
169 requires requires {
typename Math::result_type; }
172 using type =
typename math::result_type;
178#define BASE_NUMERIC_ARITHMETIC_VARIADIC(CLASS, CL_ABBR, OP_NAME) \
179 template <typename L, typename R, typename... Args> \
180 constexpr auto CL_ABBR##OP_NAME(L lhs, R rhs, Args... args) { \
181 return CL_ABBR##MathOp<CLASS##OP_NAME##Op, L, R, Args...>(lhs, rhs, \
185#define BASE_NUMERIC_ARITHMETIC_OPERATORS(CLASS, CL_ABBR, OP_NAME, OP, CMP_OP) \
187 template <typename L, typename R> \
188 requires(Is##CLASS##Op<L, R>) \
189 constexpr CLASS##Numeric<typename MathWrapper<CLASS##OP_NAME##Op, L, \
190 R>::type> operator OP(L lhs, \
192 return decltype(lhs OP rhs)::template MathOp<CLASS##OP_NAME##Op>(lhs, \
196 template <typename L> \
197 requires std::is_arithmetic_v<L> \
198 template <typename R> \
199 constexpr CLASS##Numeric<L>& CLASS##Numeric<L>::operator CMP_OP(R rhs) { \
200 return MathOp<CLASS##OP_NAME##Op>(rhs); \
203 BASE_NUMERIC_ARITHMETIC_VARIADIC(CLASS, CL_ABBR, OP_NAME)
constexpr auto SafeUnsignedAbs(T value)
constexpr T NegateWrapper(T value)
constexpr std::make_unsigned< T >::type InvertWrapper(T value)
UnderlyingTypeImpl< T >::type UnderlyingType
constexpr T AbsWrapper(T value)
static const bool is_supported
static constexpr bool Do(T, U, V *)
static const bool is_supported
static constexpr bool Do(T, U, V *)
static const bool is_supported
static constexpr bool Do(T, U, V *)
static constexpr V Do(T, U)
static const bool is_supported
static constexpr V Do(T, U)
static const bool is_supported
static const bool is_supported
static constexpr V Do(T, U)
static const bool is_supported
typename math::result_type type
typename std::make_unsigned< Numeric >::type type
std::unique_ptr< ValueMirror > value