#ifndef PARTITION_ALLOC_PARTITION_ALLOC_BASE_NUMERICS_SAFE_MATH_SHARED_IMPL_H_
#define PARTITION_ALLOC_PARTITION_ALLOC_BASE_NUMERICS_SAFE_MATH_SHARED_IMPL_H_
#include <cassert>
#include <climits>
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <limits>
#include <type_traits>
#include "partition_alloc/build_config.h"
#include "partition_alloc/partition_alloc_base/numerics/safe_conversions.h"
#if PA_BUILDFLAG(IS_ASMJS)
#define PA_BASE_HAS_OPTIMIZED_SAFE_MATH …
#elif !defined(__native_client__) && \
((defined(__clang__) && \
((__clang_major__ > 3) || \
(__clang_major__ == 3 && __clang_minor__ >= 4))) || \
(defined(__GNUC__) && __GNUC__ >= 5))
#include "partition_alloc/partition_alloc_base/numerics/safe_math_clang_gcc_impl.h"
#define PA_BASE_HAS_OPTIMIZED_SAFE_MATH …
#else
#define PA_BASE_HAS_OPTIMIZED_SAFE_MATH …
#endif
namespace partition_alloc::internal::base::internal {
#if !PA_BASE_HAS_OPTIMIZED_SAFE_MATH
template <typename T, typename U>
struct CheckedAddFastOp {
static const bool is_supported = false;
template <typename V>
static constexpr bool Do(T, U, V*) {
return CheckOnFailure::template HandleFailure<bool>();
}
};
template <typename T, typename U>
struct CheckedSubFastOp {
static const bool is_supported = false;
template <typename V>
static constexpr bool Do(T, U, V*) {
return CheckOnFailure::template HandleFailure<bool>();
}
};
template <typename T, typename U>
struct CheckedMulFastOp {
static const bool is_supported = false;
template <typename V>
static constexpr bool Do(T, U, V*) {
return CheckOnFailure::template HandleFailure<bool>();
}
};
template <typename T, typename U>
struct ClampedAddFastOp {
static const bool is_supported = false;
template <typename V>
static constexpr V Do(T, U) {
return CheckOnFailure::template HandleFailure<V>();
}
};
template <typename T, typename U>
struct ClampedSubFastOp {
static const bool is_supported = false;
template <typename V>
static constexpr V Do(T, U) {
return CheckOnFailure::template HandleFailure<V>();
}
};
template <typename T, typename U>
struct ClampedMulFastOp {
static const bool is_supported = false;
template <typename V>
static constexpr V Do(T, U) {
return CheckOnFailure::template HandleFailure<V>();
}
};
template <typename T>
struct ClampedNegFastOp {
static const bool is_supported = false;
static constexpr T Do(T) {
return CheckOnFailure::template HandleFailure<T>();
}
};
#endif
#undef PA_BASE_HAS_OPTIMIZED_SAFE_MATH
template <typename Numeric,
bool IsInteger = std::is_integral_v<Numeric>,
bool IsFloat = std::is_floating_point_v<Numeric>>
struct UnsignedOrFloatForSize;
UnsignedOrFloatForSize<Numeric, true, false>;
UnsignedOrFloatForSize<Numeric, false, true>;
template <typename T,
typename std::enable_if<std::is_integral_v<T>>::type* = nullptr>
constexpr T NegateWrapper(T value) { … }
template <typename T,
typename std::enable_if<std::is_floating_point_v<T>>::type* = nullptr>
constexpr T NegateWrapper(T value) { … }
template <typename T,
typename std::enable_if<std::is_integral_v<T>>::type* = nullptr>
constexpr typename std::make_unsigned<T>::type InvertWrapper(T value) { … }
template <typename T,
typename std::enable_if<std::is_integral_v<T>>::type* = nullptr>
constexpr T AbsWrapper(T value) { … }
template <typename T,
typename std::enable_if<std::is_floating_point_v<T>>::type* = nullptr>
constexpr T AbsWrapper(T value) { … }
template <template <typename, typename, typename> class M,
typename L,
typename R>
struct MathWrapper { … };
#define PA_BASE_NUMERIC_ARITHMETIC_VARIADIC(CLASS, CL_ABBR, OP_NAME) …
#define PA_BASE_NUMERIC_ARITHMETIC_OPERATORS(CLASS, CL_ABBR, OP_NAME, OP, \
CMP_OP) …
}
#endif