5#ifndef BASE_NUMERICS_SAFE_CONVERSIONS_H_
6#define BASE_NUMERICS_SAFE_CONVERSIONS_H_
15#if !defined(__native_client__) && (defined(__ARMEL__) || defined(__arch64__))
17#define BASE_HAS_OPTIMIZED_SAFE_CONVERSIONS (1)
19#define BASE_HAS_OPTIMIZED_SAFE_CONVERSIONS (0)
22#if !BASE_NUMERICS_DISABLE_OSTREAM_OPERATORS
29#if !BASE_HAS_OPTIMIZED_SAFE_CONVERSIONS
30template <
typename Dst,
typename Src>
33 static constexpr Dst
Do(Src) {
35 return CheckOnFailure::template HandleFailure<Dst>();
39#undef BASE_HAS_OPTIMIZED_SAFE_CONVERSIONS
43template <
typename Dst,
typename Src,
typename Enable =
void>
48 return CheckOnFailure::template HandleFailure<bool>();
53template <
typename Dst,
typename Src>
57 typename
std::enable_if<
58 std::is_integral<Dst>::value && std::is_integral<Src>::value &&
59 std::is_signed<Dst>::value && std::is_signed<Src>::value &&
60 !IsTypeInRangeForNumericType<Dst, Src>::value>
::type> {
71template <
typename Dst,
typename Src>
75 typename
std::enable_if<
76 std::is_integral<Dst>::value && std::is_integral<Src>::value &&
77 !std::is_signed<Dst>::value && std::is_signed<Src>::value &&
78 !IsTypeInRangeForNumericType<Dst, Src>::value>
::type> {
90template <
typename Dst,
typename Src>
96 : internal::DstRangeRelationToSrcRange<Dst>(
104template <
typename Dst,
113 : CheckHandler::template HandleFailure<Dst>();
122 return std::numeric_limits<T>::has_quiet_NaN
123 ? std::numeric_limits<T>::quiet_NaN()
126 using std::numeric_limits<
T>
::max;
128 return std::numeric_limits<T>::has_infinity
129 ? std::numeric_limits<T>::infinity()
132 using std::numeric_limits<
T>::lowest;
134 return std::numeric_limits<T>::has_infinity
135 ? std::numeric_limits<T>::infinity() * -1
136 : std::numeric_limits<T>::lowest();
140template <
typename Dst,
template <
typename>
class S,
typename Src>
146 : S<Dst>::Underflow())
156template <
typename Dst,
typename Src,
typename Enable =
void>
161 return CheckOnFailure::template HandleFailure<Dst>();
165template <
typename Dst,
typename Src>
169 typename
std::enable_if<std::is_integral<Src>::value &&
170 std::is_integral<Dst>::value &&
171 SaturateFastAsmOp<Dst, Src>::is_supported>
::type> {
178template <
typename Dst,
typename Src>
182 typename
std::enable_if<std::is_integral<Src>::value &&
183 std::is_integral<Dst>::value &&
184 !SaturateFastAsmOp<Dst, Src>::is_supported>
::type> {
190 const Dst saturated = CommonMaxOrMin<Dst, Src>(
191 IsMaxInRangeForNumericType<Dst, Src>() ||
194 ?
static_cast<Dst
>(
value)
203template <
typename Dst,
204 template <
typename>
class SaturationHandler = SaturationDefaultLimits,
210 std::is_same<SaturationHandler<Dst>,
213 : saturated_cast_impl<Dst, SaturationHandler, SrcType>(
215 DstRangeRelationToSrcRange<Dst, SaturationHandler, SrcType>(
222template <
typename Dst,
typename Src>
236 "The source type is out of range for the destination type. "
237 "Please see strict_cast<> comments for more information.");
243template <
typename Dst,
typename Src,
class Enable =
void>
245 static constexpr bool value =
false;
248template <
typename Dst,
typename Src>
252 typename
std::enable_if<ArithmeticOrUnderlyingEnum<Dst>::value &&
253 ArithmeticOrUnderlyingEnum<Src>::value>
::type> {
277 template <
typename Src>
283 template <
typename Src>
299 template <
typename Dst,
300 typename std::enable_if<
302 constexpr operator Dst()
const {
317#if !BASE_NUMERICS_DISABLE_OSTREAM_OPERATORS
321 os << static_cast<T>(
value);
326#define BASE_NUMERIC_COMPARISON_OPERATORS(CLASS, NAME, OP) \
327 template <typename L, typename R, \
328 typename std::enable_if< \
329 internal::Is##CLASS##Op<L, R>::value>::type* = nullptr> \
330 constexpr bool operator OP(const L lhs, const R rhs) { \
331 return SafeCompare<NAME, typename UnderlyingType<L>::type, \
332 typename UnderlyingType<R>::type>(lhs, rhs); \
347using internal::IsTypeInRangeForNumericType;
354using internal::StrictNumeric;
362template <typename Dst =
int,
365 std::is_floating_point<Src>::
value>>
369template <
typename Dst =
int,
376template <
typename Dst =
int,
383 return saturated_cast<Dst>(rounded);
static bool is_integral(const SkRect &r)
constexpr bool IsOverflowFlagSet() const
constexpr bool IsUnderflowFlagSet() const
constexpr StrictNumeric()
constexpr StrictNumeric(const StrictNumeric< Src > &rhs)
constexpr StrictNumeric(Src value)
static float max(float r, float g, float b)
constexpr Dst strict_cast(Src value)
@ NUMERIC_RANGE_CONTAINED
constexpr Dst saturated_cast_impl(Src value, RangeCheck constraint)
constexpr bool IsValueNegative(T value)
constexpr std::make_unsigned< T >::type SafeUnsignedAbs(T value)
constexpr std::make_signed< typenamebase::internal::UnderlyingType< Src >::type >::type as_signed(const Src value)
constexpr StrictNumeric< typename UnderlyingType< T >::type > MakeStrictNum(const T value)
constexpr std::make_unsigned< typenamebase::internal::UnderlyingType< Src >::type >::type as_unsigned(const Src value)
constexpr bool IsCompileTimeConstant(const T)
constexpr bool IsValueInRangeForNumericType(Src value)
std::ostream & operator<<(std::ostream &os, const ClampedNumeric< T > &value)
constexpr Dst checked_cast(Src value)
constexpr Dst saturated_cast(Src value)
Dst ClampFloor(Src value)
Dst ClampRound(Src value)
SIN Vec< N, float > floor(const Vec< N, float > &x)
SIN Vec< N, float > ceil(const Vec< N, float > &x)
#define BASE_NUMERIC_COMPARISON_OPERATORS(CLASS, NAME, OP)
#define BASE_NUMERICS_LIKELY(x)
static constexpr bool value
static constexpr bool Do(Src value)
static constexpr bool Do(Src value)
static constexpr bool Do(Src value)
static constexpr bool is_supported
static constexpr Dst Do(Src)
static constexpr bool is_supported
static constexpr Dst Do(Src value)
static constexpr Dst Do(Src value)
static constexpr bool is_supported
static constexpr Dst Do(Src value)
static constexpr T Overflow()
static constexpr T Underflow()
typename ArithmeticOrUnderlyingEnum< T >::type type