mirror of
https://github.com/BlackMATov/vmath.hpp.git
synced 2025-12-13 12:15:56 +07:00
relation funcs non-arithmetic T support
This commit is contained in:
199
README.md
199
README.md
@@ -1388,97 +1388,184 @@ constexpr bool not_equal_to(T x, T y) noexcept;
|
||||
#### Vector
|
||||
|
||||
```cpp
|
||||
template < typename T, size_t Size >
|
||||
constexpr bool any(const vec<T, Size>& xs);
|
||||
template < typename T, std::size_t Size
|
||||
, typename U = decltype(any(std::declval<T>())) >
|
||||
constexpr U any(const vec<T, Size>& xs);
|
||||
|
||||
template < typename T, size_t Size >
|
||||
constexpr bool all(const vec<T, Size>& xs);
|
||||
template < typename T, std::size_t Size
|
||||
, typename U = decltype(all(std::declval<T>())) >
|
||||
constexpr U all(const vec<T, Size>& xs);
|
||||
|
||||
template < typename T, size_t Size >
|
||||
constexpr vec<bool, Size> approx(const vec<T, Size>& xs, const vec<T, Size>& ys);
|
||||
template < typename T, std::size_t Size
|
||||
, 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 >
|
||||
constexpr vec<bool, Size> approx(const vec<T, Size>& xs, const vec<T, Size>& ys, T epsilon);
|
||||
template < typename T, std::size_t Size
|
||||
, 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 >
|
||||
constexpr vec<bool, Size> less(const vec<T, Size>& xs, const vec<T, Size>& ys);
|
||||
template < typename T, std::size_t Size
|
||||
, 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 >
|
||||
constexpr vec<bool, Size> less_equal(const vec<T, Size>& xs, const vec<T, Size>& ys);
|
||||
template < typename T, std::size_t Size
|
||||
, 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 >
|
||||
constexpr vec<bool, Size> greater(const vec<T, Size>& xs, const vec<T, Size>& ys);
|
||||
template < typename T, std::size_t Size
|
||||
, 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 >
|
||||
constexpr vec<bool, Size> greater_equal(const vec<T, Size>& xs, const vec<T, Size>& ys);
|
||||
template < typename T, std::size_t Size
|
||||
, 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 >
|
||||
constexpr vec<bool, Size> equal_to(const vec<T, Size>& xs, const vec<T, Size>& ys);
|
||||
template < typename T, std::size_t Size
|
||||
, 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 >
|
||||
constexpr vec<bool, Size> not_equal_to(const vec<T, Size>& xs, const vec<T, Size>& ys);
|
||||
template < typename T, std::size_t Size
|
||||
, 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
|
||||
|
||||
```cpp
|
||||
template < typename T, size_t Size >
|
||||
constexpr bool any(const mat<T, Size>& xs);
|
||||
template < typename T, std::size_t Size
|
||||
, typename U = decltype(any(std::declval<vec<T, Size>>())) >
|
||||
constexpr U any(const mat<T, Size>& xs);
|
||||
|
||||
template < typename T, size_t Size >
|
||||
constexpr bool all(const mat<T, Size>& xs);
|
||||
template < typename T, std::size_t Size
|
||||
, typename U = decltype(all(std::declval<vec<T, Size>>())) >
|
||||
constexpr U all(const mat<T, Size>& xs);
|
||||
|
||||
template < typename T, size_t Size >
|
||||
constexpr mat<bool, Size> approx(const mat<T, Size>& xs, const mat<T, Size>& ys);
|
||||
template < typename T, std::size_t Size
|
||||
, 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 >
|
||||
constexpr mat<bool, Size> approx(const mat<T, Size>& xs, const mat<T, Size>& ys, T epsilon);
|
||||
template < typename T, std::size_t Size
|
||||
, 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 >
|
||||
constexpr mat<bool, Size> less(const mat<T, Size>& xs, const mat<T, Size>& ys);
|
||||
template < typename T, std::size_t Size
|
||||
, 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 >
|
||||
constexpr mat<bool, Size> less_equal(const mat<T, Size>& xs, const mat<T, Size>& ys);
|
||||
template < typename T, std::size_t Size
|
||||
, 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 >
|
||||
constexpr mat<bool, Size> greater(const mat<T, Size>& xs, const mat<T, Size>& ys);
|
||||
template < typename T, std::size_t Size
|
||||
, 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 >
|
||||
constexpr mat<bool, Size> greater_equal(const mat<T, Size>& xs, const mat<T, Size>& ys);
|
||||
template < typename T, std::size_t Size
|
||||
, 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 >
|
||||
constexpr mat<bool, Size> equal_to(const mat<T, Size>& xs, const mat<T, Size>& ys);
|
||||
template < typename T, std::size_t Size
|
||||
, 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 >
|
||||
constexpr mat<bool, Size> not_equal_to(const mat<T, Size>& xs, const mat<T, Size>& ys);
|
||||
template < typename T, std::size_t Size
|
||||
, 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
|
||||
|
||||
```cpp
|
||||
template < typename T >
|
||||
constexpr vec<bool, 4> approx(const qua<T>& xs, const qua<T>& ys);
|
||||
template < typename T
|
||||
, typename U = decltype(any(std::declval<vec<T, 4>>())) >
|
||||
constexpr U any(const qua<T>& xs);
|
||||
|
||||
template < typename T >
|
||||
constexpr vec<bool, 4> approx(const qua<T>& xs, const qua<T>& ys, T epsilon);
|
||||
template < typename T
|
||||
, typename U = decltype(all(std::declval<vec<T, 4>>())) >
|
||||
constexpr U all(const qua<T>& xs);
|
||||
|
||||
template < typename T >
|
||||
constexpr vec<bool, 4> less(const qua<T>& xs, const qua<T>& ys);
|
||||
template < typename T
|
||||
, 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 >
|
||||
constexpr vec<bool, 4> less_equal(const qua<T>& xs, const qua<T>& ys);
|
||||
template < typename T
|
||||
, 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 >
|
||||
constexpr vec<bool, 4> greater(const qua<T>& xs, const qua<T>& ys);
|
||||
template < typename T
|
||||
, 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 >
|
||||
constexpr vec<bool, 4> greater_equal(const qua<T>& xs, const qua<T>& ys);
|
||||
template < typename T
|
||||
, 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 >
|
||||
constexpr vec<bool, 4> equal_to(const qua<T>& xs, const qua<T>& ys);
|
||||
template < typename T
|
||||
, 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 >
|
||||
constexpr vec<bool, 4> not_equal_to(const qua<T>& xs, const qua<T>& ys);
|
||||
template < typename T
|
||||
, 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
|
||||
|
||||
@@ -501,53 +501,80 @@ namespace vmath_hpp
|
||||
|
||||
namespace vmath_hpp
|
||||
{
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr bool any(const mat<T, Size>& xs) {
|
||||
return fold_join([](bool acc, const vec<T, Size>& x){ return acc || any(x); }, false, xs);
|
||||
template < typename T, std::size_t Size
|
||||
, typename U = decltype(any(std::declval<vec<T, Size>>())) >
|
||||
[[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 >
|
||||
[[nodiscard]] constexpr bool all(const mat<T, Size>& xs) {
|
||||
return fold_join([](bool acc, const vec<T, Size>& x){ return acc && all(x); }, true, xs);
|
||||
template < typename T, std::size_t Size
|
||||
, typename U = decltype(all(std::declval<vec<T, Size>>())) >
|
||||
[[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 >
|
||||
[[nodiscard]] constexpr mat<bool, Size> approx(const mat<T, Size>& xs, const mat<T, Size>& ys) {
|
||||
template < typename T, std::size_t Size
|
||||
, 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);
|
||||
}
|
||||
|
||||
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) {
|
||||
template < typename T, std::size_t Size
|
||||
, 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);
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr mat<bool, Size> less(const mat<T, Size>& xs, const mat<T, Size>& ys) {
|
||||
template < typename T, std::size_t Size
|
||||
, 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);
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr mat<bool, Size> less_equal(const mat<T, Size>& xs, const mat<T, Size>& ys) {
|
||||
template < typename T, std::size_t Size
|
||||
, 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);
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr mat<bool, Size> greater(const mat<T, Size>& xs, const mat<T, Size>& ys) {
|
||||
template < typename T, std::size_t Size
|
||||
, 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);
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr mat<bool, Size> greater_equal(const mat<T, Size>& xs, const mat<T, Size>& ys) {
|
||||
template < typename T, std::size_t Size
|
||||
, 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);
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr mat<bool, Size> equal_to(const mat<T, Size>& xs, const mat<T, Size>& ys) {
|
||||
template < typename T, std::size_t Size
|
||||
, 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);
|
||||
}
|
||||
|
||||
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) {
|
||||
template < typename T, std::size_t Size
|
||||
, 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,7 +169,7 @@ namespace vmath_hpp
|
||||
|
||||
template < typename T >
|
||||
[[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));
|
||||
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);
|
||||
|
||||
// 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 rsin_theta = rsqrt(T(1) - sqr(cos_theta));
|
||||
const T xs_scale = sin((T(1) - a) * theta) * rsin_theta;
|
||||
const T rsin_theta = rsqrt(T{1} - sqr(cos_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;
|
||||
return lerp(unit_xs, unit_ys, xs_scale, ys_scale);
|
||||
} else {
|
||||
// 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;
|
||||
return normalize(lerp(unit_xs, unit_ys, xs_scale, ys_scale));
|
||||
}
|
||||
@@ -222,7 +222,7 @@ namespace vmath_hpp
|
||||
template < typename T >
|
||||
[[nodiscard]] T distance(const qua<T>& xs, const qua<T>& 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 >
|
||||
@@ -237,43 +237,80 @@ namespace vmath_hpp
|
||||
|
||||
namespace vmath_hpp
|
||||
{
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr vec<bool, 4> approx(const qua<T>& xs, const qua<T>& ys) {
|
||||
template < typename T
|
||||
, 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});
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr vec<bool, 4> approx(const qua<T>& xs, const qua<T>& ys, T epsilon) {
|
||||
template < typename T
|
||||
, 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);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr vec<bool, 4> less(const qua<T>& xs, const qua<T>& ys) {
|
||||
template < typename T
|
||||
, 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});
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr vec<bool, 4> less_equal(const qua<T>& xs, const qua<T>& ys) {
|
||||
template < typename T
|
||||
, 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});
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr vec<bool, 4> greater(const qua<T>& xs, const qua<T>& ys) {
|
||||
template < typename T
|
||||
, 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});
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr vec<bool, 4> greater_equal(const qua<T>& xs, const qua<T>& ys) {
|
||||
template < typename T
|
||||
, 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});
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr vec<bool, 4> equal_to(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 >
|
||||
[[nodiscard]] constexpr vec<U, 4> equal_to(const qua<T>& xs, const qua<T>& ys) {
|
||||
return equal_to(vec{xs}, vec{ys});
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr vec<bool, 4> not_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 >
|
||||
[[nodiscard]] constexpr vec<U, 4> not_equal_to(const qua<T>& xs, const qua<T>& ys) {
|
||||
return not_equal_to(vec{xs}, vec{ys});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -821,7 +821,7 @@ namespace vmath_hpp
|
||||
[[nodiscard]] constexpr T dot(const vec<T, Size>& xs, const vec<T, Size>& ys) {
|
||||
return fold_join([](T acc, T x, T y){
|
||||
return acc + (x * y);
|
||||
}, T(0), xs, ys);
|
||||
}, T{0}, xs, ys);
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
@@ -869,53 +869,80 @@ namespace vmath_hpp
|
||||
|
||||
namespace vmath_hpp
|
||||
{
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr bool any(const vec<T, Size>& xs) {
|
||||
return fold_join([](bool acc, T x){ return acc || any(x); }, false, xs);
|
||||
template < typename T, std::size_t Size
|
||||
, typename U = decltype(any(std::declval<T>())) >
|
||||
[[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 >
|
||||
[[nodiscard]] constexpr bool all(const vec<T, Size>& xs) {
|
||||
return fold_join([](bool acc, T x){ return acc && all(x); }, true, xs);
|
||||
template < typename T, std::size_t Size
|
||||
, typename U = decltype(all(std::declval<T>())) >
|
||||
[[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 >
|
||||
[[nodiscard]] constexpr vec<bool, Size> approx(const vec<T, Size>& xs, const vec<T, Size>& ys) {
|
||||
template < typename T, std::size_t Size
|
||||
, 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);
|
||||
}
|
||||
|
||||
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) {
|
||||
template < typename T, std::size_t Size
|
||||
, 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);
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr vec<bool, Size> less(const vec<T, Size>& xs, const vec<T, Size>& ys) {
|
||||
template < typename T, std::size_t Size
|
||||
, 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);
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr vec<bool, Size> less_equal(const vec<T, Size>& xs, const vec<T, Size>& ys) {
|
||||
template < typename T, std::size_t Size
|
||||
, 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);
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr vec<bool, Size> greater(const vec<T, Size>& xs, const vec<T, Size>& ys) {
|
||||
template < typename T, std::size_t Size
|
||||
, 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);
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr vec<bool, Size> greater_equal(const vec<T, Size>& xs, const vec<T, Size>& ys) {
|
||||
template < typename T, std::size_t Size
|
||||
, 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);
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr vec<bool, Size> equal_to(const vec<T, Size>& xs, const vec<T, Size>& ys) {
|
||||
template < typename T, std::size_t Size
|
||||
, 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);
|
||||
}
|
||||
|
||||
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) {
|
||||
template < typename T, std::size_t Size
|
||||
, 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,6 +150,19 @@ TEST_CASE("vmath/qua_fun") {
|
||||
}
|
||||
|
||||
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), 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));
|
||||
|
||||
Reference in New Issue
Block a user