5#ifndef BASE_NUMERICS_CLAMPED_MATH_IMPL_H_
6#define BASE_NUMERICS_CLAMPED_MATH_IMPL_H_
24 typename std::enable_if<std::is_integral<T>::value &&
25 std::is_signed<T>::value>
::type* =
nullptr>
30 : std::numeric_limits<T>::max())
35 typename std::enable_if<std::is_integral<T>::value &&
36 !std::is_signed<T>::value>
::type* =
nullptr>
43 typename std::enable_if<std::is_floating_point<T>::value>
::type* =
nullptr>
49 typename std::enable_if<std::is_integral<T>::value>
::type* =
nullptr>
65 typename std::enable_if<std::is_floating_point<T>::value>
::type* =
nullptr>
70template <
typename T,
typename U,
class Enable =
void>
73template <
typename T,
typename U>
76 typename
std::enable_if<std::is_integral<T>::value &&
77 std::is_integral<U>::value>
::type> {
79 template <
typename V = result_type>
84 static_assert(std::is_same<V, result_type>::value ||
86 "The saturation result cannot be determined from the "
96template <
typename T,
typename U,
class Enable =
void>
99template <
typename T,
typename U>
102 typename
std::enable_if<std::is_integral<T>::value &&
103 std::is_integral<U>::value>
::type> {
105 template <
typename V = result_type>
111 static_assert(std::is_same<V, result_type>::value ||
113 "The saturation result cannot be determined from the "
123template <
typename T,
typename U,
class Enable =
void>
126template <
typename T,
typename U>
129 typename
std::enable_if<std::is_integral<T>::value &&
130 std::is_integral<U>::value>
::type> {
132 template <
typename V = result_type>
147template <
typename T,
typename U,
class Enable =
void>
150template <
typename T,
typename U>
153 typename
std::enable_if<std::is_integral<T>::value &&
154 std::is_integral<U>::value>
::type> {
156 template <
typename V = result_type>
167template <
typename T,
typename U,
class Enable =
void>
170template <
typename T,
typename U>
173 typename
std::enable_if<std::is_integral<T>::value &&
174 std::is_integral<U>::value>
::type> {
176 template <
typename V = result_type>
185template <
typename T,
typename U,
class Enable =
void>
190template <
typename T,
typename U>
193 typename
std::enable_if<std::is_integral<T>::value &&
194 std::is_integral<U>::value>
::type> {
196 template <
typename V = result_type>
197 static constexpr V Do(
T x, U shift) {
198 static_assert(!std::is_signed<U>::value,
"Shift value must be unsigned.");
210template <
typename T,
typename U,
class Enable =
void>
214template <
typename T,
typename U>
217 typename
std::enable_if<std::is_integral<T>::value &&
218 std::is_integral<U>::value>
::type> {
220 template <
typename V = result_type>
221 static constexpr V Do(
T x, U shift) {
222 static_assert(!std::is_signed<U>::value,
"Shift value must be unsigned.");
226 ? saturated_cast<V>(
x >> shift)
231template <
typename T,
typename U,
class Enable =
void>
234template <
typename T,
typename U>
237 typename
std::enable_if<std::is_integral<T>::value &&
238 std::is_integral<U>::value>
::type> {
241 template <
typename V>
247template <
typename T,
typename U,
class Enable =
void>
251template <
typename T,
typename U>
254 typename
std::enable_if<std::is_integral<T>::value &&
255 std::is_integral<U>::value>
::type> {
258 template <
typename V>
264template <
typename T,
typename U,
class Enable =
void>
268template <
typename T,
typename U>
271 typename
std::enable_if<std::is_integral<T>::value &&
272 std::is_integral<U>::value>
::type> {
275 template <
typename V>
281template <
typename T,
typename U,
class Enable =
void>
284template <
typename T,
typename U>
288 typename
std::enable_if<std::is_arithmetic<T>::value &&
289 std::is_arithmetic<U>::value>
::type> {
291 template <
typename V = result_type>
294 : saturated_cast<V>(
y);
298template <
typename T,
typename U,
class Enable =
void>
301template <
typename T,
typename U>
305 typename
std::enable_if<std::is_arithmetic<T>::value &&
306 std::is_arithmetic<U>::value>
::type> {
308 template <
typename V = result_type>
311 : saturated_cast<V>(
y);
317#define BASE_FLOAT_ARITHMETIC_OPS(NAME, OP) \
318 template <typename T, typename U> \
319 struct Clamped##NAME##Op< \
321 typename std::enable_if<std::is_floating_point<T>::value || \
322 std::is_floating_point<U>::value>::type> { \
323 using result_type = typename MaxExponentPromotion<T, U>::type; \
324 template <typename V = result_type> \
325 static constexpr V Do(T x, U y) { \
326 return saturated_cast<V>(x OP y); \
335#undef BASE_FLOAT_ARITHMETIC_OPS
#define BASE_FLOAT_ARITHMETIC_OPS(NAME, OP)
T __attribute__((ext_vector_type(N))) V
constexpr T NegateWrapper(T value)
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 T SaturatedNegWrapper(T value)
constexpr T SaturatedAbsWrapper(T value)
constexpr bool MustTreatAsConstexpr(const T v)
#define BASE_NUMERICS_LIKELY(x)
static constexpr V Do(T x, U y)
typename MaxExponentPromotion< T, U >::type result_type
typename std::make_unsigned< typename MaxExponentPromotion< T, U >::type >::type result_type
static constexpr V Do(T x, U y)
static constexpr V Do(T x, U y)
typename MaxExponentPromotion< T, U >::type result_type
static constexpr V Do(T x, U shift)
typename MaxExponentPromotion< T, U >::type result_type
static constexpr V Do(T x, U y)
typename LowestValuePromotion< T, U >::type result_type
static constexpr V Do(T x, U y)
static constexpr V Do(T x, U y)
typename MaxExponentPromotion< T, U >::type result_type
typename MaxExponentPromotion< T, U >::type result_type
static constexpr V Do(T x, U y)
typename std::make_unsigned< typename MaxExponentPromotion< T, U >::type >::type result_type
static constexpr V Do(T x, U y)
static constexpr V Do(T x, U shift)
static constexpr V Do(T x, U y)
typename MaxExponentPromotion< T, U >::type result_type
static constexpr V Do(T x, U y)
typename std::make_unsigned< typename MaxExponentPromotion< T, U >::type >::type result_type
static constexpr bool Test(const L lhs, const R rhs)
static constexpr bool Test(const L lhs, const R rhs)