22 template<std::
size_t len,
typename Ty,
typename Enable =
void>
27 template<
typename... Args> VecMembers(Args&&... args) : data{ std::forward<Args>(args)... } {}
31 template<std::
size_t len,
typename Ty>
32 struct VecMembers<len, Ty, std::enable_if_t<(len == 2)>>
40 template<
typename... Args> VecMembers(Args&&... args) : data{ std::forward<Args>(args)... } {}
44 template<std::
size_t len,
typename Ty>
45 struct VecMembers<len, Ty, std::enable_if_t<(len == 3)>>
49 struct { Ty x, y, z; };
50 struct { Ty r, g, b; };
54 template<
typename... Args> VecMembers(Args&&... args) : data{ std::forward<Args>(args)... } {}
58 template<std::
size_t len,
typename Ty>
59 struct VecMembers<len, Ty, std::enable_if_t<(len == 4)>>
63 struct { Ty x, y, z, w; };
64 struct { Ty r, g, b, a; };
68 template<
typename... Args> VecMembers(Args&&... args) : data{ std::forward<Args>(args)... } {}
72 template<
typename Ty,
typename... Args>
concept AllSameType = (std::is_same_v<Ty, Args> && ...);
75 template<
typename LhsTy,
typename RhsTy>
76 concept CanAdd =
requires(LhsTy lhs, RhsTy rhs)
78 { lhs + rhs } -> std::same_as<
decltype(lhs + rhs)>;
82 template<
typename LhsTy,
typename RhsTy>
83 using AddResultT =
decltype(std::declval<LhsTy>() + std::declval<RhsTy>());
86 template<
typename LhsTy,
typename RhsTy>
87 concept CanSub =
requires(LhsTy lhs, RhsTy rhs)
89 { lhs - rhs } -> std::same_as<
decltype(lhs - rhs)>;
93 template<
typename LhsTy,
typename RhsTy>
94 using SubResultT =
decltype(std::declval<LhsTy>() + std::declval<RhsTy>());
97 template<
typename LhsTy,
typename RhsTy>
98 concept CanMul =
requires(LhsTy lhs, RhsTy rhs)
100 { lhs * rhs } -> std::same_as<
decltype(lhs * rhs)>;
104 template<
typename LhsTy,
typename RhsTy>
105 using MulResultT =
decltype(std::declval<LhsTy>() * std::declval<RhsTy>());
108 template<
typename LhsTy,
typename RhsTy>
109 concept CanDiv =
requires(LhsTy lhs, RhsTy rhs)
111 { lhs / rhs } -> std::same_as<
decltype(lhs + rhs)>;
115 template<
typename LhsTy,
typename RhsTy>
116 using DivResultT =
decltype(std::declval<LhsTy>() / std::declval<RhsTy>());
119 template<
typename LhsTy,
typename RhsTy>
120 concept CanEqualityCheck =
requires(LhsTy lhs, RhsTy rhs)
122 { lhs == rhs } -> std::convertible_to<bool>;
123 { lhs != rhs } -> std::convertible_to<bool>;
213 template<std::
size_t len,
typename Ty>
214 requires (len != 0 && len != 1) && std::is_copy_constructible_v<Ty>
215 struct Vec : public Internal::VecMembers<len, Ty>
223 template<
typename = std::enable_if_t<std::is_default_constructible_v<Ty>>>
226 for (std::size_t index = 0; index < len; index++)
227 this->data[index] = Ty{};
235 explicit Vec(
const Ty& value)
237 for (std::size_t index = 0; index < len; index++)
238 this->data[index] = value;
249 template<
typename... Args>
requires Internal::AllSameType<Ty, Args...> && (
sizeof...(Args) == len)
250 explicit Vec(Args&&... args) : Internal::VecMembers<len, Ty>(std::forward<Args>(args)...) {}
261 Ty&
operator[](std::size_t index) {
return this->data[index]; }
269 Ty*
begin() noexcept {
return this->data; }
277 Ty*
end() {
return this->data + len; }
282 const Ty& operator[](std::size_t index)
const {
return this->data[index]; }
284 const Ty* begin() const noexcept {
return this->data; }
285 const Ty* cbegin() const noexcept {
return this->data; }
287 const Ty* end() const noexcept {
return this->data + len; }
288 const Ty* cend() const noexcept {
return this->data + len; }
299 template<
typename OtherTy>
300 requires Internal::CanAdd<Ty, OtherTy> && std::is_same_v<Ty, Internal::AddResultT<Ty, OtherTy>>
303 for (std::size_t index = 0; index < len; index++)
304 this->data[index] += other[index];
316 template<
typename OtherTy>
317 requires Internal::CanSub<Ty, OtherTy> && std::is_same_v<Ty, Internal::SubResultT<Ty, OtherTy>>
320 for (std::size_t index = 0; index < len; index++)
321 this->data[index] += other[index];
333 template<
typename OtherTy>
334 requires Internal::CanMul<Ty, OtherTy> && std::is_same_v<Ty, Internal::MulResultT<Ty, OtherTy>>
337 for (std::size_t index = 0; index < len; index++)
338 this->data[index] += other[index];
350 template<
typename OtherTy>
351 requires Internal::CanDiv<Ty, OtherTy> && std::is_same_v<Ty, Internal::DivResultT<Ty, OtherTy>>
354 for (std::size_t index = 0; index < len; index++)
355 this->data[index] += other[index];
369 template<std::
size_t len,
typename LhsTy,
typename RhsTy,
typename ResTy = Internal::AddResultT<LhsTy, RhsTy>>
370 requires Internal::CanAdd<LhsTy, RhsTy>
373 return [&]<std::size_t... index>(std::index_sequence<index...>) {
return Vec<len, ResTy>{ (lhs[index] + rhs[index])... }; } (std::make_index_sequence<len>{});
383 template<std::
size_t len,
typename LhsTy,
typename RhsTy,
typename ResTy = Internal::SubResultT<LhsTy, RhsTy>>
384 requires Internal::CanSub<LhsTy, RhsTy>
387 return [&]<std::size_t... index>(std::index_sequence<index...>) {
return Vec<len, ResTy>{ (lhs[index] - rhs[index])... }; } (std::make_index_sequence<len>{});
398 template<std::
size_t len,
typename LhsTy,
typename RhsTy,
typename ResTy = Internal::MulResultT<LhsTy, RhsTy>>
399 requires Internal::CanMul<LhsTy, RhsTy>
402 return [&]<std::size_t... index>(std::index_sequence<index...>) {
return Vec<len, ResTy>{ (lhs[index] * rhs[index])... }; } (std::make_index_sequence<len>{});
413 template<std::
size_t len,
typename LhsTy,
typename RhsTy,
typename ResTy = Internal::SubResultT<LhsTy, RhsTy>>
414 requires Internal::CanDiv<LhsTy, RhsTy>
417 return [&]<std::size_t... index>(std::index_sequence<index...>) {
return Vec<len, ResTy>{ (lhs[index] / rhs[index])... }; } (std::make_index_sequence<len>{});
426 template<std::
size_t len,
typename LhsTy,
typename RhsTy>
427 requires Internal::CanEqualityCheck<LhsTy, RhsTy>
430 for (std::size_t index = 0; index < len; index++)
432 if (lhs[index] != rhs[index])
445 template<std::
size_t len,
typename LhsTy,
typename RhsTy>
446 requires Internal::CanEqualityCheck<LhsTy, RhsTy>
449 for (
size_t index = 0; index < len; index++)
451 if (lhs[index] == rhs[index])
462 template<
typename Ty =
float>
463 using Vec2 = Vec<2, Ty>;
465 template<
typename Ty =
float>
466 using Vec3 = Vec<3, Ty>;
468 template<
typename Ty =
float>
469 using Vec4 = Vec<4, Ty>;
471 using Vec2s = Vec3<short>;
472 using Vec2i = Vec3<int>;
473 using Vec2u = Vec3<unsigned int>;
474 using Vec2l = Vec3<long>;
475 using Vec2d = Vec3<double>;
477 using Vec3s = Vec3<short>;
478 using Vec3i = Vec3<int>;
479 using Vec3u = Vec3<unsigned int>;
480 using Vec3l = Vec3<long>;
481 using Vec3d = Vec3<double>;
483 using Vec3s = Vec3<short>;
484 using Vec3i = Vec3<int>;
485 using Vec3u = Vec3<unsigned int>;
486 using Vec3l = Vec3<long>;
487 using Vec3d = Vec3<double>;
bool operator==(const Vec< len, LhsTy > &lhs, const Vec< len, RhsTy > &rhs)
Checks if two vectors are equal.
Definition Vec.h:428
bool operator!=(const Vec< len, LhsTy > &lhs, const Vec< len, RhsTy > &rhs)
Checks if two vectors are not equal.
Definition Vec.h:447
Vec< len, ResTy > operator-(const Vec< len, LhsTy > &lhs, const Vec< len, RhsTy > &rhs)
Subtracts the right vector by the left vector.
Definition Vec.h:385
Vec< len, ResTy > operator+(const Vec< len, LhsTy > &lhs, const Vec< len, RhsTy > &rhs)
Adds two vectors together.
Definition Vec.h:371
Vec< len, ResTy > operator/(const Vec< len, LhsTy > &lhs, const Vec< len, RhsTy > &rhs)
Divides the left vector by the right vector.
Definition Vec.h:415
Vec< len, ResTy > operator*(const Vec< len, LhsTy > &lhs, const Vec< len, RhsTy > &rhs)
Multiplies two vectors together.
Definition Vec.h:400
Mathmatical vector class.
Definition Vec.h:216
Ty & operator[](std::size_t index)
Returns a reference to the item at that index.
Definition Vec.h:261
Vec(Args &&... args)
Creates a vector with a given value for each item.
Definition Vec.h:250
Ty * end()
Returns a pointer to the end of the vector.
Definition Vec.h:277
Vec()
Default constructor which default constructs all items.
Definition Vec.h:224
Vec(const Ty &value)
Constructor to create each item in the vector with a given value.
Definition Vec.h:235
Ty * begin() noexcept
Returns a pointer to the beginning of the array.
Definition Vec.h:269