1010#include < limits>
1111#include < type_traits>
1212
13+ template <typename Source, typename Target>
14+ constexpr bool is_float_to_int_v = std::conjunction_v<std::is_floating_point<Source>, std::is_integral<Target>>;
15+
1316// / Type for describing a 2D value (position, size, offset...)
1417// / Note: Combining a signed with an unsigned point will result in a signed type!
1518// / Allowed operations:
@@ -35,15 +38,15 @@ struct Point //-V690
3538 T x, y;
3639 constexpr Point () noexcept : x(getInvalidValue()), y(getInvalidValue()) {}
3740 constexpr Point (const T x, const T y) noexcept : x(x), y(y) {}
38- template <typename U, std::enable_if_t <!(std::is_integral_v<T> && std::is_floating_point_v<U>) , int > = 0 >
41+ template <typename U, std::enable_if_t <!is_float_to_int_v<U, T> , int > = 0 >
3942 constexpr explicit Point (const Point<U>& pt) noexcept : x(static_cast <T>(pt.x)), y(static_cast <T>(pt.y))
4043 {}
4144 // / Convert floating-point to integer by truncating
42- template <typename U, std::enable_if_t <std::is_integral_v<T> && std::is_floating_point_v<U >, int > = 0 >
45+ template <typename U, std::enable_if_t <is_float_to_int_v<U, T >, int > = 0 >
4346 constexpr explicit Point (Truncate_t, const Point<U>& pt) noexcept : x(static_cast <T>(pt.x)), y(static_cast <T>(pt.y))
4447 {}
4548 // / Convert floating-point to integer with rounding (default behavior)
46- template <typename U, std::enable_if_t <std::is_integral_v<T> && std::is_floating_point_v<U >, int > = 0 >
49+ template <typename U, std::enable_if_t <is_float_to_int_v<U, T >, int > = 0 >
4750 constexpr explicit Point (const Point<U>& pt) noexcept : x(helpers::iround<T>(pt.x)), y(helpers::iround<T>(pt.y))
4851 {}
4952 constexpr Point (const Point&) = default;
0 commit comments