rewrite fold1 funcs

This commit is contained in:
BlackMATov
2021-02-24 22:33:26 +07:00
parent 08051bcc4a
commit 2ef015d148
5 changed files with 176 additions and 215 deletions

View File

@@ -18,55 +18,28 @@ namespace vmath_hpp::detail::impl
{
template < typename A, std::size_t Size, typename F, std::size_t... Is >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
mat<typename std::invoke_result_t<
F,
vec<A, Size>
>::component_type, Size>
map_join_impl(
auto map_join_impl(
F&& f,
const mat<A, Size>& a,
std::index_sequence<Is...>)
{
return { f(a[Is])... };
return mat{ f(a[Is])... };
}
template < typename A, typename B, std::size_t Size, typename F, std::size_t... Is >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
mat<typename std::invoke_result_t<
F,
vec<A, Size>,
vec<B, Size>
>::component_type, Size>
map_join_impl(
auto map_join_impl(
F&& f,
const mat<A, Size>& a,
const mat<B, Size>& b,
std::index_sequence<Is...>)
{
return { f(a[Is], b[Is])... };
}
template < typename A, typename B, typename C, std::size_t Size, typename F, std::size_t... Is >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
mat<typename std::invoke_result_t<
F,
vec<A, Size>,
vec<B, Size>,
vec<C, Size>
>::component_type, Size>
map_join_impl(
F&& f,
const mat<A, Size>& a,
const mat<B, Size>& b,
const mat<C, Size>& c,
std::index_sequence<Is...>)
{
return { f(a[Is], b[Is], c[Is])... };
return mat{ f(a[Is], b[Is])... };
}
template < typename A, typename B, std::size_t Size, typename F, std::size_t... Is >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
A fold_join_impl(
auto fold_join_impl(
F&& f,
A init,
const mat<B, Size>& b,
@@ -75,39 +48,57 @@ namespace vmath_hpp::detail::impl
return ((init = f(std::move(init), b[Is])), ...);
}
template < typename A, typename B, typename C, std::size_t Size, typename F, std::size_t... Is >
template < typename A, std::size_t Size, typename F, std::size_t... Is >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
A fold_join_impl(
F&& f,
A init,
const vec<B, Size>& b,
const mat<C, Size>& c,
std::index_sequence<Is...>)
{
return ((init = f(std::move(init), b[Is], c[Is])), ...);
}
template < typename A, typename B, typename C, std::size_t Size, typename F, std::size_t... Is >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
A fold_join_impl(
F&& f,
A init,
const mat<B, Size>& b,
const mat<C, Size>& c,
std::index_sequence<Is...>)
{
return ((init = f(std::move(init), b[Is], c[Is])), ...);
}
template < typename A, std::size_t Size, typename F, std::size_t I, std::size_t... Is >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
vec<A, Size> fold1_join_impl(
auto fold1_and_join_impl(
F&& f,
const mat<A, Size>& a,
std::index_sequence<I, Is...>)
std::index_sequence<Is...>)
{
vec<A, Size> init = a[I];
return ((init = f(std::move(init), a[Is])), ...);
return (... && f(a[Is]));
}
template < typename A, typename B, std::size_t Size, typename F, std::size_t... Is >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto fold1_and_join_impl(
F&& f,
const mat<A, Size>& a,
const mat<B, Size>& b,
std::index_sequence<Is...>)
{
return (... && f(a[Is], b[Is]));
}
template < typename A, std::size_t Size, typename F, std::size_t... Is >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto fold1_or_join_impl(
F&& f,
const mat<A, Size>& a,
std::index_sequence<Is...>)
{
return (... || f(a[Is]));
}
template < typename A, typename B, std::size_t Size, typename F, std::size_t... Is >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto fold1_or_join_impl(
F&& f,
const mat<A, Size>& a,
const mat<B, Size>& b,
std::index_sequence<Is...>)
{
return (... || f(a[Is], b[Is]));
}
template < typename A, typename B, std::size_t Size, typename F, std::size_t... Is >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto fold1_plus_join_impl(
F&& f,
const vec<A, Size>& a,
const mat<B, Size>& b,
std::index_sequence<Is...>)
{
return (... + f(a[Is], b[Is]));
}
}
@@ -125,34 +116,40 @@ namespace vmath_hpp::detail
return impl::map_join_impl(std::forward<F>(f), a, b, std::make_index_sequence<Size>{});
}
template < typename A, typename B, typename C, std::size_t Size, typename F >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto map_join(F&& f, const mat<A, Size>& a, const mat<B, Size>& b, const mat<C, Size>& c) {
return impl::map_join_impl(std::forward<F>(f), a, b, c, std::make_index_sequence<Size>{});
}
template < typename A, typename B, std::size_t Size, typename F >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto fold_join(F&& f, A init, const mat<B, Size>& b) {
return impl::fold_join_impl(std::forward<F>(f), std::move(init), b, std::make_index_sequence<Size>{});
}
template < typename A, typename B, typename C, std::size_t Size, typename F >
template < typename A, std::size_t Size, typename F >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto fold_join(F&& f, A init, const vec<B, Size>& b, const mat<C, Size>& c) {
return impl::fold_join_impl(std::forward<F>(f), std::move(init), b, c, std::make_index_sequence<Size>{});
auto fold1_and_join(F&& f, const mat<A, Size>& a) {
return impl::fold1_and_join_impl(std::forward<F>(f), a, std::make_index_sequence<Size>{});
}
template < typename A, typename B, typename C, std::size_t Size, typename F >
template < typename A, typename B, std::size_t Size, typename F >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto fold_join(F&& f, A init, const mat<B, Size>& b, const mat<C, Size>& c) {
return impl::fold_join_impl(std::forward<F>(f), std::move(init), b, c, std::make_index_sequence<Size>{});
auto fold1_and_join(F&& f, const mat<A, Size>& a, const mat<B, Size>& b) {
return impl::fold1_and_join_impl(std::forward<F>(f), a, b, std::make_index_sequence<Size>{});
}
template < typename A, std::size_t Size, typename F >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto fold1_join(F&& f, const mat<A, Size>& a) {
return impl::fold1_join_impl(std::forward<F>(f), a, std::make_index_sequence<Size>{});
auto fold1_or_join(F&& f, const mat<A, Size>& a) {
return impl::fold1_or_join_impl(std::forward<F>(f), a, std::make_index_sequence<Size>{});
}
template < typename A, typename B, std::size_t Size, typename F >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto fold1_or_join(F&& f, const mat<A, Size>& a, const mat<B, Size>& b) {
return impl::fold1_or_join_impl(std::forward<F>(f), a, b, std::make_index_sequence<Size>{});
}
template < typename A, typename B, std::size_t Size, typename F >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto fold1_plus_join(F&& f, const vec<A, Size>& a, const mat<B, Size>& b) {
return impl::fold1_plus_join_impl(std::forward<F>(f), a, b, std::make_index_sequence<Size>{});
}
}
@@ -262,17 +259,12 @@ namespace vmath_hpp
template < typename T, typename U, std::size_t Size >
[[nodiscard]] constexpr auto operator*(const vec<T, Size>& xs, const mat<U, Size>& ys) {
using V = decltype(std::declval<T>() * std::declval<U>());
return fold_join([](const vec<V, Size>& acc, T x, const vec<U, Size>& y){
return acc + x * y;
}, vec<V, Size>{}, xs, ys);
return fold1_plus_join([](T x, const vec<U, Size>& y){ return x * y; }, xs, ys);
}
template < typename T, typename U, std::size_t Size >
[[nodiscard]] constexpr auto operator*(const mat<T, Size>& xs, const mat<U, Size>& ys) {
return map_join([&ys](const vec<T, Size>& x){
return x * ys;
}, xs);
return map_join([&ys](const vec<T, Size>& x){ return x * ys; }, xs);
}
// operator*=
@@ -436,18 +428,14 @@ namespace vmath_hpp
template < typename T, std::size_t Size >
[[nodiscard]] constexpr bool operator==(const mat<T, Size>& xs, const mat<T, Size>& ys) {
return fold_join([](bool acc, const vec<T, Size>& x, const vec<T, Size>& y){
return acc && (x == y);
}, true, xs, ys);
return fold1_and_join([](const vec<T, Size>& x, const vec<T, Size>& y){ return x == y; }, xs, ys);
}
// operator!=
template < typename T, std::size_t Size >
[[nodiscard]] constexpr bool operator!=(const mat<T, Size>& xs, const mat<T, Size>& ys) {
return fold_join([](bool acc, const vec<T, Size>& x, const vec<T, Size>& y){
return acc || (x != y);
}, false, xs, ys);
return fold1_or_join([](const vec<T, Size>& x, const vec<T, Size>& y){ return x != y; }, xs, ys);
}
// operator<
@@ -475,13 +463,13 @@ namespace vmath_hpp
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);
return fold1_or_join([](const vec<T, Size>& x){ return any(x); }, 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);
return fold1_and_join([](const vec<T, Size>& x){ return all(x); }, xs);
}
template < typename T, std::size_t Size

View File

@@ -22,41 +22,11 @@ namespace vmath_hpp::detail
return qua(map_join(std::forward<F>(f), vec{a}));
}
template < typename A, typename B, typename F >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto map_join(F&& f, const qua<A>& a, const qua<B>& b) {
return qua(map_join(std::forward<F>(f), vec{a}, vec{b}));
}
template < typename A, typename B, typename C, typename F >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto map_join(F&& f, const qua<A>& a, const qua<B>& b, const qua<C>& c) {
return qua(map_join(std::forward<F>(f), vec{a}, vec{b}, vec{c}));
}
template < typename A, typename B, typename C, typename D, typename F >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto map_join(F&& f, const qua<A>& a, const qua<B>& b, const qua<C>& c, const qua<D>& d) {
return qua(map_join(std::forward<F>(f), vec{a}, vec{b}, vec{c}, vec{d}));
}
template < typename A, typename B, typename F >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto fold_join(F&& f, A init, const qua<B>& b) {
return fold_join(std::forward<F>(f), std::move(init), vec{b});
}
template < typename A, typename B, typename C, typename F >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto fold_join(F&& f, A init, const qua<B>& b, const qua<C>& c) {
return fold_join(std::forward<F>(f), std::move(init), vec{b}, vec{c});
}
template < typename A, typename F >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto fold1_join(F&& f, const qua<A>& a) {
return fold1_join(std::forward<F>(f), vec{a});
}
}
//

