Merge pull request #4 from BlackMATov/dev

Dev
This commit is contained in:
2020-12-05 09:56:27 +07:00
committed by GitHub
12 changed files with 872 additions and 333 deletions

View File

@@ -122,18 +122,41 @@ public:
template < typename T, size_t Size >
class vec final : public vec_base<T, Size> {
public:
using value_type = T;
using component_type = T;
using pointer = value_type*;
using const_pointer = const value_type*;
using pointer = component_type*;
using const_pointer = const component_type*;
using reference = value_type&;
using const_reference = const value_type&;
using reference = component_type&;
using const_reference = const component_type&;
using iterator = pointer;
using const_iterator = const_pointer;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
static constexpr size_t size = Size;
void swap(vec& other) noexcept(is_nothrow_swappable_v<T>);
iterator begin() noexcept;
const_iterator begin() const noexcept;
iterator end() noexcept;
const_iterator end() const noexcept;
reverse_iterator rbegin() noexcept;
const_reverse_iterator rbegin() const noexcept;
reverse_iterator rend() noexcept;
const_reverse_iterator rend() const noexcept;
const_iterator cbegin() const noexcept;
const_iterator cend() const noexcept;
const_reverse_iterator crbegin() const noexcept;
const_reverse_iterator crend() const noexcept;
pointer data() noexcept;
const_pointer data() const noexcept;
constexpr reference at(size_t index);
constexpr const_reference at(size_t index) const;
@@ -186,7 +209,8 @@ public:
{0, 1}};
constexpr mat_base() = default;
constexpr explicit mat_base(T v);
constexpr explicit mat_base(T d);
constexpr explicit mat_base(const row_type& d);
constexpr mat_base(
T m11, T m12,
@@ -211,7 +235,8 @@ public:
{0, 0, 1}};
constexpr mat_base() = default;
constexpr explicit mat_base(T v);
constexpr explicit mat_base(T d);
constexpr explicit mat_base(const row_type& d);
constexpr mat_base(
T m11, T m12, T m13,
@@ -223,6 +248,10 @@ public:
const row_type& row1,
const row_type& row2);
constexpr mat_base(
const mat_base<T, 2>& m,
const vec_base<T, 2>& v);
constexpr explicit mat_base(const mat_base<T, 2>& other);
constexpr explicit mat_base(const mat_base<T, 4>& other);
};
@@ -239,7 +268,8 @@ public:
{0, 0, 0, 1}};
constexpr mat_base() = default;
constexpr explicit mat_base(T v);
constexpr explicit mat_base(T d);
constexpr explicit mat_base(const row_type& d);
constexpr mat_base(
T m11, T m12, T m13, T m14,
@@ -253,6 +283,10 @@ public:
const row_type& row2,
const row_type& row3);
constexpr mat_base(
const mat_base<T, 3>& m,
const vec_base<T, 3>& v);
constexpr explicit mat_base(const mat_base<T, 2>& other);
constexpr explicit mat_base(const mat_base<T, 3>& other);
};
@@ -268,10 +302,33 @@ public:
using reference = row_type&;
using const_reference = const row_type&;
using iterator = pointer;
using const_iterator = const_pointer;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
static constexpr size_t size = Size;
void swap(mat& other) noexcept(is_nothrow_swappable_v<T>);
iterator begin() noexcept;
const_iterator begin() const noexcept;
iterator end() noexcept;
const_iterator end() const noexcept;
reverse_iterator rbegin() noexcept;
const_reverse_iterator rbegin() const noexcept;
reverse_iterator rend() noexcept;
const_reverse_iterator rend() const noexcept;
const_iterator cbegin() const noexcept;
const_iterator cend() const noexcept;
const_reverse_iterator crbegin() const noexcept;
const_reverse_iterator crend() const noexcept;
pointer data() noexcept;
const_pointer data() const noexcept;
constexpr reference at(size_t index);
constexpr const_reference at(size_t index) const;

View File

@@ -66,12 +66,12 @@ namespace vmath_hpp::detail
template < typename T, size_t Size >
[[nodiscard]] std::size_t hash(const vec<T, Size>& v) noexcept {
return fold(hash_combiner{}, std::size_t{}, v);
return fold_join(hash_combiner{}, std::size_t{}, v);
}
template < typename T, size_t Size >
[[nodiscard]] std::size_t hash(const mat<T, Size>& m) noexcept {
return fold(hash_combiner{}, std::size_t{}, m);
return fold_join(hash_combiner{}, std::size_t{}, m);
}
}
@@ -108,12 +108,12 @@ namespace vmath_hpp
template < typename To, typename From, std::size_t Size >
[[nodiscard]] constexpr vec<To, Size> cast_to(const vec<From, Size>& v) {
return detail::map([](From x){ return cast_to<To>(x); }, v);
return detail::map_join([](From x){ return cast_to<To>(x); }, v);
}
template < typename To, typename From, std::size_t Size >
[[nodiscard]] constexpr mat<To, Size> cast_to(const mat<From, Size>& m) {
return detail::map([](const vec<From, Size>& v){ return cast_to<To>(v); }, m);
return detail::map_join([](const vec<From, Size>& v){ return cast_to<To>(v); }, m);
}
}

View File

@@ -9,6 +9,8 @@
#include <cmath>
#include <cstddef>
#include <initializer_list>
#include <iterator>
#include <stdexcept>
#include <type_traits>
#include <utility>

View File

