summaryrefslogtreecommitdiffhomepage
path: root/entity
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2022-11-19 13:01:10 +0100
committerStanislaw Halik <sthalik@misaki.pl>2022-11-19 13:01:10 +0100
commitd1c04ea956d40ba3ccc4977b7427c1f4acae8597 (patch)
treef551db46baabc184463d62245c2128808ecd3634 /entity
parent0bb7d39ccc93b8ba0c0da3ffc5210759c6a5685b (diff)
entity/contraints: fix clamping to T's range
Diffstat (limited to 'entity')
-rw-r--r--entity/constraints.hpp16
1 files changed, 12 insertions, 4 deletions
diff --git a/entity/constraints.hpp b/entity/constraints.hpp
index 21d549c5..f629b149 100644
--- a/entity/constraints.hpp
+++ b/entity/constraints.hpp
@@ -1,8 +1,9 @@
#pragma once
+#include <cstddef>
#include <cmath>
#include <type_traits>
+#include <limits>
#include <utility>
-#include <algorithm>
#include <Corrade/Containers/StringView.h>
namespace floormat::entities::erased_constraints {
@@ -28,16 +29,23 @@ struct range final {
template<typename T> constexpr std::pair<T, T> range::convert() const
{
+ using std::size_t;
+ static_assert(sizeof(T) <= sizeof(size_t) || !std::is_integral_v<T>);
+
+ constexpr auto min_ = []<typename u>(U a, U b) { return a < b ? a : b; };
+ constexpr auto max_ = []<typename u>(U a, U b) { return a > b ? a : b; };
using limits = std::numeric_limits<T>;
+ constexpr auto lmin = limits::min(), lmax = limits::max();
+
switch (type) {
case type_float:
if constexpr (limits::is_integer())
return { T(std::floor(min.f)), T(std::ceil(max.f)) };
else
return { min.f, max.f };
- case type_uint: return { std::max(T(min.u), limits::min()), std::min(T(max.u), limits::max()) };
- case type_int: return { std::max(T(min.i), limits::min()), std::min(T(max.i), limits::max()) };
- default: case type_none: return { limits::min(), limits::max() };
+ case type_uint: return { max_(T(min.u), lmin), T(min_(size_t(max.u), size_t(lmax))) };
+ case type_int: return { max_(T(min.i), lmin), T(min_(size_t(max.i), size_t(lmax))) };
+ default: case type_none: return { lmin, lmax };
}
}