diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2024-03-24 23:34:14 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2024-03-24 23:34:14 +0100 |
commit | 8b6b822cbda6b9275672646921a10b60d5134ebc (patch) | |
tree | 2eeec3172f700e59171e181afb3b647c35e2fea9 /entity | |
parent | d79f93b7fcb2b4d7ab782987b2dbb53cb2d4cac8 (diff) |
entity: add support for min/max values for vectors
Diffstat (limited to 'entity')
-rw-r--r-- | entity/constraints.hpp | 66 |
1 files changed, 55 insertions, 11 deletions
diff --git a/entity/constraints.hpp b/entity/constraints.hpp index c90353ac..472b8c0b 100644 --- a/entity/constraints.hpp +++ b/entity/constraints.hpp @@ -3,7 +3,7 @@ #include <type_traits> #include <limits> #include <utility> -#include <Corrade/Containers/StringView.h> +#include <mg/Vector.h> namespace floormat::entities::constraints { @@ -19,34 +19,78 @@ template<typename T> struct range template<typename T> range(T min, T max) -> range<T>; -template<typename T> constexpr erased_constraints::range erased_range_from_range(T, T) -{ return { {}, {}, erased_constraints::range::type_none }; } - template<typename T> -requires (std::is_floating_point_v<T> && !std::is_integral_v<T>) +requires (std::is_floating_point_v<T>) constexpr erased_constraints::range erased_range_from_range(T min, T max) { return { { .f = min }, { .f = max }, erased_constraints::range::type_::type_float }; } template<typename T> -requires (std::is_integral_v<T> && std::is_unsigned_v<T> && !std::is_floating_point_v<T>) +requires (std::is_integral_v<T> && std::is_unsigned_v<T>) constexpr erased_constraints::range erased_range_from_range(T min, T max) { return { { .u = min }, { .u = max }, erased_constraints::range::type_::type_uint }; } template<typename T> -requires (std::is_integral_v<T> && std::is_signed_v<T> && !std::is_floating_point_v<T>) +requires (std::is_integral_v<T> && std::is_signed_v<T>) constexpr erased_constraints::range erased_range_from_range(T min, T max) { return { { .i = min }, { .i = max }, erased_constraints::range::type_::type_int }; } +template<size_t N, typename T> +requires (std::is_integral_v<T> || std::is_floating_point_v<T>) +constexpr erased_constraints::range erased_range_from_range(const Math::Vector<N, T>& min0, + const Math::Vector<N, T>& max0) +{ + static_assert(N <= 4); + static_assert(sizeof T{} <= sizeof 0uz); + using limits = std::numeric_limits<T>; + using type = erased_constraints::range::type_; + + using Element = std::conditional_t<std::is_floating_point_v<T>, float, + std::conditional_t<std::is_unsigned_v<T>, size_t, + std::make_signed_t<size_t>>>; + + Math::Vector4<Element> min{limits::min()}, max{limits::max()}; + for (auto i = 0u; i < N; i++) + { + min[i] = Element(min0[i]); + max[i] = Element(max0[i]); + } + + if constexpr(std::is_floating_point_v<T>) + { + static_assert(std::is_same_v<T, float>); + return { .min = {.f4 = min}, .max = {.f4 = max}, .type = type::type_float4 }; + } + else if constexpr(std::is_unsigned_v<T>) + { + static_assert(sizeof T{} <= sizeof 0uz); + return { .min = {.u4 = min}, .max = {.u4 = max}, .type = type::type_uint4 }; + } + else if constexpr(std::is_signed_v<T>) + { + static_assert(sizeof T{} <= sizeof 0uz); + return { .min = {.i4 = min}, .max = {.i4 = max}, .type = type::type_int4 }; + } + else + { + static_assert(sizeof T{} == (size_t)-1); + static_assert(sizeof T{} != (size_t)-1); + return {}; + } +} + +template<typename T> +requires (std::is_enum_v<T>) +constexpr erased_constraints::range erased_range_from_range(T min, T max) +{ return erased_range_from_range(std::underlying_type_t<T>(min), std::underlying_type_t<T>(max)); } + template<typename T> constexpr range<T>::operator erased_constraints::range() const noexcept { return erased_range_from_range(min, max); } template<typename T> constexpr range<T>::operator std::pair<T, T>() const noexcept { return { min, max }; } -template<> struct range<String> -{ - constexpr operator erased_constraints::range() const noexcept { return {}; } -}; +template<> struct range<String> { constexpr operator erased_constraints::range() const noexcept { return {}; } }; +template<> struct range<StringView> { constexpr operator erased_constraints::range() const noexcept { return {}; } }; using max_length = erased_constraints::max_length; |