1#ifndef LIBSBX_MATH_VECTOR_HPP_
2#define LIBSBX_MATH_VECTOR_HPP_
8#include <libsbx/utility/make_array.hpp>
9#include <libsbx/utility/assert.hpp>
10#include <libsbx/utility/zip.hpp>
13#include <libsbx/math/concepts.hpp>
17template<std::
size_t Size, scalar Type>
21 template<std::
size_t S, scalar T>
27 using value_type = Type;
28 using reference = value_type&;
29 using const_reference =
const value_type&;
30 using size_type = std::size_t;
31 using length_type = std::float_t;
33 template<scalar Other = value_type>
35 : _components{utility::make_array<value_type, Size>(value)} { }
37 template<scalar Other = value_type>
39 : _components{utility::make_array<value_type, Size>(other._components)} { }
41 constexpr auto data()
noexcept -> value_type* {
42 return _components.data();
45 [[nodiscard]]
constexpr auto operator[](size_type index)
noexcept -> reference {
46 return _components[index];
49 [[nodiscard]]
constexpr auto operator[](size_type index)
const noexcept -> const_reference {
50 return _components[index];
53 template<scalar Other>
55 for (
auto i : std::views::iota(0u, Size)) {
56 _components[i] +=
static_cast<value_type
>(other[i]);
62 template<scalar Other>
64 for (
auto i : std::views::iota(0u, Size)) {
65 _components[i] -=
static_cast<value_type
>(other[i]);
71 template<scalar Other>
72 constexpr auto operator*=(Other scalar)
noexcept ->
basic_vector& {
73 for (
auto i : std::views::iota(0u, Size)) {
74 _components[i] *=
static_cast<value_type
>(scalar);
80 template<scalar Other>
82 for (
auto i : std::views::iota(0u, Size)) {
83 _components[i] *=
static_cast<value_type
>(other[i]);
89 template<scalar Other>
90 constexpr auto operator/=(Other scalar)
noexcept ->
basic_vector& {
93 for (
auto i : std::views::iota(0u, Size)) {
94 _components[i] /=
static_cast<value_type
>(scalar);
100 [[nodiscard]]
constexpr auto length_squared()
const noexcept -> length_type {
101 auto result =
static_cast<length_type
>(0);
103 for (
auto i : std::views::iota(0u, Size)) {
104 result +=
static_cast<length_type
>(_components[i] * _components[i]);
110 [[nodiscard]]
constexpr auto length()
const noexcept -> length_type {
111 return std::sqrt(length_squared());
115 const auto length_squared = this->length_squared();
118 *
this /= std::sqrt(length_squared);
126 template<std::convertible_to<value_type>... Args>
127 requires (
sizeof...(Args) == Size)
129 : _components{utility::make_array<value_type, Size>(std::forward<Args>(args)...)} { }
131 constexpr basic_vector(std::array<value_type, Size>&& components) noexcept
132 : _components{std::move(components)} { }
134 template<scalar Other>
135 [[nodiscard]]
static constexpr auto fill(Other value)
noexcept ->
basic_vector {
139 template<std::
size_t Index, scalar Other>
140 [[nodiscard]]
static constexpr auto axis(Other value)
noexcept ->
basic_vector {
141 return basic_vector{utility::make_array<value_type, Size, Index>(value)};
146 std::array<Type, Size> _components;
150template<std::
size_t Size, scalar Lhs, scalar Rhs>
152 for (
auto i : std::views::iota(0u, Size)) {
161template<std::
size_t Size, scalar Lhs, scalar Rhs>
162[[nodiscard]]
constexpr auto operator+(basic_vector<Size, Lhs> lhs,
const basic_vector<Size, Rhs>& rhs)
noexcept -> basic_vector<Size, Lhs> {
166template<std::
size_t Size, scalar Lhs, scalar Rhs>
167[[nodiscard]]
constexpr auto operator-(basic_vector<Size, Lhs> lhs,
const basic_vector<Size, Rhs>& rhs)
noexcept -> basic_vector<Size, Lhs> {
171template<std::
size_t Size, scalar Lhs, scalar Rhs>
172[[nodiscard]]
constexpr auto operator*(basic_vector<Size, Lhs> lhs, Rhs scalar)
noexcept -> basic_vector<Size, Lhs> {
173 return lhs *= scalar;
176template<std::
size_t Size, scalar Lhs, scalar Rhs>
177[[nodiscard]]
constexpr auto operator/(basic_vector<Size, Lhs> lhs, Rhs scalar)
noexcept -> basic_vector<Size, Lhs> {
178 return lhs /= scalar;
Definition: vector.hpp:19
Definition: concepts.hpp:59