diff options
-rw-r--r-- | entity/constraints.hpp | 40 | ||||
-rw-r--r-- | test/entity.cpp | 46 |
2 files changed, 81 insertions, 5 deletions
diff --git a/entity/constraints.hpp b/entity/constraints.hpp index 472b8c0b..c807fddc 100644 --- a/entity/constraints.hpp +++ b/entity/constraints.hpp @@ -1,16 +1,47 @@ #pragma once +#include "compat/limits.hpp" #include "erased-constraints.hpp" #include <type_traits> -#include <limits> #include <utility> #include <mg/Vector.h> +namespace floormat::entities::limit_detail { + +template<typename T> struct limit_traits; + +template<typename T> +requires Math::IsVector<T>::value +struct limit_traits<T> +{ + static constexpr auto min() { return T(limits<typename T::Type>::min); } + static constexpr auto max() { return T(limits<typename T::Type>::max); } +}; + +template<typename T> +requires std::is_arithmetic_v<T> +struct limit_traits<T> +{ + static constexpr auto min() { return limits<T>::min; } + static constexpr auto max() { return limits<T>::max; } +}; + +template<typename T> +struct limit_traits +{ + static_assert(std::is_nothrow_default_constructible_v<T>); + static constexpr T min() { return T{}; } + static constexpr T max() { return T{}; } +}; + +} // namespace floormat::entities::limit_detail + + namespace floormat::entities::constraints { template<typename T> struct range { - using limits = std::numeric_limits<T>; - T min = limits::min(), max = limits::max(); + T min = limit_detail::limit_traits<T>::min(); + T max = limit_detail::limit_traits<T>::max(); constexpr operator erased_constraints::range() const noexcept; constexpr operator std::pair<T, T>() const noexcept; @@ -41,14 +72,13 @@ constexpr erased_constraints::range erased_range_from_range(const Math::Vector<N { 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()}; + Math::Vector4<Element> min{limits<Element>::min}, max{limits<Element>::max}; for (auto i = 0u; i < N; i++) { min[i] = Element(min0[i]); diff --git a/test/entity.cpp b/test/entity.cpp index 3c099a37..36302662 100644 --- a/test/entity.cpp +++ b/test/entity.cpp @@ -1,6 +1,8 @@ #include "app.hpp" #include "compat/assert.hpp" +#include "compat/limits.hpp" #include "entity/metadata.hpp" +#include "entity/accessor.hpp" #include <tuple> using namespace floormat; @@ -148,8 +150,10 @@ void test_type_name() constexpr StringView name = name_of<foobar>; fm_assert(name.contains("foobar"_s)); static_assert(name.data() == name_of<foobar>.data()); +#ifndef __CLION_IDE__ static_assert(name_of<int> != name_of<unsigned>); static_assert(name_of<foobar*> != name_of<const foobar*>); +#endif using foobar2 = foobar; static_assert(name_of<foobar2>.data() == name_of<foobar>.data()); } @@ -239,6 +243,44 @@ void test_erased_constraints() fm_assert(erased.get_max_length(&x) == 42); } +constexpr bool test_range1() +{ + constexpr auto x = TestAccessors{}; + constexpr auto r = m_foo.get_range(x); + static_assert(r.max == limits<int>::max); + return true; +} + +void test_range2() +{ + constexpr auto x = TestAccessors{}; + constexpr auto rʹ = m_foo.get_range(x); + constexpr auto A = m_foo.erased(); + auto r = A.get_range(&x); + auto i = r.convert<int>(); + fm_assert(i.second == rʹ.max); +} + +constexpr bool test_range3() +{ + constexpr auto f = entity::type<Vector2i>::field("vec"_s, constantly(Vector2i(0)), [](auto&&, auto&&) {}); + constexpr auto r = f.get_range(f.range, TestAccessors{}); + static_assert(r.max == Vector2i(limits<int>::max)); + + return true; +} + +void test_range4() +{ + constexpr auto x = TestAccessors{}; + constexpr auto f = entity::type<Vector2i>::field("vec"_s, constantly(Vector2i(0)), [](auto&&, auto&&) {}); + constexpr auto rʹ = f.get_range(f.range, TestAccessors{}); + const auto A = f.erased(); + const auto r = A.get_range(&x).convert<Vector2i>(); + fm_assert(r.first == rʹ.min); + fm_assert(r.second == rʹ.max); +} + } // namespace void test_app::test_entity() @@ -254,6 +296,10 @@ void test_app::test_entity() test_metadata(); test_constraints(); test_erased_constraints(); + static_assert(test_range1()); + test_range2(); + static_assert(test_range3()); + test_range4(); } } // namespace floormat |