aboutsummaryrefslogtreecommitdiff
path: root/reference_model/src/arith_util.h
diff options
context:
space:
mode:
Diffstat (limited to 'reference_model/src/arith_util.h')
-rw-r--r--reference_model/src/arith_util.h46
1 files changed, 46 insertions, 0 deletions
diff --git a/reference_model/src/arith_util.h b/reference_model/src/arith_util.h
index fee9fef..fa6d136 100644
--- a/reference_model/src/arith_util.h
+++ b/reference_model/src/arith_util.h
@@ -317,4 +317,50 @@ int32_t getUnsignedMinimum()
return 0;
}
+template <typename T>
+T applyMax(T a, T b)
+{
+ if (std::is_floating_point<T>::value)
+ {
+ if (std::isnan(a) || std::isnan(b))
+ {
+ return NAN;
+ }
+ }
+ return (a >= b) ? a : b;
+}
+
+template <typename T>
+T applyMin(T a, T b)
+{
+ if (std::is_floating_point<T>::value)
+ {
+ if (std::isnan(a) || std::isnan(b))
+ {
+ return NAN;
+ }
+ }
+ return (a < b) ? a : b;
+}
+
+// Clip the input value of type T into the range [min, max] of type U, and return the result as type T.
+template <typename T, typename U>
+T applyClip(T value, U min_val, U max_val)
+{
+ assert(min_val <= max_val);
+ assert(sizeof(T) == sizeof(U));
+
+ value = applyMax<T>(value, min_val);
+
+ // Handle the numbers of an unsigned type U that becomes unrepresentable when type casting to signed.
+ if (std::is_signed_v<T> && std::is_unsigned_v<U> && max_val > std::numeric_limits<T>::max())
+ {
+ max_val = std::numeric_limits<T>::max();
+ }
+
+ value = applyMin<T>(value, max_val);
+
+ return value;
+}
+
#endif /* _ARITH_UTIL_H */