relation funcs non-arithmetic T support

This commit is contained in:
BlackMATov
2021-02-21 01:39:57 +07:00
parent 2a19b789eb
commit bb6a04855d
5 changed files with 314 additions and 123 deletions

199
README.md
View File

@@ -1388,97 +1388,184 @@ constexpr bool not_equal_to(T x, T y) noexcept;
#### Vector #### Vector
```cpp ```cpp
template < typename T, size_t Size > template < typename T, std::size_t Size
constexpr bool any(const vec<T, Size>& xs); , typename U = decltype(any(std::declval<T>())) >
constexpr U any(const vec<T, Size>& xs);
template < typename T, size_t Size > template < typename T, std::size_t Size
constexpr bool all(const vec<T, Size>& xs); , typename U = decltype(all(std::declval<T>())) >
constexpr U all(const vec<T, Size>& xs);
template < typename T, size_t Size > template < typename T, std::size_t Size
constexpr vec<bool, Size> approx(const vec<T, Size>& xs, const vec<T, Size>& ys); , typename U = decltype(approx(
std::declval<T>(),
std::declval<T>())) >
constexpr vec<U, Size> approx(const vec<T, Size>& xs, const vec<T, Size>& ys);
template < typename T, size_t Size > template < typename T, std::size_t Size
constexpr vec<bool, Size> approx(const vec<T, Size>& xs, const vec<T, Size>& ys, T epsilon); , typename U = decltype(approx(
std::declval<T>(),
std::declval<T>(),
std::declval<T>())) >
constexpr vec<U, Size> approx(const vec<T, Size>& xs, const vec<T, Size>& ys, T epsilon);
template < typename T, size_t Size > template < typename T, std::size_t Size
constexpr vec<bool, Size> less(const vec<T, Size>& xs, const vec<T, Size>& ys); , typename U = decltype(less(
std::declval<T>(),
std::declval<T>())) >
constexpr vec<U, Size> less(const vec<T, Size>& xs, const vec<T, Size>& ys);
template < typename T, size_t Size > template < typename T, std::size_t Size
constexpr vec<bool, Size> less_equal(const vec<T, Size>& xs, const vec<T, Size>& ys); , typename U = decltype(less_equal(
std::declval<T>(),
std::declval<T>())) >
constexpr vec<U, Size> less_equal(const vec<T, Size>& xs, const vec<T, Size>& ys);
template < typename T, size_t Size > template < typename T, std::size_t Size
constexpr vec<bool, Size> greater(const vec<T, Size>& xs, const vec<T, Size>& ys); , typename U = decltype(greater(
std::declval<T>(),
std::declval<T>())) >
constexpr vec<U, Size> greater(const vec<T, Size>& xs, const vec<T, Size>& ys);
template < typename T, size_t Size > template < typename T, std::size_t Size
constexpr vec<bool, Size> greater_equal(const vec<T, Size>& xs, const vec<T, Size>& ys); , typename U = decltype(greater_equal(
std::declval<T>(),
std::declval<T>())) >
constexpr vec<U, Size> greater_equal(const vec<T, Size>& xs, const vec<T, Size>& ys);
template < typename T, size_t Size > template < typename T, std::size_t Size
constexpr vec<bool, Size> equal_to(const vec<T, Size>& xs, const vec<T, Size>& ys); , typename U = decltype(equal_to(
std::declval<T>(),
std::declval<T>())) >
constexpr vec<U, Size> equal_to(const vec<T, Size>& xs, const vec<T, Size>& ys);
template < typename T, size_t Size > template < typename T, std::size_t Size
constexpr vec<bool, Size> not_equal_to(const vec<T, Size>& xs, const vec<T, Size>& ys); , typename U = decltype(not_equal_to(
std::declval<T>(),
std::declval<T>())) >
constexpr vec<U, Size> not_equal_to(const vec<T, Size>& xs, const vec<T, Size>& ys);
``` ```
#### Matrix #### Matrix
```cpp ```cpp
template < typename T, size_t Size > template < typename T, std::size_t Size
constexpr bool any(const mat<T, Size>& xs); , typename U = decltype(any(std::declval<vec<T, Size>>())) >
constexpr U any(const mat<T, Size>& xs);
template < typename T, size_t Size > template < typename T, std::size_t Size
constexpr bool all(const mat<T, Size>& xs); , typename U = decltype(all(std::declval<vec<T, Size>>())) >
constexpr U all(const mat<T, Size>& xs);
template < typename T, size_t Size > template < typename T, std::size_t Size
constexpr mat<bool, Size> approx(const mat<T, Size>& xs, const mat<T, Size>& ys); , typename U = typename decltype(approx(
std::declval<vec<T, Size>>(),
std::declval<vec<T, Size>>()))::component_type >
constexpr mat<U, Size> approx(const mat<T, Size>& xs, const mat<T, Size>& ys);
template < typename T, size_t Size > template < typename T, std::size_t Size
constexpr mat<bool, Size> approx(const mat<T, Size>& xs, const mat<T, Size>& ys, T epsilon); , typename U = typename decltype(approx(
std::declval<vec<T, Size>>(),
std::declval<vec<T, Size>>(),
std::declval<T>()))::component_type >
constexpr mat<U, Size> approx(const mat<T, Size>& xs, const mat<T, Size>& ys, T epsilon);
template < typename T, size_t Size > template < typename T, std::size_t Size
constexpr mat<bool, Size> less(const mat<T, Size>& xs, const mat<T, Size>& ys); , typename U = typename decltype(less(
std::declval<vec<T, Size>>(),
std::declval<vec<T, Size>>()))::component_type >
constexpr mat<U, Size> less(const mat<T, Size>& xs, const mat<T, Size>& ys);
template < typename T, size_t Size > template < typename T, std::size_t Size
constexpr mat<bool, Size> less_equal(const mat<T, Size>& xs, const mat<T, Size>& ys); , typename U = typename decltype(less_equal(
std::declval<vec<T, Size>>(),
std::declval<vec<T, Size>>()))::component_type >
constexpr mat<U, Size> less_equal(const mat<T, Size>& xs, const mat<T, Size>& ys);
template < typename T, size_t Size > template < typename T, std::size_t Size
constexpr mat<bool, Size> greater(const mat<T, Size>& xs, const mat<T, Size>& ys); , typename U = typename decltype(greater(
std::declval<vec<T, Size>>(),
std::declval<vec<T, Size>>()))::component_type >
constexpr mat<U, Size> greater(const mat<T, Size>& xs, const mat<T, Size>& ys);
template < typename T, size_t Size > template < typename T, std::size_t Size
constexpr mat<bool, Size> greater_equal(const mat<T, Size>& xs, const mat<T, Size>& ys); , typename U = typename decltype(greater_equal(
std::declval<vec<T, Size>>(),
std::declval<vec<T, Size>>()))::component_type >
constexpr mat<U, Size> greater_equal(const mat<T, Size>& xs, const mat<T, Size>& ys);
template < typename T, size_t Size > template < typename T, std::size_t Size
constexpr mat<bool, Size> equal_to(const mat<T, Size>& xs, const mat<T, Size>& ys); , typename U = typename decltype(equal_to(
std::declval<vec<T, Size>>(),
std::declval<vec<T, Size>>()))::component_type >
constexpr mat<U, Size> equal_to(const mat<T, Size>& xs, const mat<T, Size>& ys);
template < typename T, size_t Size > template < typename T, std::size_t Size
constexpr mat<bool, Size> not_equal_to(const mat<T, Size>& xs, const mat<T, Size>& ys); , typename U = typename decltype(not_equal_to(
std::declval<vec<T, Size>>(),
std::declval<vec<T, Size>>()))::component_type >
constexpr mat<U, Size> not_equal_to(const mat<T, Size>& xs, const mat<T, Size>& ys);
``` ```
#### Quaternion #### Quaternion
```cpp ```cpp
template < typename T > template < typename T
constexpr vec<bool, 4> approx(const qua<T>& xs, const qua<T>& ys); , typename U = decltype(any(std::declval<vec<T, 4>>())) >
constexpr U any(const qua<T>& xs);
template < typename T > template < typename T
constexpr vec<bool, 4> approx(const qua<T>& xs, const qua<T>& ys, T epsilon); , typename U = decltype(all(std::declval<vec<T, 4>>())) >
constexpr U all(const qua<T>& xs);
template < typename T > template < typename T
constexpr vec<bool, 4> less(const qua<T>& xs, const qua<T>& ys); , typename U = typename decltype(approx(
std::declval<vec<T, 4>>(),
std::declval<vec<T, 4>>()))::component_type >
constexpr vec<U, 4> approx(const qua<T>& xs, const qua<T>& ys);
template < typename T > template < typename T
constexpr vec<bool, 4> less_equal(const qua<T>& xs, const qua<T>& ys); , typename U = typename decltype(approx(
std::declval<vec<T, 4>>(),
std::declval<vec<T, 4>>(),
std::declval<T>()))::component_type >
constexpr vec<U, 4> approx(const qua<T>& xs, const qua<T>& ys, T epsilon);
template < typename T > template < typename T
constexpr vec<bool, 4> greater(const qua<T>& xs, const qua<T>& ys); , typename U = typename decltype(less(
std::declval<vec<T, 4>>(),
std::declval<vec<T, 4>>()))::component_type >
constexpr vec<U, 4> less(const qua<T>& xs, const qua<T>& ys);
template < typename T > template < typename T
constexpr vec<bool, 4> greater_equal(const qua<T>& xs, const qua<T>& ys); , typename U = typename decltype(less_equal(
std::declval<vec<T, 4>>(),
std::declval<vec<T, 4>>()))::component_type >
constexpr vec<U, 4> less_equal(const qua<T>& xs, const qua<T>& ys);
template < typename T > template < typename T
constexpr vec<bool, 4> equal_to(const qua<T>& xs, const qua<T>& ys); , typename U = typename decltype(greater(
std::declval<vec<T, 4>>(),
std::declval<vec<T, 4>>()))::component_type >
constexpr vec<U, 4> greater(const qua<T>& xs, const qua<T>& ys);
template < typename T > template < typename T
constexpr vec<bool, 4> not_equal_to(const qua<T>& xs, const qua<T>& ys); , typename U = typename decltype(greater_equal(
std::declval<vec<T, 4>>(),
std::declval<vec<T, 4>>()))::component_type >
constexpr vec<U, 4> greater_equal(const qua<T>& xs, const qua<T>& ys);
template < typename T
, typename U = typename decltype(equal_to(
std::declval<vec<T, 4>>(),
std::declval<vec<T, 4>>()))::component_type >
constexpr vec<U, 4> equal_to(const qua<T>& xs, const qua<T>& ys);
template < typename T
, typename U = typename decltype(not_equal_to(
std::declval<vec<T, 4>>(),
std::declval<vec<T, 4>>()))::component_type >
constexpr vec<U, 4> not_equal_to(const qua<T>& xs, const qua<T>& ys);
``` ```
### Matrix Functions ### Matrix Functions