@@ -26,10 +26,15 @@ namespace vmath_hpp::detail
public:
constexpr mat_base() = default;
constexpr explicit mat_base(T v)
constexpr explicit mat_base(T d)
: rows{
row_type{v, 0},
row_type{0, v}} {}
row_type{d, 0},
row_type{0, d}} {}
constexpr explicit mat_base(const row_type& d)
: rows{
row_type{d[0], 0},
row_type{0, d[1]}} {}
constexpr mat_base(
T m11, T m12,
@@ -67,11 +72,17 @@ namespace vmath_hpp::detail
public:
constexpr mat_base() = default;
constexpr explicit mat_base(T v)
constexpr explicit mat_base(T d)
: rows{
row_type{v, 0, 0},
row_type{0, v, 0},
row_type{0, 0, v}} {}
row_type{d, 0, 0},
row_type{0, d, 0},
row_type{0, 0, d}} {}
constexpr explicit mat_base(const row_type& d)
: rows{
row_type{d[0], 0, 0},
row_type{0, d[1], 0},
row_type{0, 0, d[2]}} {}
constexpr mat_base(
T m11, T m12, T m13,
@@ -88,6 +99,14 @@ namespace vmath_hpp::detail
const row_type& row2)
: rows{row0, row1, row2} {}
constexpr mat_base(
const mat_base<T, 2>& m,
const vec_base<T, 2>& v)
: rows{
row_type{m.rows[0], 0},
row_type{m.rows[1], 0},
row_type{v, 1}} {}
constexpr explicit mat_base(
const mat_base<T, 2>& other)
: rows{
@@ -115,12 +134,19 @@ namespace vmath_hpp::detail
public:
constexpr mat_base() = default;
constexpr explicit mat_base(T v)
constexpr explicit mat_base(T d)
: rows{
row_type{v, 0, 0, 0},
row_type{0, v, 0, 0},
row_type{0, 0, v, 0},
row_type{0, 0, 0, v}} {}
row_type{d, 0, 0, 0},
row_type{0, d, 0, 0},
row_type{0, 0, d, 0},
row_type{0, 0, 0, d}} {}
constexpr explicit mat_base(const row_type& d)
: rows{
row_type{d[0], 0, 0, 0},
row_type{0, d[1], 0, 0},
row_type{0, 0, d[2], 0},
row_type{0, 0, 0, d[3]}} {}
constexpr mat_base(
T m11, T m12, T m13, T m14,
@@ -140,6 +166,15 @@ namespace vmath_hpp::detail
const row_type& row3)
: rows{row0, row1, row2, row3} {}
constexpr mat_base(
const mat_base<T, 3>& m,
const vec_base<T, 3>& v)
: rows{
row_type{m.rows[0], 0},
row_type{m.rows[1], 0},
row_type{m.rows[2], 0},
row_type{v, 1}} {}
constexpr explicit mat_base(
const mat_base<T, 2>& other)
: rows{
@@ -174,6 +209,11 @@ namespace vmath_hpp
using reference = row_type&;
using const_reference = const row_type&;
using iterator = pointer;
using const_iterator = const_pointer;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
static constexpr std::size_t size = Size;
public:
using base_type::mat_base;
@@ -186,10 +226,33 @@ namespace vmath_hpp
void swap(mat& other) noexcept(std::is_nothrow_swappable_v<T>) {
for ( std::size_t i = 0; i < Size; ++i ) {
using std::swap;
swap((*this)[i], other[i]);
swap(rows[i], other.rows[i]);
}
}
[[nodiscard]] iterator begin() noexcept { return iterator(data()); }
[[nodiscard]] const_iterator begin() const noexcept { return const_iterator(data()); }
[[nodiscard]] iterator end() noexcept { return iterator(data() + Size); }
[[nodiscard]] const_iterator end() const noexcept { return const_iterator(data() + Size); }
[[nodiscard]] reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
[[nodiscard]] const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); }
[[nodiscard]] reverse_iterator rend() noexcept { return reverse_iterator(begin()); }
[[nodiscard]] const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); }
[[nodiscard]] const_iterator cbegin() const noexcept { return begin(); }
[[nodiscard]] const_iterator cend() const noexcept { return end(); }
[[nodiscard]] const_reverse_iterator crbegin() const noexcept { return rbegin(); }
[[nodiscard]] const_reverse_iterator crend() const noexcept { return rend(); }
[[nodiscard]] pointer data() noexcept {
return &rows[0];
}
[[nodiscard]] const_pointer data() const noexcept {
return &rows[0];
}
[[nodiscard]] constexpr reference operator[](std::size_t index) noexcept {
return rows[index];
}
@@ -212,6 +275,50 @@ namespace vmath_hpp
return rows[index];
}
};
}
namespace vmath_hpp
{
// mat2
template < typename T >
mat(T, T, T, T) -> mat<T, 2>;
template < typename T >
mat(const vec<T, 2>&, const vec<T, 2>&) -> mat<T, 2>;
template < typename T >
mat(std::initializer_list<T>, std::initializer_list<T>) -> mat<T, 2>;
// mat3
template < typename T >
mat(T, T, T, T, T, T, T, T, T) -> mat<T, 3>;
template < typename T >
mat(const vec<T, 3>&, const vec<T, 3>&, const vec<T, 3>&) -> mat<T, 3>;
template < typename T >
mat(const mat<T, 2>&, const vec<T, 2>&) -> mat<T, 3>;
template < typename T >
mat(std::initializer_list<T>, std::initializer_list<T>, std::initializer_list<T>) -> mat<T, 3>;
// mat4
template < typename T >
mat(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) -> mat<T, 4>;
template < typename T >
mat(const vec<T, 4>&, const vec<T, 4>&, const vec<T, 4>&, const vec<T, 4>&) -> mat<T, 4>;
template < typename T >
mat(const mat<T, 3>&, const vec<T, 3>&) -> mat<T, 4>;
template < typename T >
mat(std::initializer_list<T>, std::initializer_list<T>, std::initializer_list<T>, std::initializer_list<T>) -> mat<T, 4>;
// swap
template < typename T, std::size_t Size >
void swap(mat<T, Size>& l, mat<T, Size>& r) noexcept(noexcept(l.swap(r))) {

View File

@@ -14,94 +14,175 @@
#include "vmath_vec.hpp"
#include "vmath_vec_fun.hpp"
namespace vmath_hpp::detail::impl
{
template < typename A, std::size_t Size, typename F, std::size_t... Is >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto map_join_impl(
F&& f,
const mat<A, Size>& a,
std::index_sequence<Is...>
) -> mat<typename decltype(f(
std::declval<vec<A, Size>>()))::component_type, Size>
{
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 map_join_impl(
F&& f,
const mat<A, Size>& a,
const mat<B, Size>& b,
std::index_sequence<Is...>
) -> mat<typename decltype(f(
std::declval<vec<A, Size>>(),
std::declval<vec<B, Size>>()))::component_type, Size>
{
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
auto map_join_impl(
F&& f,
const mat<A, Size>& a,
const mat<B, Size>& b,
const mat<C, Size>& c,
std::index_sequence<Is...>
) -> mat<typename decltype(f(
std::declval<vec<A, Size>>(),
std::declval<vec<B, Size>>(),
std::declval<vec<C, Size>>()))::component_type, Size>
{
return { f(a[Is], b[Is], c[Is])... };
}
template < typename A, typename B, std::size_t Size, typename F, std::size_t... Is >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto fold_join_impl(
F&& f,
A init,
const mat<B, Size>& b,
std::index_sequence<Is...>
) -> A {
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
auto fold_join_impl(
F&& f,
A init,
const vec<B, Size>& b,
const mat<C, Size>& c,
std::index_sequence<Is...>
) -> A {
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
auto fold_join_impl(
F&& f,
A init,
const mat<B, Size>& b,
const mat<C, Size>& c,
std::index_sequence<Is...>
) -> A {
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
auto fold1_join_impl(
F&& f,
const mat<A, Size>& a,
std::index_sequence<I, Is...>
) -> vec<A, Size> {
vec<A, Size> init = a[I];
return ((init = f(std::move(init), a[Is])), ...);
}
}
namespace vmath_hpp::detail
{
namespace impl
{
template < typename A, std::size_t Size, typename F, std::size_t... Is >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto map_impl(F&& f, const mat<A, Size>& a, std::index_sequence<Is...>)
-> mat<typename std::invoke_result_t<F, vec<A, Size>>::value_type, Size>
{
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 zip_impl(F&& f, const mat<A, Size>& a, const mat<B, Size>& b, std::index_sequence<Is...>)
-> mat<typename std::invoke_result_t<F, vec<A, Size>, vec<B, Size>>::value_type, Size>
{
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
auto zip_impl(F&& f, const mat<A, Size>& a, const mat<B, Size>& b, const mat<C, Size>& c, std::index_sequence<Is...>)
-> mat<typename std::invoke_result_t<F, vec<A, Size>, vec<B, Size>, vec<C, Size>>::value_type, Size>
{
return { f(a[Is], b[Is], c[Is])... };
}
template < typename A, typename B, std::size_t Size, typename F, std::size_t... Is >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
A fold_impl(F&& f, A init, const mat<B, Size>& b, std::index_sequence<Is...>) {
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_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_impl(F&& f, const mat<A, Size>& a, std::index_sequence<I, Is...>) {
vec<A, Size> init = a[I];
return ((init = f(std::move(init), a[Is])), ...);
}
}
template < typename A, std::size_t Size, typename F >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto map(F&& f, const mat<A, Size>& a)
-> mat<typename std::invoke_result_t<F, vec<A, Size>>::value_type, Size>
{
return impl::map_impl(std::forward<F>(f), a, std::make_index_sequence<Size>{});
auto map_join(
F&& f,
const mat<A, Size>& a
) {
return impl::map_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 zip(F&& f, const mat<A, Size>& a, const mat<B, Size>& b)
-> mat<typename std::invoke_result_t<F, vec<A, Size>, vec<B, Size>>::value_type, Size>
{
return impl::zip_impl(std::forward<F>(f), a, b, std::make_index_sequence<Size>{});
auto map_join(
F&& f,
const mat<A, Size>& a,
const mat<B, Size>& b
) {
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 zip(F&& f, const mat<A, Size>& a, const mat<B, Size>& b, const mat<C, Size>& c)
-> mat<typename std::invoke_result_t<F, vec<A, Size>, vec<B, Size>, vec<C, Size>>::value_type, Size>
{
return impl::zip_impl(std::forward<F>(f), a, b, c, std::make_index_sequence<Size>{});
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
A fold(F&& f, A init, const mat<B, Size>& b) {
return impl::fold_impl(std::forward<F>(f), std::move(init), b, std::make_index_sequence<Size>{});
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 >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
A fold(F&& f, A init, const mat<B, Size>& b, const mat<C, Size>& c) {
return impl::fold_impl(std::forward<F>(f), std::move(init), b, c, std::make_index_sequence<Size>{});
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>{});
}
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 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>{});
}
template < typename A, std::size_t Size, typename F >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
vec<A, Size> fold1(F&& f, const mat<A, Size>& a) {
return impl::fold1_impl(std::forward<F>(f), a, std::make_index_sequence<Size>{});
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>{});
}
}
@@ -115,24 +196,24 @@ namespace vmath_hpp
template < typename T, std::size_t Size >
[[nodiscard]] constexpr mat<T, Size> operator-(const mat<T, Size>& xs) {
return map([](const vec<T, Size>& x){ return -x; }, xs);
return map_join([](const vec<T, Size>& x){ return -x; }, xs);
}
// operator+
template < typename T, std::size_t Size >
[[nodiscard]] constexpr mat<T, Size> operator+(const mat<T, Size>& xs, T y) {
return map([y](const vec<T, Size>& x){ return x + y; }, xs);
return map_join([y](const vec<T, Size>& x){ return x + y; }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr mat<T, Size> operator+(T x, const mat<T, Size>& ys) {
return map([x](const vec<T, Size>& y){ return x + y; }, ys);
return map_join([x](const vec<T, Size>& y){ return x + y; }, ys);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr mat<T, Size> operator+(const mat<T, Size>& xs, const mat<T, Size>& ys) {
return zip([](const vec<T, Size>& x, const vec<T, Size>& y){ return x + y; }, xs, ys);
return map_join([](const vec<T, Size>& x, const vec<T, Size>& y){ return x + y; }, xs, ys);
}
// operator+=
@@ -151,17 +232,17 @@ namespace vmath_hpp
template < typename T, std::size_t Size >
[[nodiscard]] constexpr mat<T, Size> operator-(const mat<T, Size>& xs, T y) {
return map([y](const vec<T, Size>& x){ return x - y; }, xs);
return map_join([y](const vec<T, Size>& x){ return x - y; }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr mat<T, Size> operator-(T x, const mat<T, Size>& ys) {
return map([x](const vec<T, Size>& y){ return x - y; }, ys);
return map_join([x](const vec<T, Size>& y){ return x - y; }, ys);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr mat<T, Size> operator-(const mat<T, Size>& xs, const mat<T, Size>& ys) {
return zip([](const vec<T, Size>& x, const vec<T, Size>& y){ return x - y; }, xs, ys);
return map_join([](const vec<T, Size>& x, const vec<T, Size>& y){ return x - y; }, xs, ys);
}
// operator-=
@@ -180,86 +261,26 @@ namespace vmath_hpp
template < typename T, std::size_t Size >
[[nodiscard]] constexpr mat<T, Size> operator*(const mat<T, Size>& xs, T y) {
return map([y](const vec<T, Size>& x){ return x * y; }, xs);
return map_join([y](const vec<T, Size>& x){ return x * y; }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr mat<T, Size> operator*(T x, const mat<T, Size>& ys) {
return map([x](const vec<T, Size>& y){ return x * y; }, ys);
return map_join([x](const vec<T, Size>& y){ return x * y; }, ys);
}
template < typename T >
[[nodiscard]] constexpr vec<T, 2> operator*(const vec<T, 2>& xs, const mat<T, 2>& ys) {
return {
xs.x * ys[0][0] + xs.y * ys[1][0],
xs.x * ys[0][1] + xs.y * ys[1][1]};
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> operator*(const vec<T, Size>& xs, const mat<T, Size>& ys) {
return fold_join([](const vec<T, Size>& acc, T x, const vec<T, Size>& y){
return acc + x * y;
}, vec<T, Size>{}, xs, ys);
}
template < typename T >
[[nodiscard]] constexpr mat<T, 2> operator*(const mat<T, 2>& xs, const mat<T, 2>& ys) {
return {
xs[0][0] * ys[0][0] + xs[0][1] * ys[1][0],
xs[0][0] * ys[0][1] + xs[0][1] * ys[1][1],
xs[1][0] * ys[0][0] + xs[1][1] * ys[1][0],
xs[1][0] * ys[0][1] + xs[1][1] * ys[1][1]};
}
template < typename T >
[[nodiscard]] constexpr vec<T, 3> operator*(const vec<T, 3>& xs, const mat<T, 3>& ys) {
return {
xs.x * ys[0][0] + xs.y * ys[1][0] + xs.z * ys[2][0],
xs.x * ys[0][1] + xs.y * ys[1][1] + xs.z * ys[2][1],
xs.x * ys[0][2] + xs.y * ys[1][2] + xs.z * ys[2][2]};
}
template < typename T >
[[nodiscard]] constexpr mat<T, 3> operator*(const mat<T, 3>& xs, const mat<T, 3>& ys) {
return {
xs[0][0] * ys[0][0] + xs[0][1] * ys[1][0] + xs[0][2] * ys[2][0],
xs[0][0] * ys[0][1] + xs[0][1] * ys[1][1] + xs[0][2] * ys[2][1],
xs[0][0] * ys[0][2] + xs[0][1] * ys[1][2] + xs[0][2] * ys[2][2],
xs[1][0] * ys[0][0] + xs[1][1] * ys[1][0] + xs[1][2] * ys[2][0],
xs[1][0] * ys[0][1] + xs[1][1] * ys[1][1] + xs[1][2] * ys[2][1],
xs[1][0] * ys[0][2] + xs[1][1] * ys[1][2] + xs[1][2] * ys[2][2],
xs[2][0] * ys[0][0] + xs[2][1] * ys[1][0] + xs[2][2] * ys[2][0],
xs[2][0] * ys[0][1] + xs[2][1] * ys[1][1] + xs[2][2] * ys[2][1],
xs[2][0] * ys[0][2] + xs[2][1] * ys[1][2] + xs[2][2] * ys[2][2]};
}
template < typename T >
[[nodiscard]] constexpr vec<T, 4> operator*(const vec<T, 4>& xs, const mat<T, 4>& ys) {
return {
xs.x * ys[0][0] + xs.y * ys[1][0] + xs.z * ys[2][0] + xs.w * ys[3][0],
xs.x * ys[0][1] + xs.y * ys[1][1] + xs.z * ys[2][1] + xs.w * ys[3][1],
xs.x * ys[0][2] + xs.y * ys[1][2] + xs.z * ys[2][2] + xs.w * ys[3][2],
xs.x * ys[0][3] + xs.y * ys[1][3] + xs.z * ys[2][3] + xs.w * ys[3][3]};
}
template < typename T >
[[nodiscard]] constexpr mat<T, 4> operator*(const mat<T, 4>& xs, const mat<T, 4>& ys) {
return {
xs[0][0] * ys[0][0] + xs[0][1] * ys[1][0] + xs[0][2] * ys[2][0] + xs[0][3] * ys[3][0],
xs[0][0] * ys[0][1] + xs[0][1] * ys[1][1] + xs[0][2] * ys[2][1] + xs[0][3] * ys[3][1],
xs[0][0] * ys[0][2] + xs[0][1] * ys[1][2] + xs[0][2] * ys[2][2] + xs[0][3] * ys[3][2],
xs[0][0] * ys[0][3] + xs[0][1] * ys[1][3] + xs[0][2] * ys[2][3] + xs[0][3] * ys[3][3],
xs[1][0] * ys[0][0] + xs[1][1] * ys[1][0] + xs[1][2] * ys[2][0] + xs[1][3] * ys[3][0],
xs[1][0] * ys[0][1] + xs[1][1] * ys[1][1] + xs[1][2] * ys[2][1] + xs[1][3] * ys[3][1],
xs[1][0] * ys[0][2] + xs[1][1] * ys[1][2] + xs[1][2] * ys[2][2] + xs[1][3] * ys[3][2],
xs[1][0] * ys[0][3] + xs[1][1] * ys[1][3] + xs[1][2] * ys[2][3] + xs[1][3] * ys[3][3],
xs[2][0] * ys[0][0] + xs[2][1] * ys[1][0] + xs[2][2] * ys[2][0] + xs[2][3] * ys[3][0],
xs[2][0] * ys[0][1] + xs[2][1] * ys[1][1] + xs[2][2] * ys[2][1] + xs[2][3] * ys[3][1],
xs[2][0] * ys[0][2] + xs[2][1] * ys[1][2] + xs[2][2] * ys[2][2] + xs[2][3] * ys[3][2],
xs[2][0] * ys[0][3] + xs[2][1] * ys[1][3] + xs[2][2] * ys[2][3] + xs[2][3] * ys[3][3],
xs[3][0] * ys[0][0] + xs[3][1] * ys[1][0] + xs[3][2] * ys[2][0] + xs[3][3] * ys[3][0],
xs[3][0] * ys[0][1] + xs[3][1] * ys[1][1] + xs[3][2] * ys[2][1] + xs[3][3] * ys[3][1],
xs[3][0] * ys[0][2] + xs[3][1] * ys[1][2] + xs[3][2] * ys[2][2] + xs[3][3] * ys[3][2],
xs[3][0] * ys[0][3] + xs[3][1] * ys[1][3] + xs[3][2] * ys[2][3] + xs[3][3] * ys[3][3]};
template < typename T, std::size_t Size >
[[nodiscard]] constexpr mat<T, Size> operator*(const mat<T, Size>& xs, const mat<T, Size>& ys) {
return map_join([&ys](const vec<T, Size>& x){
return x * ys;
}, xs);
}
// operator*=
@@ -283,17 +304,17 @@ namespace vmath_hpp
template < typename T, std::size_t Size >
[[nodiscard]] constexpr mat<T, Size> operator/(const mat<T, Size>& xs, T y) {
return map([y](const vec<T, Size>& x){ return x / y; }, xs);
return map_join([y](const vec<T, Size>& x){ return x / y; }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr mat<T, Size> operator/(T x, const mat<T, Size>& ys) {
return map([x](const vec<T, Size>& y){ return x / y; }, ys);
return map_join([x](const vec<T, Size>& y){ return x / y; }, ys);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr mat<T, Size> operator/(const mat<T, Size>& xs, const mat<T, Size>& ys) {
return zip([](const vec<T, Size>& x, const vec<T, Size>& y){ return x / y; }, xs, ys);
return map_join([](const vec<T, Size>& x, const vec<T, Size>& y){ return x / y; }, xs, ys);
}
// operator/=
@@ -312,14 +333,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([](bool acc, const vec<T, Size>& x, const vec<T, Size>& y){
return fold_join([](bool acc, const vec<T, Size>& x, const vec<T, Size>& y){
return acc && (x == y);
}, true, xs, ys);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr bool operator!=(const mat<T, Size>& xs, const mat<T, Size>& ys) {
return fold([](bool acc, const vec<T, Size>& x, const vec<T, Size>& y){
return fold_join([](bool acc, const vec<T, Size>& x, const vec<T, Size>& y){
return acc || (x != y);
}, false, xs, ys);
}

View File

@@ -151,13 +151,18 @@ namespace vmath_hpp
using self_type = vec;
using base_type = detail::vec_base<T, Size>;
public:
using value_type = T;
using component_type = T;
using pointer = value_type*;
using const_pointer = const value_type*;
using pointer = component_type*;
using const_pointer = const component_type*;
using reference = value_type&;
using const_reference = const value_type&;
using reference = component_type&;
using const_reference = const component_type&;
using iterator = pointer;
using const_iterator = const_pointer;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
static constexpr std::size_t size = Size;
public:
@@ -175,6 +180,29 @@ namespace vmath_hpp
}
}
[[nodiscard]] iterator begin() noexcept { return iterator(data()); }
[[nodiscard]] const_iterator begin() const noexcept { return const_iterator(data()); }
[[nodiscard]] iterator end() noexcept { return iterator(data() + Size); }
[[nodiscard]] const_iterator end() const noexcept { return const_iterator(data() + Size); }
[[nodiscard]] reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
[[nodiscard]] const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); }
[[nodiscard]] reverse_iterator rend() noexcept { return reverse_iterator(begin()); }
[[nodiscard]] const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); }
[[nodiscard]] const_iterator cbegin() const noexcept { return begin(); }
[[nodiscard]] const_iterator cend() const noexcept { return end(); }
[[nodiscard]] const_reverse_iterator crbegin() const noexcept { return rbegin(); }
[[nodiscard]] const_reverse_iterator crend() const noexcept { return rend(); }
[[nodiscard]] pointer data() noexcept {
return &(*this)[0];
}
[[nodiscard]] const_pointer data() const noexcept {
return &(*this)[0];
}
[[nodiscard]] constexpr reference at(std::size_t index) {
if ( index >= Size ) {
throw std::out_of_range("vec::at");
@@ -189,6 +217,50 @@ namespace vmath_hpp
return (*this)[index];
}
};
}
namespace vmath_hpp
{
// vec2
template < typename T >
vec(T, T) -> vec<T, 2>;
// vec3
template < typename T >
vec(T, T, T) -> vec<T, 3>;
template < typename T >
vec(const vec<T, 2>&, T) -> vec<T, 3>;
template < typename T >
vec(T, const vec<T, 2>&) -> vec<T, 3>;
// vec4
template < typename T >
vec(T, T, T, T) -> vec<T, 4>;
template < typename T >
vec(const vec<T, 2>&, T, T) -> vec<T, 4>;
template < typename T >
vec(T, const vec<T, 2>&, T) -> vec<T, 4>;
template < typename T >
vec(T, T, const vec<T, 2>&) -> vec<T, 4>;
template < typename T >
vec(const vec<T, 2>&, const vec<T, 2>&) -> vec<T, 4>;
template < typename T >
vec(const vec<T, 3>&, T) -> vec<T, 4>;
template < typename T >
vec(T, const vec<T, 3>&) -> vec<T, 4>;
// swap
template < typename T, std::size_t Size >
void swap(vec<T, Size>& l, vec<T, Size>& r) noexcept(noexcept(l.swap(r))) {

View File

@@ -11,94 +11,151 @@
#include "vmath_fun.hpp"
#include "vmath_vec.hpp"
namespace vmath_hpp::detail::impl
{
template < typename A, std::size_t Size, typename F, std::size_t... Is >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto map_join_impl(
F&& f,
const vec<A, Size>& a,
std::index_sequence<Is...>
) -> vec<decltype(f(
std::declval<A>())), Size>
{
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 map_join_impl(
F&& f,
const vec<A, Size>& a,
const vec<B, Size>& b,
std::index_sequence<Is...>
) -> vec<decltype(f(
std::declval<A>(),
std::declval<B>())), Size>
{
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
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...>
) -> vec<decltype(f(
std::declval<A>(),
std::declval<B>(),
std::declval<C>())), Size>
{
return { f(a[Is], b[Is], c[Is])... };
}
template < typename A, typename B, std::size_t Size, typename F, std::size_t... Is >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto fold_join_impl(
F&& f,
A init,
const vec<B, Size>& b,
std::index_sequence<Is...>
) -> A {
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
auto fold_join_impl(
F&& f,
A init,
const vec<B, Size>& b,
const vec<C, Size>& c,
std::index_sequence<Is...>
) -> A {
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
auto fold1_join_impl(
F&& f,
const vec<A, Size>& a,
std::index_sequence<I, Is...>
) -> A {
A init = a[I];
return ((init = f(std::move(init), a[Is])), ...);
}
}
namespace vmath_hpp::detail
{
namespace impl
{
template < typename A, std::size_t Size, typename F, std::size_t... Is >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto map_impl(F&& f, const vec<A, Size>& a, std::index_sequence<Is...>)
-> vec<std::invoke_result_t<F, A>, Size>
{
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 zip_impl(F&& f, const vec<A, Size>& a, const vec<B, Size>& b, std::index_sequence<Is...>)
-> vec<std::invoke_result_t<F, A, B>, Size>
{
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
auto zip_impl(F&& f, const vec<A, Size>& a, const vec<B, Size>& b, const vec<C, Size>& c, std::index_sequence<Is...>)
-> vec<std::invoke_result_t<F, A, B, C>, Size>
{
return { f(a[Is], b[Is], c[Is])... };
}
template < typename A, typename B, std::size_t Size, typename F, std::size_t... Is >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
A fold_impl(F&& f, A init, const vec<B, Size>& b, std::index_sequence<Is...>) {
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_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_impl(F&& f, const vec<A, Size>& a, std::index_sequence<I, Is...>) {
A init = a[I];
return ((init = f(std::move(init), a[Is])), ...);
}
}
template < typename A, std::size_t Size, typename F >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto map(F&& f, const vec<A, Size>& a)
-> vec<std::invoke_result_t<F, A>, Size>
{
return impl::map_impl(std::forward<F>(f), a, std::make_index_sequence<Size>{});
auto map_join(
F&& f,
const vec<A, Size>& a
) {
return impl::map_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 zip(F&& f, const vec<A, Size>& a, const vec<B, Size>& b)
-> vec<std::invoke_result_t<F, A, B>, Size>
{
return impl::zip_impl(std::forward<F>(f), a, b, std::make_index_sequence<Size>{});
auto map_join(
F&& f,
const vec<A, Size>& a,
const vec<B, Size>& b
) {
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 zip(F&& f, const vec<A, Size>& a, const vec<B, Size>& b, const vec<C, Size>& c)
-> vec<std::invoke_result_t<F, A, B, C>, Size>
{
return impl::zip_impl(std::forward<F>(f), a, b, c, std::make_index_sequence<Size>{});
auto map_join(
F&& f,
const vec<A, Size>& a,
const vec<B, Size>& b,
const vec<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
A fold(F&& f, A init, const vec<B, Size>& b) {
return impl::fold_impl(std::forward<F>(f), std::move(init), b, std::make_index_sequence<Size>{});
auto fold_join(
F&& f,
A init,
const vec<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 >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
A fold(F&& f, A init, const vec<B, Size>& b, const vec<C, Size>& c) {
return impl::fold_impl(std::forward<F>(f), std::move(init), b, c, std::make_index_sequence<Size>{});
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
A fold1(F&& f, const vec<A, Size>& a) {
return impl::fold1_impl(std::forward<F>(f), a, std::make_index_sequence<Size>{});
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>{});
}
}
@@ -112,24 +169,24 @@ namespace vmath_hpp
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> operator-(const vec<T, Size>& xs) {
return map([](T x){ return -x; }, xs);
return map_join([](T x){ return -x; }, xs);
}
// operator+
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> operator+(const vec<T, Size>& xs, T y) {
return map([y](T x){ return x + y; }, xs);
return map_join([y](T x){ return x + y; }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> operator+(T x, const vec<T, Size>& ys) {
return map([x](T y){ return x + y; }, ys);
return map_join([x](T y){ return x + y; }, ys);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> operator+(const vec<T, Size>& xs, const vec<T, Size>& ys) {
return zip([](T x, T y){ return x + y; }, xs, ys);
return map_join([](T x, T y){ return x + y; }, xs, ys);
}
// operator+=
@@ -148,17 +205,17 @@ namespace vmath_hpp
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> operator-(const vec<T, Size>& xs, T y) {
return map([y](T x){ return x - y; }, xs);
return map_join([y](T x){ return x - y; }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> operator-(T x, const vec<T, Size>& ys) {
return map([x](T y){ return x - y; }, ys);
return map_join([x](T y){ return x - y; }, ys);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> operator-(const vec<T, Size>& xs, const vec<T, Size>& ys) {
return zip([](T x, T y){ return x - y; }, xs, ys);
return map_join([](T x, T y){ return x - y; }, xs, ys);
}
// operator-=
@@ -177,17 +234,17 @@ namespace vmath_hpp
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> operator*(const vec<T, Size>& xs, T y) {
return map([y](T x){ return x * y; }, xs);
return map_join([y](T x){ return x * y; }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> operator*(T x, const vec<T, Size>& ys) {
return map([x](T y){ return x * y; }, ys);
return map_join([x](T y){ return x * y; }, ys);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> operator*(const vec<T, Size>& xs, const vec<T, Size>& ys) {
return zip([](T x, T y){ return x * y; }, xs, ys);
return map_join([](T x, T y){ return x * y; }, xs, ys);
}
// operator*=
@@ -206,17 +263,17 @@ namespace vmath_hpp
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> operator/(const vec<T, Size>& xs, T y) {
return map([y](T x){ return x / y; }, xs);
return map_join([y](T x){ return x / y; }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> operator/(T x, const vec<T, Size>& ys) {
return map([x](T y){ return x / y; }, ys);
return map_join([x](T y){ return x / y; }, ys);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> operator/(const vec<T, Size>& xs, const vec<T, Size>& ys) {
return zip([](T x, T y){ return x / y; }, xs, ys);
return map_join([](T x, T y){ return x / y; }, xs, ys);
}
// operator/=
@@ -235,14 +292,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([](bool acc, T x, T y){
return fold_join([](bool acc, T x, T y){
return acc && (x == y);
}, true, xs, ys);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr bool operator!=(const vec<T, Size>& xs, const vec<T, Size>& ys) {
return fold([](bool acc, T x, T y){
return fold_join([](bool acc, T x, T y){
return acc || (x != y);
}, false, xs, ys);
}
@@ -271,77 +328,77 @@ namespace vmath_hpp
{
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> radians(const vec<T, Size>& degrees) {
return map([](T x) { return radians(x); }, degrees);
return map_join([](T x) { return radians(x); }, degrees);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> degrees(const vec<T, Size>& radians) {
return map([](T x) { return degrees(x); }, radians);
return map_join([](T x) { return degrees(x); }, radians);
}
template < typename T, std::size_t Size >
[[nodiscard]] vec<T, Size> sin(const vec<T, Size>& xs) {
return map([](T x) { return sin(x); }, xs);
return map_join([](T x) { return sin(x); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] vec<T, Size> cos(const vec<T, Size>& xs) {
return map([](T x) { return cos(x); }, xs);
return map_join([](T x) { return cos(x); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] vec<T, Size> tan(const vec<T, Size>& xs) {
return map([](T x) { return tan(x); }, xs);
return map_join([](T x) { return tan(x); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] vec<T, Size> asin(const vec<T, Size>& xs) {
return map([](T x) { return asin(x); }, xs);
return map_join([](T x) { return asin(x); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] vec<T, Size> acos(const vec<T, Size>& xs) {
return map([](T x) { return acos(x); }, xs);
return map_join([](T x) { return acos(x); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] vec<T, Size> atan(const vec<T, Size>& xs) {
return map([](T x) { return atan(x); }, xs);
return map_join([](T x) { return atan(x); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] vec<T, Size> atan2(const vec<T, Size>& ys, const vec<T, Size>& xs) {
return zip([](T y, T x) { return atan2(y, x); }, ys, xs);
return map_join([](T y, T x) { return atan2(y, x); }, ys, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] vec<T, Size> sinh(const vec<T, Size>& xs) {
return map([](T x) { return sinh(x); }, xs);
return map_join([](T x) { return sinh(x); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] vec<T, Size> cosh(const vec<T, Size>& xs) {
return map([](T x) { return cosh(x); }, xs);
return map_join([](T x) { return cosh(x); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] vec<T, Size> tanh(const vec<T, Size>& xs) {
return map([](T x) { return tanh(x); }, xs);
return map_join([](T x) { return tanh(x); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] vec<T, Size> asinh(const vec<T, Size>& xs) {
return map([](T x) { return asinh(x); }, xs);
return map_join([](T x) { return asinh(x); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] vec<T, Size> acosh(const vec<T, Size>& xs) {
return map([](T x) { return acosh(x); }, xs);
return map_join([](T x) { return acosh(x); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] vec<T, Size> atanh(const vec<T, Size>& xs) {
return map([](T x) { return atanh(x); }, xs);
return map_join([](T x) { return atanh(x); }, xs);
}
}
@@ -353,37 +410,37 @@ namespace vmath_hpp
{
template < typename T, std::size_t Size >
[[nodiscard]] vec<T, Size> pow(const vec<T, Size>& xs, const vec<T, Size>& ys) {
return zip([](T x, T y) { return pow(x, y); }, xs, ys);
return map_join([](T x, T y) { return pow(x, y); }, xs, ys);
}
template < typename T, std::size_t Size >
[[nodiscard]] vec<T, Size> exp(const vec<T, Size>& xs) {
return map([](T x) { return exp(x); }, xs);
return map_join([](T x) { return exp(x); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] vec<T, Size> log(const vec<T, Size>& xs) {
return map([](T x) { return log(x); }, xs);
return map_join([](T x) { return log(x); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] vec<T, Size> exp2(const vec<T, Size>& xs) {
return map([](T x) { return exp2(x); }, xs);
return map_join([](T x) { return exp2(x); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] vec<T, Size> log2(const vec<T, Size>& xs) {
return map([](T x) { return log2(x); }, xs);
return map_join([](T x) { return log2(x); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] vec<T, Size> sqrt(const vec<T, Size>& xs) {
return map([](T x) { return sqrt(x); }, xs);
return map_join([](T x) { return sqrt(x); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] vec<T, Size> rsqrt(const vec<T, Size>& xs) {
return map([](T x) { return rsqrt(x); }, xs);
return map_join([](T x) { return rsqrt(x); }, xs);
}
}
@@ -395,52 +452,52 @@ namespace vmath_hpp
{
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> abs(const vec<T, Size>& xs) {
return map([](T x) { return abs(x); }, xs);
return map_join([](T x) { return abs(x); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> sign(const vec<T, Size>& xs) {
return map([](T x) { return sign(x); }, xs);
return map_join([](T x) { return sign(x); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> reciprocal(const vec<T, Size>& xs) {
return map([](T x) { return reciprocal(x); }, xs);
return map_join([](T x) { return reciprocal(x); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] vec<T, Size> floor(const vec<T, Size>& xs) {
return map([](T x) { return floor(x); }, xs);
return map_join([](T x) { return floor(x); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] vec<T, Size> trunc(const vec<T, Size>& xs) {
return map([](T x) { return trunc(x); }, xs);
return map_join([](T x) { return trunc(x); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] vec<T, Size> round(const vec<T, Size>& xs) {
return map([](T x) { return round(x); }, xs);
return map_join([](T x) { return round(x); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] vec<T, Size> ceil(const vec<T, Size>& xs) {
return map([](T x) { return ceil(x); }, xs);
return map_join([](T x) { return ceil(x); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] vec<T, Size> fract(const vec<T, Size>& xs) {
return map([](T x) { return fract(x); }, xs);
return map_join([](T x) { return fract(x); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] vec<T, Size> fmod(const vec<T, Size>& xs, T y) {
return map([y](T x) { return fmod(x, y); }, xs);
return map_join([y](T x) { return fmod(x, y); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] vec<T, Size> fmod(const vec<T, Size>& xs, const vec<T, Size>& ys) {
return zip([](T x, T y) { return fmod(x, y); }, xs, ys);
return map_join([](T x, T y) { return fmod(x, y); }, xs, ys);
}
namespace impl
@@ -459,97 +516,97 @@ namespace vmath_hpp
template < typename T, std::size_t Size >
[[nodiscard]] constexpr T min(const vec<T, Size>& xs) {
return fold1([](T acc, T x){ return min(acc, x); }, xs);
return fold1_join([](T acc, T x){ return min(acc, x); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> min(const vec<T, Size>& xs, T y) {
return map([y](T x) { return min(x, y); }, xs);
return map_join([y](T x) { return min(x, y); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> min(const vec<T, Size>& xs, const vec<T, Size>& ys) {
return zip([](T x, T y) { return min(x, y); }, xs, ys);
return map_join([](T x, T y) { return min(x, y); }, xs, ys);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr T max(const vec<T, Size>& xs) {
return fold1([](T acc, T x){ return max(acc, x); }, xs);
return fold1_join([](T acc, T x){ return max(acc, x); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> max(const vec<T, Size>& xs, T y) {
return map([y](T x) { return max(x, y); }, xs);
return map_join([y](T x) { return max(x, y); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> max(const vec<T, Size>& xs, const vec<T, Size>& ys) {
return zip([](T x, T y) { return max(x, y); }, xs, ys);
return map_join([](T x, T y) { return max(x, y); }, xs, ys);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> clamp(const vec<T, Size>& xs, T min_x, T max_x) {
return map([min_x, max_x](T x) { return clamp(x, min_x, max_x); }, xs);
return map_join([min_x, max_x](T x) { return clamp(x, min_x, max_x); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> clamp(const vec<T, Size>& xs, const vec<T, Size>& min_xs, const vec<T, Size>& max_xs) {
return zip([](T x, T min_x, T max_x) { return clamp(x, min_x, max_x); }, xs, min_xs, max_xs);
return map_join([](T x, T min_x, T max_x) { return clamp(x, min_x, max_x); }, xs, min_xs, max_xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> saturate(const vec<T, Size>& xs) {
return map([](T x) { return saturate(x); }, xs);
return map_join([](T x) { return saturate(x); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> lerp(const vec<T, Size>& xs, const vec<T, Size>& ys, T a) {
return zip([a](T x, T y) { return lerp(x, y, a); }, xs, ys);
return map_join([a](T x, T y) { return lerp(x, y, a); }, xs, ys);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> lerp(const vec<T, Size>& xs, const vec<T, Size>& ys, const vec<T, Size>& as) {
return zip([](T x, T y, T a) { return lerp(x, y, a); }, xs, ys, as);
return map_join([](T x, T y, T a) { return lerp(x, y, a); }, xs, ys, as);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> step(T edge, const vec<T, Size>& xs) {
return map([edge](T x) { return step(edge, x); }, xs);
return map_join([edge](T x) { return step(edge, x); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> step(const vec<T, Size>& edges, const vec<T, Size>& xs) {
return zip([](T edge, T x) { return step(edge, x); }, edges, xs);
return map_join([](T edge, T x) { return step(edge, x); }, edges, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> smoothstep(T edge0, T edge1, const vec<T, Size>& xs) {
return map([edge0, edge1](T x) { return smoothstep(edge0, edge1, x); }, xs);
return map_join([edge0, edge1](T x) { return smoothstep(edge0, edge1, x); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> smoothstep(const vec<T, Size>& edges0, const vec<T, Size>& edges1, const vec<T, Size>& xs) {
return zip([](T edge0, T edge1, T x) { return smoothstep(edge0, edge1, x); }, edges0, edges1, xs);
return map_join([](T edge0, T edge1, T x) { return smoothstep(edge0, edge1, x); }, edges0, edges1, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] vec<bool, Size> isnan(const vec<T, Size>& xs) {
return map([](T x) { return isnan(x); }, xs);
return map_join([](T x) { return isnan(x); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] vec<bool, Size> isinf(const vec<T, Size>& xs) {
return map([](T x) { return isinf(x); }, xs);
return map_join([](T x) { return isinf(x); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] vec<bool, Size> isfinite(const vec<T, Size>& xs) {
return map([](T x) { return isfinite(x); }, xs);
return map_join([](T x) { return isfinite(x); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] vec<T, Size> fma(const vec<T, Size>& as, const vec<T, Size>& bs, const vec<T, Size>& cs) {
return zip([](T a, T b, T c) { return fma(a, b, c); }, as, bs, cs);
return map_join([](T a, T b, T c) { return fma(a, b, c); }, as, bs, cs);
}
namespace impl
@@ -568,7 +625,7 @@ namespace vmath_hpp
template < typename T, std::size_t Size >
[[nodiscard]] vec<T, Size> ldexp(const vec<T, Size>& xs, const vec<int, Size>& exps) {
return zip([](T x, int exp) { return ldexp(x, exp); }, xs, exps);
return map_join([](T x, int exp) { return ldexp(x, exp); }, xs, exps);
}
}
@@ -580,7 +637,7 @@ namespace vmath_hpp
{
template < typename T, std::size_t Size >
[[nodiscard]] constexpr T dot(const vec<T, Size>& xs, const vec<T, Size>& ys) {
return fold([](T acc, T x, T y){
return fold_join([](T acc, T x, T y){
return acc + (x * y);
}, T(0), xs, ys);
}
@@ -649,51 +706,51 @@ namespace vmath_hpp
{
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<bool, Size> less(const vec<T, Size>& xs, const vec<T, Size>& ys) {
return zip([](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 >
[[nodiscard]] constexpr vec<bool, Size> less_equal(const vec<T, Size>& xs, const vec<T, Size>& ys) {
return zip([](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 >
[[nodiscard]] constexpr vec<bool, Size> greater(const vec<T, Size>& xs, const vec<T, Size>& ys) {
return zip([](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 >
[[nodiscard]] constexpr vec<bool, Size> greater_equal(const vec<T, Size>& xs, const vec<T, Size>& ys) {
return zip([](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 >
[[nodiscard]] constexpr vec<bool, Size> equal_to(const vec<T, Size>& xs, const vec<T, Size>& ys) {
return zip([](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 >
[[nodiscard]] constexpr vec<bool, Size> equal_to(const vec<T, Size>& xs, const vec<T, Size>& ys, T epsilon) {
return zip([epsilon](T x, T y){ return equal_to(x, y, epsilon); }, xs, ys);
return map_join([epsilon](T x, T y){ return equal_to(x, y, epsilon); }, 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) {
return zip([](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);
}
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, T epsilon) {
return zip([epsilon](T x, T y){ return not_equal_to(x, y, epsilon); }, xs, ys);
return map_join([epsilon](T x, T y){ return not_equal_to(x, y, epsilon); }, xs, ys);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr bool any(const vec<T, Size>& xs) {
return fold([](bool acc, T x){ return acc || any(x); }, false, xs);
return fold_join([](bool acc, T x){ return acc || any(x); }, false, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr bool all(const vec<T, Size>& xs) {
return fold([](bool acc, T x){ return acc && all(x); }, true, xs);
return fold_join([](bool acc, T x){ return acc && all(x); }, true, xs);
}
}

View File

@@ -101,7 +101,7 @@ TEST_CASE("vmath/ext") {
{
constexpr auto v = cast_to<int>(float2{1.5f});
STATIC_REQUIRE(v == int2(1));
STATIC_REQUIRE(std::is_same_v<decltype(v)::value_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(v)::component_type, int>);
}
{
constexpr auto m = cast_to<int>(float2x2{1.5f});

View File

@@ -32,27 +32,27 @@ namespace
TEST_CASE("vmath/mat_fun") {
SUBCASE("detail") {
STATIC_REQUIRE(map([](const int2& x){
STATIC_REQUIRE(map_join([](const int2& x){
return x * 2;
}, int2x2{}) == int2x2(2,0,0,2));
STATIC_REQUIRE(zip([](const int2& x, const int2& y){
STATIC_REQUIRE(map_join([](const int2& x, const int2& y){
return x + y;
}, int2x2{}, int2x2{}) == int2x2(2,0,0,2));
STATIC_REQUIRE(zip([](const int2& x, const int2& y, const int2& z){
STATIC_REQUIRE(map_join([](const int2& x, const int2& y, const int2& z){
return x + y + z;
}, int2x2{}, int2x2{}, int2x2{}) == int2x2(3,0,0,3));
STATIC_REQUIRE(fold([](int acc, const int2& x){
STATIC_REQUIRE(fold_join([](int acc, const int2& x){
return acc + x.x;
}, 0, int2x2{}) == 1);
STATIC_REQUIRE(fold([](int acc, const int2& x, const int2& y){
STATIC_REQUIRE(fold_join([](int acc, const int2& x, const int2& y){
return acc + x.x + y.x;
}, 0, int2x2{}, int2x2{}) == 2);
STATIC_REQUIRE(fold1([](const int2& acc, const int2& x){
STATIC_REQUIRE(fold1_join([](const int2& acc, const int2& x){
return acc + x;
}, int2x2{}) == int2(1,1));
}

View File

@@ -24,6 +24,22 @@ TEST_CASE("vmath/mat") {
STATIC_REQUIRE(sizeof(int4x4{}) == sizeof(int) * 4 * 4);
}
SUBCASE("guides") {
STATIC_REQUIRE(mat{1,2,3,4}.size == 2);
STATIC_REQUIRE(mat{{1,2},{3,4}}.size == 2);
STATIC_REQUIRE(mat{vec{1,2},vec{3,4}}.size == 2);
STATIC_REQUIRE(mat{1,2,3,4,5,6,7,8,9}.size == 3);
STATIC_REQUIRE(mat{{1,2,3},{4,5,6},{7,8,9}}.size == 3);
STATIC_REQUIRE(mat{vec{1,2,3},vec{4,5,6},vec{7,8,9}}.size == 3);
STATIC_REQUIRE(mat{mat{1,2,3,4},vec{5,6}}.size == 3);
STATIC_REQUIRE(mat{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}.size == 4);
STATIC_REQUIRE(mat{{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}}.size == 4);
STATIC_REQUIRE(mat{vec{1,2,3,4},vec{5,6,7,8},vec{9,10,11,12},vec{13,14,15,16}}.size == 4);
STATIC_REQUIRE(mat{mat{1,2,3,4,5,6,7,8,9},vec{5,6,7}}.size == 4);
}
SUBCASE("ctors") {
{
STATIC_REQUIRE(int2x2()[0] == int2(1,0));
@@ -48,6 +64,7 @@ TEST_CASE("vmath/mat") {
{
STATIC_REQUIRE(int2x2() == int2x2(1,0,0,1));
STATIC_REQUIRE(int2x2(2) == int2x2(2,0,0,2));
STATIC_REQUIRE(int2x2(int2{2,3}) == int2x2(2,0,0,3));
STATIC_REQUIRE(int2x2(1,2,3,4) == int2x2(1,2,3,4));
STATIC_REQUIRE(int2x2({1,2},{3,4}) == int2x2(1,2,3,4));
STATIC_REQUIRE(int2x2(int2x2({1,2},{3,4})) == int2x2(1,2,3,4));
@@ -56,16 +73,20 @@ TEST_CASE("vmath/mat") {
STATIC_REQUIRE(int3x3() == int3x3(1,0,0,0,1,0,0,0,1));
STATIC_REQUIRE(int3x3(2) == int3x3(2,0,0,0,2,0,0,0,2));
STATIC_REQUIRE(int3x3(int3{2,3,4}) == int3x3(2,0,0,0,3,0,0,0,4));
STATIC_REQUIRE(int3x3(1,2,3,4,5,6,7,8,9) == int3x3(1,2,3,4,5,6,7,8,9));
STATIC_REQUIRE(int3x3({1,2,3},{4,5,6},{7,8,9}) == int3x3(1,2,3,4,5,6,7,8,9));
STATIC_REQUIRE(int3x3(int2x2({1,2},{3,4}),int2{5,6}) == int3x3(1,2,0,3,4,0,5,6,1));
STATIC_REQUIRE(int3x3(int3x3({1,2,3},{4,5,6},{7,8,9})) == int3x3(1,2,3,4,5,6,7,8,9));
STATIC_REQUIRE(int3x3(int2x2({1,2},{3,4})) == int3x3(1,2,0,3,4,0,0,0,1));
STATIC_REQUIRE(int3x3(int4x4({1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16})) == int3x3(1,2,3,5,6,7,9,10,11));
STATIC_REQUIRE(int4x4() == int4x4(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1));
STATIC_REQUIRE(int4x4(2) == int4x4(2,0,0,0,0,2,0,0,0,0,2,0,0,0,0,2));
STATIC_REQUIRE(int4x4(int4{2,3,4,5}) == int4x4(2,0,0,0,0,3,0,0,0,0,4,0,0,0,0,5));
STATIC_REQUIRE(int4x4(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16) == int4x4(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16));
STATIC_REQUIRE(int4x4({1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}) == int4x4(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16));
STATIC_REQUIRE(int4x4(int3x3({1,2,3},{4,5,6},{7,8,9}),int3{10,11,12}) == int4x4(1,2,3,0,4,5,6,0,7,8,9,0,10,11,12,1));
STATIC_REQUIRE(int4x4(int4x4({1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16})) == int4x4(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16));
STATIC_REQUIRE(int4x4(int2x2({1,2},{3,4})) == int4x4(1,2,0,0,3,4,0,0,0,0,1,0,0,0,0,1));
STATIC_REQUIRE(int4x4(int3x3({1,2,3},{4,5,6},{7,8,9})) == int4x4(1,2,3,0,4,5,6,0,7,8,9,0,0,0,0,1));
@@ -104,6 +125,99 @@ TEST_CASE("vmath/mat") {
}
}
SUBCASE("iter") {
{
int2x2 m{1,2,3,4};
REQUIRE(*m.begin() == vec{1,2});
REQUIRE(*(m.begin() + 1) == vec{3,4});
REQUIRE(*(m.end() - 1) == vec{3,4});
REQUIRE(*(m.end() - 2) == vec{1,2});
REQUIRE(m.begin() + 2 == m.end());
REQUIRE(m.end() - 2 == m.begin());
REQUIRE(*m.cbegin() == vec{1,2});
REQUIRE(*(m.cbegin() + 1) == vec{3,4});
REQUIRE(*(m.cend() - 1) == vec{3,4});
REQUIRE(*(m.cend() - 2) == vec{1,2});
REQUIRE(m.cbegin() + 2 == m.cend());
REQUIRE(m.cend() - 2 == m.cbegin());
REQUIRE(*m.rbegin() == vec{3,4});
REQUIRE(*(m.rbegin() + 1) == vec{1,2});
REQUIRE(*(m.rend() - 1) == vec{1,2});
REQUIRE(*(m.rend() - 2) == vec{3,4});
REQUIRE(m.rbegin() + 2 == m.rend());
REQUIRE(m.rend() - 2 == m.rbegin());
REQUIRE(*m.crbegin() == vec{3,4});
REQUIRE(*(m.crbegin() + 1) == vec{1,2});
REQUIRE(*(m.crend() - 1) == vec{1,2});
REQUIRE(*(m.crend() - 2) == vec{3,4});
REQUIRE(m.crbegin() + 2 == m.crend());
REQUIRE(m.crend() - 2 == m.crbegin());
*m.begin() = {5,6};
REQUIRE(m == int2x2{5,6,3,4});
*m.rbegin() = {7,8};
REQUIRE(m == int2x2{5,6,7,8});
}
{
const int2x2 m{1,2,3,4};
REQUIRE(*m.begin() == vec{1,2});
REQUIRE(*(m.begin() + 1) == vec{3,4});
REQUIRE(*(m.end() - 1) == vec{3,4});
REQUIRE(*(m.end() - 2) == vec{1,2});
REQUIRE(m.begin() + 2 == m.end());
REQUIRE(m.end() - 2 == m.begin());
REQUIRE(*m.cbegin() == vec{1,2});
REQUIRE(*(m.cbegin() + 1) == vec{3,4});
REQUIRE(*(m.cend() - 1) == vec{3,4});
REQUIRE(*(m.cend() - 2) == vec{1,2});
REQUIRE(m.cbegin() + 2 == m.cend());
REQUIRE(m.cend() - 2 == m.cbegin());
REQUIRE(*m.rbegin() == vec{3,4});
REQUIRE(*(m.rbegin() + 1) == vec{1,2});
REQUIRE(*(m.rend() - 1) == vec{1,2});
REQUIRE(*(m.rend() - 2) == vec{3,4});
REQUIRE(m.rbegin() + 2 == m.rend());
REQUIRE(m.rend() - 2 == m.rbegin());
REQUIRE(*m.crbegin() == vec{3,4});
REQUIRE(*(m.crbegin() + 1) == vec{1,2});
REQUIRE(*(m.crend() - 1) == vec{1,2});
REQUIRE(*(m.crend() - 2) == vec{3,4});
REQUIRE(m.crbegin() + 2 == m.crend());
REQUIRE(m.crend() - 2 == m.crbegin());
}
}
SUBCASE("data") {
{
int2x2 m2;
REQUIRE(m2.data() == &m2[0]);
int3x3 m3;
REQUIRE(m3.data() == &m3[0]);
int4x4 m4;
REQUIRE(m4.data() == &m4[0]);
}
{
const int2x2 m2;
REQUIRE(m2.data() == &m2[0]);
const int3x3 m3;
REQUIRE(m3.data() == &m3[0]);
const int4x4 m4;
REQUIRE(m4.data() == &m4[0]);
}
}
SUBCASE("operator[]") {
{
STATIC_REQUIRE(int2x2()[0] == int2(1,0));

View File

@@ -15,27 +15,27 @@ namespace
TEST_CASE("vmath/vec_fun") {
SUBCASE("Detail") {
STATIC_REQUIRE(map([](const int& x){
STATIC_REQUIRE(map_join([](const int& x){
return x * 2;
}, int2{1}) == int2{2});
STATIC_REQUIRE(zip([](const int& x, const int& y){
STATIC_REQUIRE(map_join([](const int& x, const int& y){
return x + y;
}, int2{1}, int2{1}) == int2{2});
STATIC_REQUIRE(zip([](const int& x, const int& y, const int& z){
STATIC_REQUIRE(map_join([](const int& x, const int& y, const int& z){
return x + y + z;
}, int2{1}, int2{1}, int2{1}) == int2(3));
STATIC_REQUIRE(fold([](int acc, const int& x){
STATIC_REQUIRE(fold_join([](int acc, const int& x){
return acc + x;
}, 0, int2{1}) == 2);
STATIC_REQUIRE(fold([](int acc, const int& x, const int& y){
STATIC_REQUIRE(fold_join([](int acc, const int& x, const int& y){
return acc + x + y;
}, 0, int2{1}, int2{1}) == 4);
STATIC_REQUIRE(fold1([](const int& acc, const int& x){
STATIC_REQUIRE(fold1_join([](const int& acc, const int& x){
return acc + x;
}, int2{1}) == 2);
}

View File

@@ -24,6 +24,22 @@ TEST_CASE("vmath/vec") {
STATIC_REQUIRE(sizeof(int4{}) == sizeof(int) * 4);
}
SUBCASE("guides") {
STATIC_REQUIRE(vec{1,2}.size == 2);
STATIC_REQUIRE(vec{1,2,3}.size == 3);
STATIC_REQUIRE(vec{{1,2},3}.size == 3);
STATIC_REQUIRE(vec{1,{2,3}}.size == 3);
STATIC_REQUIRE(vec{1,2,3,4}.size == 4);
STATIC_REQUIRE(vec{vec{1,2},3,4}.size == 4);
STATIC_REQUIRE(vec{1,vec{2,3},4}.size == 4);
STATIC_REQUIRE(vec{1,2,vec{3,4}}.size == 4);
STATIC_REQUIRE(vec{vec{1,2},vec{3,4}}.size == 4);
STATIC_REQUIRE(vec{vec{1,2,3},4}.size == 4);
STATIC_REQUIRE(vec{1,vec{2,3,4}}.size == 4);
}
SUBCASE("ctors") {
{
STATIC_REQUIRE(int2().x == 0);
@@ -102,6 +118,99 @@ TEST_CASE("vmath/vec") {
}
}
SUBCASE("iter") {
{
int2 v{1,2};
REQUIRE(*v.begin() == 1);
REQUIRE(*(v.begin() + 1) == 2);
REQUIRE(*(v.end() - 1) == 2);
REQUIRE(*(v.end() - 2) == 1);
REQUIRE(v.begin() + 2 == v.end());
REQUIRE(v.end() - 2 == v.begin());
REQUIRE(*v.cbegin() == 1);
REQUIRE(*(v.cbegin() + 1) == 2);
REQUIRE(*(v.cend() - 1) == 2);
REQUIRE(*(v.cend() - 2) == 1);
REQUIRE(v.cbegin() + 2 == v.cend());
REQUIRE(v.cend() - 2 == v.cbegin());
REQUIRE(*v.rbegin() == 2);
REQUIRE(*(v.rbegin() + 1) == 1);
REQUIRE(*(v.rend() - 1) == 1);
REQUIRE(*(v.rend() - 2) == 2);
REQUIRE(v.rbegin() + 2 == v.rend());
REQUIRE(v.rend() - 2 == v.rbegin());
REQUIRE(*v.crbegin() == 2);
REQUIRE(*(v.crbegin() + 1) == 1);
REQUIRE(*(v.crend() - 1) == 1);
REQUIRE(*(v.crend() - 2) == 2);
REQUIRE(v.crbegin() + 2 == v.crend());
REQUIRE(v.crend() - 2 == v.crbegin());
*v.begin() = 3;
REQUIRE(v == int2{3,2});
*v.rbegin() = 4;
REQUIRE(v == int2{3,4});
}
{
const int2 v{1,2};
REQUIRE(*v.begin() == 1);
REQUIRE(*(v.begin() + 1) == 2);
REQUIRE(*(v.end() - 1) == 2);
REQUIRE(*(v.end() - 2) == 1);
REQUIRE(v.begin() + 2 == v.end());
REQUIRE(v.end() - 2 == v.begin());
REQUIRE(*v.cbegin() == 1);
REQUIRE(*(v.cbegin() + 1) == 2);
REQUIRE(*(v.cend() - 1) == 2);
REQUIRE(*(v.cend() - 2) == 1);
REQUIRE(v.cbegin() + 2 == v.cend());
REQUIRE(v.cend() - 2 == v.cbegin());
REQUIRE(*v.rbegin() == 2);
REQUIRE(*(v.rbegin() + 1) == 1);
REQUIRE(*(v.rend() - 1) == 1);
REQUIRE(*(v.rend() - 2) == 2);
REQUIRE(v.rbegin() + 2 == v.rend());
REQUIRE(v.rend() - 2 == v.rbegin());
REQUIRE(*v.crbegin() == 2);
REQUIRE(*(v.crbegin() + 1) == 1);
REQUIRE(*(v.crend() - 1) == 1);
REQUIRE(*(v.crend() - 2) == 2);
REQUIRE(v.crbegin() + 2 == v.crend());
REQUIRE(v.crend() - 2 == v.crbegin());
}
}
SUBCASE("data") {
{
int2 i2;
REQUIRE(i2.data() == &i2[0]);
int3 i3;
REQUIRE(i3.data() == &i3[0]);
int4 i4;
REQUIRE(i4.data() == &i4[0]);
}
{
const int2 i2;
REQUIRE(i2.data() == &i2[0]);
const int3 i3;
REQUIRE(i3.data() == &i3[0]);
const int4 i4;
REQUIRE(i4.data() == &i4[0]);
}
}
SUBCASE("operator[]") {
{
STATIC_REQUIRE(int2(1,2).x == 1);