Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Namespaces | Macros | Functions | Variables
saturated_math.h File Reference
#include <algorithm>
#include <limits>
#include <type_traits>
#include "flutter/fml/logging.h"
#include "impeller/geometry/scalar.h"

Go to the source code of this file.

Namespaces

namespace  impeller
 
namespace  impeller::saturated
 

Macros

#define ONLY_ON_SIGNED_INT_RET(Type, Ret)
 
#define ONLY_ON_SIGNED_INT(Type)   ONLY_ON_SIGNED_INT_RET(Type, Type)
 
#define ONLY_ON_FLOAT_RET(Type, Ret)
 
#define ONLY_ON_FLOAT(Type)   ONLY_ON_FLOAT_RET(Type, Type)
 
#define ONLY_ON_FLOAT_TO_SIGNED_INT_RET(FPType, SIType, Ret)
 
#define ONLY_ON_FLOAT_TO_SIGNED_INT(FPType, SIType)    ONLY_ON_FLOAT_TO_SIGNED_INT_RET(FPType, SIType, SIType)
 
#define ONLY_ON_DIFFERING_FLOAT_RET(FPType1, FPType2, Ret)
 
#define ONLY_ON_DIFFERING_FLOAT(FPType1, FPType2)    ONLY_ON_DIFFERING_FLOAT_RET(FPType1, FPType2, FPType2)
 
#define ONLY_ON_SAME_TYPES_RET(Type1, Type2, Ret)
 
#define ONLY_ON_SAME_TYPES(Type1, Type2)    ONLY_ON_SAME_TYPES_RET(Type1, Type2, Type2)
 

Functions

 impeller::saturated::ONLY_ON_SIGNED_INT (SI) Add(SI location
 
 impeller::saturated::ONLY_ON_FLOAT (FP) Add(FP location
 
 impeller::saturated::ONLY_ON_SIGNED_INT_RET (SI, Scalar) AverageScalar(SI a
 
 impeller::saturated::ONLY_ON_SAME_TYPES (T, U) Cast(T v)
 
 impeller::saturated::ONLY_ON_FLOAT_TO_SIGNED_INT (FP, SI) Cast(FP v)
 
 impeller::saturated::ONLY_ON_DIFFERING_FLOAT (FP1, FP2) Cast(FP1 v)
 

Variables

template<typename T >
constexpr bool impeller::saturated::is_signed_integral_v
 
SI impeller::saturated::distance
 
SI impeller::saturated::lower
 
SI impeller::saturated::b
 

Macro Definition Documentation

◆ ONLY_ON_DIFFERING_FLOAT

#define ONLY_ON_DIFFERING_FLOAT (   FPType1,
  FPType2 
)     ONLY_ON_DIFFERING_FLOAT_RET(FPType1, FPType2, FPType2)

Definition at line 48 of file saturated_math.h.

56 {
57 if (location >= 0) {
58 if (distance > std::numeric_limits<SI>::max() - location) {
59 return std::numeric_limits<SI>::max();
60 }
61 } else if (distance < std::numeric_limits<SI>::min() - location) {
62 return std::numeric_limits<SI>::min();
63 }
64 return location + distance;
65}
66
67ONLY_ON_FLOAT(FP) Add(FP location, FP distance) {
68 return location + distance;
69}
70
71ONLY_ON_SIGNED_INT(SI) Sub(SI upper, SI lower) {
72 if (upper >= 0) {
73 if (lower < 0 && upper > std::numeric_limits<SI>::max() + lower) {
74 return std::numeric_limits<SI>::max();
75 }
76 } else if (lower > 0 && upper < std::numeric_limits<SI>::min() + lower) {
77 return std::numeric_limits<SI>::min();
78 }
79 return upper - lower;
80}
81
82ONLY_ON_FLOAT(FP) Sub(FP upper, FP lower) {
83 return upper - lower;
84}
85
86ONLY_ON_SIGNED_INT_RET(SI, Scalar) AverageScalar(SI a, SI b) {
87 // scalbn has an implementation for ints that converts to double
88 // while adjusting the exponent.
89 return static_cast<Scalar>(std::scalbn(a, -1) + std::scalbn(b, -1));
90}
91
92ONLY_ON_FLOAT(FP) AverageScalar(FP a, FP b) {
93 // GetCenter might want this to return 0 for a Maximum Rect, but it
94 // will currently produce NaN instead. For the Maximum Rect itself
95 // a 0 would make sense as the center, but for a computed rect that
96 // incidentally ended up with infinities, NaN may be a better choice.
97 // return static_cast<Scalar>(std::scalbn(a, -1) + std::scalbn(b, -1));
98
99 // This equation would save an extra scalbn operation but at the cost
100 // of having very large (or very neagive) a's and b's overflow to
101 // +/- infinity. Scaling first allows finite numbers to be more likely
102 // to have a finite average.
103 // return std::scalbn(a + b, -1);
104
105 return static_cast<Scalar>(std::scalbn(a, -1) + std::scalbn(b, -1));
106}
107
108ONLY_ON_SAME_TYPES(T, U) Cast(T v) {
109 return v;
110}
111
112ONLY_ON_FLOAT_TO_SIGNED_INT(FP, SI) Cast(FP v) {
113 if (v <= static_cast<FP>(std::numeric_limits<SI>::min())) {
114 return std::numeric_limits<SI>::min();
115 } else if (v >= static_cast<FP>(std::numeric_limits<SI>::max())) {
116 return std::numeric_limits<SI>::max();
117 }
118 return static_cast<SI>(v);
119}
120
121ONLY_ON_DIFFERING_FLOAT(FP1, FP2) Cast(FP1 v) {
122 if (std::isfinite(v)) {
123 // Avoid truncation to inf/-inf.
124 return std::clamp(static_cast<FP2>(v), //
125 std::numeric_limits<FP2>::lowest(),
126 std::numeric_limits<FP2>::max());
127 } else {
128 return static_cast<FP2>(v);
129 }
130}
131
132#undef ONLY_ON_SAME_TYPES
133#undef ONLY_ON_SAME_TYPES_RET
134#undef ONLY_ON_DIFFERING_FLOAT
135#undef ONLY_ON_DIFFERING_FLOAT_RET
136#undef ONLY_ON_FLOAT_TO_SIGNED_INT
137#undef ONLY_ON_FLOAT_TO_SIGNED_INT_RET
138#undef ONLY_ON_FLOAT
139#undef ONLY_ON_FLOAT_RET
140#undef ONLY_ON_SIGNED_INT
141#undef ONLY_ON_SIGNED_INT_RET
142
143} // namespace saturated
144
145} // namespace impeller
146
147#endif // FLUTTER_IMPELLER_GEOMETRY_SATURATED_MATH_H_
#define SI
static bool b
struct MyStruct a[10]
float Scalar
Definition scalar.h:18
#define T
#define ONLY_ON_FLOAT_TO_SIGNED_INT(FPType, SIType)
#define ONLY_ON_FLOAT(Type)
#define ONLY_ON_SIGNED_INT(Type)
#define ONLY_ON_SIGNED_INT_RET(Type, Ret)
#define ONLY_ON_SAME_TYPES(Type1, Type2)
#define ONLY_ON_DIFFERING_FLOAT(FPType1, FPType2)