View File

@@ -501,53 +501,80 @@ namespace vmath_hpp
namespace vmath_hpp namespace vmath_hpp
{ {
template < typename T, std::size_t Size > template < typename T, std::size_t Size
[[nodiscard]] constexpr bool any(const mat<T, Size>& xs) { , typename U = decltype(any(std::declval<vec<T, Size>>())) >
return fold_join([](bool acc, const vec<T, Size>& x){ return acc || any(x); }, false, xs); [[nodiscard]] constexpr U any(const mat<T, Size>& xs) {
return fold_join([](U acc, const vec<T, Size>& x){ return acc || any(x); }, U{false}, xs);
} }
template < typename T, std::size_t Size > template < typename T, std::size_t Size
[[nodiscard]] constexpr bool all(const mat<T, Size>& xs) { , typename U = decltype(all(std::declval<vec<T, Size>>())) >
return fold_join([](bool acc, const vec<T, Size>& x){ return acc && all(x); }, true, xs); [[nodiscard]] constexpr U all(const mat<T, Size>& xs) {
return fold_join([](U acc, const vec<T, Size>& x){ return acc && all(x); }, U{true}, xs);
} }
template < typename T, std::size_t Size > template < typename T, std::size_t Size
[[nodiscard]] constexpr mat<bool, Size> approx(const mat<T, Size>& xs, const mat<T, Size>& ys) { , typename U = typename decltype(approx(
std::declval<vec<T, Size>>(),
std::declval<vec<T, Size>>()))::component_type >
[[nodiscard]] constexpr mat<U, Size> approx(const mat<T, Size>& xs, const mat<T, Size>& ys) {
return map_join([](const vec<T, Size>& x, const vec<T, Size>& y){ return approx(x, y); }, xs, ys); return map_join([](const vec<T, Size>& x, const vec<T, Size>& y){ return approx(x, y); }, xs, ys);
} }
template < typename T, std::size_t Size > template < typename T, std::size_t Size
[[nodiscard]] constexpr mat<bool, Size> approx(const mat<T, Size>& xs, const mat<T, Size>& ys, T epsilon) { , typename U = typename decltype(approx(
std::declval<vec<T, Size>>(),
std::declval<vec<T, Size>>(),
std::declval<T>()))::component_type >
[[nodiscard]] constexpr mat<U, Size> approx(const mat<T, Size>& xs, const mat<T, Size>& ys, T epsilon) {
return map_join([epsilon](const vec<T, Size>& x, const vec<T, Size>& y){ return approx(x, y, epsilon); }, xs, ys); return map_join([epsilon](const vec<T, Size>& x, const vec<T, Size>& y){ return approx(x, y, epsilon); }, xs, ys);
} }
template < typename T, std::size_t Size > template < typename T, std::size_t Size
[[nodiscard]] constexpr mat<bool, Size> less(const mat<T, Size>& xs, const mat<T, Size>& ys) { , typename U = typename decltype(less(
std::declval<vec<T, Size>>(),
std::declval<vec<T, Size>>()))::component_type >
[[nodiscard]] constexpr mat<U, Size> less(const mat<T, Size>& xs, const mat<T, Size>& ys) {
return map_join([](const vec<T, Size>& x, const vec<T, Size>& y){ return less(x, y); }, xs, ys); return map_join([](const vec<T, Size>& x, const vec<T, Size>& y){ return less(x, y); }, xs, ys);
} }
template < typename T, std::size_t Size > template < typename T, std::size_t Size
[[nodiscard]] constexpr mat<bool, Size> less_equal(const mat<T, Size>& xs, const mat<T, Size>& ys) { , typename U = typename decltype(less_equal(
std::declval<vec<T, Size>>(),
std::declval<vec<T, Size>>()))::component_type >
[[nodiscard]] constexpr mat<U, Size> less_equal(const mat<T, Size>& xs, const mat<T, Size>& ys) {
return map_join([](const vec<T, Size>& x, const vec<T, Size>& y){ return less_equal(x, y); }, xs, ys); return map_join([](const vec<T, Size>& x, const vec<T, Size>& y){ return less_equal(x, y); }, xs, ys);
} }
template < typename T, std::size_t Size > template < typename T, std::size_t Size
[[nodiscard]] constexpr mat<bool, Size> greater(const mat<T, Size>& xs, const mat<T, Size>& ys) { , typename U = typename decltype(greater(
std::declval<vec<T, Size>>(),
std::declval<vec<T, Size>>()))::component_type >
[[nodiscard]] constexpr mat<U, Size> greater(const mat<T, Size>& xs, const mat<T, Size>& ys) {
return map_join([](const vec<T, Size>& x, const vec<T, Size>& y){ return greater(x, y); }, xs, ys); return map_join([](const vec<T, Size>& x, const vec<T, Size>& y){ return greater(x, y); }, xs, ys);
} }
template < typename T, std::size_t Size > template < typename T, std::size_t Size
[[nodiscard]] constexpr mat<bool, Size> greater_equal(const mat<T, Size>& xs, const mat<T, Size>& ys) { , typename U = typename decltype(greater_equal(
std::declval<vec<T, Size>>(),
std::declval<vec<T, Size>>()))::component_type >
[[nodiscard]] constexpr mat<U, Size> greater_equal(const mat<T, Size>& xs, const mat<T, Size>& ys) {
return map_join([](const vec<T, Size>& x, const vec<T, Size>& y){ return greater_equal(x, y); }, xs, ys); return map_join([](const vec<T, Size>& x, const vec<T, Size>& y){ return greater_equal(x, y); }, xs, ys);
} }
template < typename T, std::size_t Size > template < typename T, std::size_t Size
[[nodiscard]] constexpr mat<bool, Size> equal_to(const mat<T, Size>& xs, const mat<T, Size>& ys) { , typename U = typename decltype(equal_to(
std::declval<vec<T, Size>>(),
std::declval<vec<T, Size>>()))::component_type >
[[nodiscard]] constexpr mat<U, Size> equal_to(const mat<T, Size>& xs, const mat<T, Size>& ys) {
return map_join([](const vec<T, Size>& x, const vec<T, Size>& y){ return equal_to(x, y); }, xs, ys); return map_join([](const vec<T, Size>& x, const vec<T, Size>& y){ return equal_to(x, y); }, xs, ys);
} }
template < typename T, std::size_t Size > template < typename T, std::size_t Size
[[nodiscard]] constexpr mat<bool, Size> not_equal_to(const mat<T, Size>& xs, const mat<T, Size>& ys) { , typename U = typename decltype(not_equal_to(
std::declval<vec<T, Size>>(),
std::declval<vec<T, Size>>()))::component_type >
[[nodiscard]] constexpr mat<U, Size> not_equal_to(const mat<T, Size>& xs, const mat<T, Size>& ys) {
return map_join([](const vec<T, Size>& x, const vec<T, Size>& y){ return not_equal_to(x, y); }, xs, ys); return map_join([](const vec<T, Size>& x, const vec<T, Size>& y){ return not_equal_to(x, y); }, xs, ys);
} }
} }

