diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2022-11-19 13:01:10 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2022-11-19 13:01:10 +0100 |
commit | d1c04ea956d40ba3ccc4977b7427c1f4acae8597 (patch) | |
tree | f551db46baabc184463d62245c2128808ecd3634 /entity | |
parent | 0bb7d39ccc93b8ba0c0da3ffc5210759c6a5685b (diff) |
entity/contraints: fix clamping to T's range
Diffstat (limited to 'entity')
-rw-r--r-- | entity/constraints.hpp | 16 |
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 }; } } |