View File

@@ -15,40 +15,40 @@ namespace vmath_hpp::detail::impl
{
template < typename A, std::size_t Size, typename F, std::size_t... Is >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
vec<std::invoke_result_t<F, A>, Size> map_join_impl(
auto map_join_impl(
F&& f,
const vec<A, Size>& a,
std::index_sequence<Is...>)
{
return { f(a[Is])... };
return vec{ f(a[Is])... };
}
template < typename A, typename B, std::size_t Size, typename F, std::size_t... Is >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
vec<std::invoke_result_t<F, A, B>, Size> map_join_impl(
auto map_join_impl(
F&& f,
const vec<A, Size>& a,
const vec<B, Size>& b,
std::index_sequence<Is...>)
{
return { f(a[Is], b[Is])... };
return vec{ f(a[Is], b[Is])... };
}
template < typename A, typename B, typename C, std::size_t Size, typename F, std::size_t... Is >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
vec<std::invoke_result_t<F, A, B, C>, Size> map_join_impl(
auto map_join_impl(
F&& f,
const vec<A, Size>& a,
const vec<B, Size>& b,
const vec<C, Size>& c,
std::index_sequence<Is...>)
{
return { f(a[Is], b[Is], c[Is])... };
return vec{ f(a[Is], b[Is], c[Is])... };
}
template < typename A, typename B, typename C, typename D, std::size_t Size, typename F, std::size_t... Is >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
vec<std::invoke_result_t<F, A, B, C, D>, Size> map_join_impl(
auto map_join_impl(
F&& f,
const vec<A, Size>& a,
const vec<B, Size>& b,
@@ -56,12 +56,12 @@ namespace vmath_hpp::detail::impl
const vec<D, Size>& d,
std::index_sequence<Is...>)
{
return { f(a[Is], b[Is], c[Is], d[Is])... };
return vec{ f(a[Is], b[Is], c[Is], d[Is])... };
}
template < typename A, typename B, std::size_t Size, typename F, std::size_t... Is >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
A fold_join_impl(
auto fold_join_impl(
F&& f,
A init,
const vec<B, Size>& b,
@@ -70,21 +70,9 @@ namespace vmath_hpp::detail::impl
return ((init = f(std::move(init), b[Is])), ...);
}
template < typename A, typename B, typename C, std::size_t Size, typename F, std::size_t... Is >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
A fold_join_impl(
F&& f,
A init,
const vec<B, Size>& b,
const vec<C, Size>& c,
std::index_sequence<Is...>)
{
return ((init = f(std::move(init), b[Is], c[Is])), ...);
}
template < typename A, std::size_t Size, typename F, std::size_t I, std::size_t... Is >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
A fold1_join_impl(
auto fold1_join_impl(
F&& f,
const vec<A, Size>& a,
std::index_sequence<I, Is...>)
@@ -92,6 +80,59 @@ namespace vmath_hpp::detail::impl
A init = a[I];
return ((init = f(std::move(init), a[Is])), ...);
}
template < typename A, std::size_t Size, typename F, std::size_t... Is >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto fold1_and_join_impl(
F&& f,
const vec<A, Size>& a,
std::index_sequence<Is...>)
{
return (... && f(a[Is]));
}
template < typename A, typename B, std::size_t Size, typename F, std::size_t... Is >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto fold1_and_join_impl(
F&& f,
const vec<A, Size>& a,
const vec<B, Size>& b,
std::index_sequence<Is...>)
{
return (... && f(a[Is], b[Is]));
}
template < typename A, std::size_t Size, typename F, std::size_t... Is >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto fold1_or_join_impl(
F&& f,
const vec<A, Size>& a,
std::index_sequence<Is...>)
{
return (... || f(a[Is]));
}
template < typename A, typename B, std::size_t Size, typename F, std::size_t... Is >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto fold1_or_join_impl(
F&& f,
const vec<A, Size>& a,
const vec<B, Size>& b,
std::index_sequence<Is...>)
{
return (... || f(a[Is], b[Is]));
}
template < typename A, typename B, std::size_t Size, typename F, std::size_t... Is >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto fold1_plus_join_impl(
F&& f,
const vec<A, Size>& a,
const vec<B, Size>& b,
std::index_sequence<Is...>)
{
return (... + f(a[Is], b[Is]));
}
}
namespace vmath_hpp::detail
@@ -126,17 +167,41 @@ namespace vmath_hpp::detail
return impl::fold_join_impl(std::forward<F>(f), std::move(init), b, std::make_index_sequence<Size>{});
}
template < typename A, typename B, typename C, std::size_t Size, typename F >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto fold_join(F&& f, A init, const vec<B, Size>& b, const vec<C, Size>& c) {
return impl::fold_join_impl(std::forward<F>(f), std::move(init), b, c, std::make_index_sequence<Size>{});
}
template < typename A, std::size_t Size, typename F >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto fold1_join(F&& f, const vec<A, Size>& a) {
return impl::fold1_join_impl(std::forward<F>(f), a, std::make_index_sequence<Size>{});
}
template < typename A, std::size_t Size, typename F >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto fold1_and_join(F&& f, const vec<A, Size>& a) {
return impl::fold1_and_join_impl(std::forward<F>(f), a, std::make_index_sequence<Size>{});
}
template < typename A, typename B, std::size_t Size, typename F >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto fold1_and_join(F&& f, const vec<A, Size>& a, const vec<B, Size>& b) {
return impl::fold1_and_join_impl(std::forward<F>(f), a, b, std::make_index_sequence<Size>{});
}
template < typename A, std::size_t Size, typename F >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto fold1_or_join(F&& f, const vec<A, Size>& a) {
return impl::fold1_or_join_impl(std::forward<F>(f), a, std::make_index_sequence<Size>{});
}
template < typename A, typename B, std::size_t Size, typename F >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto fold1_or_join(F&& f, const vec<A, Size>& a, const vec<B, Size>& b) {
return impl::fold1_or_join_impl(std::forward<F>(f), a, b, std::make_index_sequence<Size>{});
}
template < typename A, typename B, std::size_t Size, typename F >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto fold1_plus_join(F&& f, const vec<A, Size>& a, const vec<B, Size>& b) {
return impl::fold1_plus_join_impl(std::forward<F>(f), a, b, std::make_index_sequence<Size>{});
}
}
//
@@ -414,18 +479,14 @@ namespace vmath_hpp
template < typename T, std::size_t Size >
[[nodiscard]] constexpr bool operator==(const vec<T, Size>& xs, const vec<T, Size>& ys) {
return fold_join([](bool acc, T x, T y){
return acc && x == y;
}, true, xs, ys);
return fold1_and_join([](T x, T y){ return x == y; }, xs, ys);
}
// operator!=
template < typename T, std::size_t Size >
[[nodiscard]] constexpr bool operator!=(const vec<T, Size>& xs, const vec<T, Size>& ys) {
return fold_join([](bool acc, T x, T y){
return acc || x != y;
}, false, xs, ys);
return fold1_or_join([](T x, T y){ return x != y; }, xs, ys);
}
// operator<
@@ -778,9 +839,7 @@ namespace vmath_hpp
template < typename T, typename U, std::size_t Size
, typename V = decltype(std::declval<T>() * std::declval<U>()) >
[[nodiscard]] constexpr V dot(const vec<T, Size>& xs, const vec<U, Size>& ys) {
return fold_join([](V acc, T x, U y){
return acc + (x * y);
}, V{0}, xs, ys);
return fold1_plus_join([](T x, U y){ return x * y; }, xs, ys);
}
template < typename T, std::size_t Size >
@@ -860,13 +919,13 @@ namespace vmath_hpp
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);
return fold1_or_join([](T x){ return any(x); }, 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);
return fold1_and_join([](T x){ return all(x); }, xs);
}
template < typename T, std::size_t Size

View File

@@ -30,32 +30,6 @@ namespace
}
TEST_CASE("vmath/mat_fun") {
SUBCASE("detail") {
STATIC_CHECK(map_join([](const int2& x){
return x * 2;
}, int2x2{}) == int2x2(2,0,0,2));
STATIC_CHECK(map_join([](const int2& x, const int2& y){
return x + y;
}, int2x2{}, int2x2{}) == int2x2(2,0,0,2));
STATIC_CHECK(map_join([](const int2& x, const int2& y, const int2& z){
return x + y + z;
}, int2x2{}, int2x2{}, int2x2{}) == int2x2(3,0,0,3));
STATIC_CHECK(fold_join([](int acc, const int2& x){
return acc + x.x;
}, 0, int2x2{}) == 1);
STATIC_CHECK(fold_join([](int acc, const int2& x, const int2& y){
return acc + x.x + y.x;
}, 0, int2x2{}, int2x2{}) == 2);
STATIC_CHECK(fold1_join([](const int2& acc, const int2& x){
return acc + x;
}, int2x2{}) == int2(1,1));
}
SUBCASE("operators") {
STATIC_CHECK(+int2x2(1,-2,3,-4) == int2x2(1,-2,3,-4));
STATIC_CHECK(-int2x2(1,-2,3,-4) == int2x2(-1,2,-3,4));

View File

@@ -13,36 +13,6 @@ namespace
}
TEST_CASE("vmath/vec_fun") {
SUBCASE("Detail") {
STATIC_CHECK(map_join([](const int& x){
return x * 2;
}, vec{1,2,3,4}) == vec{2,4,6,8});
STATIC_CHECK(map_join([](const int& x, const int& y){
return x + y;
}, vec{1,2,3,4}, vec{2,3,4,5}) == vec{3,5,7,9});
STATIC_CHECK(map_join([](const int& x, const int& y, const int& z){
return x + y + z;
}, vec{1,2,3,4}, vec{2,3,4,5}, vec{3,4,5,6}) == vec{6,9,12,15});
STATIC_CHECK(map_join([](const int& x, const int& y, const int& z, const int& w){
return x + y + z + w;
}, vec{1,2,3,4}, vec{2,3,4,5}, vec{3,4,5,6}, vec{4,5,6,7}) == vec{10,14,18,22});
STATIC_CHECK(fold_join([](int acc, const int& x){
return acc - x;
}, 0, vec{1,2,3,4}) == -10);
STATIC_CHECK(fold_join([](int acc, const int& x, const int& y){
return acc - x - y;
}, 0, vec{1,2,3,4}, vec{2,3,4,5}) == -24);
STATIC_CHECK(fold1_join([](const int& acc, const int& x){
return acc - x;
}, vec{1,2,3,4}) == -8);
}
SUBCASE("Operators") {
STATIC_CHECK(+int2(1,-2) == int2(1,-2));
STATIC_CHECK(-int2(1,-2) == int2(-1,2));