◆ ONLY_ON_DIFFERING_FLOAT_RET

#define ONLY_ON_DIFFERING_FLOAT_RET (   FPType1,
  FPType2,
  Ret 
)
Value:
template <typename FPType1, typename FPType2> \
constexpr inline std::enable_if_t<std::is_floating_point_v<FPType1> && \
std::is_floating_point_v<FPType2> && \
!std::is_same_v<FPType1, FPType2>, \
Ret>

Definition at line 42 of file saturated_math.h.

◆ ONLY_ON_FLOAT

#define ONLY_ON_FLOAT (   Type)    ONLY_ON_FLOAT_RET(Type, Type)

Definition at line 33 of file saturated_math.h.

◆ ONLY_ON_FLOAT_RET

#define ONLY_ON_FLOAT_RET (   Type,
  Ret 
)
Value:
template <typename Type> \
constexpr inline std::enable_if_t<std::is_floating_point_v<Type>, Ret>

Definition at line 30 of file saturated_math.h.

◆ ONLY_ON_FLOAT_TO_SIGNED_INT

#define ONLY_ON_FLOAT_TO_SIGNED_INT (   FPType,
  SIType 
)     ONLY_ON_FLOAT_TO_SIGNED_INT_RET(FPType, SIType, SIType)

Definition at line 39 of file saturated_math.h.

◆ ONLY_ON_FLOAT_TO_SIGNED_INT_RET

#define ONLY_ON_FLOAT_TO_SIGNED_INT_RET (   FPType,
  SIType,
  Ret 
)
Value:
template <typename FPType, typename SIType> \
constexpr inline std::enable_if_t< \
std::is_floating_point_v<FPType> && is_signed_integral_v<SIType>, Ret>

Definition at line 35 of file saturated_math.h.

◆ ONLY_ON_SAME_TYPES

#define ONLY_ON_SAME_TYPES (   Type1,
  Type2 
)     ONLY_ON_SAME_TYPES_RET(Type1, Type2, Type2)

Definition at line 54 of file saturated_math.h.

◆ ONLY_ON_SAME_TYPES_RET

#define ONLY_ON_SAME_TYPES_RET (   Type1,
  Type2,
  Ret 
)
Value:
template <typename Type1, typename Type2> \
constexpr inline std::enable_if_t<std::is_same_v<Type1, Type2>, Ret>

Definition at line 51 of file saturated_math.h.

◆ ONLY_ON_SIGNED_INT

#define ONLY_ON_SIGNED_INT (   Type)    ONLY_ON_SIGNED_INT_RET(Type, Type)

Definition at line 28 of file saturated_math.h.

◆ ONLY_ON_SIGNED_INT_RET

#define ONLY_ON_SIGNED_INT_RET (   Type,
  Ret 
)
Value:
template <typename Type> \
constexpr inline std::enable_if_t<is_signed_integral_v<Type>, Ret>

Definition at line 25 of file saturated_math.h.