1087 lines
40 KiB
C++
1087 lines
40 KiB
C++
// =====================================================================================================================
|
|
// fennec, a free and open source game engine
|
|
// Copyright © 2025 Medusa Slockbower
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
// =====================================================================================================================
|
|
|
|
///
|
|
/// \file vector.h
|
|
/// \brief the \ref page_fennec_math_vector
|
|
///
|
|
///
|
|
/// \details
|
|
/// \author Medusa Slockbower
|
|
///
|
|
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
|
|
///
|
|
///
|
|
|
|
#ifndef FENNEC_MATH_VECTOR_H
|
|
#define FENNEC_MATH_VECTOR_H
|
|
|
|
///
|
|
///
|
|
///
|
|
/// \page page_fennec_math_vector Vectors
|
|
///
|
|
/// \brief The fennec Vector Math Module
|
|
///
|
|
///
|
|
/// \section vector_types Types
|
|
///
|
|
/// <table>
|
|
/// <caption id="table_fennec_math_vector_types"></caption>
|
|
/// <tr><th>Type <th>Brief
|
|
/// <tr><td colspan=2 style="text-align: center;">Floats
|
|
/// <tr><td>```vec2``` <td>\copybrief fennec::vec2
|
|
/// <tr><td>```vec3``` <td>\copybrief fennec::vec3
|
|
/// <tr><td>```vec4``` <td>\copybrief fennec::vec4
|
|
/// <tr><td colspan=2 style="text-align: center;">Doubles
|
|
/// <tr><td>```dvec2```<td>\copybrief fennec::dvec2
|
|
/// <tr><td>```dvec3```<td>\copybrief fennec::dvec3
|
|
/// <tr><td>```dvec4```<td>\copybrief fennec::dvec4
|
|
/// <tr><td colspan=2 style="text-align: center;">Booleans
|
|
/// <tr><td>```bvec2```<td>\copybrief fennec::bvec2
|
|
/// <tr><td>```bvec3```<td>\copybrief fennec::bvec3
|
|
/// <tr><td>```bvec4```<td>\copybrief fennec::bvec4
|
|
/// <tr><td colspan=2 style="text-align: center;">Integers
|
|
/// <tr><td>```ivec2```<td>\copybrief fennec::ivec2
|
|
/// <tr><td>```ivec3```<td>\copybrief fennec::ivec3
|
|
/// <tr><td>```ivec4```<td>\copybrief fennec::ivec4
|
|
/// <tr><td colspan=2 style="text-align: center;">Unsigned Integers
|
|
/// <tr><td>```uvec2```<td>\copybrief fennec::uvec2
|
|
/// <tr><td>```uvec3```<td>\copybrief fennec::uvec3
|
|
/// <tr><td>```uvec4```<td>\copybrief fennec::uvec4
|
|
/// </table>
|
|
///
|
|
///
|
|
///
|
|
/// \section vector_components Components
|
|
///
|
|
/// Vectors are usually made up of one to four components, named ```x```, ```y```, ```z```, and ```w```.
|
|
/// Each component also has aliases for usage in colors ```rgba```, and texture coordinates ```stpq```. Accessing a
|
|
/// component outside the vector will cause an error at compile time, for example:
|
|
///
|
|
/// \code{.cpp}
|
|
/// vec2 pos;
|
|
/// float height;
|
|
/// pos.x; // is legal
|
|
/// pos.z; // is illegal
|
|
/// height.x; // is legal in glsl, but illegal in c++
|
|
/// height.y; // is illegal
|
|
/// \endcode
|
|
///
|
|
/// Components can also be accessed with indices using the array access operator \ref fennec::vector::operator[] "vector::operator[](size_t)".
|
|
///
|
|
///
|
|
///
|
|
/// \section vector_swizzling Swizzling
|
|
///
|
|
/// The fennec \ref page_fennec_math_vector allows for the "swizzling" of vectors. Each component in the vector can be
|
|
/// used in any combination, with up to 4 components, to create another vector. For example, <br><br>
|
|
///
|
|
/// let \f$V = (0, 1, 2)\f$
|
|
/// then \f$V.xy = (0, 1)\f$
|
|
/// and \f$V.zy = (2, 1)\f$
|
|
///
|
|
///
|
|
///
|
|
|
|
#include <fennec/math/detail/__fwd.h>
|
|
|
|
#include <fennec/math/vector_base.h>
|
|
#include <fennec/math/vector_traits.h>
|
|
|
|
#include <fennec/lang/conditional_types.h>
|
|
#include <fennec/lang/type_traits.h>
|
|
#include <fennec/lang/utility.h>
|
|
|
|
namespace fennec
|
|
{
|
|
|
|
|
|
///
|
|
/// \typedef vec
|
|
/// \anchor vec
|
|
/// \brief Main \ref fennec::vector "vector" template
|
|
/// \tparam ScalarT The type of the Components
|
|
/// \tparam SizeV The number of Components
|
|
template<typename ScalarT, size_t SizeV> using vec = decltype(detail::__gen_vector<vector, ScalarT>(make_index_sequence<SizeV>{}));
|
|
|
|
|
|
|
|
///
|
|
/// \typedef tvec2
|
|
/// \anchor tvec2
|
|
/// \brief Shorthand for ```vec<ScalarT, 2>```
|
|
/// \tparam ScalarT The type of the Components
|
|
template<typename ScalarT> using tvec2 = vec<ScalarT, 2>;
|
|
|
|
///
|
|
/// \typedef tvec3
|
|
/// \anchor tvec3
|
|
/// \brief Shorthand for ```vec<ScalarT, 3>```
|
|
/// \tparam ScalarT The type of the Components
|
|
template<typename ScalarT> using tvec3 = vec<ScalarT, 3>;
|
|
|
|
///
|
|
/// \typedef tvec4
|
|
/// \anchor tvec4
|
|
/// \brief Shorthand for ```vec<ScalarT, 4>```
|
|
/// \tparam ScalarT The type of the Components
|
|
template<typename ScalarT> using tvec4 = vec<ScalarT, 4>;
|
|
|
|
|
|
|
|
///
|
|
/// \typedef bvec2
|
|
/// \anchor bvec2
|
|
/// \brief A two-component boolean \ref fennec::vector "vector"
|
|
using bvec2 = tvec2<bool_t>;
|
|
|
|
///
|
|
/// \typedef bvec3
|
|
/// \anchor bvec3
|
|
/// \brief A three-component boolean \ref fennec::vector "vector"
|
|
using bvec3 = tvec3<bool_t>;
|
|
|
|
///
|
|
/// \typedef bvec4
|
|
/// \anchor bvec4
|
|
/// \brief A four-component boolean \ref fennec::vector "vector"
|
|
using bvec4 = tvec4<bool_t>;
|
|
|
|
|
|
|
|
///
|
|
/// \typedef ivec2
|
|
/// \anchor ivec2
|
|
/// \brief A two-component signed integer \ref fennec::vector "vector"
|
|
using ivec2 = tvec2<int32_t>;
|
|
|
|
/// \typedef ivec3
|
|
/// \anchor ivec3
|
|
/// \brief A three-component signed integer \ref fennec::vector "vector"
|
|
using ivec3 = tvec3<int32_t>;
|
|
|
|
/// \typedef ivec4
|
|
/// \anchor ivec4
|
|
/// \brief A four-component signed integer \ref fennec::vector "vector"
|
|
using ivec4 = tvec4<int32_t>;
|
|
|
|
|
|
|
|
///
|
|
/// \typedef uvec2
|
|
/// \anchor uvec2
|
|
/// \brief A two-component unsigned integer \ref fennec::vector "vector"
|
|
using uvec2 = tvec2<uint32_t>;
|
|
|
|
///
|
|
/// \typedef uvec3
|
|
/// \anchor uvec3
|
|
/// \brief A three-component unsigned integer \ref fennec::vector "vector"
|
|
using uvec3 = tvec3<uint32_t>;
|
|
|
|
///
|
|
/// \typedef uvec4
|
|
/// \anchor uvec4
|
|
/// \brief A four-component unsigned integer \ref fennec::vector "vector"
|
|
using uvec4 = tvec4<uint32_t>;
|
|
|
|
|
|
|
|
///
|
|
/// \typedef vec2
|
|
/// \anchor vec2
|
|
/// \brief A two-component single-precision floating-point \ref fennec::vector "vector"
|
|
using vec2 = tvec2<float32_t>;
|
|
|
|
///
|
|
/// \typedef vec3
|
|
/// \anchor vec3
|
|
/// \brief A three-component single-precision floating-point \ref fennec::vector "vector"
|
|
using vec3 = tvec3<float32_t>;
|
|
|
|
///
|
|
/// \typedef vec4
|
|
/// \anchor vec4
|
|
/// \brief A four-component single-precision floating-point \ref fennec::vector "vector"
|
|
using vec4 = tvec4<float32_t>;
|
|
|
|
|
|
|
|
///
|
|
/// \typedef dvec2
|
|
/// \anchor dvec2
|
|
/// \brief A two-component double-precision floating-point \ref fennec::vector "vector"
|
|
using dvec2 = tvec2<float64_t>;
|
|
|
|
///
|
|
/// \typedef dvec3
|
|
/// \anchor dvec3
|
|
/// \brief A three-component double-precision floating-point \ref fennec::vector "vector"
|
|
using dvec3 = tvec3<float64_t>;
|
|
|
|
///
|
|
/// \typedef dvec4
|
|
/// \anchor dvec4
|
|
/// \brief A four-component double-precision floating-point \ref fennec::vector "vector"
|
|
using dvec4 = tvec4<float64_t>;
|
|
|
|
|
|
|
|
|
|
///
|
|
/// \struct fennec::vector
|
|
/// \brief Math Vector Type
|
|
/// \tparam ScalarT base \ref scalar type of each Component
|
|
/// \tparam IndicesV index of each Component
|
|
/// \nosubgrouping
|
|
template<typename ScalarT, size_t...IndicesV>
|
|
struct vector : detail::vector_base_type<ScalarT, sizeof...(IndicesV)>
|
|
{
|
|
// Assertions ==========================================================================================================
|
|
|
|
static_assert(is_arithmetic_v<ScalarT>);
|
|
|
|
|
|
// Forward Defs ========================================================================================================
|
|
|
|
/// \name Forward Definitions & Constants
|
|
/// @{
|
|
|
|
///
|
|
/// \typedef vector::base_type
|
|
/// \brief vector base type
|
|
using base_type = detail::vector_base_type<ScalarT, sizeof...(IndicesV)>;
|
|
|
|
///
|
|
/// \brief vector data array
|
|
using base_type::data;
|
|
|
|
///
|
|
/// \typedef scalar_t
|
|
/// \brief alias for ScalarT
|
|
using scalar_t = ScalarT;
|
|
|
|
///
|
|
/// \typedef vector::vector_t
|
|
/// \brief alias for this type
|
|
using vector_t = vector;
|
|
|
|
// Size Aliases
|
|
static constexpr size_t dimension = sizeof...(IndicesV); ///< \brief dimension of the swizzle
|
|
static constexpr size_t num_components = sizeof...(IndicesV); ///< \brief number of components
|
|
static constexpr size_t size = sizeof...(IndicesV); ///< \brief size of the swizzle
|
|
static constexpr size_t N = sizeof...(IndicesV); ///< \brief size of the swizzle
|
|
|
|
using decay_t = conditional_t<N == 1, scalar_t, vector_t>; ///< Type that the \ref fennec::vector "vector" should Decay into
|
|
|
|
/// @}
|
|
|
|
|
|
// Constructors ========================================================================================================
|
|
|
|
/// \name Constructors
|
|
/// @{
|
|
|
|
///
|
|
/// \brief default constructor, initializes components with 0
|
|
///
|
|
/// \details ** **
|
|
constexpr vector() { data = { 0 }; }
|
|
|
|
|
|
///
|
|
/// \brief copy constructor
|
|
///
|
|
/// \details
|
|
/// \param x object to copy
|
|
constexpr vector(const vector_t& x) { data = x.data; }
|
|
|
|
|
|
///
|
|
/// \brief move constructor
|
|
///
|
|
/// \details
|
|
/// \param x object to move
|
|
constexpr vector(vector_t&& x) noexcept { data = std::move(x.data); }
|
|
|
|
|
|
///
|
|
/// \brief scalar constructor
|
|
///
|
|
/// \details
|
|
/// \param s scalar value to initialize with
|
|
explicit constexpr vector(scalar_t s) { ((data[IndicesV] = s), ...); }
|
|
|
|
|
|
///
|
|
/// \brief int conversion scalar
|
|
///
|
|
/// \details
|
|
/// \param s scalar value to initialize with
|
|
explicit constexpr vector(int_t s) requires(not is_same_v<ScalarT, int_t>) {
|
|
if constexpr(N == 1) data[0] = ScalarT(s);
|
|
else ((data[IndicesV] = ScalarT(s)), ...);
|
|
}
|
|
|
|
|
|
///
|
|
/// \brief double conversion scalar
|
|
///
|
|
/// \details
|
|
/// \param s scalar value to initialize with
|
|
explicit constexpr vector(double_t s) requires(not is_same_v<ScalarT, double_t>) {
|
|
if constexpr(N == 1) data[0] = ScalarT(s);
|
|
else ((data[IndicesV] = ScalarT(s)), ...);
|
|
}
|
|
|
|
|
|
///
|
|
/// \brief vector scalar conversion constructor
|
|
///
|
|
/// \details
|
|
/// \tparam OScalarT scalar Type of the \ref fennec::vector "vector" to Convert
|
|
/// \param v \ref fennec::vector "vector" to Convert
|
|
template<typename OScalarT>
|
|
explicit constexpr vector(const vector<OScalarT, IndicesV...>& v)
|
|
{ ((data[IndicesV] = ScalarT(v[IndicesV])), ...); }
|
|
|
|
|
|
///
|
|
/// \brief vector conversion constructor
|
|
///
|
|
/// \details
|
|
/// \tparam OScalarT scalar Type of the \ref fennec::vector "vector" to Convert
|
|
/// \tparam MoreIndicesStartV
|
|
/// \tparam MoreIndicesV
|
|
/// \param v
|
|
template<typename OScalarT, size_t MoreIndicesStartV, size_t...MoreIndicesV>
|
|
explicit constexpr vector(const vector<OScalarT, IndicesV..., MoreIndicesStartV, MoreIndicesV...>& v)
|
|
{ ((data[IndicesV] = ScalarT(v[IndicesV])), ...); }
|
|
|
|
|
|
///
|
|
/// \brief swizzle conversion constructor
|
|
///
|
|
/// \details
|
|
/// \tparam SwizzleDataT swizzle Data Type
|
|
/// \tparam SwizzleScalarT swizzle scalar Type
|
|
/// \tparam SwizzleIndicesV swizzle Indices
|
|
/// \param swizzle swizzle object
|
|
template<typename SwizzleDataT, typename SwizzleScalarT, size_t...SwizzleIndicesV>
|
|
explicit constexpr vector(const detail::swizzle_storage<SwizzleDataT, SwizzleScalarT, SwizzleIndicesV...>& swizzle)
|
|
{ ((data[IndicesV] = ScalarT(swizzle[IndicesV])), ...); }
|
|
|
|
|
|
///
|
|
/// \brief piecewise constructor
|
|
///
|
|
/// \details constructs a vector from a series of scalars, swizzles, and vectors
|
|
/// \tparam ArgsT argument types
|
|
/// \param args arguments
|
|
template<typename...ArgsT> requires(total_component_count_v<ArgsT...> == N)
|
|
explicit constexpr vector(ArgsT&&...args)
|
|
{ vector::__construct<0>(args...); }
|
|
|
|
/// @}
|
|
|
|
|
|
// Public Member Functions =============================================================================================
|
|
|
|
/// \name Public Member Functions
|
|
/// @{
|
|
|
|
///
|
|
/// \brief decay implementation
|
|
///
|
|
/// \details
|
|
/// \returns scalar if \f$N==1\f$, otherwise, \ref fennec::vector "vector"
|
|
decay_t decay()
|
|
{ return static_cast<const decay_t&>(*this); }
|
|
|
|
/// @}
|
|
|
|
|
|
// Access operators ====================================================================================================
|
|
|
|
/// \name Access operators
|
|
/// @{
|
|
|
|
///
|
|
/// \copydetails vector::operator[](size_t) const
|
|
constexpr scalar_t& operator[](size_t i)
|
|
{ return data[i]; }
|
|
|
|
///
|
|
/// \brief indexed access operator
|
|
///
|
|
/// \details
|
|
/// \returns a copy of the component
|
|
/// \param i the index of the component
|
|
constexpr scalar_t operator[](size_t i) const
|
|
{ return data[i]; }
|
|
|
|
/// @}
|
|
|
|
|
|
// Assignment operators ================================================================================================
|
|
|
|
/// \name Assignment operators
|
|
/// @{
|
|
|
|
///
|
|
/// \brief copy assignment
|
|
///
|
|
/// \details
|
|
/// \returns A reference to \c this, after having set \p lhs, such that \f$lhs_i=rhs_i\f$
|
|
/// \param rhs vector to copy
|
|
constexpr vector_t& operator=(const vector_t& rhs)
|
|
{ return ((data[IndicesV] = rhs[IndicesV]), ..., *this); }
|
|
|
|
///
|
|
/// \brief move assignment
|
|
///
|
|
/// \details
|
|
/// \returns A reference to \c this, after having set \p lhs, such that \f$lhs_i=rhs_i\f$
|
|
/// \param rhs vector to move
|
|
constexpr vector_t& operator=(vector_t&& rhs) noexcept
|
|
{ return ((data[IndicesV] = fennec::move(rhs[IndicesV])), ..., *this); }
|
|
|
|
/// @}
|
|
|
|
|
|
// Comparison Operators ================================================================================================
|
|
|
|
/// \name Comparison Operators
|
|
/// @{
|
|
|
|
///
|
|
/// \brief vector equality operator
|
|
///
|
|
/// \details
|
|
/// \returns **true** if every respective component is equivalent, otherwise returns **false**
|
|
/// \param rhs vector to compare with
|
|
constexpr bool_t operator==(const vector_t& rhs) const
|
|
{ return ((data[IndicesV] == rhs.data[IndicesV]) && ...); }
|
|
|
|
///
|
|
/// \brief vector inequality operator
|
|
///
|
|
/// \details
|
|
/// \returns **false** if every respective component is equivalent, otherwise returns **true**
|
|
/// \param rhs vector to compare with
|
|
constexpr bool_t operator!=(const vector_t& rhs) const
|
|
{ return ((data[IndicesV] != rhs.data[IndicesV]) || ...); }
|
|
|
|
/// @}
|
|
|
|
|
|
// Scalar-Vector Arithmetic operators ==================================================================================
|
|
|
|
/// \name \ref page_fennec_math_scalar "scalar" - \ref fennec::vector "vector" Arithmetic operators
|
|
/// @{
|
|
|
|
///
|
|
/// \brief \ref page_fennec_math_scalar "scalar" - \ref fennec::vector "vector" addition operator
|
|
///
|
|
/// \details
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i+rhs_i\f$
|
|
/// \param lhs left hand side
|
|
/// \param rhs right hand side
|
|
constexpr friend vector_t operator+(scalar_t lhs, const vector_t& rhs)
|
|
{ return vector_t((lhs[IndicesV] + rhs[IndicesV]) ...); }
|
|
|
|
///
|
|
/// \brief \ref page_fennec_math_scalar "scalar" - \ref fennec::vector "vector" subtraction operator
|
|
///
|
|
/// \details
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i-rhs_i\f$
|
|
/// \param lhs left hand side
|
|
/// \param rhs right hand side
|
|
constexpr friend vector_t operator-(scalar_t lhs, const vector_t& rhs)
|
|
{ return vector_t((lhs[IndicesV] - rhs[IndicesV]) ...); }
|
|
|
|
///
|
|
/// \brief \ref page_fennec_math_scalar "scalar" - \ref fennec::vector "vector" multiplication operator
|
|
///
|
|
/// \details
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i={lhs_i}\cdot{rhs_i}\f$
|
|
/// \param lhs left hand side
|
|
/// \param rhs right hand side
|
|
constexpr friend vector_t operator*(scalar_t lhs, const vector_t& rhs)
|
|
{ return vector_t((lhs * rhs[IndicesV]) ...); }
|
|
|
|
///
|
|
/// \brief \ref page_fennec_math_scalar "scalar" - \ref fennec::vector "vector" division operator
|
|
///
|
|
/// \details
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=\frac{lhs_i}{rhs_i}\f$
|
|
/// \param lhs left hand side
|
|
/// \param rhs right hand side
|
|
constexpr friend vector_t operator/(scalar_t lhs, const vector_t& rhs)
|
|
{ return vector_t((lhs / rhs[IndicesV]) ...); }
|
|
|
|
///
|
|
/// \brief \ref page_fennec_math_scalar "scalar" - \ref fennec::vector "vector" integer modulus operator
|
|
///
|
|
/// \details
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i\%rhs_i\f$
|
|
/// \param lhs left hand side
|
|
/// \param rhs right hand side
|
|
constexpr friend vector_t operator%(scalar_t lhs, const vector_t& rhs) requires(is_integral_v<scalar_t>)
|
|
{ return vector_t((lhs % rhs[IndicesV]) ...); }
|
|
|
|
/// @}
|
|
|
|
// Vector-Scalar Arithmetic operators ==================================================================================
|
|
|
|
/// \name \ref fennec::vector "vector" - \ref page_fennec_math_scalar "scalar" Arithmetic operators
|
|
/// @{
|
|
|
|
///
|
|
/// \brief \ref fennec::vector "vector" - \ref page_fennec_math_scalar "scalar" addition operator
|
|
///
|
|
/// \details
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i+rhs_i\f$
|
|
/// \param lhs left hand side
|
|
/// \param rhs right hand side
|
|
constexpr friend vector_t operator+(const vector_t& lhs, scalar_t rhs)
|
|
{ return vector_t((lhs[IndicesV] + rhs) ...); }
|
|
|
|
///
|
|
/// \brief \ref fennec::vector "vector" - \ref page_fennec_math_scalar "scalar" subtraction operator
|
|
///
|
|
/// \details
|
|
/// \param lhs left hand side
|
|
/// \param rhs right hand side
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i-rhs_i\f$
|
|
constexpr friend vector_t operator-(const vector_t& lhs, scalar_t rhs)
|
|
{ return vector_t((lhs[IndicesV] - rhs) ...); }
|
|
|
|
///
|
|
/// \brief \ref fennec::vector "vector" - \ref page_fennec_math_scalar "scalar" multiplication operator
|
|
///
|
|
/// \details
|
|
/// \param lhs left hand side
|
|
/// \param rhs right hand side
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i={lhs_i}\cdot{rhs_i}\f$
|
|
constexpr friend vector_t operator*(const vector_t& lhs, scalar_t rhs)
|
|
{ return vector_t((lhs[IndicesV] * rhs) ...); }
|
|
|
|
///
|
|
/// \brief \ref fennec::vector "vector" - \ref page_fennec_math_scalar "scalar" division operator
|
|
///
|
|
/// \details
|
|
/// \param lhs left hand side
|
|
/// \param rhs right hand side
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=\frac{lhs_i}{rhs_i}\f$
|
|
constexpr friend vector_t operator/(const vector_t& lhs, scalar_t rhs)
|
|
{ return vector((lhs[IndicesV] / rhs) ...); }
|
|
|
|
///
|
|
/// \brief \ref fennec::vector "vector" - \ref page_fennec_math_scalar "scalar" integer modulus operator
|
|
///
|
|
/// \details
|
|
/// \param lhs left hand side
|
|
/// \param rhs right hand side
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i\%rhs_i\f$
|
|
constexpr friend vector_t operator%(const vector_t& lhs, scalar_t rhs) requires(is_integral_v<scalar_t>)
|
|
{ return vector((lhs[IndicesV] % rhs) ...); }
|
|
|
|
/// @}
|
|
|
|
// Vector-Scalar Arithmetic Assignment operators =======================================================================
|
|
|
|
/// \name \ref fennec::vector "vector" - \ref page_fennec_math_scalar "scalar" Arithmetic Assignment operators
|
|
/// @{
|
|
|
|
///
|
|
/// \brief \ref fennec::vector "vector" - \ref page_fennec_math_scalar "scalar" addition operator
|
|
///
|
|
/// \details
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i+rhs_i\f$
|
|
constexpr friend vector_t& operator+=(vector_t& lhs, scalar_t rhs)
|
|
{ return ((lhs[IndicesV] += rhs), ..., lhs); }
|
|
|
|
///
|
|
/// \brief \ref fennec::vector "vector" - \ref page_fennec_math_scalar "scalar" Subtraction operator
|
|
///
|
|
/// \details
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i-rhs_i\f$
|
|
constexpr friend vector_t& operator-=(vector_t& lhs, scalar_t rhs)
|
|
{ return ((lhs[IndicesV] -= rhs), ..., lhs); }
|
|
|
|
///
|
|
/// \brief \ref fennec::vector "vector" - \ref page_fennec_math_scalar "scalar" multiplication operator
|
|
///
|
|
/// \details
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i={lhs_i}\cdot{rhs_i}\f$
|
|
constexpr friend vector_t& operator*=(vector_t& lhs, scalar_t rhs)
|
|
{ return ((lhs[IndicesV] *= rhs), ..., lhs); }
|
|
|
|
///
|
|
/// \brief \ref fennec::vector "vector" - \ref page_fennec_math_scalar "scalar" division operator
|
|
///
|
|
/// \details
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=\frac{lhs_i}{rhs_i}\f$
|
|
constexpr friend vector_t& operator/=(vector_t& lhs, scalar_t rhs)
|
|
{ return ((lhs[IndicesV] /= rhs), ..., lhs); }
|
|
|
|
///
|
|
/// \brief \ref fennec::vector "vector" - \ref page_fennec_math_scalar "scalar" integer modulus operator
|
|
///
|
|
/// \details
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i\%rhs_i\f$
|
|
constexpr friend vector_t& operator%=(vector_t& lhs, scalar_t rhs) requires(is_integral_v<scalar_t>)
|
|
{ return ((lhs[IndicesV] %= rhs), ..., lhs); }
|
|
|
|
/// @}
|
|
|
|
// Vector-Vector Arithmetic operators ==================================================================================
|
|
|
|
/// \name \ref fennec::vector "vector" - \ref fennec::vector "vector" Arithmetic operators
|
|
/// @{
|
|
|
|
///
|
|
/// \brief \ref fennec::vector "vector" - \ref fennec::vector "vector" addition operator
|
|
///
|
|
/// \details
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i+rhs_i\f$
|
|
constexpr friend vector_t operator+(const vector_t& lhs, const vector_t& rhs)
|
|
{ return vector((lhs[IndicesV] + rhs[IndicesV]) ...); }
|
|
|
|
///
|
|
/// \brief \ref fennec::vector "vector" - \ref fennec::vector "vector" subtraction operator
|
|
///
|
|
/// \details
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i-rhs_i\f$
|
|
constexpr friend vector_t operator-(const vector_t& lhs, const vector_t& rhs)
|
|
{ return vector((lhs[IndicesV] - rhs[IndicesV]) ...); }
|
|
|
|
///
|
|
/// \brief \ref fennec::vector "vector" - \ref fennec::vector "vector" multiplication operator
|
|
///
|
|
/// \details
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i={lhs_i}\cdot{rhs_i}\f$
|
|
constexpr friend vector_t operator*(const vector_t& lhs, const vector_t& rhs)
|
|
{ return vector((lhs[IndicesV] * rhs[IndicesV]) ...); }
|
|
|
|
///
|
|
/// \fn vector::operator/(const vector_t&, const vector_t&)
|
|
/// \brief \ref fennec::vector "vector" - \ref fennec::vector "vector" division operator
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=\frac{lhs_i}{rhs_i}\f$
|
|
constexpr friend vector_t operator/(const vector_t& lhs, const vector_t& rhs)
|
|
{ return vector((lhs[IndicesV] / rhs[IndicesV]) ...); }
|
|
|
|
///
|
|
/// \brief \ref fennec::vector "vector" - \ref fennec::vector "vector" integer modulus operator
|
|
///
|
|
/// \details
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i\%rhs_i\f$
|
|
constexpr friend vector_t operator%(const vector_t& lhs, const vector_t& rhs) requires(is_integral_v<scalar_t>)
|
|
{ return vector((lhs[IndicesV] % rhs[IndicesV]) ...); }
|
|
|
|
/// @}
|
|
|
|
// Vector-Vector Arithmetic Assignment operators =======================================================================
|
|
|
|
/// \name \ref fennec::vector "vector" - \ref fennec::vector "vector" Arithmetic Assignment operators
|
|
/// @{
|
|
|
|
///
|
|
/// \brief \ref fennec::vector "vector" - \ref fennec::vector "vector" addition operator
|
|
///
|
|
/// \details
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i+rhs_i\f$
|
|
constexpr friend vector_t& operator+=(vector_t& lhs, const vector_t& rhs)
|
|
{ return ((lhs[IndicesV] += rhs[IndicesV]), ..., lhs); }
|
|
|
|
///
|
|
/// \brief \ref fennec::vector "vector" - \ref fennec::vector "vector" subtraction operator
|
|
///
|
|
/// \details
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i-rhs_i\f$
|
|
constexpr friend vector_t& operator-=(vector_t& lhs, const vector_t& rhs)
|
|
{ return ((lhs[IndicesV] -= rhs[IndicesV]), ..., lhs); }
|
|
|
|
///
|
|
/// \brief \ref fennec::vector "vector" - \ref fennec::vector "vector" multiplication operator
|
|
///
|
|
/// \details
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i={lhs_i}\cdot{rhs_i}\f$
|
|
constexpr friend vector_t& operator*=(vector_t& lhs, const vector_t& rhs)
|
|
{ return ((lhs[IndicesV] *= rhs[IndicesV]), ..., lhs); }
|
|
|
|
///
|
|
/// \brief \ref fennec::vector "vector" - \ref fennec::vector "vector" division operator
|
|
///
|
|
/// \details
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=\frac{lhs_i}{rhs_i}\f$
|
|
constexpr friend vector_t& operator/=(vector_t& lhs, const vector_t& rhs)
|
|
{ return ((lhs[IndicesV] /= rhs[IndicesV]), ..., lhs); }
|
|
|
|
///
|
|
/// \brief \ref fennec::vector "vector" - \ref fennec::vector "vector" integer modulus operator
|
|
///
|
|
/// \details
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i\%rhs_i\f$
|
|
constexpr friend vector_t& operator%=(vector_t& lhs, const vector_t& rhs) requires(is_integral_v<scalar_t>)
|
|
{ return ((lhs[IndicesV] %= rhs[IndicesV]), ..., lhs); }
|
|
|
|
/// @}
|
|
|
|
// Boolean Operators ===================================================================================================
|
|
|
|
/// \name Boolean Operators
|
|
/// @{
|
|
|
|
///
|
|
/// \brief \ref fennec::vector "vector" - \ref page_fennec_math_scalar "scalar" logical and operator
|
|
///
|
|
/// \details
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i\&\&rhs_i\f$
|
|
constexpr friend vector_t operator&&(const vector_t& lhs, scalar_t rhs) requires(is_bool_v<scalar_t>)
|
|
{ return vector_t((lhs[IndicesV] && rhs) ...); }
|
|
|
|
///
|
|
/// \brief \ref fennec::vector "vector" - \ref fennec::vector "vector" logical and operator
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i\&\&rhs_i\f$
|
|
constexpr friend vector_t operator&&(const vector_t& lhs, const vector_t& rhs) requires(is_bool_v<scalar_t>)
|
|
{ return vector_t((lhs[IndicesV] && rhs[IndicesV]) ...); }
|
|
|
|
///
|
|
/// \brief \ref fennec::vector "vector" - \ref page_fennec_math_scalar "scalar" logical or operator
|
|
///
|
|
/// \details
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i\|\|rhs_i\f$
|
|
constexpr friend vector_t operator||(const vector_t& lhs, scalar_t rhs) requires(is_bool_v<scalar_t>)
|
|
{ return vector_t((lhs[IndicesV] || rhs) ...); }
|
|
|
|
///
|
|
/// \brief \ref fennec::vector "vector" - \ref fennec::vector "vector" logical or operator
|
|
///
|
|
/// \details
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i\|\|rhs_i\f$
|
|
constexpr friend vector_t operator||(const vector_t& lhs, const vector_t& rhs) requires(is_bool_v<scalar_t>)
|
|
{ return vector_t((lhs[IndicesV] || rhs[IndicesV]) ...); }
|
|
|
|
/// @}
|
|
|
|
// Bitwise Operators ===================================================================================================
|
|
|
|
/// \name Bitwise Operators
|
|
/// @{
|
|
|
|
///
|
|
/// \brief \ref page_fennec_math_scalar "scalar" - \ref fennec::vector "vector" bitwise and operator
|
|
///
|
|
/// \details
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i\&rhs_i\f$
|
|
constexpr friend vector_t operator&(scalar_t rhs, const vector_t& lhs) requires(is_integral_v<scalar_t>)
|
|
{ return vector_t((lhs & rhs[IndicesV]) ...); }
|
|
|
|
///
|
|
/// \brief \ref fennec::vector "vector" - \ref page_fennec_math_scalar "scalar" bitwise and assignment operator
|
|
///
|
|
/// \details
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i\&rhs_i\f$
|
|
constexpr friend vector_t operator&=(vector_t& lhs, scalar_t rhs) requires(is_integral_v<scalar_t>)
|
|
{ return ((lhs[IndicesV] &= rhs), ..., lhs); }
|
|
|
|
///
|
|
/// \brief \ref fennec::vector "vector" - \ref page_fennec_math_scalar "scalar" bitwise and operator
|
|
///
|
|
/// \details
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i\&rhs_i\f$
|
|
constexpr friend vector_t operator&(const vector_t& lhs, scalar_t rhs) requires(is_integral_v<scalar_t>)
|
|
{ return vector_t((lhs[IndicesV] & rhs) ...); }
|
|
|
|
///
|
|
/// \brief \ref fennec::vector "vector" - \ref fennec::vector "vector" bitwise and assignment operator
|
|
///
|
|
/// \details
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i\&rhs_i\f$
|
|
constexpr friend vector_t operator&=(vector_t& lhs, const vector_t& rhs) requires(is_integral_v<scalar_t>)
|
|
{ return ((lhs[IndicesV] &= rhs), ..., lhs); }
|
|
|
|
///
|
|
/// \brief \ref fennec::vector "vector" - \ref fennec::vector "vector" bitwise and operator
|
|
///
|
|
/// \details
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i\&rhs_i\f$
|
|
constexpr friend vector_t operator&(const vector_t& lhs, const vector_t& rhs) requires(is_integral_v<scalar_t>)
|
|
{ return vector_t((lhs[IndicesV] & rhs[IndicesV]) ...); }
|
|
|
|
|
|
|
|
///
|
|
/// \brief \ref page_fennec_math_scalar "scalar" - \ref fennec::vector "vector" bitwise or operator
|
|
///
|
|
/// \details
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i|rhs_i\f$
|
|
constexpr friend vector_t operator|(scalar_t rhs, const vector_t& lhs) requires(is_integral_v<scalar_t>)
|
|
{ return vector_t((lhs & rhs[IndicesV]) ...); }
|
|
|
|
///
|
|
/// \brief \ref fennec::vector "vector" - \ref page_fennec_math_scalar "scalar" bitwise or assignment operator
|
|
///
|
|
/// \details
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i|rhs_i\f$
|
|
constexpr friend vector_t operator|=(vector_t& lhs, scalar_t rhs) requires(is_integral_v<scalar_t>)
|
|
{ return ((lhs[IndicesV] |= rhs), ..., lhs); }
|
|
|
|
///
|
|
/// \brief \ref fennec::vector "vector" - \ref page_fennec_math_scalar "scalar" bitwise or operator
|
|
///
|
|
/// \details
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i|rhs_i\f$
|
|
constexpr friend vector_t operator|(const vector_t& lhs, scalar_t rhs) requires(is_integral_v<scalar_t>)
|
|
{ return vector_t((lhs[IndicesV] | rhs) ...); }
|
|
|
|
///
|
|
/// \brief \ref fennec::vector "vector" - \ref fennec::vector "vector" bitwise or assignment operator
|
|
///
|
|
/// \details
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i|rhs_i\f$
|
|
constexpr friend vector_t operator|=(vector_t& lhs, const vector_t& rhs) requires(is_integral_v<scalar_t>)
|
|
{ return ((lhs[IndicesV] |= rhs), ..., lhs); }
|
|
|
|
///
|
|
/// \brief \ref fennec::vector "vector" - \ref fennec::vector "vector" bitwise or operator
|
|
///
|
|
/// \details
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i|rhs_i\f$
|
|
constexpr friend vector_t operator|(const vector_t& lhs, const vector_t& rhs) requires(is_integral_v<scalar_t>)
|
|
{ return vector_t((lhs[IndicesV] | rhs[IndicesV]) ...); }
|
|
|
|
|
|
|
|
///
|
|
/// \ref page_fennec_math_scalar "scalar" - \ref fennec::vector "vector" bitwise or operator
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i\^rhs_i\f$
|
|
constexpr friend vector_t operator^(scalar_t rhs, const vector_t& lhs) requires(is_integral_v<scalar_t>)
|
|
{ return vector_t((lhs ^ rhs[IndicesV]) ...); }
|
|
|
|
///
|
|
/// \fn vector::operator^=(vector_t&, scalar_t)
|
|
/// \ref fennec::vector "vector" - \ref page_fennec_math_scalar "scalar" bitwise or assignment operator
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i\^rhs_i\f$
|
|
constexpr friend vector_t operator^=(vector_t& lhs, scalar_t rhs) requires(is_integral_v<scalar_t>)
|
|
{ return ((lhs[IndicesV] ^= rhs), ..., lhs); }
|
|
|
|
///
|
|
/// \fn vector::operator^(const vector_t&, scalar_t)
|
|
/// \ref fennec::vector "vector" - \ref page_fennec_math_scalar "scalar" bitwise or operator
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i\^rhs_i\f$
|
|
constexpr friend vector_t operator^(const vector_t& lhs, scalar_t rhs) requires(is_integral_v<scalar_t>)
|
|
{ return vector_t((lhs[IndicesV] ^ rhs) ...); }
|
|
|
|
///
|
|
/// \fn vector::operator^=(vector_t&, const vector_t&)
|
|
/// \ref fennec::vector "vector" - \ref fennec::vector "vector" bitwise or assignment operator
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i\^rhs_i\f$
|
|
constexpr friend vector_t operator^=(vector_t& lhs, const vector_t& rhs) requires(is_integral_v<scalar_t>)
|
|
{ return ((lhs[IndicesV] ^= rhs), ..., lhs); }
|
|
|
|
///
|
|
/// \fn vector::operator^(const vector_t&, const vector_t&)
|
|
/// \ref fennec::vector "vector" - \ref fennec::vector "vector" bitwise or operator
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i\^rhs_i\f$
|
|
constexpr friend vector_t operator^(const vector_t& lhs, const vector_t& rhs) requires(is_integral_v<scalar_t>)
|
|
{ return vector_t((lhs[IndicesV] ^ rhs[IndicesV]) ...); }
|
|
|
|
|
|
|
|
///
|
|
/// \fn vector::operator<<=(vector_t&, scalar_t)
|
|
/// \ref fennec::vector "vector" - \ref page_fennec_math_scalar "scalar" bitwise left-shift assignment operator
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i<<=rhs_i\f$
|
|
constexpr friend vector_t operator<<=(vector_t& lhs, scalar_t rhs) requires(is_integral_v<scalar_t>)
|
|
{ return ((lhs[IndicesV] <<= rhs), ..., lhs); }
|
|
|
|
///
|
|
/// \fn vector::operator<<(const vector_t&, scalar_t)
|
|
/// \ref fennec::vector "vector" - \ref page_fennec_math_scalar "scalar" bitwise or operator
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i<<rhs_i\f$
|
|
constexpr friend vector_t operator<<(const vector_t& lhs, scalar_t rhs) requires(is_integral_v<scalar_t>)
|
|
{ return vector_t((lhs[IndicesV] << rhs) ...); }
|
|
|
|
///
|
|
/// \fn vector::operator<<=(vector_t&, const vector_t&)
|
|
/// \ref fennec::vector "vector" - \ref fennec::vector "vector" bitwise or assignment operator
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i<<=rhs_i\f$
|
|
constexpr friend vector_t operator<<=(vector_t& lhs, const vector_t& rhs) requires(is_integral_v<scalar_t>)
|
|
{ return ((lhs[IndicesV] <<= rhs), ..., lhs); }
|
|
|
|
///
|
|
/// \fn vector::operator<<(const vector_t&, const vector_t&)
|
|
/// \ref fennec::vector "vector" - \ref fennec::vector "vector" bitwise or operator
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i<<rhs_i\f$
|
|
constexpr friend vector_t operator<<(const vector_t& lhs, const vector_t& rhs) requires(is_integral_v<scalar_t>)
|
|
{ return vector_t((lhs[IndicesV] << rhs[IndicesV]) ...); }
|
|
|
|
|
|
|
|
///
|
|
/// \fn vector::operator>>=(vector_t&, scalar_t)
|
|
/// \ref fennec::vector "vector" - \ref page_fennec_math_scalar "scalar" bitwise left-shift assignment operator
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i>>=rhs_i\f$
|
|
constexpr friend vector_t operator>>=(vector_t& lhs, scalar_t rhs) requires(is_integral_v<scalar_t>)
|
|
{ return ((lhs[IndicesV] >>= rhs), ..., lhs); }
|
|
|
|
///
|
|
/// \fn vector::operator>>(const vector_t&, scalar_t)
|
|
/// \ref fennec::vector "vector" - \ref page_fennec_math_scalar "scalar" bitwise or operator
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i>>rhs_i\f$
|
|
constexpr friend vector_t operator>>(const vector_t& lhs, scalar_t rhs) requires(is_integral_v<scalar_t>)
|
|
{ return vector_t((lhs[IndicesV] >> rhs) ...); }
|
|
|
|
///
|
|
/// \fn vector::operator>>=(vector_t&, const vector_t&)
|
|
/// \ref fennec::vector "vector" - \ref fennec::vector "vector" bitwise or assignment operator
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i>>=rhs_i\f$
|
|
constexpr friend vector_t operator>>=(vector_t& lhs, const vector_t& rhs) requires(is_integral_v<scalar_t>)
|
|
{ return ((lhs[IndicesV] >>= rhs), ..., lhs); }
|
|
|
|
///
|
|
/// \fn vector::operator>>(const vector_t&, const vector_t&)
|
|
/// \ref fennec::vector "vector" - \ref fennec::vector "vector" bitwise or operator
|
|
/// \param lhs Left Hand Side of the Expression
|
|
/// \param rhs Right Hand Side of the Expression
|
|
/// \returns A \ref fennec::vector "vector" \a v such that, \f$v_i=lhs_i>>rhs_i\f$
|
|
constexpr friend vector_t operator>>(const vector_t& lhs, const vector_t& rhs) requires(is_integral_v<scalar_t>)
|
|
{ return vector_t((lhs[IndicesV] >> rhs[IndicesV]) ...); }
|
|
|
|
/// @}
|
|
|
|
|
|
// Helpers =============================================================================================================
|
|
|
|
private:
|
|
template<size_t IndexV = 0, typename HeadT, typename...TailT>
|
|
constexpr void __construct(HeadT&& head, TailT&&...rest)
|
|
{
|
|
vector::__insert<IndexV>(fennec::forward<HeadT>(head));
|
|
|
|
if constexpr(sizeof...(TailT) > 0)
|
|
vector::__construct<IndexV + component_count_v<HeadT>>(fennec::forward<TailT>(rest)...);
|
|
}
|
|
|
|
template<size_t OffsetV>
|
|
constexpr void __insert(ScalarT& x)
|
|
{ data[OffsetV] = x; }
|
|
|
|
template<size_t OffsetV, typename OScalarT>
|
|
constexpr void __insert(OScalarT& x)
|
|
{ data[OffsetV] = ScalarT(x); }
|
|
|
|
template<size_t OffsetV = 0, typename OScalarT, size_t...OIndicesV>
|
|
constexpr void __insert(vector<OScalarT, OIndicesV...>& vec)
|
|
{ ((data[OffsetV + OIndicesV] = fennec::forward<OScalarT>(vec[OIndicesV])), ...); }
|
|
|
|
template<size_t OffsetV = 0, typename OVectorT, typename ODataT, typename OScalarT, size_t...OIndicesV>
|
|
constexpr void __insert(swizzle<OVectorT, ODataT, OScalarT, OIndicesV...>& vec)
|
|
{ size_t i = 0; ((data[OffsetV + (i++)] = vec.data[OIndicesV]), ...); }
|
|
};
|
|
|
|
}
|
|
|
|
#endif // FENNEC_MATH_VECTOR_H
|