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>
14#include <libsbx/math/traits.hpp>
15#include <libsbx/math/constants.hpp>
16#include <libsbx/math/algorithm.hpp>
20template<std::
size_t Size, scalar Type>
24 template<std::
size_t S, scalar T>
30 using value_type = Type;
31 using reference = value_type&;
32 using const_reference =
const value_type&;
33 using size_type = std::size_t;
34 using length_type = std::float_t;
36 template<scalar Other = value_type>
38 : _components{utility::make_array<value_type, Size>(value)} { }
40 template<scalar Other = value_type>
42 : _components{utility::make_array<value_type, Size>(other._components)} { }
52 template<scalar Lhs = value_type, scalar Rhs = value_type>
56 for (
auto i : std::views::iota(0u, Size)) {
57 result[i] = std::min(lhs[i], rhs[i]);
63 template<scalar Lhs = value_type, scalar Rhs = value_type>
67 for (
auto i : std::views::iota(0u, Size)) {
68 result[i] = std::max(lhs[i], rhs[i]);
74 template<scalar Lhs = value_type, scalar Rhs = value_type>
78 for (
auto i : std::views::iota(0u, Size)) {
79 result[i] = std::abs(vector[i]);
85 template<
size_type Axis, scalar Other = value_type>
86 requires (Axis < Size)
90 for (
auto i : std::views::iota(0u, Size)) {
91 result[i] = vector[Axis];
100 for (
auto i : std::views::iota(0u, Size)) {
101 result[i] = math::mix(x[i], y[i], a);
107 constexpr auto data()
noexcept -> value_type* {
108 return _components.data();
111 constexpr auto data()
const noexcept ->
const value_type* {
112 return _components.data();
115 [[nodiscard]]
constexpr auto operator[](size_type index)
noexcept -> reference {
116 return _components[index];
119 [[nodiscard]]
constexpr auto operator[](size_type index)
const noexcept -> const_reference {
120 return _components[index];
123 template<scalar Other>
125 for (
auto i : std::views::iota(0u, Size)) {
126 _components[i] +=
static_cast<value_type
>(other[i]);
132 template<scalar Other>
134 for (
auto i : std::views::iota(0u, Size)) {
135 _components[i] -=
static_cast<value_type
>(other[i]);
141 template<scalar Other>
142 constexpr auto operator*=(Other scalar)
noexcept ->
basic_vector& {
143 for (
auto i : std::views::iota(0u, Size)) {
144 _components[i] *=
static_cast<value_type
>(scalar);
150 template<scalar Other>
152 for (
auto i : std::views::iota(0u, Size)) {
153 _components[i] *=
static_cast<value_type
>(other[i]);
159 template<scalar Other>
160 constexpr auto operator/=(Other scalar)
noexcept ->
basic_vector& {
163 for (
auto i : std::views::iota(0u, Size)) {
164 _components[i] /=
static_cast<value_type
>(scalar);
170 [[nodiscard]]
constexpr auto length_squared()
const noexcept -> length_type {
171 auto result =
static_cast<length_type
>(0);
173 for (
auto i : std::views::iota(0u, Size)) {
174 result +=
static_cast<length_type
>(_components[i] * _components[i]);
180 [[nodiscard]]
constexpr auto length()
const noexcept -> length_type {
181 return std::sqrt(length_squared());
185 const auto length_squared = this->length_squared();
188 *
this /= std::sqrt(length_squared);
196 template<std::convertible_to<value_type>... Args>
197 requires (
sizeof...(Args) == Size)
199 : _components{utility::make_array<value_type, Size>(std::forward<Args>(args)...)} { }
201 constexpr basic_vector(std::array<value_type, Size>&& components) noexcept
202 : _components{std::move(components)} { }
204 template<scalar Other>
205 [[nodiscard]]
static constexpr auto fill(Other value)
noexcept ->
basic_vector {
209 template<std::
size_t Index, scalar Other>
210 [[nodiscard]]
static constexpr auto axis(Other value)
noexcept ->
basic_vector {
211 return basic_vector{utility::make_array<value_type, Size, Index>(value)};
216 std::array<Type, Size> _components;
220template<std::
size_t Size, scalar Lhs, scalar Rhs>
222 for (
auto i : std::views::iota(0u, Size)) {
231template<std::
size_t Size, scalar Lhs, scalar Rhs>
232[[nodiscard]]
constexpr auto operator+(basic_vector<Size, Lhs> lhs,
const basic_vector<Size, Rhs>& rhs)
noexcept -> basic_vector<Size, Lhs> {
236template<std::
size_t Size, scalar Lhs, scalar Rhs>
237[[nodiscard]]
constexpr auto operator-(basic_vector<Size, Lhs> lhs,
const basic_vector<Size, Rhs>& rhs)
noexcept -> basic_vector<Size, Lhs> {
241template<std::
size_t Size, scalar Lhs, scalar Rhs>
242[[nodiscard]]
constexpr auto operator*(basic_vector<Size, Lhs> lhs, Rhs scalar)
noexcept -> basic_vector<Size, Lhs> {
243 return lhs *= scalar;
246template<std::
size_t Size, scalar Lhs, scalar Rhs>
247[[nodiscard]]
constexpr auto operator/(basic_vector<Size, Lhs> lhs, Rhs scalar)
noexcept -> basic_vector<Size, Lhs> {
248 return lhs /= scalar;
251template<std::
size_t Size, scalar Type>
254template<std::
size_t Size, scalar Type>
Definition: vector.hpp:22
Definition: traits.hpp:10
Definition: vector.hpp:252