View File

@@ -169,7 +169,7 @@ namespace vmath_hpp
template < typename T > template < typename T >
[[nodiscard]] qua<T> nlerp(const qua<T>& unit_xs, const qua<T>& unit_ys, T a) { [[nodiscard]] qua<T> nlerp(const qua<T>& unit_xs, const qua<T>& unit_ys, T a) {
const T xs_scale = T(1) - a; const T xs_scale = T{1} - a;
const T ys_scale = a * sign(dot(unit_xs, unit_ys)); const T ys_scale = a * sign(dot(unit_xs, unit_ys));
return normalize(lerp(unit_xs, unit_ys, xs_scale, ys_scale)); return normalize(lerp(unit_xs, unit_ys, xs_scale, ys_scale));
} }
@@ -183,15 +183,15 @@ namespace vmath_hpp
const T raw_cos_theta_sign = sign(raw_cos_theta); const T raw_cos_theta_sign = sign(raw_cos_theta);
// half degree linear threshold: cos((pi / 180) * 0.25) // half degree linear threshold: cos((pi / 180) * 0.25)
if ( const T cos_theta = raw_cos_theta * raw_cos_theta_sign; cos_theta < T(0.99999) ) { if ( const T cos_theta = raw_cos_theta * raw_cos_theta_sign; cos_theta < T{0.99999} ) {
const T theta = acos(cos_theta); const T theta = acos(cos_theta);
const T rsin_theta = rsqrt(T(1) - sqr(cos_theta)); const T rsin_theta = rsqrt(T{1} - sqr(cos_theta));
const T xs_scale = sin((T(1) - a) * theta) * rsin_theta; const T xs_scale = sin((T{1} - a) * theta) * rsin_theta;
const T ys_scale = sin(a * theta) * raw_cos_theta_sign * rsin_theta; const T ys_scale = sin(a * theta) * raw_cos_theta_sign * rsin_theta;
return lerp(unit_xs, unit_ys, xs_scale, ys_scale); return lerp(unit_xs, unit_ys, xs_scale, ys_scale);
} else { } else {
// use linear interpolation for small angles // use linear interpolation for small angles
const T xs_scale = T(1) - a; const T xs_scale = T{1} - a;
const T ys_scale = a * raw_cos_theta_sign; const T ys_scale = a * raw_cos_theta_sign;
return normalize(lerp(unit_xs, unit_ys, xs_scale, ys_scale)); return normalize(lerp(unit_xs, unit_ys, xs_scale, ys_scale));
} }
@@ -222,7 +222,7 @@ namespace vmath_hpp
template < typename T > template < typename T >
[[nodiscard]] T distance(const qua<T>& xs, const qua<T>& ys) { [[nodiscard]] T distance(const qua<T>& xs, const qua<T>& ys) {
const qua zs = xs * conjugate(ys); const qua zs = xs * conjugate(ys);
return T(2) * atan2(length(zs.v), abs(zs.s)); return T{2} * atan2(length(zs.v), abs(zs.s));
} }
template < typename T > template < typename T >
@@ -237,43 +237,80 @@ namespace vmath_hpp
namespace vmath_hpp namespace vmath_hpp
{ {
template < typename T > template < typename T
[[nodiscard]] constexpr vec<bool, 4> approx(const qua<T>& xs, const qua<T>& ys) { , typename U = decltype(any(std::declval<vec<T, 4>>())) >
[[nodiscard]] constexpr U any(const qua<T>& xs) {
return any(vec{xs});
}
template < typename T
, typename U = decltype(all(std::declval<vec<T, 4>>())) >
[[nodiscard]] constexpr U all(const qua<T>& xs) {
return all(vec{xs});
}
template < typename T
, typename U = typename decltype(approx(
std::declval<vec<T, 4>>(),
std::declval<vec<T, 4>>()))::component_type >
[[nodiscard]] constexpr vec<U, 4> approx(const qua<T>& xs, const qua<T>& ys) {
return approx(vec{xs}, vec{ys}); return approx(vec{xs}, vec{ys});
} }
template < typename T > template < typename T
[[nodiscard]] constexpr vec<bool, 4> approx(const qua<T>& xs, const qua<T>& ys, T epsilon) { , typename U = typename decltype(approx(
std::declval<vec<T, 4>>(),
std::declval<vec<T, 4>>(),
std::declval<T>()))::component_type >
[[nodiscard]] constexpr vec<U, 4> approx(const qua<T>& xs, const qua<T>& ys, T epsilon) {
return approx(vec{xs}, vec{ys}, epsilon); return approx(vec{xs}, vec{ys}, epsilon);
} }
template < typename T > template < typename T
[[nodiscard]] constexpr vec<bool, 4> less(const qua<T>& xs, const qua<T>& ys) { , typename U = typename decltype(less(
std::declval<vec<T, 4>>(),
std::declval<vec<T, 4>>()))::component_type >
[[nodiscard]] constexpr vec<U, 4> less(const qua<T>& xs, const qua<T>& ys) {
return less(vec{xs}, vec{ys}); return less(vec{xs}, vec{ys});
} }
template < typename T > template < typename T
[[nodiscard]] constexpr vec<bool, 4> less_equal(const qua<T>& xs, const qua<T>& ys) { , typename U = typename decltype(less_equal(
std::declval<vec<T, 4>>(),
std::declval<vec<T, 4>>()))::component_type >
[[nodiscard]] constexpr vec<U, 4> less_equal(const qua<T>& xs, const qua<T>& ys) {
return less_equal(vec{xs}, vec{ys}); return less_equal(vec{xs}, vec{ys});
} }
template < typename T > template < typename T
[[nodiscard]] constexpr vec<bool, 4> greater(const qua<T>& xs, const qua<T>& ys) { , typename U = typename decltype(greater(
std::declval<vec<T, 4>>(),
std::declval<vec<T, 4>>()))::component_type >
[[nodiscard]] constexpr vec<U, 4> greater(const qua<T>& xs, const qua<T>& ys) {
return greater(vec{xs}, vec{ys}); return greater(vec{xs}, vec{ys});
} }
template < typename T > template < typename T
[[nodiscard]] constexpr vec<bool, 4> greater_equal(const qua<T>& xs, const qua<T>& ys) { , typename U = typename decltype(greater_equal(
std::declval<vec<T, 4>>(),
std::declval<vec<T, 4>>()))::component_type >
[[nodiscard]] constexpr vec<U, 4> greater_equal(const qua<T>& xs, const qua<T>& ys) {
return greater_equal(vec{xs}, vec{ys}); return greater_equal(vec{xs}, vec{ys});
} }
template < typename T > template < typename T
[[nodiscard]] constexpr vec<bool, 4> equal_to(const qua<T>& xs, const qua<T>& ys) { , typename U = typename decltype(equal_to(
std::declval<vec<T, 4>>(),
std::declval<vec<T, 4>>()))::component_type >
[[nodiscard]] constexpr vec<U, 4> equal_to(const qua<T>& xs, const qua<T>& ys) {
return equal_to(vec{xs}, vec{ys}); return equal_to(vec{xs}, vec{ys});
} }
template < typename T > template < typename T
[[nodiscard]] constexpr vec<bool, 4> not_equal_to(const qua<T>& xs, const qua<T>& ys) { , typename U = typename decltype(not_equal_to(
std::declval<vec<T, 4>>(),
std::declval<vec<T, 4>>()))::component_type >
[[nodiscard]] constexpr vec<U, 4> not_equal_to(const qua<T>& xs, const qua<T>& ys) {
return not_equal_to(vec{xs}, vec{ys}); return not_equal_to(vec{xs}, vec{ys});
} }
} }

