From 8b6b822cbda6b9275672646921a10b60d5134ebc Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sun, 24 Mar 2024 23:34:14 +0100 Subject: entity: add support for min/max values for vectors --- entity/constraints.hpp | 66 +++++++++++++++++++++++++++++++++++++++++--------- 1 file 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 #include #include -#include +#include namespace floormat::entities::constraints { @@ -19,34 +19,78 @@ template struct range template range(T min, T max) -> range; -template constexpr erased_constraints::range erased_range_from_range(T, T) -{ return { {}, {}, erased_constraints::range::type_none }; } - template -requires (std::is_floating_point_v && !std::is_integral_v) +requires (std::is_floating_point_v) constexpr erased_constraints::range erased_range_from_range(T min, T max) { return { { .f = min }, { .f = max }, erased_constraints::range::type_::type_float }; } template -requires (std::is_integral_v && std::is_unsigned_v && !std::is_floating_point_v) +requires (std::is_integral_v && std::is_unsigned_v) constexpr erased_constraints::range erased_range_from_range(T min, T max) { return { { .u = min }, { .u = max }, erased_constraints::range::type_::type_uint }; } template -requires (std::is_integral_v && std::is_signed_v && !std::is_floating_point_v) +requires (std::is_integral_v && std::is_signed_v) constexpr erased_constraints::range erased_range_from_range(T min, T max) { return { { .i = min }, { .i = max }, erased_constraints::range::type_::type_int }; } +template +requires (std::is_integral_v || std::is_floating_point_v) +constexpr erased_constraints::range erased_range_from_range(const Math::Vector& min0, + const Math::Vector& max0) +{ + static_assert(N <= 4); + static_assert(sizeof T{} <= sizeof 0uz); + using limits = std::numeric_limits; + using type = erased_constraints::range::type_; + + using Element = std::conditional_t, float, + std::conditional_t, size_t, + std::make_signed_t>>; + + Math::Vector4 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) + { + static_assert(std::is_same_v); + return { .min = {.f4 = min}, .max = {.f4 = max}, .type = type::type_float4 }; + } + else if constexpr(std::is_unsigned_v) + { + static_assert(sizeof T{} <= sizeof 0uz); + return { .min = {.u4 = min}, .max = {.u4 = max}, .type = type::type_uint4 }; + } + else if constexpr(std::is_signed_v) + { + 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 +requires (std::is_enum_v) +constexpr erased_constraints::range erased_range_from_range(T min, T max) +{ return erased_range_from_range(std::underlying_type_t(min), std::underlying_type_t(max)); } + template constexpr range::operator erased_constraints::range() const noexcept { return erased_range_from_range(min, max); } template constexpr range::operator std::pair() const noexcept { return { min, max }; } -template<> struct range -{ - constexpr operator erased_constraints::range() const noexcept { return {}; } -}; +template<> struct range { constexpr operator erased_constraints::range() const noexcept { return {}; } }; +template<> struct range { constexpr operator erased_constraints::range() const noexcept { return {}; } }; using max_length = erased_constraints::max_length; -- cgit v1.2.3