5#ifndef BASE_NUMERICS_SAFE_MATH_SHARED_IMPL_H_
6#define BASE_NUMERICS_SAFE_MATH_SHARED_IMPL_H_
22#define BASE_HAS_OPTIMIZED_SAFE_MATH (0)
24#elif !defined(__native_client__) && \
25 ((defined(__clang__) && \
26 ((__clang_major__ > 3) || \
27 (__clang_major__ == 3 && __clang_minor__ >= 4))) || \
28 (defined(__GNUC__) && __GNUC__ >= 5))
30#define BASE_HAS_OPTIMIZED_SAFE_MATH (1)
32#define BASE_HAS_OPTIMIZED_SAFE_MATH (0)
40#if !BASE_HAS_OPTIMIZED_SAFE_MATH
41template <
typename T,
typename U>
42struct CheckedAddFastOp {
45 static constexpr bool Do(
T,
U,
V*) {
47 return CheckOnFailure::template HandleFailure<bool>();
51template <
typename T,
typename U>
52struct CheckedSubFastOp {
55 static constexpr bool Do(
T,
U,
V*) {
57 return CheckOnFailure::template HandleFailure<bool>();
61template <
typename T,
typename U>
62struct CheckedMulFastOp {
65 static constexpr bool Do(
T,
U,
V*) {
67 return CheckOnFailure::template HandleFailure<bool>();
71template <
typename T,
typename U>
72struct ClampedAddFastOp {
77 return CheckOnFailure::template HandleFailure<V>();
81template <
typename T,
typename U>
82struct ClampedSubFastOp {
87 return CheckOnFailure::template HandleFailure<V>();
91template <
typename T,
typename U>
92struct ClampedMulFastOp {
97 return CheckOnFailure::template HandleFailure<V>();
102struct ClampedNegFastOp {
106 return CheckOnFailure::template HandleFailure<T>();
110#undef BASE_HAS_OPTIMIZED_SAFE_MATH
116template <
typename Numeric,
121template <
typename Numeric>
126template <
typename Numeric>
141 return static_cast<T>(UnsignedT(0) -
static_cast<UnsignedT
>(
value));
170template <
template <
typename,
typename,
typename>
class M,
177 using type =
typename math::result_type;
182template <
template <
typename,
typename,
typename>
class M,
188template <
template <
typename,
typename,
typename>
class M,
195template <
template <
typename,
typename,
typename>
class M,
207#define BASE_NUMERIC_ARITHMETIC_VARIADIC(CLASS, CL_ABBR, OP_NAME) \
208 template <typename L, typename R, typename... Args> \
209 constexpr CLASS##Numeric< \
210 typename ResultType<CLASS##OP_NAME##Op, L, R, Args...>::type> \
211 CL_ABBR##OP_NAME(const L lhs, const R rhs, const Args... args) { \
212 return CL_ABBR##MathOp<CLASS##OP_NAME##Op, L, R, Args...>(lhs, rhs, \
216#define BASE_NUMERIC_ARITHMETIC_OPERATORS(CLASS, CL_ABBR, OP_NAME, OP, CMP_OP) \
218 template <typename L, typename R, \
219 typename std::enable_if<Is##CLASS##Op<L, R>::value>::type* = \
221 constexpr CLASS##Numeric< \
222 typename MathWrapper<CLASS##OP_NAME##Op, L, R>::type> \
223 operator OP(const L lhs, const R rhs) { \
224 return decltype(lhs OP rhs)::template MathOp<CLASS##OP_NAME##Op>(lhs, \
228 template <typename L> \
229 template <typename R> \
230 constexpr CLASS##Numeric<L>& CLASS##Numeric<L>::operator CMP_OP( \
232 return MathOp<CLASS##OP_NAME##Op>(rhs); \
235 BASE_NUMERIC_ARITHMETIC_VARIADIC(CLASS, CL_ABBR, OP_NAME)
T __attribute__((ext_vector_type(N))) V
constexpr T NegateWrapper(T value)
constexpr std::make_unsigned< T >::type SafeUnsignedAbs(T value)
constexpr T AbsWrapper(T value)
constexpr std::make_unsigned< T >::type InvertWrapper(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 constexpr bool Do(T, U, V *)
static const bool is_supported
static const bool is_supported
static constexpr V Do(T, U)
static constexpr V Do(T, U)
static const bool is_supported
static const bool is_supported
static const bool is_supported
static constexpr V Do(T, U)
typename math::result_type type
M< typename UnderlyingType< L >::type, typename UnderlyingType< R >::type, void > math
typename MathWrapper< M, L, R >::type type
typename ResultType< M, typename ResultType< M, L, R >::type, Args... >::type type
typename ArithmeticOrUnderlyingEnum< T >::type type
typename std::make_unsigned< Numeric >::type type