Maipa's Standard Library Extension 1.5.6
mstd
Loading...
Searching...
No Matches
vec.hpp
1/*
2 * mstd - Maipa's Standard Library
3 *
4 * Licensed under the BSD 3-Clause License with Attribution Requirement.
5 * See the LICENSE file for details: https://github.com/MAIPA01/mstd/blob/main/LICENSE
6 *
7 * Copyright (c) 2025, Patryk Antosik (MAIPA01)
8 *
9 * Tested and fixed by Muppetsg2 (https://github.com/Muppetsg2)
10 */
11
12#pragma once
13#ifndef _MSTD_VEC_HPP_
14 #define _MSTD_VEC_HPP_
15
16 #include <mstd/config.hpp>
17
19_MSTD_WARNING("this is only available for c++17 and greater!");
20 #else
21
22 #include <mstd/arithmetic_types.hpp>
23 #include <mstd/math_functions.hpp>
24
25namespace mstd {
27 template<size_t N, arithmetic T>
28 requires (N > 0)
29 #else
30 template<size_t N, class T, std::enable_if_t<(N > 0 && std::is_arithmetic_v<T>), bool> >
31 #endif
32 class vec {
33 public:
34 static _MSTD_CONSTEXPR20 const size_t size = N;
35 using value_type = T;
36
37 private:
38 T _values[N] = {};
39
40 #pragma region PRIVATE_METHODS
42 template<arithmetic... Ts, size_t... Idxs>
43 #else
44 template<class... Ts, size_t... Idxs>
45 #endif
46 _MSTD_CONSTEXPR20 void _set_values(const std::index_sequence<Idxs...>&, const Ts&... values) {
47 ((_values[Idxs] = static_cast<T>(values)), ...);
48 }
49
50 _MSTD_CONSTEXPR20 void _fill_values(const T& value) { std::fill_n(&_values[0], N, value); }
51
52 _MSTD_CONSTEXPR20 void _fill_values_from(size_t firstIdx, const T& value) {
53 if (firstIdx >= N) { return; }
54 std::fill_n(&_values[0] + firstIdx, N - firstIdx, value);
55 }
56
58 template<arithmetic OT>
59 #else
60 template<class OT>
61 #endif
62 _MSTD_CONSTEXPR20 void _copy_values_from(const OT*& values, const size_t& size) {
63 if _MSTD_CONSTEXPR17 (std::is_same_v<OT, T>) { std::memcpy(&_values[0], values, std::min(N, size) * sizeof(T)); }
64 else {
65 for (size_t i = 0; i != std::min(N, size); ++i) { _values[i] = static_cast<T>(values[i]); }
66 }
67 }
68
70 template<size_t TN, arithmetic OT>
71 #else
72 template<size_t TN, class OT>
73 #endif
74 _MSTD_CONSTEXPR20 void _copy_values_from(const OT (&values)[TN]) {
75 if _MSTD_CONSTEXPR17 (std::is_same_v<T, OT>) {
76 std::memcpy(&_values[0], &values[0], std::min(N, TN) * sizeof(T));
77 }
78 else {
79 for (size_t i = 0; i != std::min(N, TN); ++i) { _values[i] = static_cast<T>(values[i]); }
80 }
81 }
82
84 template<size_t ON, arithmetic OT>
85 requires (ON > 0)
86 #else
87 template<size_t ON, class OT>
88 #endif
89 _MSTD_CONSTEXPR20 void _copy_values_from(const vec<ON, OT>& other) {
90 if _MSTD_CONSTEXPR17 (std::is_same_v<OT, T>) {
91 std::memcpy(&_values[0], static_cast<const T*>(other), std::min(N, ON) * sizeof(T));
92 }
93 else {
94 for (size_t i = 0; i != std::min(N, ON); ++i) { _values[i] = static_cast<T>(other[i]); }
95 }
96 }
97
98 #pragma endregion // PRIVATE_METHODS
99
100 public:
101 #pragma region CONSTRUCTORS
102
103 // vecN()
104 _MSTD_CONSTEXPR20 vec() { _fill_values(T(0)); }
105
106 // vecN(x, y, ...)
108 template<arithmetic... Ts>
109 requires (sizeof...(Ts) > 0 && sizeof...(Ts) <= N)
110 #else
111 template<class... Ts,
112 std::enable_if_t<(sizeof...(Ts) > 0 && sizeof...(Ts) <= N && are_all_v<std::is_arithmetic, Ts...>), bool> = true>
113 #endif
114 _MSTD_CONSTEXPR20 vec(const Ts&... values) {
115 _set_values<Ts...>(std::index_sequence_for<Ts...>(), values...);
116 _fill_values_from(sizeof...(Ts), 0);
117 }
118
119 // vecN(vec, z, ...)
121 template<size_t ON, arithmetic OT, arithmetic... Ts>
122 requires (sizeof...(Ts) > 0 && sizeof...(Ts) <= N - ON && ON < N)
123 #else
124 template<size_t ON, class OT, class... Ts,
125 std::enable_if_t<(sizeof...(Ts) > 0 && sizeof...(Ts) <= N - ON && ON < N && are_all_v<std::is_arithmetic, OT, Ts...>),
126 bool> = true>
127 #endif
128 _MSTD_CONSTEXPR20 vec(const vec<ON, OT>& other, const Ts&... values) {
129 _copy_values_from(other);
130 _set_values<Ts...>(make_index_sequence_for_from<ON, Ts...>(), values...);
131 _fill_values_from(sizeof...(Ts) + ON, 0);
132 }
133
134 // vecN({ 1, 2 })
136 template<size_t TN, arithmetic OT>
137 #else
138 template<size_t TN, class OT, std::enable_if_t<std::is_arithmetic_v<OT>, bool> = true>
139 #endif
140 _MSTD_CONSTEXPR20 vec(const OT (&values)[TN]) {
141 _copy_values_from(values);
142 _fill_values_from(TN, 0);
143 }
144
145 // vecN(&table)
147 template<arithmetic OT>
148 #else
149 template<class OT, std::enable_if_t<std::is_arithmetic_v<OT>, bool> = true>
150 #endif
151 _MSTD_CONSTEXPR20 vec(const OT* values, const size_t& size) {
152 _copy_values_from(values, size);
153 _fill_values_from(size, 0);
154 }
155
156 // vecN(vecON)
158 template<size_t ON, arithmetic OT>
159 #else
160 template<size_t ON, class OT>
161 #endif
162 _MSTD_CONSTEXPR20 vec(const vec<ON, OT>& other) {
163 _copy_values_from(other);
164 _fill_values_from(ON, 0);
165 }
166
167 #pragma region VECTOR_3_CONSTRUCTORS
169 template<arithmetic AT, arithmetic BT, size_t ON>
170 requires (ON == 3)
171 #else
172 template<class AT, class BT, size_t ON, std::enable_if_t<(ON == 3), bool> = true>
173 #endif
174 _MSTD_CONSTEXPR20 vec(const vec<ON, AT>& otherA, const vec<ON, BT>& otherB) : vec(otherA.cross(otherB)) {
175 }
176
177 #pragma endregion // VECTOR_3_CONSTRUCTORS
178 #pragma endregion // CONSTRUCTORS
179
180 #pragma region DESTRUCTOR
181 _MSTD_CONSTEXPR20 ~vec() = default;
182 #pragma endregion // DESTRUCTOR
183
184 #pragma region ASSIGN
186 template<size_t TN, arithmetic OT>
187 #else
188 template<size_t TN, class OT, std::enable_if_t<std::is_arithmetic_v<OT>, bool> = true>
189 #endif
190 _MSTD_CONSTEXPR20 vec<N, T>& operator=(const OT (&values)[TN]) {
191 _copy_values_from(values);
192 _fill_values_from(TN, 0);
193 return *this;
194 }
196 template<size_t ON, arithmetic OT>
197 #else
198 template<size_t ON, class OT, std::enable_if_t<std::is_arithmetic_v<OT>, bool> = true>
199 #endif
200 _MSTD_CONSTEXPR20 vec<N, T>& operator=(const vec<ON, OT>& other) {
201 _copy_values_from(other);
202 _fill_values_from(ON, 0);
203 return *this;
204 }
205
206 #pragma endregion // ASSIGN
207
208 #pragma region PREDEFINED
209
210 static _MSTD_CONSTEXPR20 vec<N, T> zero() { return vec<N, T>(); }
211
212 static _MSTD_CONSTEXPR20 vec<N, T> one() { return fill(static_cast<T>(1)); }
213
214 static _MSTD_CONSTEXPR20 vec<N, T> fill(const T& value) {
215 vec<N, T> res;
216 res._fill_values(value);
217 return res;
218 }
219
220 #pragma endregion // PREDEFINED
221
222 #pragma region PREDEFINED_CHECKS
223
224 _MSTD_CONSTEXPR20 bool is_zero() const { return is_filled_with(static_cast<T>(0)); }
225
226 _MSTD_CONSTEXPR20 bool is_one() const { return is_filled_with(static_cast<T>(1)); }
227
228 _MSTD_CONSTEXPR20 bool is_filled_with(const T& value) const {
229 for (size_t i = 0; i != N; ++i) {
230 if (_values[i] != value) { return false; }
231 }
232 return true;
233 }
234
235 _MSTD_CONSTEXPR20 bool is_normalized() const { return length() == static_cast<T>(1); }
236
237 #pragma endregion // PREDEFINED_CHECKS
238
239 #pragma region VECTOR_GETTERS
240
241 _MSTD_CONSTEXPR20 T& x() { return _values[0]; }
242
243 _MSTD_CONSTEXPR20 T x() const { return _values[0]; }
244
245 _MSTD_CONSTEXPR20 T& r() { return _values[0]; }
246
247 _MSTD_CONSTEXPR20 T r() const { return _values[0]; }
248
249 _MSTD_ENABLE_IF_TEMPLATE(Type = value_type, (N > 1 && std::is_same_v<Type, value_type>))
250
251 _MSTD_CONSTEXPR20 T& y() _MSTD_REQUIRES(N > 1) { return _values[1]; }
252 _MSTD_ENABLE_IF_TEMPLATE(Type = value_type, (N > 1 && std::is_same_v<Type, value_type>))
253
254 _MSTD_CONSTEXPR20 T y() const _MSTD_REQUIRES(N > 1) { return _values[1]; }
255
256 _MSTD_ENABLE_IF_TEMPLATE(Type = value_type, (N > 1 && std::is_same_v<Type, value_type>))
257
258 _MSTD_CONSTEXPR20 T& g() _MSTD_REQUIRES(N > 1) { return _values[1]; }
259 _MSTD_ENABLE_IF_TEMPLATE(Type = value_type, (N > 1 && std::is_same_v<Type, value_type>))
260
261 _MSTD_CONSTEXPR20 T g() const _MSTD_REQUIRES(N > 1) { return _values[1]; }
262
263 _MSTD_ENABLE_IF_TEMPLATE(Type = value_type, (N > 2 && std::is_same_v<Type, value_type>))
264
265 _MSTD_CONSTEXPR20 T& z() _MSTD_REQUIRES(N > 2) { return _values[2]; }
266 _MSTD_ENABLE_IF_TEMPLATE(Type = value_type, (N > 2 && std::is_same_v<Type, value_type>))
267
268 _MSTD_CONSTEXPR20 T z() const _MSTD_REQUIRES(N > 2) { return _values[2]; }
269
270 _MSTD_ENABLE_IF_TEMPLATE(Type = value_type, (N > 2 && std::is_same_v<Type, value_type>))
271
272 _MSTD_CONSTEXPR20 T& b() _MSTD_REQUIRES(N > 2) { return _values[2]; }
273 _MSTD_ENABLE_IF_TEMPLATE(Type = value_type, (N > 2 && std::is_same_v<Type, value_type>))
274
275 _MSTD_CONSTEXPR20 T b() const _MSTD_REQUIRES(N > 2) { return _values[2]; }
276
277 _MSTD_ENABLE_IF_TEMPLATE(Type = value_type, (N > 3 && std::is_same_v<Type, value_type>))
278
279 _MSTD_CONSTEXPR20 T& w() _MSTD_REQUIRES(N > 3) { return _values[3]; }
280 _MSTD_ENABLE_IF_TEMPLATE(Type = value_type, (N > 3 && std::is_same_v<Type, value_type>))
281
282 _MSTD_CONSTEXPR20 T w() const _MSTD_REQUIRES(N > 3) { return _values[3]; }
283
284 _MSTD_ENABLE_IF_TEMPLATE(Type = value_type, (N > 3 && std::is_same_v<Type, value_type>))
285
286 _MSTD_CONSTEXPR20 T& a() _MSTD_REQUIRES(N > 3) { return _values[3]; }
287 _MSTD_ENABLE_IF_TEMPLATE(Type = value_type, (N > 3 && std::is_same_v<Type, value_type>))
288
289 _MSTD_CONSTEXPR20 T a() const _MSTD_REQUIRES(N > 3) { return _values[3]; }
290
291 #pragma endregion // VECTOR_GETTERS
292
293 #pragma region VECTOR_OPERATIONS
294
296 T value = static_cast<T>(0);
297 for (size_t i = 0; i != N; ++i) { value += _values[i] * _values[i]; }
298 return static_cast<T>(std::sqrt(value));
299 }
300
302 T len = length();
303 if (len == static_cast<T>(0)) { return *this; }
304 *this /= len;
305 return *this;
306 }
307
308 _MSTD_CONSTEXPR20 vec<N, T> normalized() const {
309 vec<N, T> res = *this;
310 return res.normalize();
311 }
312
313 _MSTD_CONSTEXPR20 T dot(const vec<N, T>& other) const {
314 T res = static_cast<T>(0);
315 for (size_t i = 0; i != N; ++i) { res += _values[i] * other[i]; }
316 return res;
317 }
318
319 _MSTD_CONSTEXPR20 T angle_between(const vec<N, T>& other) const {
320 T thisLen = length();
321 if (thisLen == static_cast<T>(0)) { return static_cast<T>(0); }
322
323 T otherLen = other.length();
324 if (otherLen == static_cast<T>(0)) { return static_cast<T>(0); }
325
326 return static_cast<T>(std::acos(dot(other) / (thisLen * otherLen)));
327 }
328
329 _MSTD_CONSTEXPR20 vec<N, T>& reflect(const vec<N, T>& normal) noexcept {
330 _MSTD_CONSTEXPR17 const float two = 2.0f;
331 *this -= two * this->dot(normal) * normal;
332 return *this;
333 }
334
335 _MSTD_CONSTEXPR20 vec<N, T> reflected(const vec<N, T>& normal) const noexcept {
336 vec<N, T> res = *this;
337 return res.reflect(normal);
338 }
339
340 _MSTD_CONSTEXPR20 vec<N, T>& refract(const vec<N, T>& normal, const T& eta) {
341 *this = this->refracted(normal, eta);
342 return *this;
343 }
344
345 _MSTD_CONSTEXPR20 vec<N, T> refracted(const vec<N, T>& normal, const T& eta) const {
346 float cosTheta = std::min((-(*this)).dot(normal), 1.0f);
347 vec<N, T> rOutPerp = eta * (*this + (cosTheta * normal));
348 float length = rOutPerp.length();
349 vec<N, T> rOutParallel = -std::sqrt(std::abs(1.0f - (length * length))) * normal;
350 return rOutPerp + rOutParallel;
351 }
352
353 _MSTD_CONSTEXPR20 vec<N, T>& saturate() noexcept {
354 for (size_t i = 0; i != N; ++i) { _values[i] = ::mstd::saturate(_values[i]); }
355 return *this;
356 }
357
358 _MSTD_CONSTEXPR20 vec<N, T> saturated() const noexcept {
359 vec<N, T> res = *this;
360 return res.saturate();
361 }
362
363 _MSTD_CONSTEXPR20 vec<N, T>& fract() noexcept {
364 for (size_t i = 0; i != N; ++i) { _values[i] = ::mstd::fract(_values[i]); }
365 return *this;
366 }
367
368 _MSTD_CONSTEXPR20 vec<N, T> fracted() const noexcept {
369 vec<N, T> res = *this;
370 return res.fract();
371 }
372
373 _MSTD_CONSTEXPR20 vec<N, T>& mod(const T& y) {
374 for (size_t i = 0; i != N; ++i) { _values[i] -= y * std::floor(_values[i] / y); }
375 return *this;
376 }
377
378 _MSTD_CONSTEXPR20 vec<N, T> modded(const T& y) const {
379 vec<N, T> res = *this;
380 return res.mod(y);
381 }
382
383 _MSTD_CONSTEXPR20 vec<N, T>& mod(const vec<N, T>& other) {
384 for (size_t i = 0; i != N; ++i) { _values[i] -= other[i] * std::floor(_values[i] / other[i]); }
385 return *this;
386 }
387
388 _MSTD_CONSTEXPR20 vec<N, T> modded(const vec<N, T>& other) const {
389 vec<N, T> res = *this;
390 return res.mod(other);
391 }
392
393 _MSTD_CONSTEXPR20 vec<N, T>& pow(const T& y) {
394 for (size_t i = 0; i != N; ++i) { _values[i] = std::pow(_values[i], y); }
395 return *this;
396 }
397
398 _MSTD_CONSTEXPR20 vec<N, T> powed(const T& y) const {
399 vec<N, T> res = *this;
400 return res.pow(y);
401 }
402
403 _MSTD_CONSTEXPR20 vec<N, T>& pow(const vec<N, T>& other) {
404 for (size_t i = 0; i != N; ++i) { _values[i] = std::pow(_values[i], other[i]); }
405 return *this;
406 }
407
408 _MSTD_CONSTEXPR20 vec<N, T> powed(const vec<N, T>& other) const {
409 vec<N, T> res = *this;
410 return res.pow(other);
411 }
412
413 _MSTD_CONSTEXPR20 vec<N, T>& clamp(const T& minVal, const T& maxVal) {
414 for (size_t i = 0; i != N; ++i) { _values[i] = std::clamp(_values[i], minVal, maxVal); }
415 return *this;
416 }
417
418 _MSTD_CONSTEXPR20 vec<N, T> clampped(const T& minVal, const T& maxVal) const {
419 vec<N, T> res = *this;
420 return res.clamp(minVal, maxVal);
421 }
422
423 _MSTD_CONSTEXPR20 vec<N, T>& clamp(const vec<N, T>& minVal, const vec<N, T>& maxVal) {
424 for (size_t i = 0; i != N; ++i) { _values[i] = std::clamp(_values[i], minVal[i], maxVal[i]); }
425 return *this;
426 }
427
428 _MSTD_CONSTEXPR20 vec<N, T> clampped(const vec<N, T>& minVal, const vec<N, T>& maxVal) const {
429 vec<N, T> res = *this;
430 return res.clamp(minVal, maxVal);
431 }
432
433 _MSTD_CONSTEXPR20 vec<N, T>& step(const T& edge) noexcept {
434 for (size_t i = 0; i != N; ++i) { _values[i] = ::mstd::step(edge, _values[i]); }
435 return *this;
436 }
437
438 _MSTD_CONSTEXPR20 vec<N, T>& step(const vec<N, T>& edge) noexcept {
439 for (size_t i = 0; i != N; ++i) { _values[i] = ::mstd::step(edge[i], _values[i]); }
440 return *this;
441 }
442
443 _MSTD_CONSTEXPR20 vec<N, T> stepped(const T& edge) const noexcept {
444 vec<N, T> res = *this;
445 return res.step(edge);
446 }
447
448 _MSTD_CONSTEXPR20 vec<N, T> stepped(const vec<N, T>& edge) const noexcept {
449 vec<N, T> res = *this;
450 return res.step(edge);
451 }
452
453 #pragma region VECTOR_3_OPERATIONS
454 _MSTD_ENABLE_IF_TEMPLATE(Type = value_type, (N == 3 && std::is_same_v<Type, value_type>))
455
456 _MSTD_CONSTEXPR20 vec<N, T> cross(const vec<N, T>& other) const _MSTD_REQUIRES(N == 3) {
457 return vec<N, T>((_values[1] * other[2]) - (_values[2] * other[1]), (_values[2] * other[0]) - (_values[0] * other[2]),
458 (_values[0] * other[1]) - (_values[1] * other[0]));
459 }
460
461 _MSTD_ENABLE_IF_TEMPLATE(Type = value_type, (N == 3 && std::is_same_v<Type, value_type>))
462
463 _MSTD_CONSTEXPR20 vec<N, T>& rotate(const vec<N, T>& axis, const T& radians) _MSTD_REQUIRES(N == 3) {
464 const quat<T> p(T(0), *this);
465
466 vec<N, T> normAxis = axis;
467 if (!normAxis.is_zero()) { normAxis.normalize(); }
468
469 const quat<T>& q = quat<T>::rotation(normAxis, radians);
470
471 const quat<T>& inversQ = q.inverted();
472
473 *this = (q * p * inversQ).v;
474 return *this;
475 }
476 _MSTD_ENABLE_IF_TEMPLATE(Type = value_type, (N == 3 && std::is_same_v<Type, value_type>))
477
478 _MSTD_CONSTEXPR20 vec<N, T> rotated(const vec<N, T>& axis, const T& radians) _MSTD_REQUIRES(N == 3) {
479 vec<N, T> res = *this;
480 return res.rotate(axis, radians);
481 }
482
483 #pragma endregion // VECTOR_3_OPERATIONS
484 #pragma endregion // VECTOR_OPERTATIONS
485
486 #pragma region OPERATORS
487
488 _MSTD_CONSTEXPR20 vec<N, T>& operator+=(const vec<N, T>& other) {
489 for (size_t i = 0; i != N; ++i) { _values[i] += other[i]; }
490 return *this;
491 }
492
493 _MSTD_CONSTEXPR20 vec<N, T>& operator-=(const vec<N, T>& other) {
494 for (size_t i = 0; i != N; ++i) { _values[i] -= other[i]; }
495 return *this;
496 }
497
498 _MSTD_CONSTEXPR20 vec<N, T>& operator*=(const vec<N, T>& other) {
499 for (size_t i = 0; i != N; ++i) { _values[i] *= other[i]; }
500 return *this;
501 }
502
503 _MSTD_CONSTEXPR20 vec<N, T>& operator/=(const vec<N, T>& other) {
504 if (other == vec<N, T>::zero()) { return *this; }
505 for (size_t i = 0; i != N; ++i) { _values[i] /= other[i]; }
506 return *this;
507 }
508
509 _MSTD_CONSTEXPR20 vec<N, T>& operator+=(const T& other) {
510 for (size_t i = 0; i != N; ++i) { _values[i] += other; }
511 return *this;
512 }
513
514 _MSTD_CONSTEXPR20 vec<N, T>& operator-=(const T& other) {
515 for (size_t i = 0; i != N; ++i) { _values[i] -= other; }
516 return *this;
517 }
518
519 _MSTD_CONSTEXPR20 vec<N, T>& operator*=(const T& other) {
520 for (size_t i = 0; i != N; ++i) { _values[i] *= other; }
521 return *this;
522 }
523
524 _MSTD_CONSTEXPR20 vec<N, T>& operator/=(const T& other) {
525 if (other == static_cast<T>(0)) { return *this; }
526 for (size_t i = 0; i != N; ++i) { _values[i] /= other; }
527 return *this;
528 }
529
530 _MSTD_CONSTEXPR20 vec<N, T> operator+(const vec<N, T>& other) const {
531 vec<N, T> res = *this;
532 res += other;
533 return res;
534 }
535
536 _MSTD_CONSTEXPR20 vec<N, T> operator-(const vec<N, T>& other) const {
537 vec<N, T> res = *this;
538 res -= other;
539 return res;
540 }
541
542 _MSTD_CONSTEXPR20 vec<N, T> operator*(const vec<N, T>& other) const {
543 vec<N, T> res = *this;
544 res *= other;
545 return res;
546 }
547
548 _MSTD_CONSTEXPR20 vec<N, T> operator/(const vec<N, T>& other) const {
549 vec<N, T> res = *this;
550 res /= other;
551 return res;
552 }
553
554 _MSTD_CONSTEXPR20 vec<N, T> operator+(const T& other) const {
555 vec<N, T> res = *this;
556 res += other;
557 return res;
558 }
559
560 _MSTD_CONSTEXPR20 vec<N, T> operator-(const T& other) const {
561 vec<N, T> res = *this;
562 res -= other;
563 return res;
564 }
565
566 _MSTD_CONSTEXPR20 vec<N, T> operator*(const T& other) const {
567 vec<N, T> res = *this;
568 res *= other;
569 return res;
570 }
571
572 friend _MSTD_CONSTEXPR20 vec<N, T> operator*(const T& other, const vec<N, T>& vector) { return vector * other; }
573
574 _MSTD_CONSTEXPR20 vec<N, T> operator/(const T& other) const {
575 vec<N, T> res = *this;
576 res /= other;
577 return res;
578 }
579
580 _MSTD_CONSTEXPR20 vec<N, T> operator+() const { return vec<N, T>(*this); }
581
582 _MSTD_CONSTEXPR20 vec<N, T> operator-() const { return *this * -1; }
583
584 _MSTD_CONSTEXPR20 vec<N, T>& operator++() { return *this += vec<N, T>::one(); }
585
586 _MSTD_CONSTEXPR20 vec<N, T> operator++(int) {
587 vec<N, T> old = *this;
588 operator++();
589 return old;
590 }
591
592 _MSTD_CONSTEXPR20 vec<N, T>& operator--() { return *this -= vec<N, T>::one(); }
593
594 _MSTD_CONSTEXPR20 vec<N, T> operator--(int) {
595 vec<N, T> old = *this;
596 operator--();
597 return old;
598 }
599
600 template<size_t ON>
601 _MSTD_CONSTEXPR20 bool operator==(const vec<ON, T>& other) const {
602 if constexpr (N != ON) { return false; }
603 else { return std::memcmp(_values, static_cast<const T*>(other), N * sizeof(T)) == 0; }
604 }
605
606 template<size_t ON>
607 _MSTD_CONSTEXPR20 bool operator!=(const vec<ON, T>& other) const {
608 return !(*this == other);
609 }
610
611 _MSTD_CONSTEXPR20 operator const T*() const { return _values; }
612
613 _MSTD_CONSTEXPR20 T& operator[](const size_t& idx) { return _values[idx]; }
614
615 _MSTD_CONSTEXPR20 T operator[](const size_t& idx) const { return _values[idx]; }
616
617 friend std::ostream& operator<<(std::ostream& str, const vec<N, T>& vector) {
618 str << "[";
619 for (size_t i = 0; i != N; ++i) {
620 str << std::to_string(vector[i]);
621 if (i != N - 1) { str << ", "; }
622 }
623 return str << "]";
624 }
625
626 #pragma endregion // OPERATORS
627 };
628
629 #pragma region EXTRA_OPERATORS
630
631 template<class T, size_t N>
632 _MSTD_INLINE17 _MSTD_CONSTEXPR20 T length(const vec<N, T>& a) noexcept {
633 return a.length();
634 }
635
636 template<class T, size_t N>
637 _MSTD_INLINE17 _MSTD_CONSTEXPR20 vec<N, T> normalize(const vec<N, T>& a) noexcept {
638 return a.normalized();
639 }
640
641 template<class T, size_t N>
642 _MSTD_INLINE17 _MSTD_CONSTEXPR20 vec<N, T> max(const vec<N, T>& a, const vec<N, T>& b) noexcept {
643 vec<N, T> res;
644 for (size_t i = 0; i != N; ++i) { res[i] = std::max(a[i], b[i]); }
645 return res;
646 }
647
648 template<class T, size_t N>
649 _MSTD_INLINE17 _MSTD_CONSTEXPR20 vec<N, T> min(const vec<N, T>& a, const vec<N, T>& b) noexcept {
650 vec<N, T> res;
651 for (size_t i = 0; i != N; ++i) { res[i] = std::min(a[i], b[i]); }
652 return res;
653 }
654
655 template<class T, size_t N>
656 _MSTD_INLINE17 _MSTD_CONSTEXPR20 T dot(const vec<N, T>& a, const vec<N, T>& b) {
657 return a.dot(b);
658 }
659
661 template<class T, size_t N>
662 requires (N == 3)
663 #else
664 template<class T, size_t N, std::enable_if_t<(N == 3), bool> = true>
665 #endif
666 _MSTD_INLINE17 _MSTD_CONSTEXPR20 vec<N, T> cross(const vec<N, T>& a, const vec<N, T>& b) {
667 return a.cross(b);
668 }
669
670 template<class T, size_t N>
671 _MSTD_INLINE17 _MSTD_CONSTEXPR20 T angle_between(const vec<N, T>& a, const vec<N, T>& b) {
672 return a.angle_between(b);
673 }
674
675 template<class T, size_t N>
676 _MSTD_INLINE17 _MSTD_CONSTEXPR20 vec<N, T> reflect(const vec<N, T>& dir, const vec<N, T>& normal) {
677 return dir.reflected(normal);
678 }
679
680 template<class T, size_t N>
681 _MSTD_INLINE17 _MSTD_CONSTEXPR20 vec<N, T> refract(const vec<N, T>& dir, const vec<N, T>& normal, const T& eta) {
682 return dir.refracted(normal, eta);
683 }
684
685 template<class T, size_t N>
686 _MSTD_INLINE17 _MSTD_CONSTEXPR20 vec<N, T> saturate(const vec<N, T>& a) {
687 return a.saturated();
688 }
689
690 template<class T, size_t N>
691 _MSTD_INLINE17 _MSTD_CONSTEXPR20 vec<N, T> fract(const vec<N, T>& a) {
692 return a.fracted();
693 }
694
695 template<class T, size_t N>
696 _MSTD_INLINE17 _MSTD_CONSTEXPR20 vec<N, T> mod(const vec<N, T>& a, const T& y) {
697 return a.modded(y);
698 }
699
700 template<class T, size_t N>
701 _MSTD_INLINE17 _MSTD_CONSTEXPR20 vec<N, T> mod(const vec<N, T>& a, const vec<N, T>& b) {
702 return a.modded(b);
703 }
704
705 template<class T, size_t N>
706 _MSTD_INLINE17 _MSTD_CONSTEXPR20 vec<N, T> pow(const vec<N, T>& a, const T& y) {
707 return a.powed(y);
708 }
709
710 template<class T, size_t N>
711 _MSTD_INLINE17 _MSTD_CONSTEXPR20 vec<N, T> pow(const vec<N, T>& a, const vec<N, T>& b) {
712 return a.powed(b);
713 }
714
715 template<class T, size_t N>
716 _MSTD_INLINE17 _MSTD_CONSTEXPR20 vec<N, T> clamp(const vec<N, T>& a, const T& minVal, const T& maxVal) {
717 return a.clampped(minVal, maxVal);
718 }
719
720 template<class T, size_t N>
721 _MSTD_INLINE17 _MSTD_CONSTEXPR20 vec<N, T> clamp(const vec<N, T>& a, const vec<N, T>& minVal, const vec<N, T>& maxVal) {
722 return a.clampped(minVal, maxVal);
723 }
724
725 template<class T, size_t N>
726 _MSTD_INLINE17 _MSTD_CONSTEXPR20 vec<N, T> step(const T& edge, const vec<N, T>& a) {
727 return a.stepped(edge);
728 }
729
730 template<class T, size_t N>
731 _MSTD_INLINE17 _MSTD_CONSTEXPR20 vec<N, T> step(const vec<N, T>& edge, const vec<N, T>& a) {
732 return a.stepped(edge);
733 }
734
735 #pragma endregion // EXTRA_OPERATORS
736} // namespace mstd
737
738 #include <mstd/quat.hpp>
739 #endif
740#endif
_MSTD_CONSTEXPR20 T length() const
Definition vec.hpp:295
_MSTD_CONSTEXPR20 void _copy_values_from(const vec< ON, OT > &other)
Definition vec.hpp:89
_MSTD_CONSTEXPR20 void _copy_values_from(const OT(&values)[TN])
Definition vec.hpp:74
_MSTD_CONSTEXPR20 T & w() _MSTD_REQUIRES(N > 3)
Definition vec.hpp:279
_MSTD_CONSTEXPR20 vec< N, T > & operator=(const vec< ON, OT > &other)
Definition vec.hpp:200
_MSTD_CONSTEXPR20 vec< N, T > & pow(const vec< N, T > &other)
Definition vec.hpp:403
_MSTD_CONSTEXPR20 vec< N, T > & operator/=(const vec< N, T > &other)
Definition vec.hpp:503
_MSTD_CONSTEXPR20 void _copy_values_from(const OT *&values, const size_t &size)
Definition vec.hpp:62
_MSTD_CONSTEXPR20 vec< N, T > operator-(const T &other) const
Definition vec.hpp:560
_MSTD_CONSTEXPR20 vec< N, T > powed(const T &y) const
Definition vec.hpp:398
_MSTD_CONSTEXPR20 bool operator==(const vec< ON, T > &other) const
Definition vec.hpp:601
_MSTD_CONSTEXPR20 bool is_normalized() const
Definition vec.hpp:235
_MSTD_CONSTEXPR20 T & operator[](const size_t &idx)
Definition vec.hpp:613
_MSTD_CONSTEXPR20 T operator[](const size_t &idx) const
Definition vec.hpp:615
_MSTD_CONSTEXPR20 T g() const _MSTD_REQUIRES(N > 1)
Definition vec.hpp:261
_MSTD_CONSTEXPR20 vec< N, T > fracted() const noexcept
Definition vec.hpp:368
_MSTD_CONSTEXPR20 T & y() _MSTD_REQUIRES(N > 1)
Definition vec.hpp:251
T _values[N]
Definition vec.hpp:38
_MSTD_CONSTEXPR20 T y() const _MSTD_REQUIRES(N > 1)
Definition vec.hpp:254
_MSTD_CONSTEXPR20 bool operator!=(const vec< ON, T > &other) const
Definition vec.hpp:607
static _MSTD_CONSTEXPR20 vec< N, T > fill(const T &value)
Definition vec.hpp:214
_MSTD_CONSTEXPR20 vec< N, T > & normalize()
Definition vec.hpp:301
_MSTD_CONSTEXPR20 vec< N, T > operator+(const vec< N, T > &other) const
Definition vec.hpp:530
_MSTD_CONSTEXPR20 T & g() _MSTD_REQUIRES(N > 1)
Definition vec.hpp:258
_MSTD_CONSTEXPR20 void _set_values(const std::index_sequence< Idxs... > &, const Ts &... values)
Definition vec.hpp:46
_MSTD_CONSTEXPR20 vec< N, T > modded(const T &y) const
Definition vec.hpp:378
_MSTD_CONSTEXPR20 vec< N, T > & operator*=(const vec< N, T > &other)
Definition vec.hpp:498
_MSTD_CONSTEXPR20 vec< N, T > clampped(const vec< N, T > &minVal, const vec< N, T > &maxVal) const
Definition vec.hpp:428
_MSTD_CONSTEXPR20 operator const T *() const
Definition vec.hpp:611
_MSTD_CONSTEXPR20 T a() const _MSTD_REQUIRES(N > 3)
Definition vec.hpp:289
_MSTD_CONSTEXPR20 vec< N, T > & step(const T &edge) noexcept
Definition vec.hpp:433
_MSTD_CONSTEXPR20 vec(const OT(&values)[TN])
Definition vec.hpp:140
_MSTD_CONSTEXPR20 vec< N, T > & clamp(const vec< N, T > &minVal, const vec< N, T > &maxVal)
Definition vec.hpp:423
friend _MSTD_CONSTEXPR20 vec< N, T > operator*(const T &other, const vec< N, T > &vector)
Definition vec.hpp:572
_MSTD_CONSTEXPR20 vec< N, T > & operator++()
Definition vec.hpp:584
_MSTD_CONSTEXPR20 vec< N, T > T T rotated(const vec< N, T > &axis, const T &radians) _MSTD_REQUIRES(N
_MSTD_CONSTEXPR20 T z() const _MSTD_REQUIRES(N > 2)
Definition vec.hpp:268
_MSTD_CONSTEXPR20 vec< N, T > operator/(const vec< N, T > &other) const
Definition vec.hpp:548
_MSTD_CONSTEXPR20 vec< N, T > powed(const vec< N, T > &other) const
Definition vec.hpp:408
_MSTD_CONSTEXPR20 vec< N, T > & operator+=(const T &other)
Definition vec.hpp:509
_MSTD_CONSTEXPR20 vec< N, T > & fract() noexcept
Definition vec.hpp:363
_MSTD_CONSTEXPR20 vec< N, T > & refract(const vec< N, T > &normal, const T &eta)
Definition vec.hpp:340
static _MSTD_CONSTEXPR20 vec< N, T > zero()
Definition vec.hpp:210
_MSTD_CONSTEXPR20 T angle_between(const vec< N, T > &other) const
Definition vec.hpp:319
_MSTD_CONSTEXPR20 T & a() _MSTD_REQUIRES(N > 3)
Definition vec.hpp:286
_MSTD_CONSTEXPR20 vec< N, T > operator*(const vec< N, T > &other) const
Definition vec.hpp:542
_MSTD_CONSTEXPR20 T & z() _MSTD_REQUIRES(N > 2)
Definition vec.hpp:265
_MSTD_CONSTEXPR20 T b() const _MSTD_REQUIRES(N > 2)
Definition vec.hpp:275
_MSTD_CONSTEXPR20 void _fill_values(const T &value)
Definition vec.hpp:50
_MSTD_CONSTEXPR20 vec< N, T > & saturate() noexcept
Definition vec.hpp:353
_MSTD_CONSTEXPR20 vec< N, T > normalized() const
Definition vec.hpp:308
_MSTD_CONSTEXPR20 bool is_zero() const
Definition vec.hpp:224
_MSTD_CONSTEXPR20 vec< N, T > T & rotate(const vec< N, T > &axis, const T &radians) _MSTD_REQUIRES(N
_MSTD_CONSTEXPR20 vec< N, T > operator++(int)
Definition vec.hpp:586
_MSTD_CONSTEXPR20 vec< N, T > & operator--()
Definition vec.hpp:592
_MSTD_CONSTEXPR20 vec< N, T > stepped(const vec< N, T > &edge) const noexcept
Definition vec.hpp:448
_MSTD_CONSTEXPR20 T x() const
Definition vec.hpp:243
_MSTD_CONSTEXPR20 vec(const vec< ON, AT > &otherA, const vec< ON, BT > &otherB)
Definition vec.hpp:174
_MSTD_CONSTEXPR20 T dot(const vec< N, T > &other) const
Definition vec.hpp:313
_MSTD_CONSTEXPR20 vec< N, T > & operator=(const OT(&values)[TN])
Definition vec.hpp:190
_MSTD_CONSTEXPR20 vec< N, T > & operator/=(const T &other)
Definition vec.hpp:524
_MSTD_CONSTEXPR20 vec< N, T > & operator-=(const T &other)
Definition vec.hpp:514
static _MSTD_CONSTEXPR20 vec< N, T > one()
Definition vec.hpp:212
_MSTD_CONSTEXPR20 T & b() _MSTD_REQUIRES(N > 2)
Definition vec.hpp:272
_MSTD_CONSTEXPR20 bool is_one() const
Definition vec.hpp:226
_MSTD_CONSTEXPR20 vec< N, T > operator/(const T &other) const
Definition vec.hpp:574
static _MSTD_CONSTEXPR20 const size_t size
Definition vec.hpp:34
_MSTD_CONSTEXPR20 vec(const vec< ON, OT > &other)
Definition vec.hpp:162
T value_type
Definition vec.hpp:35
_MSTD_CONSTEXPR20 vec< N, T > reflected(const vec< N, T > &normal) const noexcept
Definition vec.hpp:335
_MSTD_CONSTEXPR20 T w() const _MSTD_REQUIRES(N > 3)
Definition vec.hpp:282
_MSTD_CONSTEXPR20 T r() const
Definition vec.hpp:247
_MSTD_CONSTEXPR20 vec< N, T > & clamp(const T &minVal, const T &maxVal)
Definition vec.hpp:413
_MSTD_CONSTEXPR20 bool is_filled_with(const T &value) const
Definition vec.hpp:228
_MSTD_CONSTEXPR20 vec< N, T > stepped(const T &edge) const noexcept
Definition vec.hpp:443
_MSTD_CONSTEXPR20 vec< N, T > & mod(const T &y)
Definition vec.hpp:373
_MSTD_CONSTEXPR20 vec()
Definition vec.hpp:104
_MSTD_CONSTEXPR20 vec< N, T > saturated() const noexcept
Definition vec.hpp:358
_MSTD_CONSTEXPR20 vec< N, T > & mod(const vec< N, T > &other)
Definition vec.hpp:383
_MSTD_CONSTEXPR20 vec< N, T > & reflect(const vec< N, T > &normal) noexcept
Definition vec.hpp:329
_MSTD_CONSTEXPR20 vec< N, T > refracted(const vec< N, T > &normal, const T &eta) const
Definition vec.hpp:345
_MSTD_CONSTEXPR20 vec< N, T > modded(const vec< N, T > &other) const
Definition vec.hpp:388
_MSTD_CONSTEXPR20 vec(const Ts &... values)
Definition vec.hpp:114
_MSTD_CONSTEXPR20 vec< N, T > & pow(const T &y)
Definition vec.hpp:393
_MSTD_CONSTEXPR20 vec< N, T > operator*(const T &other) const
Definition vec.hpp:566
_MSTD_CONSTEXPR20 vec< N, T > operator+(const T &other) const
Definition vec.hpp:554
_MSTD_CONSTEXPR20 vec< N, T > & step(const vec< N, T > &edge) noexcept
Definition vec.hpp:438
_MSTD_CONSTEXPR20 T & r()
Definition vec.hpp:245
_MSTD_CONSTEXPR20 vec< N, T > cross(const vec< N, T > &other) const _MSTD_REQUIRES(N
_MSTD_CONSTEXPR20 vec< N, T > & operator-=(const vec< N, T > &other)
Definition vec.hpp:493
_MSTD_CONSTEXPR20 vec(const OT *values, const size_t &size)
Definition vec.hpp:151
_MSTD_CONSTEXPR20 vec(const vec< ON, OT > &other, const Ts &... values)
Definition vec.hpp:128
_MSTD_CONSTEXPR20 vec< N, T > operator-(const vec< N, T > &other) const
Definition vec.hpp:536
_MSTD_CONSTEXPR20 vec< N, T > operator+() const
Definition vec.hpp:580
_MSTD_CONSTEXPR20 ~vec()=default
_MSTD_CONSTEXPR20 void _fill_values_from(size_t firstIdx, const T &value)
Definition vec.hpp:52
_MSTD_CONSTEXPR20 vec< N, T > operator-() const
Definition vec.hpp:582
_MSTD_CONSTEXPR20 vec< N, T > & operator*=(const T &other)
Definition vec.hpp:519
_MSTD_CONSTEXPR20 vec< N, T > clampped(const T &minVal, const T &maxVal) const
Definition vec.hpp:418
_MSTD_CONSTEXPR20 T & x()
Definition vec.hpp:241
_MSTD_CONSTEXPR20 vec< N, T > operator--(int)
Definition vec.hpp:594
_MSTD_CONSTEXPR20 vec< N, T > T T T & operator+=(const vec< N, T > &other)
Definition vec.hpp:488
#define _MSTD_HAS_CXX17
Definition config.hpp:45
#define _MSTD_CONSTEXPR17
Definition config.hpp:76
#define _MSTD_HAS_CXX20
Definition config.hpp:52
#define _MSTD_REQUIRES(condition)
Definition config.hpp:86
#define _MSTD_ENABLE_IF_TEMPLATE(class_name, condition)
Definition config.hpp:87
#define _MSTD_INLINE17
Definition config.hpp:83
#define _MSTD_CONSTEXPR20
Definition config.hpp:84
Definition arithmetic_types.hpp:23
_MSTD_INLINE17 _MSTD_CONSTEXPR20 vec< N, T > normalize(const vec< N, T > &a) noexcept
Definition vec.hpp:637
_MSTD_INLINE17 _MSTD_CONSTEXPR20 vec< N, T > fract(const vec< N, T > &a)
Definition vec.hpp:691
_MSTD_INLINE17 _MSTD_CONSTEXPR20 vec< N, T > clamp(const vec< N, T > &a, const vec< N, T > &minVal, const vec< N, T > &maxVal)
Definition vec.hpp:721
_MSTD_INLINE17 _MSTD_CONSTEXPR20 T angle_between(const vec< N, T > &a, const vec< N, T > &b)
Definition vec.hpp:671
_MSTD_INLINE17 _MSTD_CONSTEXPR20 T dot(const vec< N, T > &a, const vec< N, T > &b)
Definition vec.hpp:656
_MSTD_INLINE17 _MSTD_CONSTEXPR20 vec< N, T > mod(const vec< N, T > &a, const T &y)
Definition vec.hpp:696
_MSTD_INLINE17 _MSTD_CONSTEXPR20 vec< N, T > clamp(const vec< N, T > &a, const T &minVal, const T &maxVal)
Definition vec.hpp:716
_MSTD_INLINE17 _MSTD_CONSTEXPR20 T length(const vec< N, T > &a) noexcept
Definition vec.hpp:632
_MSTD_INLINE17 _MSTD_CONSTEXPR20 vec< N, T > mod(const vec< N, T > &a, const vec< N, T > &b)
Definition vec.hpp:701
_MSTD_INLINE17 _MSTD_CONSTEXPR20 vec< N, T > pow(const vec< N, T > &a, const vec< N, T > &b)
Definition vec.hpp:711
_MSTD_INLINE17 _MSTD_CONSTEXPR20 vec< N, T > cross(const vec< N, T > &a, const vec< N, T > &b)
Definition vec.hpp:666
_MSTD_INLINE17 _MSTD_CONSTEXPR20 vec< N, T > step(const vec< N, T > &edge, const vec< N, T > &a)
Definition vec.hpp:731
_MSTD_INLINE17 _MSTD_CONSTEXPR20 vec< N, T > pow(const vec< N, T > &a, const T &y)
Definition vec.hpp:706
_MSTD_INLINE17 _MSTD_CONSTEXPR20 vec< N, T > reflect(const vec< N, T > &dir, const vec< N, T > &normal)
Definition vec.hpp:676
_MSTD_INLINE17 _MSTD_CONSTEXPR20 vec< N, T > min(const vec< N, T > &a, const vec< N, T > &b) noexcept
Definition vec.hpp:649
_MSTD_INLINE17 _MSTD_CONSTEXPR20 vec< N, T > refract(const vec< N, T > &dir, const vec< N, T > &normal, const T &eta)
Definition vec.hpp:681
_MSTD_INLINE17 _MSTD_CONSTEXPR20 vec< N, T > max(const vec< N, T > &a, const vec< N, T > &b) noexcept
Definition vec.hpp:642
_MSTD_INLINE17 _MSTD_CONSTEXPR20 vec< N, T > step(const T &edge, const vec< N, T > &a)
Definition vec.hpp:726
_MSTD_INLINE17 _MSTD_CONSTEXPR20 vec< N, T > saturate(const vec< N, T > &a)
Definition vec.hpp:686