5#ifndef BASE_NUMERICS_CHECKED_MATH_IMPL_H_
6#define BASE_NUMERICS_CHECKED_MATH_IMPL_H_
29 UnsignedDst ux =
static_cast<UnsignedDst
>(
x);
30 UnsignedDst uy =
static_cast<UnsignedDst
>(
y);
31 UnsignedDst uresult =
static_cast<UnsignedDst
>(ux + uy);
32 *
result =
static_cast<T>(uresult);
36 ?
static_cast<SignedDst
>((uresult ^ ux) & (uresult ^ uy)) >= 0
40template <
typename T,
typename U,
class Enable =
void>
43template <
typename T,
typename U>
46 typename
std::enable_if<std::is_integral<T>::value &&
47 std::is_integral<U>::value>
::type> {
65 !IsValueInRangeForNumericType<Promotion>(
y))) {
69 Promotion presult = {};
72 presult =
static_cast<Promotion
>(
x) +
static_cast<Promotion
>(
y);
75 static_cast<Promotion
>(
y), &presult);
77 *
result =
static_cast<V>(presult);
78 return is_valid && IsValueInRangeForNumericType<V>(presult);
89 UnsignedDst ux =
static_cast<UnsignedDst
>(
x);
90 UnsignedDst uy =
static_cast<UnsignedDst
>(
y);
91 UnsignedDst uresult =
static_cast<UnsignedDst
>(ux - uy);
92 *
result =
static_cast<T>(uresult);
96 ?
static_cast<SignedDst
>((uresult ^ ux) & (ux ^ uy)) >= 0
100template <
typename T,
typename U,
class Enable =
void>
103template <
typename T,
typename U>
106 typename
std::enable_if<std::is_integral<T>::value &&
107 std::is_integral<U>::value>
::type> {
109 template <
typename V>
125 !IsValueInRangeForNumericType<Promotion>(
y))) {
129 Promotion presult = {};
132 presult =
static_cast<Promotion
>(
x) -
static_cast<Promotion
>(
y);
135 static_cast<Promotion
>(
y), &presult);
137 *
result =
static_cast<V>(presult);
138 return is_valid && IsValueInRangeForNumericType<V>(presult);
151 UnsignedDst uresult =
static_cast<UnsignedDst
>(ux * uy);
152 const bool is_negative =
154 *
result = is_negative ? 0 - uresult : uresult;
162template <
typename T,
typename U,
class Enable =
void>
165template <
typename T,
typename U>
168 typename
std::enable_if<std::is_integral<T>::value &&
169 std::is_integral<U>::value>
::type> {
171 template <
typename V>
180 !IsValueInRangeForNumericType<Promotion>(
y)) &&
185 Promotion presult = {};
191 presult =
static_cast<Promotion
>(
x) *
static_cast<Promotion
>(
y);
194 static_cast<Promotion
>(
y), &presult);
196 *
result =
static_cast<V>(presult);
197 return is_valid && IsValueInRangeForNumericType<V>(presult);
203template <
typename T,
typename U,
class Enable =
void>
206template <
typename T,
typename U>
209 typename
std::enable_if<std::is_integral<T>::value &&
210 std::is_integral<U>::value>
::type> {
212 template <
typename V>
223 static_cast<Promotion
>(
x) ==
224 std::numeric_limits<Promotion>::lowest() &&
225 y ==
static_cast<U>(-1)))) {
231 !IsValueInRangeForNumericType<Promotion>(
y)) &&
236 Promotion presult = Promotion(
x) / Promotion(
y);
237 *
result =
static_cast<V>(presult);
238 return IsValueInRangeForNumericType<V>(presult);
242template <
typename T,
typename U,
class Enable =
void>
245template <
typename T,
typename U>
248 typename
std::enable_if<std::is_integral<T>::value &&
249 std::is_integral<U>::value>
::type> {
251 template <
typename V>
260 static_cast<Promotion
>(
x) ==
261 std::numeric_limits<Promotion>::lowest() &&
262 y ==
static_cast<U>(-1)))) {
267 Promotion presult =
static_cast<Promotion
>(
x) %
static_cast<Promotion
>(
y);
268 *
result =
static_cast<Promotion
>(presult);
269 return IsValueInRangeForNumericType<V>(presult);
273template <
typename T,
typename U,
class Enable =
void>
279template <
typename T,
typename U>
282 typename
std::enable_if<std::is_integral<T>::value &&
283 std::is_integral<U>::value>
::type> {
285 template <
typename V>
303template <
typename T,
typename U,
class Enable =
void>
309template <
typename T,
typename U>
312 typename
std::enable_if<std::is_integral<T>::value &&
313 std::is_integral<U>::value>
::type> {
315 template <
typename V>
322 return IsValueInRangeForNumericType<V>(tmp);
328template <
typename T,
typename U,
class Enable =
void>
332template <
typename T,
typename U>
335 typename
std::enable_if<std::is_integral<T>::value &&
336 std::is_integral<U>::value>
::type> {
339 template <
typename V>
343 return IsValueInRangeForNumericType<V>(tmp);
347template <
typename T,
typename U,
class Enable =
void>
351template <
typename T,
typename U>
354 typename
std::enable_if<std::is_integral<T>::value &&
355 std::is_integral<U>::value>
::type> {
358 template <
typename V>
362 return IsValueInRangeForNumericType<V>(tmp);
366template <
typename T,
typename U,
class Enable =
void>
370template <
typename T,
typename U>
373 typename
std::enable_if<std::is_integral<T>::value &&
374 std::is_integral<U>::value>
::type> {
377 template <
typename V>
381 return IsValueInRangeForNumericType<V>(tmp);
387template <
typename T,
typename U,
class Enable =
void>
390template <
typename T,
typename U>
394 typename
std::enable_if<std::is_arithmetic<T>::value &&
395 std::is_arithmetic<U>::value>
::type> {
397 template <
typename V>
402 return IsValueInRangeForNumericType<V>(tmp);
408template <
typename T,
typename U,
class Enable =
void>
411template <
typename T,
typename U>
415 typename
std::enable_if<std::is_arithmetic<T>::value &&
416 std::is_arithmetic<U>::value>
::type> {
418 template <
typename V>
423 return IsValueInRangeForNumericType<V>(tmp);
429#define BASE_FLOAT_ARITHMETIC_OPS(NAME, OP) \
430 template <typename T, typename U> \
431 struct Checked##NAME##Op< \
433 typename std::enable_if<std::is_floating_point<T>::value || \
434 std::is_floating_point<U>::value>::type> { \
435 using result_type = typename MaxExponentPromotion<T, U>::type; \
436 template <typename V> \
437 static constexpr bool Do(T x, U y, V* result) { \
438 using Promotion = typename MaxExponentPromotion<T, U>::type; \
439 Promotion presult = x OP y; \
440 *result = static_cast<V>(presult); \
441 return IsValueInRangeForNumericType<V>(presult); \
450#undef BASE_FLOAT_ARITHMETIC_OPS
461template <
typename NumericType>
485 template <
typename Src>
486 static constexpr T WellDefinedConversionOrZero(
const Src
value,
495 template <
typename Src, NumericRepresentation type>
500 template <
typename Src>
503 value_(WellDefinedConversionOrZero(
value, is_valid_)) {
508 template <
typename Src>
510 : is_valid_(rhs.IsValid()),
511 value_(WellDefinedConversionOrZero(rhs.
value(), is_valid_)) {}
513 template <
typename Src>
516 value_(WellDefinedConversionOrZero(
value, is_valid_)) {}
518 constexpr bool is_valid()
const {
return is_valid_; }
519 constexpr T value()
const {
return value_; }
529 template <
typename Src>
530 static constexpr T WellDefinedConversionOrNaN(
const Src
value,
537 : std::numeric_limits<T>::quiet_NaN();
541 template <
typename Src, NumericRepresentation type>
546 template <
typename Src>
550 template <
typename Src>
552 : value_(WellDefinedConversionOrNaN(
557 template <
typename Src>
559 : value_(WellDefinedConversionOrNaN(
567 value_ >= std::numeric_limits<T>::lowest()
570 constexpr T value()
const {
return value_; }
static bool is_valid(SkISize dim)
#define BASE_FLOAT_ARITHMETIC_OPS(NAME, OP)
constexpr bool is_valid() const
constexpr CheckedNumericState(Src value, bool is_valid)
constexpr CheckedNumericState(const CheckedNumericState< Src > &rhs)
constexpr CheckedNumericState(Src value)
constexpr CheckedNumericState()
constexpr T value() const
constexpr bool is_valid() const
constexpr CheckedNumericState(const CheckedNumericState< Src > &rhs)
constexpr CheckedNumericState()
constexpr T value() const
constexpr CheckedNumericState(Src value, bool is_valid)
constexpr CheckedNumericState(Src value)
static float max(float r, float g, float b)
T __attribute__((ext_vector_type(N))) V
constexpr bool CheckedMulImpl(T x, T y, T *result)
constexpr bool CheckedSubImpl(T x, T y, T *result)
@ NUMERIC_RANGE_CONTAINED
constexpr bool CheckedAddImpl(T x, T y, T *result)
constexpr bool IsValueNegative(T value)
constexpr std::make_unsigned< T >::type SafeUnsignedAbs(T value)
constexpr std::make_unsigned< typenamebase::internal::UnderlyingType< Src >::type >::type as_unsigned(const Src value)
constexpr bool IsValueInRangeForNumericType(Src value)
constexpr bool MustTreatAsConstexpr(const T v)
SINT bool isfinite(const Vec< N, T > &v)
#define BASE_NUMERICS_LIKELY(x)
#define BASE_NUMERICS_UNLIKELY(x)
static constexpr bool Do(T, U, V *)
static constexpr bool Do(T x, U y, V *result)
typename MaxExponentPromotion< T, U >::type result_type
static constexpr bool Do(T x, U y, V *result)
typename std::make_unsigned< typename MaxExponentPromotion< T, U >::type >::type result_type
static constexpr bool Do(T x, U y, V *result)
typename MaxExponentPromotion< T, U >::type result_type
static constexpr bool Do(T x, U shift, V *result)
typename MaxExponentPromotion< T, U >::type result_type
static constexpr bool Do(T x, U y, V *result)
typename LowestValuePromotion< T, U >::type result_type
static constexpr bool Do(T x, U y, V *result)
typename MaxExponentPromotion< T, U >::type result_type
static constexpr bool Do(T x, U y, V *result)
static constexpr bool Do(T, U, V *)
static constexpr bool Do(T x, U y, V *result)
typename MaxExponentPromotion< T, U >::type result_type
typename std::make_unsigned< typename MaxExponentPromotion< T, U >::type >::type result_type
static constexpr bool Do(T x, U y, V *result)
static bool Do(T x, U shift, V *result)
static constexpr bool Do(T, U, V *)
typename MaxExponentPromotion< T, U >::type result_type
static constexpr bool Do(T x, U y, V *result)
static constexpr bool Do(T x, U y, V *result)
typename std::make_unsigned< typename MaxExponentPromotion< T, U >::type >::type result_type
static const NumericRepresentation value
static constexpr bool Test(const L lhs, const R rhs)
static constexpr bool Test(const L lhs, const R rhs)
typename ArithmeticOrUnderlyingEnum< T >::type type