OGLplus  (0.59.0) a C++ wrapper for rendering APIs

vector.hpp
Go to the documentation of this file.
1 #ifndef EAGINE_MATH_VECTOR_HPP
9 #define EAGINE_MATH_VECTOR_HPP
10 
11 #include "../assert.hpp"
12 #include "../vec_mat_traits.hpp"
13 #include "../vect/axis.hpp"
14 #include "../vect/cast.hpp"
15 #include "../vect/compare.hpp"
16 #include "../vect/esum.hpp"
17 #include "../vect/from.hpp"
18 #include "../vect/hsum.hpp"
19 #include "../vect/sdiv.hpp"
20 #include "../vect/sqrt.hpp"
21 #include "../vect/view.hpp"
22 #include "scalar.hpp"
23 #include <utility>
24 
25 namespace eagine {
26 namespace math {
27 
32 template <typename T, int N, bool V>
33 struct vector {
34  using type = vector;
35 
38 
40  using value_type = T;
41 
43  using is_vectorized = vect::has_vect_data_t<T, N, V>;
44 
45  using data_type = vect::data_t<T, N, V>;
46 
47  data_type _v;
48 
50  using vector_param = const vector&;
51 
53  using scalar_param = const scalar_type&;
54 
56  static auto zero() noexcept {
57  return vector{vect::fill<T, N, V>::apply(T(0))};
58  }
59 
61  static auto fill(T v) noexcept {
62  return vector{vect::fill<T, N, V>::apply(v)};
63  }
64 
67  template <int I>
68  static auto axis() noexcept {
69  return vector{vect::axis<T, N, I, V>::apply(T(1))};
70  }
71 
74  template <int I>
75  static auto axis(T v) noexcept {
76  return vector{vect::axis<T, N, I, V>::apply(v)};
77  }
78 
81  static auto axis(int i, T v) noexcept {
82  EAGINE_ASSERT(i < N);
83  vector r = zero();
84  r._v[i] = v;
85  return r;
86  }
87 
88  template <
89  typename P,
90  typename = std::enable_if_t<(N == 1) && (std::is_convertible_v<P, T>)>>
91  static constexpr auto make(P&& p) noexcept {
92  return vector{{T(std::forward<P>(p))}};
93  }
94 
96  template <
97  typename... P,
98  typename = std::enable_if_t<(N > 1) && (sizeof...(P) == N)>>
99  static constexpr auto make(P&&... p) noexcept {
100  return vector{{T(std::forward<P>(p))...}};
101  }
102 
105  template <
106  typename P,
107  int M,
108  bool W,
109  typename =
110  std::enable_if_t<(!std::is_same_v<T, P> || (N != M) || (V != W))>>
111  static constexpr auto from(const vector<P, M, W>& v, T d = T(0)) noexcept {
112  return vector{vect::cast<P, M, W, T, N, V>::apply(v._v, d)};
113  }
114 
116  template <typename P, int M, bool W>
117  static constexpr auto
118  from(const vector<P, M, W>& v, const vector<T, N - M, W>& u) noexcept {
119  return vector{vect::cast<P, M, W, T, N, V>::apply(v._v, u._v)};
120  }
121 
123  static auto from(const T* dt, span_size_t sz) noexcept {
124  return vector{vect::from_array<T, N, V>::apply(dt, sz)};
125  }
126 
128  static auto from(const T* dt, span_size_t sz, T fv) noexcept {
129  return vector{vect::from_saafv<T, N, V>::apply(dt, sz, fv)};
130  }
131 
133  constexpr auto operator[](int pos) const noexcept {
134  return _v[pos];
135  }
136 
139  template <int M = N>
140  constexpr auto x() const noexcept -> std::enable_if_t<(M > 0), T> {
141  static_assert(M == N);
142  return _v[0];
143  }
144 
147  template <int M = N>
148  constexpr auto y() const noexcept -> std::enable_if_t<(M > 1), T> {
149  static_assert(M == N);
150  return _v[1];
151  }
152 
155  template <int M = N>
156  constexpr auto z() const noexcept -> std::enable_if_t<(M > 2), T> {
157  static_assert(M == N);
158  return _v[2];
159  }
160 
163  template <int M = N>
164  constexpr auto w() const noexcept -> std::enable_if_t<(M > 3), T> {
165  static_assert(M == N);
166  return _v[3];
167  }
168 
170  friend constexpr auto operator+(vector_param a) noexcept {
171  return a;
172  }
173 
175  friend constexpr auto operator-(vector_param a) noexcept {
176  return vector{-a._v};
177  }
178 
180  friend constexpr auto operator+(vector_param a, vector_param b) noexcept {
181  return vector{a._v + b._v};
182  }
183 
185  auto operator+=(vector_param a) noexcept -> auto& {
186  _v = _v + a._v;
187  return *this;
188  }
189 
191  friend constexpr auto operator-(vector_param a, vector_param b) noexcept {
192  return vector{a._v - b._v};
193  }
194 
196  auto operator-=(vector_param a) noexcept -> auto& {
197  _v = _v - a._v;
198  return *this;
199  }
200 
202  friend constexpr auto operator*(vector_param a, vector_param b) noexcept {
203  return vector{a._v * b._v};
204  }
205 
207  auto operator*=(vector_param a) noexcept -> auto& {
208  _v = _v * a._v;
209  return *this;
210  }
211 
213  friend constexpr auto operator*(scalar_param c, vector_param a) noexcept {
214  static_assert(scalar_type::is_vectorized::value);
215  return vector{c._v * a._v};
216  }
217 
219  friend constexpr auto operator*(vector_param a, scalar_param c) noexcept {
220  static_assert(scalar_type::is_vectorized::value);
221  return vector{a._v * c._v};
222  }
223 
225  auto operator*=(scalar_param c) noexcept -> auto& {
226  static_assert(scalar_type::is_vectorized::value);
227  _v = _v * c._v;
228  return *this;
229  }
230 
232  friend constexpr auto operator*(T c, vector_param a) noexcept {
233  return vector{a._v * vect::fill<T, N, V>::apply(c)};
234  }
235 
237  friend constexpr auto operator*(vector_param a, T c) noexcept {
238  return vector{a._v * vect::fill<T, N, V>::apply(c)};
239  }
240 
242  auto operator*=(T c) noexcept -> auto& {
243  _v = _v * vect::fill<T, N, V>::apply(c);
244  return *this;
245  }
246 
248  friend constexpr auto operator/(vector_param a, vector_param b) noexcept {
249  return vector{vect::sdiv<T, N, V>::apply(a._v, b._v)};
250  }
251 
253  friend constexpr auto operator/(scalar_param c, vector_param a) noexcept {
254  static_assert(scalar_type::is_vectorized::value);
255  return vector{vect::sdiv<T, N, V>::apply(c._v, a._v)};
256  }
257 
259  friend constexpr auto operator/(vector_param a, scalar_param c) noexcept {
260  static_assert(scalar_type::is_vectorized::value);
261  return vector{vect::sdiv<T, N, V>::apply(a._v, c._v)};
262  }
263 
265  friend constexpr auto operator/(vector_param a, T c) noexcept {
266  return vector{
267  vect::sdiv<T, N, V>::apply(a._v, vect::fill<T, N, V>::apply(c))};
268  }
269 
271  friend constexpr auto operator/(T c, vector_param a) noexcept {
272  return vector{
273  vect::sdiv<T, N, V>::apply(vect::fill<T, N, V>::apply(c), a._v)};
274  }
275 };
276 
279 template <typename T, int N, bool V>
280 static constexpr auto dimension(const vector<T, N, V>&) noexcept {
281  return span_size_t(N);
282 }
283 
286 template <typename T, int N, bool V>
287 static inline auto is_zero(const vector<T, N, V>& v) noexcept -> bool {
288  return vect::is_zero<T, N, V>::apply(v._v);
289 }
290 
291 template <typename T, int N, bool V>
292 static constexpr auto _dot(
293  const vector<T, N, V>& a,
294  const vector<T, N, V>& b,
295  std::true_type) noexcept {
296  return scalar<T, N, V>{vect::hsum<T, N, V>::apply(a._v * b._v)};
297 }
298 
299 template <typename T, int N, bool V>
300 static constexpr auto _dot(
301  const vector<T, N, V>& a,
302  const vector<T, N, V>& b,
303  std::false_type) noexcept {
304  return scalar<T, N, V>{vect::esum<T, N, V>::apply(a._v * b._v)};
305 }
306 
309 template <typename T, int N, bool V>
310 static constexpr auto
311 dot(const vector<T, N, V>& a, const vector<T, N, V>& b) noexcept {
312  return _dot(a, b, vect::has_vect_data<T, N, V>());
313 }
314 
317 template <typename T, bool V>
318 static inline auto perpendicular(const vector<T, 2, V>& a) noexcept {
319  return vector<T, 2, V>{{-a._v[1], a._v[0]}};
320 }
321 
324 template <typename T, bool V>
325 static inline auto
326 cross(const vector<T, 3, V>& a, const vector<T, 3, V>& b) noexcept {
327  using _sh = vect::shuffle<T, 3, V>;
328  return vector<T, 3, V>{
329  _sh::template apply<1, 2, 0>(a._v) * _sh::template apply<2, 0, 1>(b._v) -
330  _sh::template apply<2, 0, 1>(a._v) * _sh::template apply<1, 2, 0>(b._v)};
331 }
332 
333 template <typename T, int N, bool V>
334 static constexpr auto _mag(const vector<T, N, V>& a, std::true_type) noexcept {
335  return scalar<T, N, V>{
336  vect::sqrt<T, N, V>::apply(vect::hsum<T, N, V>::apply(a._v * a._v))};
337 }
338 
339 template <typename T, int N, bool V>
340 static constexpr auto _mag(const vector<T, N, V> a, std::false_type) noexcept {
341  using std::sqrt;
342  return scalar<T, N, V>{T(sqrt(vect::esum<T, N, V>::apply(a._v * a._v)))};
343 }
344 
347 template <typename T, int N, bool V>
348 static constexpr auto magnitude(const vector<T, N, V>& a) noexcept {
349  return _mag(a, vect::has_vect_data<T, N, V>());
350 }
351 
354 template <typename T, int N, bool V>
355 static constexpr auto length(const vector<T, N, V>& a) noexcept {
356  return magnitude(a);
357 }
358 
359 template <typename T, int N, bool V>
360 static inline auto _nmld(
361  const vector<T, N, V>& a,
362  const scalar<T, N, V>& l,
363  std::true_type) noexcept {
364  return vector<T, N, V>{vect::sdiv<T, N, V>::apply(a._v, l._v)};
365 }
366 
367 template <typename T, int N, bool V>
368 static inline auto _nmld(
369  const vector<T, N, V>& a,
370  const scalar<T, N, V>& l,
371  std::false_type) noexcept {
372  return vector<T, N, V>{
373  vect::sdiv<T, N, V>::apply(a._v, vect::fill<T, N, V>::apply(l._v))};
374 }
375 
378 template <typename T, int N, bool V>
379 static inline auto normalized(const vector<T, N, V>& a) noexcept {
380  scalar<T, N, V> l = length(a);
381  return _nmld(a, l, vect::has_vect_data<T, N, V>());
382 }
383 
386 template <typename T, int N, bool V>
387 static constexpr auto
388 distance(const vector<T, N, V>& a, const vector<T, N, V>& b) noexcept {
389  return magnitude(a - b);
390 }
391 
392 } // namespace math
393 
394 template <typename T, int N, bool V>
395 struct is_known_vector_type<math::vector<T, N, V>> : std::is_scalar<T> {};
396 
397 template <typename T, int N, bool V>
398 struct canonical_compound_type<math::vector<T, N, V>>
399  : type_identity<std::remove_cv_t<T[N]>> {};
400 
401 template <typename T, int N, bool V>
402 struct compound_view_maker<math::vector<T, N, V>> {
403  inline auto operator()(const math::vector<T, N, V>& v) const noexcept {
404  return vect::view<T, N, V>::apply(v._v);
405  }
406 };
407 
408 } // namespace eagine
409 
410 #endif // EAGINE_MATH_VECTOR_HPP
constexpr friend auto operator*(scalar_param c, vector_param a) noexcept
Multiplication by scalar operator.
Definition: vector.hpp:213
std::ptrdiff_t span_size_t
Signed span size type used by eagine.
Definition: types.hpp:36
constexpr auto z() const noexcept -> std::enable_if_t<(M > 2), T >
Returns the z-coordinate value.
Definition: vector.hpp:156
static constexpr auto from(const vector< P, M, W > &v, T d=T(0)) noexcept
Creates vector instance from vector of another dimension.
Definition: vector.hpp:111
Common code is placed in this namespace.
Definition: eagine.hpp:21
static auto fill(T v) noexcept
Creates a zero vector instance with all elements set to v.
Definition: vector.hpp:61
constexpr auto operator[](int pos) const noexcept
Subscript operator.
Definition: vector.hpp:133
constexpr auto w() const noexcept -> std::enable_if_t<(M > 3), T >
Returns the w-coordinate value.
Definition: vector.hpp:164
constexpr friend auto operator/(T c, vector_param a) noexcept
Constant division operator.
Definition: vector.hpp:271
constexpr friend auto operator+(vector_param a, vector_param b) noexcept
Addition operator.
Definition: vector.hpp:180
static auto is_zero(const vector< T, N, V > &v) noexcept -> bool
Tests if a vector has zero lenght.
Definition: vector.hpp:287
static auto normalized(const vector< T, N, V > &a) noexcept
Returns normalized argument.
Definition: vector.hpp:379
vect::has_vect_data_t< T, N, V > is_vectorized
Indicates if the implementation uses SIMD extensions.
Definition: vector.hpp:43
static constexpr auto distance(const vector< T, N, V > &a, const vector< T, N, V > &b) noexcept
Returns the distance between two vectors.
Definition: vector.hpp:388
constexpr friend auto operator*(vector_param a, scalar_param c) noexcept
Multiplication by scalar operator.
Definition: vector.hpp:219
auto operator+=(vector_param a) noexcept -> auto &
Addition operator.
Definition: vector.hpp:185
static auto axis() noexcept
Creates an unit axis vector for the I-th dimension.
Definition: vector.hpp:68
constexpr auto y() const noexcept -> std::enable_if_t<(M > 1), T >
Returns the y-coordinate value.
Definition: vector.hpp:148
Basic N-dimensional vector implementation template.
Definition: fwd.hpp:19
static auto from(const T *dt, span_size_t sz) noexcept
Creates vector instance from data pointer and length.
Definition: vector.hpp:123
static constexpr auto dimension(const matrix< T, N, N, RM, V > &) noexcept
Returns the dimension of a square matrix.
Definition: matrix.hpp:108
constexpr auto x() const noexcept -> std::enable_if_t<(M > 0), T >
Returns the x-coordinate value.
Definition: vector.hpp:140
constexpr friend auto operator+(vector_param a) noexcept
Unary plus operator.
Definition: vector.hpp:170
auto operator*=(vector_param a) noexcept -> auto &
Multiplication operator.
Definition: vector.hpp:207
auto operator*=(T c) noexcept -> auto &
Multiplication by constant operator.
Definition: vector.hpp:242
constexpr friend auto operator-(vector_param a) noexcept
Negation operator.
Definition: vector.hpp:175
static constexpr auto dot(const vector< T, N, V > &a, const vector< T, N, V > &b) noexcept
Vector dot product.
Definition: vector.hpp:311
constexpr friend auto operator*(vector_param a, vector_param b) noexcept
Multiplication operator.
Definition: vector.hpp:202
static constexpr auto magnitude(const vector< T, N, V > &a) noexcept
Returns the magnitude of a vector. Same as length.
Definition: vector.hpp:348
constexpr friend auto operator/(scalar_param c, vector_param a) noexcept
Scalar division operator.
Definition: vector.hpp:253
static constexpr auto make(P &&... p) noexcept
Creates vector instance with the specified elements.
Definition: vector.hpp:99
static auto perpendicular(const vector< T, 2, V > &a) noexcept
Returns a vector perpendicular to argument.
Definition: vector.hpp:318
static constexpr auto length(const vector< T, N, V > &a) noexcept
Returns the length of a vector.
Definition: vector.hpp:355
static auto from(const T *dt, span_size_t sz, T fv) noexcept
Creates vector instance from data pointer, length and additional value.
Definition: vector.hpp:128
constexpr friend auto operator*(vector_param a, T c) noexcept
Multiplication by constant operator.
Definition: vector.hpp:237
static constexpr auto from(const vector< P, M, W > &v, const vector< T, N - M, W > &u) noexcept
Creates vector instance from two other vectors.
Definition: vector.hpp:118
constexpr friend auto operator/(vector_param a, vector_param b) noexcept
Division operator.
Definition: vector.hpp:248
T value_type
Element value type.
Definition: vector.hpp:40
static auto zero() noexcept
Creates a new zero vector instance.
Definition: vector.hpp:56
constexpr friend auto operator/(vector_param a, scalar_param c) noexcept
Division by scalar operator.
Definition: vector.hpp:259
Basic scalar implementation template.
Definition: fwd.hpp:16
static auto axis(T v) noexcept
Creates an axis vector for the I-th dimension with specified length.
Definition: vector.hpp:75
constexpr friend auto operator*(T c, vector_param a) noexcept
Multiplication by constant operator.
Definition: vector.hpp:232
auto operator*=(scalar_param c) noexcept -> auto &
Multiplication by scalar operator.
Definition: vector.hpp:225
static auto axis(int i, T v) noexcept
Creates an axis vector for the i-th dimension with specified length.
Definition: vector.hpp:81
constexpr friend auto operator/(vector_param a, T c) noexcept
Division by constant operator.
Definition: vector.hpp:265
static auto cross(const vector< T, 3, V > &a, const vector< T, 3, V > &b) noexcept
3D vector cross product.
Definition: vector.hpp:326
auto operator-=(vector_param a) noexcept -> auto &
Subtraction operator.
Definition: vector.hpp:196
constexpr friend auto operator-(vector_param a, vector_param b) noexcept
Subtraction operator.
Definition: vector.hpp:191

Copyright © 2015-2021 Matúš Chochlík.
<chochlik -at -gmail.com>
Documentation generated on Tue Apr 13 2021 by Doxygen (version 1.8.17).