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 [[nodiscard]]
constexpr auto operator[](size_type index)
noexcept -> reference {
112 return _components[index];
115 [[nodiscard]]
constexpr auto operator[](size_type index)
const noexcept -> const_reference {
116 return _components[index];
119 template<scalar Other>
121 for (
auto i : std::views::iota(0u, Size)) {
122 _components[i] +=
static_cast<value_type
>(other[i]);
128 template<scalar Other>
130 for (
auto i : std::views::iota(0u, Size)) {
131 _components[i] -=
static_cast<value_type
>(other[i]);
137 template<scalar Other>
138 constexpr auto operator*=(Other scalar)
noexcept ->
basic_vector& {
139 for (
auto i : std::views::iota(0u, Size)) {
140 _components[i] *=
static_cast<value_type
>(scalar);
146 template<scalar Other>
148 for (
auto i : std::views::iota(0u, Size)) {
149 _components[i] *=
static_cast<value_type
>(other[i]);
155 template<scalar Other>
156 constexpr auto operator/=(Other scalar)
noexcept ->
basic_vector& {
159 for (
auto i : std::views::iota(0u, Size)) {
160 _components[i] /=
static_cast<value_type
>(scalar);
166 [[nodiscard]]
constexpr auto length_squared()
const noexcept -> length_type {
167 auto result =
static_cast<length_type
>(0);
169 for (
auto i : std::views::iota(0u, Size)) {
170 result +=
static_cast<length_type
>(_components[i] * _components[i]);
176 [[nodiscard]]
constexpr auto length()
const noexcept -> length_type {
177 return std::sqrt(length_squared());
181 const auto length_squared = this->length_squared();
184 *
this /= std::sqrt(length_squared);
192 template<std::convertible_to<value_type>... Args>
193 requires (
sizeof...(Args) == Size)
195 : _components{utility::make_array<value_type, Size>(std::forward<Args>(args)...)} { }
197 constexpr basic_vector(std::array<value_type, Size>&& components) noexcept
198 : _components{std::move(components)} { }
200 template<scalar Other>
201 [[nodiscard]]
static constexpr auto fill(Other value)
noexcept ->
basic_vector {
205 template<std::
size_t Index, scalar Other>
206 [[nodiscard]]
static constexpr auto axis(Other value)
noexcept ->
basic_vector {
207 return basic_vector{utility::make_array<value_type, Size, Index>(value)};
212 std::array<Type, Size> _components;
216template<std::
size_t Size, scalar Lhs, scalar Rhs>
218 for (
auto i : std::views::iota(0u, Size)) {
227template<std::
size_t Size, scalar Lhs, scalar Rhs>
228[[nodiscard]]
constexpr auto operator+(basic_vector<Size, Lhs> lhs,
const basic_vector<Size, Rhs>& rhs)
noexcept -> basic_vector<Size, Lhs> {
232template<std::
size_t Size, scalar Lhs, scalar Rhs>
233[[nodiscard]]
constexpr auto operator-(basic_vector<Size, Lhs> lhs,
const basic_vector<Size, Rhs>& rhs)
noexcept -> basic_vector<Size, Lhs> {
237template<std::
size_t Size, scalar Lhs, scalar Rhs>
238[[nodiscard]]
constexpr auto operator*(basic_vector<Size, Lhs> lhs, Rhs scalar)
noexcept -> basic_vector<Size, Lhs> {
239 return lhs *= scalar;
242template<std::
size_t Size, scalar Lhs, scalar Rhs>
243[[nodiscard]]
constexpr auto operator/(basic_vector<Size, Lhs> lhs, Rhs scalar)
noexcept -> basic_vector<Size, Lhs> {
244 return lhs /= scalar;
Definition: vector.hpp:22
Definition: traits.hpp:10