6#ifndef SIMPLE_VECTOR_VECTOR_HPP
7#define SIMPLE_VECTOR_VECTOR_HPP
34 template <value_type T, std::
size_t VDimensions>
35 requires (0 < VDimensions)
42 constexpr static std::size_t dimensions{ VDimensions };
56 constexpr Vector() noexcept = default;
60 constexpr ~
Vector() noexcept = default;
77 template <class... TArgs>
78 requires (sizeof...(TArgs) == dimensions && (std::convertible_to<TArgs, T> && ...))
79 explicit (VDimensions <= 1)
80 constexpr
Vector(TArgs&&...args) noexcept
81 : m_Values{
static_cast<T
>(args)... }
95 template <std::convertible_to<value_type> T2, auto VOtherDimensions>
96 requires (!std::same_as<T2, value_type> || dimensions != VOtherDimensions)
97 constexpr explicit Vector(
const Vector<T2, VOtherDimensions>& other)
101 std::ranges::take_view{ other, std::min(dimensions, VOtherDimensions) },
102 std::ranges::begin(m_Values),
103 fn::cast_invoke_result<value_type>(std::identity{})
118 template <std::invocable TGenerator>
119 requires std::convertible_to<std::invoke_result_t<TGenerator&>, value_type>
120 constexpr explicit Vector(TGenerator generator)
122 std::ranges::generate(m_Values, std::ref(generator));
143 constexpr
bool operator ==(const
Vector&) const noexcept = default;
153 constexpr const
value_type& operator [](std::integral auto index) const noexcept
155 assert(std::in_range<std::size_t>(index) &&
"index must be in range of type std::size_t");
156 return m_Values[
static_cast<std::size_t
>(index)];
166 template <std::
integral TIndex>
168 constexpr value_type& operator [](std::integral
auto index)
noexcept
170 assert(std::in_range<std::size_t>(index) &&
"index must be in range of type std::size_t");
171 return m_Values[
static_cast<std::size_t
>(index)];
202 requires (1 < VDimensions)
215 requires (1 < VDimensions)
228 requires (2 < VDimensions)
241 requires (2 < VDimensions)
252 template <std::convertible_to<value_type> T2>
259 std::ranges::begin(m_Values),
260 fn::cast_invoke_result<value_type>(std::plus{})
271 template <std::convertible_to<value_type> T2>
278 std::ranges::begin(m_Values),
279 fn::cast_invoke_result<value_type>(std::minus{})
290 template <std::convertible_to<value_type> T2>
291 constexpr Vector& operator +=(
const T2& value)
296 std::ranges::begin(m_Values),
297 fn::cast_invoke_result<value_type>([&value](
const auto& lhs) {
return lhs + value; })
308 template <std::convertible_to<value_type> T2>
309 constexpr Vector& operator -=(
const T2& value)
314 std::ranges::begin(m_Values),
315 fn::cast_invoke_result<value_type>([&value](
const auto& lhs) {
return lhs - value; })
326 template <std::convertible_to<value_type> T2>
327 constexpr Vector& operator *=(
const T2& value)
332 std::ranges::begin(m_Values),
333 fn::cast_invoke_result<value_type>([&value](
const auto& lhs) {
return lhs * value; })
346 template <std::convertible_to<value_type> T2>
347 constexpr Vector& operator /=(
const T2& value)
349 assert(value != 0 &&
"division by 0 is undefined.");
354 std::ranges::begin(m_Values),
355 fn::cast_invoke_result<value_type>([&value](
const auto& lhs) {
return lhs / value; })
368 template <std::convertible_to<value_type> T2>
370 constexpr Vector& operator %=(
const T2& rawValue)
372 const auto value =
static_cast<value_type>(rawValue);
373 assert(value != 0 &&
"division by 0 is undefined.");
378 std::ranges::begin(m_Values),
379 [value](
const auto& lhs) {
return lhs % value; }
389 constexpr auto begin() noexcept {
return std::ranges::begin(m_Values); }
396 constexpr auto begin() const noexcept {
return std::ranges::begin(m_Values); }
403 constexpr auto cbegin() const noexcept {
return std::ranges::cbegin(m_Values); }
410 constexpr auto end() noexcept {
return std::ranges::end(m_Values); }
417 constexpr auto end() const noexcept {
return std::ranges::end(m_Values); }
424 constexpr auto cend() const noexcept {
return std::ranges::cend(m_Values); }
431 constexpr auto rbegin() noexcept {
return std::ranges::rbegin(m_Values); }
438 constexpr auto rbegin() const noexcept {
return std::ranges::rbegin(m_Values); }
445 constexpr auto crbegin() const noexcept {
return std::ranges::crbegin(m_Values); }
452 constexpr auto rend() noexcept {
return std::ranges::rend(m_Values); }
459 constexpr auto rend() const noexcept {
return std::ranges::rend(m_Values); }
466 constexpr auto crend() const noexcept {
return std::ranges::crend(m_Values); }
469 storage_type m_Values{};
476 template <
class... T>
490 template <value_type T, std::
size_t VDimensions>
503 template <value_type T, auto VDimensions>
522 template <vectorial TVector, add_assignable<TVector> T2>
526 lhs += std::forward<T2>(rhs);
538 template <vectorial TVector, sub_assignable<TVector> T2>
542 lhs -= std::forward<T2>(rhs);
554 template <vectorial TVector, mul_assignable<TVector> T2>
558 lhs *= std::forward<T2>(rhs);
570 template <vectorial TVector, mul_assignable<TVector> T2>
574 rhs *= std::forward<T2>(lhs);
586 template <vectorial TVector, div_assignable<TVector> T2>
590 lhs /= std::forward<T2>(rhs);
602 template <vectorial TVector, mod_assignable<TVector> T2>
606 lhs %= std::forward<T2>(rhs);
618 template <vectorial TVector1, vectorial TVector2>
619 requires mulable<vector_value_t<TVector2>, vector_value_t<TVector1>>
630 fn::cast_invoke_result<T>(std::multiplies{})
640 template <vectorial TVector>
655 template <vectorial TVector>
665 template <vectorial TVector>
666 requires std::floating_point<vector_value_t<TVector>>
670 assert(vec != TVector{});
672 return vec /=
length(vec);
682 template <vectorial TVector>
684 constexpr TVector
projected(
const TVector& vector, TVector target)
686 assert(vector != TVector{} &&
"vector must not be the null vector.");
687 assert(target != TVector{} &&
"target must not be the null vector.");
691 target *= (dot / targetLengthSq);
706 template <vectorial TVector,
class T>
707 requires std::is_arithmetic_v<T>
709 constexpr TVector
lerp(TVector vector1,
const TVector& vector2, T t)
715 std::ranges::begin(vector1),
727 template <vectorial TVector>
728 requires std::floating_point<vector_value_t<TVector>>
735 std::ranges::begin(vector),
736 [](
auto value) {
return 1. / value; }
A mathematically vector implementation.
Definition: Vector.hpp:37
constexpr value_type & z() noexcept
Accesses the third element.
Definition: Vector.hpp:240
constexpr value_type & x() noexcept
Accesses the first element.
Definition: Vector.hpp:189
constexpr auto begin() const noexcept
Returns an const iterator to the first element.
Definition: Vector.hpp:396
constexpr auto rend() const noexcept
Returns an const iterator to the reverse-end of the given range (i.e. the element before the first el...
Definition: Vector.hpp:459
constexpr auto begin() noexcept
Returns an iterator to the first element.
Definition: Vector.hpp:389
constexpr auto rbegin() noexcept
Returns an iterator to the reverse-beginning.
Definition: Vector.hpp:431
std::array< value_type, dimensions > storage_type
Used storage type.
Definition: Vector.hpp:50
constexpr const value_type & z() const noexcept
Accesses the third element.
Definition: Vector.hpp:227
std::remove_cvref_t< T > value_type
Alias for T, but without modifiers.
Definition: Vector.hpp:46
constexpr Vector() noexcept=default
Default constructor.
constexpr const value_type & y() const noexcept
Accesses the second element.
Definition: Vector.hpp:201
constexpr auto rbegin() const noexcept
Returns an const iterator to the reverse-beginning.
Definition: Vector.hpp:438
constexpr const value_type & x() const noexcept
Accesses the first element.
Definition: Vector.hpp:179
VDimensions<=1) constexpr Vector(TArgs &&...args) noexcept :m_Values{ static_cast< T >(args)... } { } template< std::convertible_to< value_type > T2, auto VOtherDimensions > requires(!std::same_as< T2, value_type >||dimensions !=VOtherDimensions) constexpr explicit Vector(const Vector< T2, VOtherDimensions > &other) { transform_unseq(std::ranges::take_view{ other, std::min(dimensions, VOtherDimensions) }, std::ranges::begin(m_Values), fn::cast_invoke_result< value_type >(std::identity{}));} template< std::invocable TGenerator > constexpr Vector(TGenerator generator)
Aggregate initialization like constructor.
Definition: Vector.hpp:120
constexpr auto cbegin() const noexcept
Returns an const iterator to the first element.
Definition: Vector.hpp:403
constexpr auto end() noexcept
Returns an iterator to the end (i.e. the element after the last element).
Definition: Vector.hpp:410
constexpr auto rend() noexcept
Returns an iterator to the reverse-end of the given range (i.e. the element before the first element)...
Definition: Vector.hpp:452
constexpr auto cend() const noexcept
Returns an const iterator to the end (i.e. the element after the last element).
Definition: Vector.hpp:424
constexpr auto crend() const noexcept
Returns an const iterator to the reverse-end of the given range (i.e. the element before the first el...
Definition: Vector.hpp:466
constexpr auto end() const noexcept
Returns an const iterator to the end (i.e. the element after the last element).
Definition: Vector.hpp:417
constexpr auto crbegin() const noexcept
Returns an const iterator to the reverse-beginning.
Definition: Vector.hpp:445
constexpr value_type & y() noexcept
Accesses the second element.
Definition: Vector.hpp:214
Checks if the given type can be used in immutable module operations.
Definition: Concepts.hpp:135
Checks if the given type is regular and can be used in common arithmetically operations.
Definition: Concepts.hpp:162
constexpr void transform_unseq(TRange &&range, TOut result, TUnaryOp unaryOp)
Applies the given unary operation to each element and writes into result.
Definition: Algorithm.hpp:52
constexpr T transform_reduce_unseq(TRange &&range, T init, TBinaryOp binaryOp, TUnaryOp unaryOp)
Applies the unaryOp to each elements from the range and reduces the results (possibly permuted and ag...
Definition: Algorithm.hpp:169
constexpr auto cast_invoke_result(TFunc func) noexcept
Factory function creating a wrapper function object, which invokes the provided function object and c...
Definition: Functional.hpp:47
typename vector_traits< std::remove_cvref_t< T > >::value_type vector_value_t
Convenience alias type to the value_type of Vectors.
Definition: Concepts.hpp:188
constexpr vector_value_t< TVector > length_squared(const TVector &vector)
Calculates the squared length of a Vector.
Definition: Vector.hpp:642
constexpr TVector operator-(TVector lhs, T2 &&rhs)
Minus operator.
Definition: Vector.hpp:540
constexpr TVector normalized(TVector vec)
Calculates the normalization of a Vector.
Definition: Vector.hpp:668
constexpr TVector lerp(TVector vector1, const TVector &vector2, T t)
Computes the linear interpolation between both vectors for the parameter t (or extrapolation,...
Definition: Vector.hpp:709
constexpr auto length(const TVector &vector)
Calculates the length of a Vector.
Definition: Vector.hpp:657
constexpr TVector operator%(TVector lhs, T2 &&rhs)
Modulo operator.
Definition: Vector.hpp:604
constexpr vector_value_t< TVector1 > dot_product(const TVector1 &lhs, const TVector2 &rhs)
Calculates the dot product of to Vectors.
Definition: Vector.hpp:621
Vector(T &&...) -> Vector< std::common_type_t< T... >, sizeof...(T)>
Vector deduction guide to make aggregate-like construction easier.
constexpr TVector operator/(TVector lhs, T2 &&rhs)
Division operator.
Definition: Vector.hpp:588
constexpr TVector projected(const TVector &vector, TVector target)
Projects vector onto the target Vector.
Definition: Vector.hpp:684
constexpr TVector operator*(TVector lhs, T2 &&rhs)
Multiplication operator.
Definition: Vector.hpp:556
constexpr TVector inversed(TVector vector)
Computes the inverse of the vector (1./v[0], 1./v[1], ...).
Definition: Vector.hpp:730
constexpr TVector operator+(TVector lhs, T2 &&rhs)
Sum operator.
Definition: Vector.hpp:524
Definition: Algorithm.hpp:19
Checks whether T is a vector type.
Definition: Concepts.hpp:203
Uniform interface to Vector types.
Definition: Concepts.hpp:180