nngn
Loading...
Searching...
No Matches
vec.h
Go to the documentation of this file.
1#ifndef NNGN_MATH_VEC_H
2#define NNGN_MATH_VEC_H
3
4#include <cstddef>
5#include <cstring>
6#include <functional>
7#include <numeric>
8#include <utility>
9
10#include "utils/concepts.h"
11#include "utils/utils.h"
12
13namespace nngn {
14
15template<typename T, std::size_t N>
16struct vec_type;
17
18template<typename T, std::size_t N>
20
21template<template<typename> typename CRTP, typename T, std::size_t N>
22struct vec {
23 using type = T;
24 static constexpr std::size_t n_dim = N;
25 template<typename R = T, typename F, typename ...Args>
26 static constexpr CRTP<R> map(F f, Args &&...args);
27 template<typename R = T, typename F, std::size_t ...I>
28 static constexpr CRTP<R> map_impl(
29 F f, std::index_sequence<I...>, const vec &v);
30 template<typename R = T, typename F, std::size_t ...I>
31 static constexpr CRTP<R> map_impl(
32 F f, std::index_sequence<I...>, T t, const vec &v0);
33 template<typename R = T, typename F, std::size_t ...I>
34 static constexpr CRTP<R> map_impl(
35 F f, std::index_sequence<I...>, const vec &v0, T t);
36 template<typename R = T, typename F, std::size_t ...I>
37 static constexpr CRTP<R> map_impl(
38 F f, std::index_sequence<I...>, const vec &v0, const vec &v1);
39 template<typename U> explicit constexpr operator CRTP<U>(void) const;
40 constexpr vec &operator=(const CRTP<T> &v);
41 constexpr T &operator[](std::size_t i);
42 constexpr const T &operator[](std::size_t i) const;
43 constexpr CRTP<T> operator-(void) const;
44 constexpr CRTP<T> &operator+=(T t);
45 constexpr CRTP<T> &operator-=(T t);
46 constexpr CRTP<T> &operator*=(T t);
47 constexpr CRTP<T> &operator/=(T t);
48 constexpr CRTP<T> &operator+=(const CRTP<T> &v);
49 constexpr CRTP<T> &operator-=(const CRTP<T> &v);
50 constexpr CRTP<T> &operator*=(const CRTP<T> &v);
51 constexpr CRTP<T> &operator/=(const CRTP<T> &v);
52 template<std::size_t I> constexpr T &get(void);
53 template<std::size_t I> constexpr const T &get(void) const;
54 constexpr T *data(void);
55 constexpr const T *data(void) const;
56 constexpr auto as_tuple(void) const;
57};
58
59template<template<typename> typename T, typename U>
60concept vector = derived_from<T<U>, vec<T, U, T<U>::n_dim>>;
61
62template<typename T> using vector_type = typename T::type;
63
64template<template<typename> typename CRTP, typename T, std::size_t N>
65template<typename R, typename F, typename ...Args>
66inline constexpr CRTP<R> vec<CRTP, T, N>::map(F f, Args &&...args) {
67 return vec::map_impl<R>(f, std::make_index_sequence<N>{}, FWD(args)...);
68}
69
70template<template<typename> typename CRTP, typename T, std::size_t N>
71template<typename R, typename F, std::size_t ...I>
72inline constexpr CRTP<R> vec<CRTP, T, N>::map_impl(
73 F f, std::index_sequence<I...>, const vec &v)
74{
75 return {static_cast<R>(f(v.get<I>()))...};
76}
77
78template<template<typename> typename CRTP, typename T, std::size_t N>
79template<typename R, typename F, std::size_t ...I>
80inline constexpr CRTP<R> vec<CRTP, T, N>::map_impl(
81 F f, std::index_sequence<I...>, T t, const vec &v)
82{
83 return {static_cast<R>(f(t, v.get<I>()))...};
84}
85
86template<template<typename> typename CRTP, typename T, std::size_t N>
87template<typename R, typename F, std::size_t ...I>
88inline constexpr CRTP<R> vec<CRTP, T, N>::map_impl(
89 F f, std::index_sequence<I...>, const vec &v, T t)
90{
91 return {static_cast<R>(f(v.get<I>(), t))...};
92}
93
94template<template<typename> typename CRTP, typename T, std::size_t N>
95template<typename R, typename F, std::size_t ...I>
96inline constexpr CRTP<R> vec<CRTP, T, N>::map_impl(
97 F f, std::index_sequence<I...>, const vec &v0, const vec &v1)
98{
99 return {static_cast<R>(f(v0.get<I>(), v1.get<I>()))...};
100}
101
102template<template<typename> typename CRTP, typename T, std::size_t N>
103template<typename U>
104inline constexpr vec<CRTP, T, N>::operator CRTP<U>(void) const {
105 return vec::map<U>([](auto x) { return static_cast<U>(x); }, *this);
106}
107
108template<template<typename> typename CRTP, typename T, std::size_t N>
109inline constexpr vec<CRTP, T, N> &vec<CRTP, T, N>::operator=(const CRTP<T> &v) {
110 std::memcpy(this, &v, sizeof(CRTP<T>)); return *this;
111}
112
113template<template<typename> typename CRTP, typename T, std::size_t N>
114inline constexpr const T &vec<CRTP, T, N>::operator[](std::size_t i) const {
115 return this->data()[i];
116}
117
118template<template<typename> typename CRTP, typename T, std::size_t N>
119inline constexpr T &vec<CRTP, T, N>::operator[](std::size_t i) {
120 return const_cast<T&>(static_cast<const vec&>(*this)[i]);
121}
122
123template<template<typename> typename CRTP, typename T, std::size_t N>
124inline constexpr CRTP<T> vec<CRTP, T, N>::operator-(void) const {
125 return vec::map(std::negate<>(), *this);
126}
127
128template<template<typename> typename CRTP, typename T, std::size_t N>
129inline constexpr CRTP<T> &vec<CRTP, T, N>::operator+=(T t) {
130 auto &d = static_cast<CRTP<T>&>(*this); return d = d + t;
131}
132
133template<template<typename> typename CRTP, typename T, std::size_t N>
134inline constexpr CRTP<T> &vec<CRTP, T, N>::operator-=(T t) {
135 auto &d = static_cast<CRTP<T>&>(*this); return d = d - t;
136}
137
138template<template<typename> typename CRTP, typename T, std::size_t N>
139inline constexpr CRTP<T> &vec<CRTP, T, N>::operator*=(T t) {
140 auto &d = static_cast<CRTP<T>&>(*this); return d = d * t;
141}
142
143template<template<typename> typename CRTP, typename T, std::size_t N>
144inline constexpr CRTP<T> &vec<CRTP, T, N>::operator/=(T t) {
145 auto &d = static_cast<CRTP<T>&>(*this); return d = d / t;
146}
147
148template<template<typename> typename CRTP, typename T, std::size_t N>
149inline constexpr CRTP<T> &vec<CRTP, T, N>::operator+=(const CRTP<T> &v) {
150 auto &d = static_cast<CRTP<T>&>(*this); return d = d + v;
151}
152
153template<template<typename> typename CRTP, typename T, std::size_t N>
154inline constexpr CRTP<T> &vec<CRTP, T, N>::operator-=(const CRTP<T> &v) {
155 auto &d = static_cast<CRTP<T>&>(*this); return d = d - v;
156}
157
158template<template<typename> typename CRTP, typename T, std::size_t N>
159inline constexpr CRTP<T> &vec<CRTP, T, N>::operator*=(const CRTP<T> &v) {
160 auto &d = static_cast<CRTP<T>&>(*this); return d = d * v;
161}
162
163template<template<typename> typename CRTP, typename T, std::size_t N>
164inline constexpr CRTP<T> &vec<CRTP, T, N>::operator/=(const CRTP<T> &v) {
165 auto &d = static_cast<CRTP<T>&>(*this); return d = d / v;
166}
167
168template<template<typename> typename CRTP, typename T, std::size_t N>
169template<std::size_t I> constexpr const T &vec<CRTP, T, N>::get(void) const {
170 static_assert(I < N);
171 auto *p = static_cast<const CRTP<T>*>(this);
172 if constexpr(I == 0)
173 return p->x;
174 else if constexpr(I == 1)
175 return p->y;
176 else if constexpr(I == 2)
177 return p->z;
178 else if constexpr(I == 3)
179 return p->w;
180}
181
182template<template<typename> typename CRTP, typename T, std::size_t N>
183template<std::size_t I>
184constexpr T &vec<CRTP, T, N>::get(void) {
185 return const_cast<T&>(static_cast<const vec*>(this)->get<I>());
186}
187
188template<template<typename> typename CRTP, typename T, std::size_t N>
189constexpr auto vec<CRTP, T, N>::as_tuple(void) const {
190 return [this]<std::size_t ...I>(std::index_sequence<I...>) {
191 return std::tuple{static_cast<const CRTP<T>&>(*this)[I]...};
192 }(std::make_index_sequence<N>());
193}
194
195template<template<typename> typename CRTP, typename T, std::size_t N>
196constexpr T *vec<CRTP, T, N>::data(void) {
197 return &static_cast<CRTP<T>&>(*this).x;
198}
199
200template<template<typename> typename CRTP, typename T, std::size_t N>
201constexpr const T *vec<CRTP, T, N>::data(void) const {
202 return &static_cast<const CRTP<T>&>(*this).x;
203}
204
205template<template<typename> typename T, typename R>
206requires vector<T, R>
207inline constexpr const R *begin(const T<R> &v) { return &v[0]; }
208
209template<template<typename> typename T, typename R>
210requires vector<T, R>
211inline constexpr const R *end(const T<R> &v) { return &v[T<R>::n_dim]; }
212
213template<template<typename> typename T, typename R>
214requires vector<T, R>
215inline constexpr R *begin(T<R> &v) { return &v[0]; }
216
217template<template<typename> typename T, typename R>
218requires vector<T, R>
219inline constexpr R *end(T<R> &v) { return &v[T<R>::n_dim]; }
220
221template<template<typename> typename T, typename R>
222requires vector<T, R>
223constexpr bool operator==(const T<R> &v0, const T<R> &v1) {
224 return std::equal(begin(v0), end(v0), begin(v1));
225}
226
227template<template<typename> typename T, typename R>
228requires vector<T, R>
229constexpr bool operator!=(const T<R> &v0, const T<R> &v1) {
230 return !(v0 == v1);
231}
232
233template<template<typename> typename T, typename R>
234requires vector<T, R>
235inline constexpr T<R> operator+(R s, const T<R> &v) {
236 return T<R>::map(std::plus<>(), s, v);
237}
238
239template<template<typename> typename T, typename R>
240requires vector<T, R>
241inline constexpr T<R> operator-(R s, const T<R> &v) {
242 return T<R>::map(std::minus<>(), s, v);
243}
244
245template<template<typename> typename T, typename R>
246requires vector<T, R>
247inline constexpr T<R> operator*(R s, const T<R> &v) {
248 return T<R>::map(std::multiplies<>(), s, v);
249}
250
251template<template<typename> typename T, typename R>
252requires vector<T, R>
253inline constexpr T<R> operator/(R s, const T<R> &v) {
254 return T<R>::map(std::divides<>(), s, v);
255}
256
257template<template<typename> typename T, typename R>
258requires vector<T, R>
259inline constexpr T<R> operator+(const T<R> &v, R s) {
260 return T<R>::map(std::plus<>(), v, s);
261}
262
263template<template<typename> typename T, typename R>
264requires vector<T, R>
265inline constexpr T<R> operator-(const T<R> &v, R s) {
266 return T<R>::map(std::minus<>(), v, s);
267}
268
269template<template<typename> typename T, typename R>
270requires vector<T, R>
271inline constexpr T<R> operator*(const T<R> &v, R s) {
272 return T<R>::map(std::multiplies<>(), v, s);
273}
274
275template<template<typename> typename T, typename R>
276requires vector<T, R>
277inline constexpr T<R> operator/(const T<R> &v, R s) {
278 return T<R>::map(std::divides<>(), v, s);
279}
280
281template<template<typename> typename T, typename R>
282requires vector<T, R>
283inline constexpr T<R> operator+(const T<R> &v0, const T<R> &v1) {
284 return T<R>::map(std::plus<>(), v0, v1);
285}
286
287template<template<typename> typename T, typename R>
288requires vector<T, R>
289inline constexpr T<R> operator-(const T<R> &v0, const T<R> &v1) {
290 return T<R>::map(std::minus<>(), v0, v1);
291}
292
293template<template<typename> typename T, typename R>
294requires vector<T, R>
295inline constexpr T<R> operator*(const T<R> &v0, const T<R> &v1) {
296 return T<R>::map(std::multiplies<>(), v0, v1);
297}
298
299template<template<typename> typename T, typename R>
300requires vector<T, R>
301inline constexpr T<R> operator/(const T<R> &v0, const T<R> &v1) {
302 return T<R>::map(std::divides<>(), v0, v1);
303}
304
305}
306
307#endif
Definition: concepts.h:17
Definition: vec.h:60
end
Definition: entities.lua:9
Definition: debug.h:45
constexpr const R * begin(const T< R > &v)
Definition: vec.h:207
constexpr T< R > operator-(R s, const T< R > &v)
Definition: vec.h:241
constexpr bool operator!=(const T< R > &v0, const T< R > &v1)
Definition: vec.h:229
constexpr T< R > operator/(R s, const T< R > &v)
Definition: vec.h:253
typename vec_type< T, N >::type vec_type_t
Definition: vec.h:19
typename T::type vector_type
Definition: vec.h:62
constexpr bool operator==(const mat< CRTP, T, N > &m0, const mat< CRTP, T, N > &m1)
Definition: mat.h:57
constexpr T< R > operator+(R s, const T< R > &v)
Definition: vec.h:235
constexpr CRTP< T > operator*(T s, const mat< CRTP, T, N > &m)
Definition: mat.h:65
#define F(...)
Definition: pp.cpp:12
function f()) end
v[1]
Definition: math.lua:19
Definition: vec.h:16
Definition: vec.h:22
static constexpr CRTP< R > map_impl(F f, std::index_sequence< I... >, const vec &v0, const vec &v1)
Definition: vec.h:96
T type
Definition: vec.h:23
constexpr CRTP< T > & operator*=(T t)
Definition: vec.h:139
constexpr CRTP< T > & operator+=(const CRTP< T > &v)
Definition: vec.h:149
static constexpr CRTP< R > map_impl(F f, std::index_sequence< I... >, const vec &v0, T t)
Definition: vec.h:88
constexpr CRTP< T > & operator-=(const CRTP< T > &v)
Definition: vec.h:154
constexpr CRTP< T > & operator/=(T t)
Definition: vec.h:144
constexpr T * data(void)
Definition: vec.h:196
constexpr const T * data(void) const
Definition: vec.h:201
static constexpr CRTP< R > map_impl(F f, std::index_sequence< I... >, T t, const vec &v0)
Definition: vec.h:80
constexpr T & operator[](std::size_t i)
Definition: vec.h:119
constexpr CRTP< T > operator-(void) const
Definition: vec.h:124
constexpr CRTP< T > & operator/=(const CRTP< T > &v)
Definition: vec.h:164
static constexpr CRTP< R > map_impl(F f, std::index_sequence< I... >, const vec &v)
Definition: vec.h:72
constexpr vec & operator=(const CRTP< T > &v)
Definition: vec.h:109
constexpr auto as_tuple(void) const
Definition: vec.h:189
constexpr T & get(void)
Definition: vec.h:184
constexpr CRTP< T > & operator+=(T t)
Definition: vec.h:129
constexpr CRTP< T > & operator-=(T t)
Definition: vec.h:134
static constexpr std::size_t n_dim
Definition: vec.h:24
constexpr const T & get(void) const
Definition: vec.h:169
constexpr CRTP< T > & operator*=(const CRTP< T > &v)
Definition: vec.h:159
static constexpr CRTP< R > map(F f, Args &&...args)
Definition: vec.h:66
constexpr const T & operator[](std::size_t i) const
Definition: vec.h:114
std::chrono::seconds s
Definition: timing.cpp:6
#define FWD(...)
Definition: utils.h:18