Antkeeper  0.0.1
vector.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2023 Christopher J. Howard
3  *
4  * This file is part of Antkeeper source code.
5  *
6  * Antkeeper source code is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Antkeeper source code is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef ANTKEEPER_MATH_VECTOR_HPP
21 #define ANTKEEPER_MATH_VECTOR_HPP
22 
23 #include <algorithm>
24 #include <cstddef>
25 #include <cstring>
26 #include <cmath>
27 #include <concepts>
28 #include <format>
29 #include <iterator>
30 #include <limits>
31 #include <type_traits>
32 #include <utility>
33 
34 namespace math {
35 
42 template <class T, std::size_t N>
43 struct vector
44 {
46  using element_type = T;
47 
49  static constexpr std::size_t element_count = N;
50 
53 
56 
58  template <class U, std::size_t... I>
59  [[nodiscard]] inline constexpr vector<U, N> type_cast(std::index_sequence<I...>) const noexcept
60  {
61  return {static_cast<U>(elements[I])...};
62  }
63 
71  template <class U>
72  [[nodiscard]] inline constexpr explicit operator vector<U, N>() const noexcept
73  {
74  return type_cast<U>(std::make_index_sequence<N>{});
75  }
76 
78  template <std::size_t M, std::size_t... I>
79  [[nodiscard]] inline constexpr vector<T, M> size_cast(std::index_sequence<I...>) const noexcept
80  {
81  return {(I < N) ? elements[I] : T{0} ...};
82  }
83 
91  template <std::size_t M>
92  [[nodiscard]] inline constexpr explicit operator vector<T, M>() const noexcept
93  {
94  return size_cast<M>(std::make_index_sequence<M>{});
95  }
96 
98 
101 
110  [[nodiscard]] inline constexpr element_type& operator[](std::size_t i) noexcept
111  {
112  return elements[i];
113  }
114  [[nodiscard]] inline constexpr const element_type& operator[](std::size_t i) const noexcept
115  {
116  return elements[i];
117  }
119 
124  [[nodiscard]] inline constexpr element_type& front() noexcept
125  {
126  return elements[0];
127  }
128  [[nodiscard]] inline constexpr const element_type& front() const noexcept
129  {
130  return elements[0];
131  }
133 
138  [[nodiscard]] inline constexpr element_type& back() noexcept
139  {
140  return elements[N - 1];
141  }
142  [[nodiscard]] inline constexpr const element_type& back() const noexcept
143  {
144  return elements[N - 1];
145  }
147 
152  [[nodiscard]] inline constexpr element_type* data() noexcept
153  {
154  return elements;
155  };
156  [[nodiscard]] inline constexpr const element_type* data() const noexcept
157  {
158  return elements;
159  };
161 
164  [[nodiscard]] inline constexpr element_type& x() noexcept
165  {
166  static_assert(N > 0, "Vector does not contain an x element.");
167  return elements[0];
168  }
169  [[nodiscard]] inline constexpr const element_type& x() const noexcept
170  {
171  static_assert(N > 0, "Vector does not contain an x element.");
172  return elements[0];
173  }
175 
180  [[nodiscard]] inline constexpr element_type& y() noexcept
181  {
182  static_assert(N > 1, "Vector does not contain a y element.");
183  return elements[1];
184  }
185  [[nodiscard]] inline constexpr const element_type& y() const noexcept
186  {
187  static_assert(N > 1, "Vector does not contain a y element.");
188  return elements[1];
189  }
191 
196  [[nodiscard]] inline constexpr element_type& z() noexcept
197  {
198  static_assert(N > 2, "Vector does not contain a z element.");
199  return elements[2];
200  }
201  [[nodiscard]] inline constexpr const element_type& z() const noexcept
202  {
203  static_assert(N > 2, "Vector does not contain a z element.");
204  return elements[2];
205  }
207 
209 
212 
217  [[nodiscard]] inline constexpr element_type* begin() noexcept
218  {
219  return elements;
220  }
221  [[nodiscard]] inline constexpr const element_type* begin() const noexcept
222  {
223  return elements;
224  }
225  [[nodiscard]] inline constexpr const element_type* cbegin() const noexcept
226  {
227  return elements;
228  }
230 
235  [[nodiscard]] inline constexpr element_type* end() noexcept
236  {
237  return elements + N;
238  }
239  [[nodiscard]] inline constexpr const element_type* end() const noexcept
240  {
241  return elements + N;
242  }
243  [[nodiscard]] inline constexpr const element_type* cend() const noexcept
244  {
245  return elements + N;
246  }
248 
253  [[nodiscard]] inline constexpr std::reverse_iterator<element_type*> rbegin() noexcept
254  {
255  return std::reverse_iterator<element_type*>(elements + N);
256  }
257  [[nodiscard]] inline constexpr std::reverse_iterator<const element_type*> rbegin() const noexcept
258  {
259  return std::reverse_iterator<const element_type*>(elements + N);
260  }
261  [[nodiscard]] inline constexpr std::reverse_iterator<const element_type*> crbegin() const noexcept
262  {
263  return std::reverse_iterator<const element_type*>(elements + N);
264  }
266 
271  [[nodiscard]] inline constexpr std::reverse_iterator<element_type*> rend() noexcept
272  {
273  return std::reverse_iterator<element_type*>(elements);
274  }
275  [[nodiscard]] inline constexpr std::reverse_iterator<const element_type*> rend() const noexcept
276  {
277  return std::reverse_iterator<const element_type*>(elements);
278  }
279  [[nodiscard]] inline constexpr std::reverse_iterator<const element_type*> crend() const noexcept
280  {
281  return std::reverse_iterator<const element_type*>(elements);
282  }
284 
286 
289 
293  [[nodiscard]] inline constexpr std::size_t size() const noexcept
294  {
295  return N;
296  };
297 
299 
302 
306  [[nodiscard]] inline static constexpr vector zero() noexcept
307  {
308  return {};
309  }
310 
312  template <std::size_t... I>
313  [[nodiscard]] inline static constexpr vector one(std::index_sequence<I...>) noexcept
314  {
315  //return {element_type{1}...};
316 
317  // MSVC bug workaround (I must be referenced for parameter pack expansion)
318  return {(I ? element_type{1} : element_type{1})...};
319  }
320 
324  [[nodiscard]] inline static constexpr vector one() noexcept
325  {
326  return one(std::make_index_sequence<N>{});
327  }
328 
330  template <std::size_t... I>
331  [[nodiscard]] inline static constexpr vector infinity(std::index_sequence<I...>) noexcept
332  {
333  //return {element_type{1}...};
334 
335  // MSVC bug workaround (I must be referenced for parameter pack expansion)
336  return {(I ? std::numeric_limits<element_type>::infinity() : std::numeric_limits<element_type>::infinity())...};
337  }
338 
342  [[nodiscard]] inline static constexpr vector infinity() noexcept
343  {
344  return infinity(std::make_index_sequence<N>{});
345  }
346 
348 };
349 
351 namespace vector_types {
352 
358 template <class T>
360 
366 template <class T>
368 
374 template <class T>
376 
383 template <std::size_t N>
385 using bvec2 = bvec<2>;
386 using bvec3 = bvec<3>;
387 using bvec4 = bvec<4>;
389 
396 template <std::size_t N>
398 using ivec2 = ivec<2>;
399 using ivec3 = ivec<3>;
400 using ivec4 = ivec<4>;
402 
409 template <std::size_t N>
411 using uvec2 = uvec<2>;
412 using uvec3 = uvec<3>;
413 using uvec4 = uvec<4>;
415 
422 template <std::size_t N>
424 using fvec2 = fvec<2>;
425 using fvec3 = fvec<3>;
426 using fvec4 = fvec<4>;
428 
435 template <std::size_t N>
437 using dvec2 = dvec<2>;
438 using dvec3 = dvec<3>;
439 using dvec4 = dvec<4>;
441 
442 } // namespace vector_types
443 
444 // Bring vector types into math namespace
445 using namespace vector_types;
446 
447 // Bring vector types into math::types namespace
448 namespace types { using namespace math::vector_types; }
449 
457 template <class T, std::size_t N>
458 [[nodiscard]] constexpr vector<T, N> abs(const vector<T, N>& x);
459 
469 template <class T, std::size_t N>
470 [[nodiscard]] constexpr vector<T, N> add(const vector<T, N>& x, const vector<T, N>& y) noexcept;
471 template <class T, std::size_t N>
472 [[nodiscard]] constexpr vector<T, N> add(const vector<T, N>& x, T y) noexcept;
474 
482 template <std::size_t N>
483 [[nodiscard]] constexpr bool all(const vector<bool, N>& x) noexcept;
484 
493 template <std::floating_point T, std::size_t N>
494 [[nodiscard]] T angle(const vector<T, N>& from, const vector<T, N>& to);
495 
503 template <std::size_t N>
504 [[nodiscard]] constexpr bool any(const vector<bool, N>& x) noexcept;
505 
513 template <std::floating_point T, std::size_t N>
514 [[nodiscard]] constexpr vector<T, N> ceil(const vector<T, N>& x);
515 
526 template <class T, std::size_t N>
527 [[nodiscard]] constexpr vector<T, N> clamp(const vector<T, N>& x, const vector<T, N>& min, const vector<T, N>& max);
528 template <class T, std::size_t N>
529 [[nodiscard]] constexpr vector<T, N> clamp(const vector<T, N>& x, T min, T max);
531 
540 template <std::floating_point T, std::size_t N>
541 [[nodiscard]] vector<T, N> clamp_length(const vector<T, N>& x, T max_length);
542 
551 template <class T>
552 [[nodiscard]] constexpr vector<T, 3> cross(const vector<T, 3>& x, const vector<T, 3>& y) noexcept;
553 
562 template <std::floating_point T, std::size_t N>
563 [[nodiscard]] T distance(const vector<T, N>& p0, const vector<T, N>& p1);
564 
574 template <class T, std::size_t N>
575 [[nodiscard]] constexpr vector<T, N> div(const vector<T, N>& x, const vector<T, N>& y) noexcept;
576 template <class T, std::size_t N>
577 [[nodiscard]] constexpr vector<T, N> div(const vector<T, N>& x, T y) noexcept;
578 template <class T, std::size_t N>
579 [[nodiscard]] constexpr vector<T, N> div(T x, const vector<T, N>& y) noexcept;
581 
590 template <class T, std::size_t N>
591 [[nodiscard]] constexpr T dot(const vector<T, N>& x, const vector<T, N>& y) noexcept;
592 
601 template <class T, std::size_t N>
602 [[nodiscard]] constexpr vector<bool, N> equal(const vector<T, N>& x, const vector<T, N>& y) noexcept;
603 
611 template <std::floating_point T, std::size_t N>
612 [[nodiscard]] constexpr vector<T, N> floor(const vector<T, N>& x);
613 
624 template <class T, std::size_t N>
625 [[nodiscard]] constexpr vector<T, N> fma(const vector<T, N>& x, const vector<T, N>& y, const vector<T, N>& z);
626 template <class T, std::size_t N>
627 [[nodiscard]] constexpr vector<T, N> fma(const vector<T, N>& x, T y, T z);
629 
637 template <std::floating_point T, std::size_t N>
638 [[nodiscard]] constexpr vector<T, N> fract(const vector<T, N>& x);
639 
652 template<std::size_t I, class T, std::size_t N>
653 [[nodiscard]] constexpr T& get(math::vector<T, N>& v) noexcept;
654 template<std::size_t I, class T, std::size_t N>
655 [[nodiscard]] constexpr T&& get(math::vector<T, N>&& v) noexcept;
656 template<std::size_t I, class T, std::size_t N>
657 [[nodiscard]] constexpr const T& get(const math::vector<T, N>& v) noexcept;
658 template<std::size_t I, class T, std::size_t N>
659 [[nodiscard]] constexpr const T&& get(const math::vector<T, N>&& v) noexcept;
661 
670 template <class T, std::size_t N>
671 [[nodiscard]] constexpr vector<bool, N> greater_than(const vector<T, N>& x, const vector<T, N>& y) noexcept;
672 
681 template <class T, std::size_t N>
682 [[nodiscard]] constexpr vector<bool, N> greater_than_equal(const vector<T, N>& x, const vector<T, N>& y) noexcept;
683 
691 template <std::floating_point T, std::size_t N>
692 [[nodiscard]] T inv_length(const vector<T, N>& x);
693 
701 template <std::floating_point T, std::size_t N>
702 [[nodiscard]] T length(const vector<T, N>& x);
703 
712 template <class T, std::size_t N>
713 [[nodiscard]] constexpr vector<bool, N> less_than(const vector<T, N>& x, const vector<T, N>& y) noexcept;
714 
723 template <class T, std::size_t N>
724 [[nodiscard]] constexpr vector<bool, N> less_than_equal(const vector<T, N>& x, const vector<T, N>& y) noexcept;
725 
734 template <class T, std::size_t N>
735 [[nodiscard]] constexpr vector<T, N> max(const vector<T, N>& x, const vector<T, N>& y);
736 
744 template <class T, std::size_t N>
745 [[nodiscard]] constexpr T max(const vector<T, N>& x);
746 
755 template <class T, std::size_t N>
756 [[nodiscard]] constexpr vector<T, N> min(const vector<T, N>& x, const vector<T, N>& y);
757 
765 template <class T, std::size_t N>
766 [[nodiscard]] constexpr T min(const vector<T, N>& x);
767 
777 template <std::floating_point T, std::size_t N>
778 [[nodiscard]] constexpr vector<T, N> mod(const vector<T, N>& x, const vector<T, N>& y);
779 template <std::floating_point T, std::size_t N>
780 [[nodiscard]] constexpr vector<T, N> mod(const vector<T, N>& x, T y);
782 
792 template <class T, std::size_t N>
793 [[nodiscard]] constexpr vector<T, N> mul(const vector<T, N>& x, const vector<T, N>& y) noexcept;
794 template <class T, std::size_t N>
795 [[nodiscard]] constexpr vector<T, N> mul(const vector<T, N>& x, T y) noexcept;
797 
805 template <class T, std::size_t N>
806 [[nodiscard]] constexpr vector<T, N> negate(const vector<T, N>& x) noexcept;
807 
815 template <std::floating_point T, std::size_t N>
816 [[nodiscard]] vector<T, N> normalize(const vector<T, N>& x);
817 
825 template <class T, std::size_t N>
826 [[nodiscard]] constexpr vector<bool, N> logical_not(const vector<T, N>& x) noexcept;
827 
836 template <class T, std::size_t N>
837 [[nodiscard]] constexpr vector<bool, N> not_equal(const vector<T, N>& x, const vector<T, N>& y) noexcept;
838 
848 template <std::floating_point T, std::size_t N>
849 [[nodiscard]] vector<T, N> pow(const vector<T, N>& x, const vector<T, N>& y);
850 template <std::floating_point T, std::size_t N>
851 [[nodiscard]] vector<T, N> pow(const vector<T, N>& x, T y);
853 
861 template <std::floating_point T, std::size_t N>
862 [[nodiscard]] constexpr vector<T, N> round(const vector<T, N>& x);
863 
870 template <std::floating_point T, std::size_t N>
871 [[nodiscard]] constexpr vector<T, N> sign(const vector<T, N>& x);
872 
882 template <std::floating_point T>
883 [[nodiscard]] T signed_angle(const vector<T, 3>& x, const vector<T, 3>& y, const vector<T, 3>& n);
884 
893 template <class T, std::size_t N>
894 [[nodiscard]] constexpr T sqr_distance(const vector<T, N>& p0, const vector<T, N>& p1) noexcept;
895 
903 template <class T, std::size_t N>
904 [[nodiscard]] constexpr T sqr_length(const vector<T, N>& x) noexcept;
905 
913 template <std::floating_point T, std::size_t N>
914 [[nodiscard]] vector<T, N> sqrt(const vector<T, N>& x);
915 
925 template <class T, std::size_t N>
926 [[nodiscard]] constexpr vector<T, N> sub(const vector<T, N>& x, const vector<T, N>& y) noexcept;
927 template <class T, std::size_t N>
928 [[nodiscard]] constexpr vector<T, N> sub(const vector<T, N>& x, T y) noexcept;
929 template <class T, std::size_t N>
930 [[nodiscard]] constexpr vector<T, N> sub(T x, const vector<T, N>& y) noexcept;
932 
939 template <class T, std::size_t N>
940 [[nodiscard]] constexpr T sum(const vector<T, N>& x) noexcept;
941 
953 template <std::size_t... Indices, class T, std::size_t N>
954 [[nodiscard]] constexpr vector<T, sizeof...(Indices)> swizzle(const vector<T, N>& x) noexcept;
955 
965 template <class T>
966 [[nodiscard]] constexpr T triple(const vector<T, 3>& x, const vector<T, 3>& y, const vector<T, 3>& z) noexcept;
967 
974 template <std::floating_point T, std::size_t N>
975 [[nodiscard]] constexpr vector<T, N> trunc(const vector<T, N>& x);
976 
978 template <class T, std::size_t N, std::size_t... I>
979 inline constexpr vector<T, N> abs(const vector<T, N>& x, std::index_sequence<I...>)
980 {
981  return {std::abs(x[I])...};
982 }
983 
984 template <class T, std::size_t N>
985 inline constexpr vector<T, N> abs(const vector<T, N>& x)
986 {
987  return abs(x, std::make_index_sequence<N>{});
988 }
989 
991 template <class T, std::size_t N, std::size_t... I>
992 inline constexpr vector<T, N> add(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
993 {
994  return {(x[I] + y[I])...};
995 }
996 
997 template <class T, std::size_t N>
998 inline constexpr vector<T, N> add(const vector<T, N>& x, const vector<T, N>& y) noexcept
999 {
1000  return add(x, y, std::make_index_sequence<N>{});
1001 }
1002 
1004 template <class T, std::size_t N, std::size_t... I>
1005 inline constexpr vector<T, N> add(const vector<T, N>& x, T y, std::index_sequence<I...>) noexcept
1006 {
1007  return {(x[I] + y)...};
1008 }
1009 
1010 template <class T, std::size_t N>
1011 inline constexpr vector<T, N> add(const vector<T, N>& x, T y) noexcept
1012 {
1013  return add(x, y, std::make_index_sequence<N>{});
1014 }
1015 
1017 template <std::size_t N, std::size_t... I>
1018 inline constexpr bool all(const vector<bool, N>& x, std::index_sequence<I...>) noexcept
1019 {
1020  return (x[I] && ...);
1021 }
1022 
1023 template <std::size_t N>
1024 inline constexpr bool all(const vector<bool, N>& x) noexcept
1025 {
1026  return all(x, std::make_index_sequence<N>{});
1027 }
1028 
1029 template <std::floating_point T, std::size_t N>
1030 T angle(const vector<T, N>& from, const vector<T, N>& to)
1031 {
1032  return std::acos(std::min<T>(std::max<T>(dot(from, to), T{-1}), T{1}));
1033 }
1034 
1036 template <std::size_t N, std::size_t... I>
1037 inline constexpr bool any(const vector<bool, N>& x, std::index_sequence<I...>) noexcept
1038 {
1039  return (x[I] || ...);
1040 }
1041 
1042 template <std::size_t N>
1043 inline constexpr bool any(const vector<bool, N>& x) noexcept
1044 {
1045  return any(x, std::make_index_sequence<N>{});
1046 }
1047 
1049 template <std::floating_point T, std::size_t N, std::size_t... I>
1050 inline constexpr vector<T, N> ceil(const vector<T, N>& x, std::index_sequence<I...>)
1051 {
1052  return {std::ceil(x[I])...};
1053 }
1054 
1055 template <std::floating_point T, std::size_t N>
1056 inline constexpr vector<T, N> ceil(const vector<T, N>& x)
1057 {
1058  return ceil(x, std::make_index_sequence<N>{});
1059 }
1060 
1062 template <class T, std::size_t N, std::size_t... I>
1063 inline constexpr vector<T, N> clamp(const vector<T, N>& x, const vector<T, N>& min_val, const vector<T, N>& max_val, std::index_sequence<I...>)
1064 {
1065  return {std::min<T>(max_val[I], std::max<T>(min_val[I], x[I]))...};
1066 }
1067 
1068 template <class T, std::size_t N>
1069 inline constexpr vector<T, N> clamp(const vector<T, N>& x, const vector<T, N>& min, const vector<T, N>& max)
1070 {
1071  return clamp(x, min, max, std::make_index_sequence<N>{});
1072 }
1073 
1075 template <class T, std::size_t N, std::size_t... I>
1076 inline constexpr vector<T, N> clamp(const vector<T, N>& x, T min, T max, std::index_sequence<I...>)
1077 {
1078  return {std::min<T>(max, std::max<T>(min, x[I]))...};
1079 }
1080 
1081 template <class T, std::size_t N>
1082 inline constexpr vector<T, N> clamp(const vector<T, N>& x, T min, T max)
1083 {
1084  return clamp(x, min, max, std::make_index_sequence<N>{});
1085 }
1086 
1087 template <std::floating_point T, std::size_t N>
1089 {
1090  const auto length2 = sqr_length(x);
1091  return (length2 > max_length * max_length) ? (x * (max_length / std::sqrt(length2))) : x;
1092 }
1093 
1094 template <class T>
1095 inline constexpr vector<T, 3> cross(const vector<T, 3>& x, const vector<T, 3>& y) noexcept
1096 {
1097  return
1098  {
1099  x[1] * y[2] - x[2] * y[1],
1100  x[2] * y[0] - x[0] * y[2],
1101  x[0] * y[1] - x[1] * y[0]
1102  };
1103 }
1104 
1105 template <std::floating_point T, std::size_t N>
1106 inline T distance(const vector<T, N>& p0, const vector<T, N>& p1)
1107 {
1108  return length(sub(p0, p1));
1109 }
1110 
1112 template <class T, std::size_t N, std::size_t... I>
1113 inline constexpr vector<T, N> div(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
1114 {
1115  return {(x[I] / y[I])...};
1116 }
1117 
1118 template <class T, std::size_t N>
1119 inline constexpr vector<T, N> div(const vector<T, N>& x, const vector<T, N>& y) noexcept
1120 {
1121  return div(x, y, std::make_index_sequence<N>{});
1122 }
1123 
1125 template <class T, std::size_t N, std::size_t... I>
1126 inline constexpr vector<T, N> div(const vector<T, N>& x, T y, std::index_sequence<I...>) noexcept
1127 {
1128  return {(x[I] / y)...};
1129 }
1130 
1131 template <class T, std::size_t N>
1132 inline constexpr vector<T, N> div(const vector<T, N>& x, T y) noexcept
1133 {
1134  return div(x, y, std::make_index_sequence<N>{});
1135 }
1136 
1138 template <class T, std::size_t N, std::size_t... I>
1139 inline constexpr vector<T, N> div(T x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
1140 {
1141  return {(x / y[I])...};
1142 }
1143 
1144 template <class T, std::size_t N>
1145 inline constexpr vector<T, N> div(T x, const vector<T, N>& y) noexcept
1146 {
1147  return div(x, y, std::make_index_sequence<N>{});
1148 }
1149 
1151 template <class T, std::size_t N, std::size_t... I>
1152 inline constexpr T dot(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
1153 {
1154  return ((x[I] * y[I]) + ...);
1155 }
1156 
1157 template <class T, std::size_t N>
1158 inline constexpr T dot(const vector<T, N>& x, const vector<T, N>& y) noexcept
1159 {
1160  return dot(x, y, std::make_index_sequence<N>{});
1161 }
1162 
1164 template <class T, std::size_t N, std::size_t... I>
1165 inline constexpr vector<bool, N> equal(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
1166 {
1167  return {(x[I] == y[I])...};
1168 }
1169 
1170 template <class T, std::size_t N>
1171 inline constexpr vector<bool, N> equal(const vector<T, N>& x, const vector<T, N>& y) noexcept
1172 {
1173  return equal(x, y, std::make_index_sequence<N>{});
1174 }
1175 
1177 template <std::floating_point T, std::size_t N, std::size_t... I>
1178 inline constexpr vector<T, N> floor(const vector<T, N>& x, std::index_sequence<I...>)
1179 {
1180  return {std::floor(x[I])...};
1181 }
1182 
1183 template <std::floating_point T, std::size_t N>
1184 inline constexpr vector<T, N> floor(const vector<T, N>& x)
1185 {
1186  return floor(x, std::make_index_sequence<N>{});
1187 }
1188 
1190 template <std::floating_point T, std::size_t N, std::size_t... I>
1191 inline constexpr vector<T, N> fma(const vector<T, N>& x, const vector<T, N>& y, const vector<T, N>& z, std::index_sequence<I...>)
1192 {
1193  return {std::fma(x[I], y[I], z[I])...};
1194 }
1195 
1196 template <std::floating_point T, std::size_t N>
1197 inline constexpr vector<T, N> fma(const vector<T, N>& x, const vector<T, N>& y, const vector<T, N>& z)
1198 {
1199  return fma(x, y, z, std::make_index_sequence<N>{});
1200 }
1201 
1203 template <std::floating_point T, std::size_t N, std::size_t... I>
1204 inline constexpr vector<T, N> fma(const vector<T, N>& x, T y, T z, std::index_sequence<I...>)
1205 {
1206  return {std::fma(x[I], y, z)...};
1207 }
1208 
1209 template <std::floating_point T, std::size_t N>
1210 inline constexpr vector<T, N> fma(const vector<T, N>& x, T y, T z)
1211 {
1212  return fma(x, y, z, std::make_index_sequence<N>{});
1213 }
1214 
1216 template <std::floating_point T, std::size_t N, std::size_t... I>
1217 inline constexpr vector<T, N> fract(const vector<T, N>& x, std::index_sequence<I...>)
1218 {
1219  return {x[I] - std::floor(x[I])...};
1220 }
1221 
1222 template <std::floating_point T, std::size_t N>
1223 inline constexpr vector<T, N> fract(const vector<T, N>& x)
1224 {
1225  return fract(x, std::make_index_sequence<N>{});
1226 }
1227 
1228 template<std::size_t I, class T, std::size_t N>
1229 inline constexpr T& get(math::vector<T, N>& v) noexcept
1230 {
1231  static_assert(I < N);
1232  return v.elements[I];
1233 }
1234 
1235 template<std::size_t I, class T, std::size_t N>
1236 inline constexpr T&& get(math::vector<T, N>&& v) noexcept
1237 {
1238  static_assert(I < N);
1239  return std::move(v.elements[I]);
1240 }
1241 
1242 template<std::size_t I, class T, std::size_t N>
1243 inline constexpr const T& get(const math::vector<T, N>& v) noexcept
1244 {
1245  static_assert(I < N);
1246  return v.elements[I];
1247 }
1248 
1249 template<std::size_t I, class T, std::size_t N>
1250 inline constexpr const T&& get(const math::vector<T, N>&& v) noexcept
1251 {
1252  static_assert(I < N);
1253  return std::move(v.elements[I]);
1254 }
1255 
1257 template <class T, std::size_t N, std::size_t... I>
1258 inline constexpr vector<bool, N> greater_than(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
1259 {
1260  return {(x[I] > y[I])...};
1261 }
1262 
1263 template <class T, std::size_t N>
1264 inline constexpr vector<bool, N> greater_than(const vector<T, N>& x, const vector<T, N>& y) noexcept
1265 {
1266  return greater_than(x, y, std::make_index_sequence<N>{});
1267 }
1268 
1270 template <class T, std::size_t N, std::size_t... I>
1271 inline constexpr vector<bool, N> greater_than_equal(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
1272 {
1273  return {(x[I] >= y[I])...};
1274 }
1275 
1276 template <class T, std::size_t N>
1277 inline constexpr vector<bool, N> greater_than_equal(const vector<T, N>& x, const vector<T, N>& y) noexcept
1278 {
1279  return greater_than_equal(x, y, std::make_index_sequence<N>{});
1280 }
1281 
1282 template <std::floating_point T, std::size_t N>
1283 inline T inv_length(const vector<T, N>& x)
1284 {
1285  return T{1} / length(x);
1286 }
1287 
1288 template <std::floating_point T, std::size_t N>
1289 inline T length(const vector<T, N>& x)
1290 {
1291  return std::sqrt(sqr_length(x));
1292 }
1293 
1295 template <class T, std::size_t N, std::size_t... I>
1296 inline constexpr vector<bool, N> less_than(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
1297 {
1298  return {(x[I] < y[I])...};
1299 }
1300 
1301 template <class T, std::size_t N>
1302 inline constexpr vector<bool, N> less_than(const vector<T, N>& x, const vector<T, N>& y) noexcept
1303 {
1304  return less_than(x, y, std::make_index_sequence<N>{});
1305 }
1306 
1308 template <class T, std::size_t N, std::size_t... I>
1309 inline constexpr vector<bool, N> less_than_equal(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
1310 {
1311  return {(x[I] <= y[I])...};
1312 }
1313 
1314 template <class T, std::size_t N>
1315 inline constexpr vector<bool, N> less_than_equal(const vector<T, N>& x, const vector<T, N>& y) noexcept
1316 {
1317  return less_than_equal(x, y, std::make_index_sequence<N>{});
1318 }
1319 
1321 template <class T, std::size_t N, std::size_t... I>
1322 inline constexpr vector<T, N> max(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>)
1323 {
1324  return {std::max<T>(x[I], y[I])...};
1325 }
1326 
1327 template <class T, std::size_t N>
1328 constexpr vector<T, N> max(const vector<T, N>& x, const vector<T, N>& y)
1329 {
1330  return max(x, y, std::make_index_sequence<N>{});
1331 }
1332 
1333 template <class T, std::size_t N>
1334 inline constexpr T max(const vector<T, N>& x)
1335 {
1336  return *std::max_element(x.elements, x.elements + N);
1337 }
1338 
1340 template <class T, std::size_t N, std::size_t... I>
1341 inline constexpr vector<T, N> min(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>)
1342 {
1343  return {std::min<T>(x[I], y[I])...};
1344 }
1345 
1346 template <class T, std::size_t N>
1347 constexpr vector<T, N> min(const vector<T, N>& x, const vector<T, N>& y)
1348 {
1349  return min(x, y, std::make_index_sequence<N>{});
1350 }
1351 
1352 template <class T, std::size_t N>
1353 inline constexpr T min(const vector<T, N>& x)
1354 {
1355  return *std::min_element(x.elements, x.elements + N);
1356 }
1357 
1359 template <std::floating_point T, std::size_t N, std::size_t... I>
1360 inline constexpr vector<T, N> mod(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>)
1361 {
1362  return {std::fmod(x[I], y[I])...};
1363 }
1364 
1365 template <std::floating_point T, std::size_t N>
1366 inline constexpr vector<T, N> mod(const vector<T, N>& x, const vector<T, N>& y)
1367 {
1368  return mod(x, y, std::make_index_sequence<N>{});
1369 }
1370 
1372 template <std::floating_point T, std::size_t N, std::size_t... I>
1373 inline constexpr vector<T, N> mod(const vector<T, N>& x, T y, std::index_sequence<I...>)
1374 {
1375  return {std::fmod(x[I], y)...};
1376 }
1377 
1378 template <std::floating_point T, std::size_t N>
1379 inline constexpr vector<T, N> mod(const vector<T, N>& x, T y)
1380 {
1381  return mod(x, y, std::make_index_sequence<N>{});
1382 }
1383 
1385 template <class T, std::size_t N, std::size_t... I>
1386 inline constexpr vector<T, N> mul(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
1387 {
1388  return {(x[I] * y[I])...};
1389 }
1390 
1391 template <class T, std::size_t N>
1392 inline constexpr vector<T, N> mul(const vector<T, N>& x, const vector<T, N>& y) noexcept
1393 {
1394  return mul(x, y, std::make_index_sequence<N>{});
1395 }
1396 
1398 template <class T, std::size_t N, std::size_t... I>
1399 inline constexpr vector<T, N> mul(const vector<T, N>& x, T y, std::index_sequence<I...>) noexcept
1400 {
1401  return {(x[I] * y)...};
1402 }
1403 
1404 template <class T, std::size_t N>
1405 inline constexpr vector<T, N> mul(const vector<T, N>& x, T y) noexcept
1406 {
1407  return mul(x, y, std::make_index_sequence<N>{});
1408 }
1409 
1411 template <class T, std::size_t N, std::size_t... I>
1412 inline constexpr vector<T, N> negate(const vector<T, N>& x, std::index_sequence<I...>) noexcept
1413 {
1414  return {(-x[I])...};
1415 }
1416 
1417 template <class T, std::size_t N>
1418 inline constexpr vector<T, N> negate(const vector<T, N>& x) noexcept
1419 {
1420  return negate(x, std::make_index_sequence<N>{});
1421 }
1422 
1423 template <std::floating_point T, std::size_t N>
1425 {
1426  return mul(x, inv_length(x));
1427 }
1428 
1430 template <class T, std::size_t N, std::size_t... I>
1431 inline constexpr vector<bool, N> logical_not(const vector<T, N>& x, std::index_sequence<I...>) noexcept
1432 {
1433  return {!x[I]...};
1434 }
1435 
1436 template <class T, std::size_t N>
1437 inline constexpr vector<bool, N> logical_not(const vector<T, N>& x) noexcept
1438 {
1439  return logical_not(x, std::make_index_sequence<N>{});
1440 }
1441 
1443 template <class T, std::size_t N, std::size_t... I>
1444 inline constexpr vector<bool, N> not_equal(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
1445 {
1446  return {(x[I] != y[I])...};
1447 }
1448 
1449 template <class T, std::size_t N>
1450 inline constexpr vector<bool, N> not_equal(const vector<T, N>& x, const vector<T, N>& y) noexcept
1451 {
1452  return not_equal(x, y, std::make_index_sequence<N>{});
1453 }
1454 
1456 template <std::floating_point T, std::size_t N, std::size_t... I>
1457 inline vector<T, N> pow(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>)
1458 {
1459  return {std::pow(x[I], y[I])...};
1460 }
1461 
1462 template <std::floating_point T, std::size_t N>
1464 {
1465  return pow(x, y, std::make_index_sequence<N>{});
1466 }
1467 
1469 template <std::floating_point T, std::size_t N, std::size_t... I>
1470 inline vector<T, N> pow(const vector<T, N>& x, T y, std::index_sequence<I...>)
1471 {
1472  return {std::pow(x[I], y)...};
1473 }
1474 
1475 template <std::floating_point T, std::size_t N>
1476 inline vector<T, N> pow(const vector<T, N>& x, T y)
1477 {
1478  return pow(x, y, std::make_index_sequence<N>{});
1479 }
1480 
1482 template <std::floating_point T, std::size_t N, std::size_t... I>
1483 inline constexpr vector<T, N> round(const vector<T, N>& x, std::index_sequence<I...>)
1484 {
1485  return {std::round(x[I])...};
1486 }
1487 
1488 template <std::floating_point T, std::size_t N>
1489 inline constexpr vector<T, N> round(const vector<T, N>& x)
1490 {
1491  return round(x, std::make_index_sequence<N>{});
1492 }
1493 
1495 template <std::floating_point T, std::size_t N, std::size_t... I>
1496 inline constexpr vector<T, N> sign(const vector<T, N>& x, std::index_sequence<I...>)
1497 {
1498  return {std::copysign(T{1}, x[I])...};
1499 }
1500 
1501 template <std::floating_point T, std::size_t N>
1502 inline constexpr vector<T, N> sign(const vector<T, N>& x)
1503 {
1504  return sign(x, std::make_index_sequence<N>{});
1505 }
1506 
1507 template <std::floating_point T>
1508 T signed_angle(const vector<T, 3>& from, const vector<T, 3>& to, const vector<T, 3>& axis)
1509 {
1510  return std::atan2(triple(axis, from, to), dot(from, to));
1511 }
1512 
1513 template <class T, std::size_t N>
1514 inline constexpr T sqr_distance(const vector<T, N>& p0, const vector<T, N>& p1) noexcept
1515 {
1516  return sqr_length(sub(p0, p1));
1517 }
1518 
1519 template <class T, std::size_t N>
1520 inline constexpr T sqr_length(const vector<T, N>& x) noexcept
1521 {
1522  return dot(x, x);
1523 }
1524 
1526 template <std::floating_point T, std::size_t N, std::size_t... I>
1527 inline vector<T, N> sqrt(const vector<T, N>& x, std::index_sequence<I...>)
1528 {
1529  return {std::sqrt(x[I])...};
1530 }
1531 
1532 template <std::floating_point T, std::size_t N>
1534 {
1535  return sqrt(x, std::make_index_sequence<N>{});
1536 }
1537 
1539 template <class T, std::size_t N, std::size_t... I>
1540 inline constexpr vector<T, N> sub(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
1541 {
1542  return {(x[I] - y[I])...};
1543 }
1544 
1545 template <class T, std::size_t N>
1546 inline constexpr vector<T, N> sub(const vector<T, N>& x, const vector<T, N>& y) noexcept
1547 {
1548  return sub(x, y, std::make_index_sequence<N>{});
1549 }
1550 
1552 template <class T, std::size_t N, std::size_t... I>
1553 inline constexpr vector<T, N> sub(const vector<T, N>& x, T y, std::index_sequence<I...>) noexcept
1554 {
1555  return {(x[I] - y)...};
1556 }
1557 
1558 template <class T, std::size_t N>
1559 inline constexpr vector<T, N> sub(const vector<T, N>& x, T y) noexcept
1560 {
1561  return sub(x, y, std::make_index_sequence<N>{});
1562 }
1563 
1565 template <class T, std::size_t N, std::size_t... I>
1566 inline constexpr vector<T, N> sub(T x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
1567 {
1568  return {(x - y[I])...};
1569 }
1570 
1571 template <class T, std::size_t N>
1572 inline constexpr vector<T, N> sub(T x, const vector<T, N>& y) noexcept
1573 {
1574  return sub(x, y, std::make_index_sequence<N>{});
1575 }
1576 
1578 template <class T, std::size_t N, std::size_t... I>
1579 inline constexpr T sum(const vector<T, N>& x, std::index_sequence<I...>) noexcept
1580 {
1581  return (x[I] + ...);
1582 }
1583 
1584 template <class T, std::size_t N>
1585 inline constexpr T sum(const vector<T, N>& x) noexcept
1586 {
1587  return sum(x, std::make_index_sequence<N>{});
1588 }
1589 
1590 template <std::size_t... Indices, class T, std::size_t N>
1591 inline constexpr vector<T, sizeof...(Indices)> swizzle(const vector<T, N>& x) noexcept
1592 {
1593  return {x[Indices]...};
1594 }
1595 
1596 template <class T>
1597 inline constexpr T triple(const vector<T, 3>& x, const vector<T, 3>& y, const vector<T, 3>& z) noexcept
1598 {
1599  return dot(x, cross(y, z));
1600 }
1601 
1603 template <std::floating_point T, std::size_t N, std::size_t... I>
1604 inline constexpr vector<T, N> trunc(const vector<T, N>& x, std::index_sequence<I...>)
1605 {
1606  return {std::trunc(x[I])...};
1607 }
1608 
1609 template <std::floating_point T, std::size_t N>
1610 inline constexpr vector<T, N> trunc(const vector<T, N>& x)
1611 {
1612  return trunc(x, std::make_index_sequence<N>{});
1613 }
1614 
1615 namespace operators {
1616 
1618 template <class T, std::size_t N>
1619 [[nodiscard]] inline constexpr vector<T, N> operator+(const vector<T, N>& x, const vector<T, N>& y) noexcept
1620 {
1621  return add(x, y);
1622 }
1623 
1626 template <class T, std::size_t N>
1627 [[nodiscard]] inline constexpr vector<T, N> operator+(const vector<T, N>& x, T y) noexcept
1628 {
1629  return add(x, y);
1630 }
1631 template <class T, std::size_t N>
1632 [[nodiscard]] inline constexpr vector<T, N> operator+(T x, const vector<T, N>& y) noexcept
1633 {
1634  return add(y, x);
1635 }
1637 
1639 template <class T, std::size_t N>
1640 [[nodiscard]] inline constexpr vector<T, N> operator/(const vector<T, N>& x, const vector<T, N>& y) noexcept
1641 {
1642  return div(x, y);
1643 }
1644 
1646 template <class T, std::size_t N>
1647 [[nodiscard]] inline constexpr vector<T, N> operator/(const vector<T, N>& x, T y) noexcept
1648 {
1649  return div(x, y);
1650 }
1651 
1653 template <class T, std::size_t N>
1654 [[nodiscard]] inline constexpr vector<T, N> operator/(T x, const vector<T, N>& y) noexcept
1655 {
1656  return div(x, y);
1657 }
1658 
1660 template <class T, std::size_t N>
1661 [[nodiscard]] inline constexpr vector<T, N> operator*(const vector<T, N>& x, const vector<T, N>& y) noexcept
1662 {
1663  return mul(x, y);
1664 }
1665 
1668 template <class T, std::size_t N>
1669 [[nodiscard]] inline constexpr vector<T, N> operator*(const vector<T, N>& x, T y) noexcept
1670 {
1671  return mul(x, y);
1672 }
1673 template <class T, std::size_t N>
1674 [[nodiscard]] inline constexpr vector<T, N> operator*(T x, const vector<T, N>& y) noexcept
1675 {
1676  return mul(y, x);
1677 }
1679 
1681 template <class T, std::size_t N>
1682 [[nodiscard]] inline constexpr vector<T, N> operator-(const vector<T, N>& x) noexcept
1683 {
1684  return negate(x);
1685 }
1686 
1688 template <class T, std::size_t N>
1689 [[nodiscard]] inline constexpr vector<T, N> operator-(const vector<T, N>& x, const vector<T, N>& y) noexcept
1690 {
1691  return sub(x, y);
1692 }
1693 
1695 template <class T, std::size_t N>
1696 [[nodiscard]] inline constexpr vector<T, N> operator-(const vector<T, N>& x, T y) noexcept
1697 {
1698  return sub(x, y);
1699 }
1700 
1702 template <class T, std::size_t N>
1703 [[nodiscard]] inline constexpr vector<T, N> operator-(T x, const vector<T, N>& y) noexcept
1704 {
1705  return sub(x, y);
1706 }
1707 
1717 template <class T, std::size_t N>
1718 inline constexpr vector<T, N>& operator+=(vector<T, N>& x, const vector<T, N>& y) noexcept
1719 {
1720  return (x = x + y);
1721 }
1722 template <class T, std::size_t N>
1723 inline constexpr vector<T, N>& operator+=(vector<T, N>& x, T y) noexcept
1724 {
1725  return (x = x + y);
1726 }
1728 
1738 template <class T, std::size_t N>
1739 inline constexpr vector<T, N>& operator-=(vector<T, N>& x, const vector<T, N>& y) noexcept
1740 {
1741  return (x = x - y);
1742 }
1743 template <class T, std::size_t N>
1744 inline constexpr vector<T, N>& operator-=(vector<T, N>& x, T y) noexcept
1745 {
1746  return (x = x - y);
1747 }
1749 
1759 template <class T, std::size_t N>
1760 inline constexpr vector<T, N>& operator*=(vector<T, N>& x, const vector<T, N>& y) noexcept
1761 {
1762  return (x = x * y);
1763 }
1764 template <class T, std::size_t N>
1765 inline constexpr vector<T, N>& operator*=(vector<T, N>& x, T y) noexcept
1766 {
1767  return (x = x * y);
1768 }
1770 
1780 template <class T, std::size_t N>
1781 inline constexpr vector<T, N>& operator/=(vector<T, N>& x, const vector<T, N>& y) noexcept
1782 {
1783  return (x = x / y);
1784 }
1785 template <class T, std::size_t N>
1786 inline constexpr vector<T, N>& operator/=(vector<T, N>& x, T y) noexcept
1787 {
1788  return (x = x / y);
1789 }
1791 
1800 template <class T, std::size_t N>
1801 inline constexpr bool operator==(const vector<T, N>& x, const vector<T, N>& y) noexcept
1802 {
1803  // if consteval
1804  // {
1805  for (std::size_t i = 0; i < N; ++i)
1806  {
1807  if (x[i] != y[i])
1808  {
1809  return false;
1810  }
1811  }
1812 
1813  return true;
1814  // }
1815  // else
1816  // {
1817  // !std::memcmp(x.data(), y.data(), N * sizeof(T));
1818  // }
1819 }
1820 
1829 template <class T, std::size_t N>
1830 inline constexpr bool operator!=(const vector<T, N>& x, const vector<T, N>& y) noexcept
1831 {
1832  return !(x == y);
1833 }
1834 
1835 } // namespace operators
1836 
1837 } // namespace math
1838 
1839 // Bring vector operators into global namespace
1840 using namespace math::operators;
1841 
1842 namespace std
1843 {
1850  template<class T, std::size_t N>
1851  struct tuple_size<math::vector<T, N>>
1852  {
1854  static constexpr std::size_t value = math::vector<T, N>::element_count;
1855  };
1856 
1864  template<std::size_t I, class T, std::size_t N>
1865  struct tuple_element<I, math::vector<T, N>>
1866  {
1869  };
1870 
1877  template <class T, std::size_t N>
1878  struct formatter<math::vector<T, N>>: formatter<T>
1879  {
1880  auto format(const math::vector<T, N>& t, format_context& fc) const
1881  {
1882  auto&& out = fc.out();
1883  format_to(out, "{{");
1884 
1885  for (std::size_t i = 0; i < N; ++i)
1886  {
1887  formatter<T>::format(t[i], fc);
1888  if (i < N - 1)
1889  {
1890  format_to(out, ", ");
1891  }
1892  }
1893 
1894  return format_to(out, "}}");
1895  }
1896  };
1897 }
1898 
1899 // Ensure vectors are POD types
1900 static_assert(std::is_standard_layout_v<math::fvec3>);
1901 static_assert(std::is_trivial_v<math::fvec3>);
1902 
1903 #endif // ANTKEEPER_MATH_VECTOR_HPP
format
Image and vertex formats.
Definition: format.hpp:29
Mathematical operators.
constexpr vector< T, N > operator+(T x, const vector< T, N > &y) noexcept
Definition: vector.hpp:1632
constexpr vector< T, N > operator/(T x, const vector< T, N > &y) noexcept
Divides a vector by a value.
Definition: vector.hpp:1654
constexpr vector< T, N > & operator*=(vector< T, N > &x, T y) noexcept
Multiplies two values and stores the result in the first value.
Definition: vector.hpp:1765
constexpr vector< T, N > & operator-=(vector< T, N > &x, T y) noexcept
Subtracts the first value by the second value and stores the result in the first value.
Definition: vector.hpp:1744
constexpr vector< T, N > & operator/=(vector< T, N > &x, T y) noexcept
Divides the first value by the second value and stores the result in the first value.
Definition: vector.hpp:1786
constexpr vector< T, N > operator-(T x, const vector< T, N > &y) noexcept
Subtracts a value by another value.
Definition: vector.hpp:1703
constexpr vector< T, N > & operator+=(vector< T, N > &x, T y) noexcept
Adds two values and stores the result in the first value.
Definition: vector.hpp:1723
constexpr vector< T, N > operator*(T x, const vector< T, N > &y) noexcept
Multiplies two values.
Definition: vector.hpp:1674
constexpr bool operator==(const vector< T, N > &x, const vector< T, N > &y) noexcept
Tests two vector for equality.
Definition: vector.hpp:1801
constexpr bool operator!=(const vector< T, N > &x, const vector< T, N > &y) noexcept
Tests two vector for inequality.
Definition: vector.hpp:1830
Vector types.
Definition: vector.hpp:351
Mathematical functions and data types.
Definition: angles.hpp:26
T fract(T x)
Returns the fractional part of a floating-point number.
Definition: fract.hpp:38
constexpr vector< T, N > sign(const vector< T, N > &x)
Returns a vector containing the signs of each element.
Definition: vector.hpp:1502
constexpr T sqr_distance(const vector< T, N > &p0, const vector< T, N > &p1) noexcept
Calculates the square distance between two points.
Definition: vector.hpp:1514
constexpr vector< bool, N > not_equal(const vector< T, N > &x, const vector< T, N > &y) noexcept
Compares two vectors for inequality.
Definition: vector.hpp:1450
constexpr vector< T, N > round(const vector< T, N > &x)
Performs a element-wise round operation.
Definition: vector.hpp:1489
constexpr vector< T, N > floor(const vector< T, N > &x)
Performs a element-wise floor operation.
Definition: vector.hpp:1184
T signed_angle(const vector< T, 3 > &x, const vector< T, 3 > &y, const vector< T, 3 > &n)
Calculates the signed angle between two direction vectors about axis.
Definition: vector.hpp:1508
constexpr matrix< T, P, M > mul(const matrix< T, N, M > &a, const matrix< T, P, N > &b) noexcept
Multiplies two matrices.
constexpr vector< T, N > trunc(const vector< T, N > &x)
Performs a element-wise trunc operation.
Definition: vector.hpp:1610
T angle(const vector< T, N > &from, const vector< T, N > &to)
Calculates the angle between two direction vectors.
Definition: vector.hpp:1030
constexpr vector< T, N > fma(const vector< T, N > &x, const vector< T, N > &y, const vector< T, N > &z)
Performs a multiply-add operation.
Definition: vector.hpp:1197
constexpr vector< T, sizeof...(Indices)> swizzle(const vector< T, N > &x) noexcept
Makes an m-dimensional vector by rearranging and/or duplicating elements of an n-dimensional vector.
Definition: vector.hpp:1591
vector< T, N > clamp_length(const vector< T, N > &x, T max_length)
Clamps the length of a vector.
Definition: vector.hpp:1088
constexpr vector< T, N > max(const vector< T, N > &x, const vector< T, N > &y)
Returns a vector containing the maximum elements of two vectors.
Definition: vector.hpp:1328
quaternion< T > normalize(const quaternion< T > &q)
Normalizes a quaternion.
Definition: quaternion.hpp:679
constexpr matrix< T, N, M > div(const matrix< T, N, M > &a, const matrix< T, N, M > &b) noexcept
Divides a matrix by a matrix.
constexpr vector< T, N > mod(const vector< T, N > &x, const vector< T, N > &y)
Calculates the element-wise remainder of the division operation x / y.
Definition: vector.hpp:1366
T length(const quaternion< T > &q)
Calculates the length of a quaternion.
Definition: quaternion.hpp:602
constexpr vector< T, N > ceil(const vector< T, N > &x)
Performs an element-wise ceil operation.
Definition: vector.hpp:1056
vector< T, N > pow(const vector< T, N > &x, const vector< T, N > &y)
Raises each element to a power.
Definition: vector.hpp:1463
constexpr matrix< T, N, M > add(const matrix< T, N, M > &a, const matrix< T, N, M > &b) noexcept
Adds two matrices.
constexpr vector< T, N > abs(const vector< T, N > &x)
Returns the absolute values of each element.
Definition: vector.hpp:985
constexpr vector< bool, N > less_than_equal(const vector< T, N > &x, const vector< T, N > &y) noexcept
Performs a element-wise less-than or equal-to comparison of two vectors.
Definition: vector.hpp:1315
constexpr bool all(const vector< bool, N > &x) noexcept
Checks if all elements of a boolean vector are true.
Definition: vector.hpp:1024
constexpr T sqr_length(const quaternion< T > &q) noexcept
Calculates the square length of a quaternion.
Definition: quaternion.hpp:744
constexpr vector< bool, N > logical_not(const vector< T, N > &x) noexcept
Logically inverts a boolean vector.
Definition: vector.hpp:1437
constexpr T triple(const vector< T, 3 > &x, const vector< T, 3 > &y, const vector< T, 3 > &z) noexcept
Calculates the triple product of three vectors.
Definition: vector.hpp:1597
constexpr vector< bool, N > less_than(const vector< T, N > &x, const vector< T, N > &y) noexcept
Performs a element-wise less-than comparison of two vectors.
Definition: vector.hpp:1302
constexpr vector< bool, N > equal(const vector< T, N > &x, const vector< T, N > &y) noexcept
Compares two vectors for equality.
Definition: vector.hpp:1171
T distance(const vector< T, N > &p0, const vector< T, N > &p1)
Calculates the distance between two points.
Definition: vector.hpp:1106
constexpr matrix< T, N, M > sub(const matrix< T, N, M > &a, const matrix< T, N, M > &b) noexcept
Subtracts a matrix from another matrix.
constexpr vector< T, N > clamp(const vector< T, N > &x, const vector< T, N > &min, const vector< T, N > &max)
Clamps the values of a vector's elements.
Definition: vector.hpp:1069
constexpr matrix< T, N, M >::column_vector_type & get(matrix< T, N, M > &m) noexcept
Extracts the Ith column from a matrix.
constexpr vector< bool, N > greater_than_equal(const vector< T, N > &x, const vector< T, N > &y) noexcept
Performs a element-wise greater-than or equal-to comparison of two vectors.
Definition: vector.hpp:1277
constexpr vector< T, 3 > cross(const vector< T, 3 > &x, const vector< T, 3 > &y) noexcept
Calculates the cross product of two vectors.
Definition: vector.hpp:1095
constexpr bool any(const vector< bool, N > &x) noexcept
Checks if any elements of a boolean vector are true.
Definition: vector.hpp:1043
constexpr vector< bool, N > greater_than(const vector< T, N > &x, const vector< T, N > &y) noexcept
Performs a element-wise greater-than comparison of two vectors.
Definition: vector.hpp:1264
vector< T, N > sqrt(const vector< T, N > &x)
Takes the square root of each element.
constexpr T dot(const quaternion< T > &a, const quaternion< T > &b) noexcept
Calculates the dot product of two quaternions.
Definition: quaternion.hpp:572
vector< T, N > sqrt(const vector< T, N > &x, const vector< T, N > &y)
Definition: vector.hpp:1533
T inv_length(const quaternion< T > &q)
Calculates the inverse length of a quaternion.
Definition: quaternion.hpp:596
constexpr T sum(const vector< T, N > &x) noexcept
Calculates the sum of all elements in a vector.
Definition: vector.hpp:1585
constexpr vector< T, N > min(const vector< T, N > &x, const vector< T, N > &y)
Returns a vector containing the minimum elements of two vectors.
Definition: vector.hpp:1347
constexpr quaternion< T > negate(const quaternion< T > &q) noexcept
Negates a quaternion.
Definition: quaternion.hpp:667
Text and typography.
Definition: bitmap-font.cpp:24
n-dimensional vector.
Definition: vector.hpp:44
constexpr const element_type & operator[](std::size_t i) const noexcept
Returns a reference to the element at a given index.
Definition: vector.hpp:114
constexpr const element_type & front() const noexcept
Returns a reference to the first element.
Definition: vector.hpp:128
constexpr element_type & x() noexcept
Returns a reference to the first element.
Definition: vector.hpp:164
constexpr element_type & back() noexcept
Returns a reference to the last element.
Definition: vector.hpp:138
constexpr std::reverse_iterator< const element_type * > rend() const noexcept
Returns a reverse iterator to the element following the last element of the reversed vector.
Definition: vector.hpp:275
constexpr element_type & y() noexcept
Returns a reference to the second element.
Definition: vector.hpp:180
constexpr element_type * data() noexcept
Returns a pointer to the element array.
Definition: vector.hpp:152
constexpr std::reverse_iterator< const element_type * > crbegin() const noexcept
Returns a reverse iterator to the first element of the reversed vector.
Definition: vector.hpp:261
constexpr std::reverse_iterator< const element_type * > crend() const noexcept
Returns a reverse iterator to the element following the last element of the reversed vector.
Definition: vector.hpp:279
constexpr const element_type * cbegin() const noexcept
Returns an iterator to the first element.
Definition: vector.hpp:225
constexpr std::reverse_iterator< element_type * > rbegin() noexcept
Returns a reverse iterator to the first element of the reversed vector.
Definition: vector.hpp:253
constexpr const element_type * data() const noexcept
Returns a pointer to the element array.
Definition: vector.hpp:156
static constexpr vector zero() noexcept
Returns a zero vector, where every element is equal to zero.
Definition: vector.hpp:306
static constexpr vector one() noexcept
Returns a vector of ones, where every element is equal to one.
Definition: vector.hpp:324
static constexpr vector infinity() noexcept
Returns a vector of infinities, where every element is equal to infinity.
Definition: vector.hpp:342
constexpr element_type * begin() noexcept
Returns an iterator to the first element.
Definition: vector.hpp:217
constexpr element_type & operator[](std::size_t i) noexcept
Returns a reference to the element at a given index.
Definition: vector.hpp:110
constexpr const element_type & z() const noexcept
Returns a reference to the third element.
Definition: vector.hpp:201
constexpr element_type & front() noexcept
Returns a reference to the first element.
Definition: vector.hpp:124
T element_type
Element type.
Definition: vector.hpp:46
constexpr const element_type & x() const noexcept
Returns a reference to the first element.
Definition: vector.hpp:169
constexpr const element_type & y() const noexcept
Returns a reference to the second element.
Definition: vector.hpp:185
constexpr element_type & z() noexcept
Returns a reference to the third element.
Definition: vector.hpp:196
static constexpr std::size_t element_count
Number of elements.
Definition: vector.hpp:49
constexpr const element_type * cend() const noexcept
Returns an iterator to the element following the last element.
Definition: vector.hpp:243
constexpr const element_type * end() const noexcept
Returns an iterator to the element following the last element.
Definition: vector.hpp:239
constexpr const element_type & back() const noexcept
Returns a reference to the last element.
Definition: vector.hpp:142
constexpr std::reverse_iterator< element_type * > rend() noexcept
Returns a reverse iterator to the element following the last element of the reversed vector.
Definition: vector.hpp:271
constexpr std::size_t size() const noexcept
Returns the number of elements in the vector.
Definition: vector.hpp:293
constexpr std::reverse_iterator< const element_type * > rbegin() const noexcept
Returns a reverse iterator to the first element of the reversed vector.
Definition: vector.hpp:257
constexpr const element_type * begin() const noexcept
Returns an iterator to the first element.
Definition: vector.hpp:221
element_type elements[N]
Array of elements.
Definition: vector.hpp:52
constexpr element_type * end() noexcept
Returns an iterator to the element following the last element.
Definition: vector.hpp:235
auto format(const math::vector< T, N > &t, format_context &fc) const
Definition: vector.hpp:1880