diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2022-11-19 13:44:11 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2022-11-19 13:59:48 +0100 |
commit | cf6c2ba03d9029a064f624bcbad227259e02276a (patch) | |
tree | 5f51afad822aa45290f926b994d5a39f5870b71b | |
parent | eaee8b78edd7b3499ada27d377150be6306f8016 (diff) |
entity: move out erased constraints
-rw-r--r-- | entity/constraints.hpp | 55 | ||||
-rw-r--r-- | entity/erased-constraints.hpp | 60 |
2 files changed, 61 insertions, 54 deletions
diff --git a/entity/constraints.hpp b/entity/constraints.hpp index 248a8422..3e106f21 100644 --- a/entity/constraints.hpp +++ b/entity/constraints.hpp @@ -1,4 +1,5 @@ #pragma once +#include "erased-constraints.hpp" #include <cstddef> #include <cmath> #include <type_traits> @@ -6,60 +7,6 @@ #include <utility> #include <Corrade/Containers/StringView.h> -namespace floormat::entities::erased_constraints { - -static_assert(sizeof(std::size_t) == sizeof(std::uintptr_t)); -static_assert(sizeof(std::size_t) == sizeof(std::ptrdiff_t)); - -struct range final -{ - using U = std::size_t; - using I = std::make_signed_t<U>; - enum type_ : unsigned char { type_none, type_float, type_uint, type_int, }; - union element { - float f; - U u; - I i; - }; - - element min {.i = 0}, max {.i = 0}; - type_ type = type_none; - - template<typename T> constexpr std::pair<T, T> convert() const; -}; - -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 { 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 }; - } -} - -struct length final { - std::size_t value = std::numeric_limits<std::size_t>::max(); -}; - -struct group final { - StringView group_name; -}; - -} // namespace floormat::entities::erased_constraints - namespace floormat::entities::constraints { template<typename T> struct range diff --git a/entity/erased-constraints.hpp b/entity/erased-constraints.hpp new file mode 100644 index 00000000..4f1262f1 --- /dev/null +++ b/entity/erased-constraints.hpp @@ -0,0 +1,60 @@ +#pragma once +#include <cstddef> +#include <limits> + +namespace floormat::entities::erased_constraints { + +static_assert(sizeof(std::size_t) == sizeof(std::uintptr_t)); +static_assert(sizeof(std::size_t) == sizeof(std::ptrdiff_t)); + +struct range final +{ + using U = std::size_t; + using I = std::make_signed_t<U>; + enum type_ : unsigned char { type_none, type_float, type_uint, type_int, }; + union element { + float f; + U u; + I i; + }; + + element min {.i = 0}, max {.i = 0}; + type_ type = type_none; + + template<typename T> constexpr std::pair<T, T> convert() const; +}; + +template<typename T> constexpr std::pair<T, T> range::convert() const +{ + if constexpr (!std::is_floating_point_v<T> && !std::is_integral_v<T>) + return {{}, {}}; + + using std::size_t; + static_assert(sizeof(T) <= sizeof(size_t) || !std::is_integral_v<T>); + + constexpr auto min_ = []<typename V>(V a, V b) { return a < b ? a : b; }; + constexpr auto max_ = []<typename V>(V a, V 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 { T(min.f), T(max.f) }; + 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 }; + } +} + +struct length final { + std::size_t value = std::numeric_limits<std::size_t>::max(); +}; + +struct group final { + StringView group_name; +}; + +} // namespace floormat::entities::erased_constraints |