View File

@@ -821,7 +821,7 @@ namespace vmath_hpp
[[nodiscard]] constexpr T dot(const vec<T, Size>& xs, const vec<T, Size>& ys) { [[nodiscard]] constexpr T dot(const vec<T, Size>& xs, const vec<T, Size>& ys) {
return fold_join([](T acc, T x, T y){ return fold_join([](T acc, T x, T y){
return acc + (x * y); return acc + (x * y);
}, T(0), xs, ys); }, T{0}, xs, ys);
} }
template < typename T, std::size_t Size > template < typename T, std::size_t Size >
@@ -869,53 +869,80 @@ namespace vmath_hpp
namespace vmath_hpp namespace vmath_hpp
{ {
template < typename T, std::size_t Size > template < typename T, std::size_t Size
[[nodiscard]] constexpr bool any(const vec<T, Size>& xs) { , typename U = decltype(any(std::declval<T>())) >
return fold_join([](bool acc, T x){ return acc || any(x); }, false, xs); [[nodiscard]] constexpr U any(const vec<T, Size>& xs) {
return fold_join([](U acc, T x){ return acc || any(x); }, U{false}, xs);
} }
template < typename T, std::size_t Size > template < typename T, std::size_t Size
[[nodiscard]] constexpr bool all(const vec<T, Size>& xs) { , typename U = decltype(all(std::declval<T>())) >
return fold_join([](bool acc, T x){ return acc && all(x); }, true, xs); [[nodiscard]] constexpr U all(const vec<T, Size>& xs) {
return fold_join([](U acc, T x){ return acc && all(x); }, U{true}, xs);
} }
template < typename T, std::size_t Size > template < typename T, std::size_t Size
[[nodiscard]] constexpr vec<bool, Size> approx(const vec<T, Size>& xs, const vec<T, Size>& ys) { , typename U = decltype(approx(
std::declval<T>(),
std::declval<T>())) >
[[nodiscard]] constexpr vec<U, Size> approx(const vec<T, Size>& xs, const vec<T, Size>& ys) {
return map_join([](T x, T y){ return approx(x, y); }, xs, ys); return map_join([](T x, T y){ return approx(x, y); }, xs, ys);
} }
template < typename T, std::size_t Size > template < typename T, std::size_t Size
[[nodiscard]] constexpr vec<bool, Size> approx(const vec<T, Size>& xs, const vec<T, Size>& ys, T epsilon) { , typename U = decltype(approx(
std::declval<T>(),
std::declval<T>(),
std::declval<T>())) >
[[nodiscard]] constexpr vec<U, Size> approx(const vec<T, Size>& xs, const vec<T, Size>& ys, T epsilon) {
return map_join([epsilon](T x, T y){ return approx(x, y, epsilon); }, xs, ys); return map_join([epsilon](T x, T y){ return approx(x, y, epsilon); }, xs, ys);
} }
template < typename T, std::size_t Size > template < typename T, std::size_t Size
[[nodiscard]] constexpr vec<bool, Size> less(const vec<T, Size>& xs, const vec<T, Size>& ys) { , typename U = decltype(less(
std::declval<T>(),
std::declval<T>())) >
[[nodiscard]] constexpr vec<U, Size> less(const vec<T, Size>& xs, const vec<T, Size>& ys) {
return map_join([](T x, T y){ return less(x, y); }, xs, ys); return map_join([](T x, T y){ return less(x, y); }, xs, ys);
} }
template < typename T, std::size_t Size > template < typename T, std::size_t Size
[[nodiscard]] constexpr vec<bool, Size> less_equal(const vec<T, Size>& xs, const vec<T, Size>& ys) { , typename U = decltype(less_equal(
std::declval<T>(),
std::declval<T>())) >
[[nodiscard]] constexpr vec<U, Size> less_equal(const vec<T, Size>& xs, const vec<T, Size>& ys) {
return map_join([](T x, T y){ return less_equal(x, y); }, xs, ys); return map_join([](T x, T y){ return less_equal(x, y); }, xs, ys);
} }
template < typename T, std::size_t Size > template < typename T, std::size_t Size
[[nodiscard]] constexpr vec<bool, Size> greater(const vec<T, Size>& xs, const vec<T, Size>& ys) { , typename U = decltype(greater(
std::declval<T>(),
std::declval<T>())) >
[[nodiscard]] constexpr vec<U, Size> greater(const vec<T, Size>& xs, const vec<T, Size>& ys) {
return map_join([](T x, T y){ return greater(x, y); }, xs, ys); return map_join([](T x, T y){ return greater(x, y); }, xs, ys);
} }
template < typename T, std::size_t Size > template < typename T, std::size_t Size
[[nodiscard]] constexpr vec<bool, Size> greater_equal(const vec<T, Size>& xs, const vec<T, Size>& ys) { , typename U = decltype(greater_equal(
std::declval<T>(),
std::declval<T>())) >
[[nodiscard]] constexpr vec<U, Size> greater_equal(const vec<T, Size>& xs, const vec<T, Size>& ys) {
return map_join([](T x, T y){ return greater_equal(x, y); }, xs, ys); return map_join([](T x, T y){ return greater_equal(x, y); }, xs, ys);
} }
template < typename T, std::size_t Size > template < typename T, std::size_t Size
[[nodiscard]] constexpr vec<bool, Size> equal_to(const vec<T, Size>& xs, const vec<T, Size>& ys) { , typename U = decltype(equal_to(
std::declval<T>(),
std::declval<T>())) >
[[nodiscard]] constexpr vec<U, Size> equal_to(const vec<T, Size>& xs, const vec<T, Size>& ys) {
return map_join([](T x, T y){ return equal_to(x, y); }, xs, ys); return map_join([](T x, T y){ return equal_to(x, y); }, xs, ys);
} }
template < typename T, std::size_t Size > template < typename T, std::size_t Size
[[nodiscard]] constexpr vec<bool, Size> not_equal_to(const vec<T, Size>& xs, const vec<T, Size>& ys) { , typename U = decltype(not_equal_to(
std::declval<T>(),
std::declval<T>())) >
[[nodiscard]] constexpr vec<U, Size> not_equal_to(const vec<T, Size>& xs, const vec<T, Size>& ys) {
return map_join([](T x, T y){ return not_equal_to(x, y); }, xs, ys); return map_join([](T x, T y){ return not_equal_to(x, y); }, xs, ys);
} }
} }

