summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--entity/constraints.hpp40
-rw-r--r--test/entity.cpp46
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