View File

@@ -150,6 +150,19 @@ TEST_CASE("vmath/qua_fun") {
} }
SUBCASE("Relational Functions") { SUBCASE("Relational Functions") {
STATIC_CHECK(any(qua(1,0,0,0)));
STATIC_CHECK(any(qua(0,1,0,0)));
STATIC_CHECK(any(qua(0,0,1,0)));
STATIC_CHECK(any(qua(0,0,0,1)));
STATIC_CHECK(any(qua(1,1,1,1)));
STATIC_CHECK_FALSE(any(qua(0,0,0,0)));
STATIC_CHECK_FALSE(all(qua(1,0,0,0)));
STATIC_CHECK_FALSE(all(qua(0,1,0,0)));
STATIC_CHECK_FALSE(all(qua(0,0,1,0)));
STATIC_CHECK(all(qua(1,1,1,1)));
STATIC_CHECK_FALSE(all(qua(0,0,0,0)));
STATIC_CHECK(approx(qua(1,1,1,1), qua(0,1,2,3)) == bool4(false, true, false, false)); STATIC_CHECK(approx(qua(1,1,1,1), qua(0,1,2,3)) == bool4(false, true, false, false));
STATIC_CHECK(approx(qua(1,1,1,1), qua(0,1,2,3), 0) == bool4(false, true, false, false)); STATIC_CHECK(approx(qua(1,1,1,1), qua(0,1,2,3), 0) == bool4(false, true, false, false));
STATIC_CHECK(approx(qua(1,1,1,1), qua(0,1,2,3), 1) == bool4(true, true, true, false)); STATIC_CHECK(approx(qua(1,1,1,1), qua(0,1,2,3), 1) == bool4(true, true, true, false));