25#include <vcruntime_typeinfo.h>
35#include "../utils/compiling.hpp"
45template <
typename _Tp,
size_t _length>
46 requires(_length > 0 && std::is_default_constructible_v<_Tp>)
56concept Vec =
requires(T a) {
59 std::is_same_v<typename T::template Self<typename T::DataType>, T>;
62 { T::dim } -> std::same_as<const size_t&>;
63 { T::length } -> std::same_as<const size_t&>;
64 { a[T::length - 1] } -> std::same_as<typename T::ItemType&>;
75template <
class vec,
class _Item>
78 requires(std::convertible_to<typename vec::ItemType, _Item>);
86template <
class Arg,
class... Args>
111 static constexpr size_t Dim = []() ->
size_t {
115 static constexpr auto Zero = []() {
124 static constexpr size_t dim = []() ->
size_t {
129 static constexpr auto Zero = []() {
143 template <
class _Sl,
class... _Sls>
145 if constexpr (
sizeof...(_Sls))
148 return std::declval<float>();
150 template <
class _Sl,
class... _Sls>
159template <
class T,
size_t len,
size_t... lens>
173template <
class T,
size_t len>
188template <
class T,
size_t... lens>
204template <
typename _Tp,
size_t _length>
205 requires(_length > 0 && std::is_default_constructible_v<_Tp>)
232 template <
class __Tp,
size_t __len,
size_t... __lens>
235 template <
size_t __len,
size_t... __lens>
239 template <
size_t __len>
244 template <
size_t __len,
size_t... __lens>
256 constexpr static auto datatype = TypeName<DataType>;
261 constexpr static auto itemtype = TypeName<ItemType>;
266 constexpr static auto length = _length;
274 requires(std::is_default_constructible_v<_Tp>)
287 template <
class _Tp1,
class... _T>
288 requires(std::is_convertible_v<_Tp1, _Tp> &&
289 (std::is_convertible_v<_T, _Tp> && ...))
290 constexpr vec(
const _Tp1& arg1,
const _T&... args) {
293 ((data[++i] = args), ...);
304 template <
typename... _Args>
308 std::is_convertible_v<_Args, ItemType>) &&
310 constexpr explicit vec(
const _Args&... args) {
312 (([&]<
class _Arg>(_Arg _arg) {
313 if constexpr (std::is_convertible_v<_Arg, ItemType>)
316 for (
auto& i : _arg) data[n++] = i;
328 requires(std::is_convertible_v<T, ItemType>)
329 constexpr explicit vec(
const T& fill_value) {
330 for (
size_t i = 0; i < length; i++) {
331 data[i] = fill_value;
341 for (
size_t i = 0; i < _length; i++) {
353 for (
size_t i = 0; i < _length; i++) {
358 constexpr vec(
const std::initializer_list<ItemType>& list) {
360 for (
auto it : list) {
371 constexpr const _Tp*
begin()
const {
return data; }
378 constexpr const _Tp*
end()
const {
return data + length; }
386 constexpr _Tp&
operator[](
size_t index) {
return data[index]; }
395 assert(index < length);
406 for (
size_t i = 0; i < _length; i++) {
419 for (
size_t i = 0; i < _length; i++) {
431 template <
size_t... idx,
class... _Ss>
432 requires(
sizeof...(_Ss) < dim)
433 constexpr
SubVec<sizeof...(idx), (_Ss::length, ...)> operator()(
434 Slice<idx...>, _Ss... ns)
const {
435 return {(data[idx](ns...))...};
444 template <
size_t... idx>
446 return {data[idx]...};
455 requires(_length < 5)
457 return this->data[0];
466 requires(_length < 5 && _length > 1)
468 return this->data[1];
477 requires(_length < 5 && _length > 2)
479 return this->data[2];
488 requires(_length < 5 && _length > 3)
490 return this->data[3];
498 constexpr const _Tp&
x() const
499 requires(_length < 5)
501 return this->data[0];
509 constexpr const _Tp&
y() const
510 requires(_length < 5 && _length > 1)
512 return this->data[1];
520 constexpr const _Tp&
z() const
521 requires(_length < 5 && _length > 2)
523 return this->data[2];
531 constexpr const _Tp&
w() const
532 requires(_length < 5 && _length > 3)
534 return this->data[3];
538 requires(_length < 5 && _length > 1)
540 return *
reinterpret_cast<const vec<_Tp, 2>*
>(data);
543 requires(_length < 5 && _length > 1)
549 requires(_length < 5 && _length > 2)
551 return *
reinterpret_cast<const vec<_Tp, 2>*
>(data + 1);
554 requires(_length < 5 && _length > 2)
560 requires(_length < 5 && _length > 3)
562 return *
reinterpret_cast<const vec<_Tp, 2>*
>(data + 2);
565 requires(_length < 5 && _length > 3)
571 requires(_length < 5 && _length > 2)
573 return *
reinterpret_cast<const vec<_Tp, 3>*
>(data);
576 requires(_length < 5 && _length > 2)
581 requires(_length < 5 && _length > 2)
583 return *
reinterpret_cast<const vec<_Tp, 3>*
>(data + 1);
586 requires(_length < 5 && _length > 2)
592 requires(_length < 5 && _length > 2)
594 return {data[0], data[2]};
597 requires(_length < 5 && _length > 3)
599 return {data[0], data[3]};
602 requires(_length < 5 && _length > 3)
604 return {data[1], data[3]};
619 res[0] = data[1] * other[2] - data[2] * other[1];
620 res[1] = data[2] * other[0] - data[0] * other[2];
621 res[2] = data[0] * other[1] - data[1] * other[0];
633 for (
size_t i = 0; i < _length; i++) {
634 res += data[i] * other[i];
647 auto disten = distance({});
648 for (
size_t i = 0; i < _length; i++) {
649 res[i] = data[i] / disten;
662 for (
size_t i = 0; i < _length; i++) {
663 res += (data[i] - other[i]) * (data[i] - other[i]);
665 return std::sqrt(res);
673 constexpr _Tp
mod()
const {
675 for (
size_t i = 0; i < _length; i++) {
676 res += data[i] * data[i];
688 _Tp cos_theta = dot(other) / (mod() * other.
mod());
689 return std::acos(cos_theta);
697 constexpr bool any() const
698 requires(std::is_convertible_v<
DataType,
bool>)
700 if constexpr (std::is_convertible_v<ItemType, bool>) {
701 for (
size_t i = 0; i < _length; i++)
707 for (
size_t i = 0; i < _length; i++) {
722 requires(std::is_convertible_v<
DataType,
bool>)
724 if constexpr (std::is_convertible_v<ItemType, bool>) {
725 for (
size_t i = 0; i < _length; i++)
731 for (
size_t i = 0; i < _length; i++) {
732 if (!data[i].every()) {
748 constexpr inline bool all() const
749 requires(std::is_convertible_v<
DataType,
bool>)
754 template <
typename _OTp>
755 requires(std::is_convertible_v<ItemType, _OTp>)
758 for (
size_t i = 0; i < _length; i++)
759 ret[i] =
static_cast<_OTp
>(data(i));
769 Self<
decltype(-data[0])> res;
770 for (
size_t i = 0; i < _length; i++) {
782 Self<
decltype(+data[0])> res;
783 for (
size_t i = 0; i < _length; i++) {
796 for (
size_t i = 0; i < _length; i++) {
808 for (
size_t i = 0; i < _length; i++) {
821 for (
size_t i = 0; i < _length; i++) {
833 for (
size_t i = 0; i < _length; i++) {
846#define __VEC_OP_VEC_ON_EQ_LENGTH(op) \
847 template <class _OTp> \
848 requires(dim == VecInfo<_OTp>::dim) \
849 auto operator op(const _OTp& o) const { \
850 Self<decltype(data[0] op o[0])> res; \
851 auto length = (_length > _OTp::length) ? _OTp::length : _length; \
852 for (size_t i = 0; i < length; i++) { \
853 res[i] = data[i] op o[i]; \
871#undef __VEC_OP_VEC_ON_EQ_LENGTH
880#define __VEC_OP_ITEM_ON_OP_ABLE(op) \
881 template <class _OTp> \
882 requires(VecInfo<_OTp>::dim == 0 || dim == VecInfo<_OTp>::dim + 1) \
883 inline constexpr auto operator op(const _OTp& o) const { \
884 Self<decltype(data[0] op o)> res; \
885 for (size_t i = 0; i < _length; i++) { \
886 res[i] = data[i] op o; \
904#undef __VEC_OP_ITEM_ON_OP_ABLE
907#define __ITEM_OP_VEC_ON_OP_ENABLE(op) \
908 template <class _OTp, Vec _Tp> \
909 requires(VecInfo<_OTp>::dim == 0 || \
910 (VecInfo<_OTp>::dim == _Tp::dim - 1)) \
911 inline constexpr auto operator op(const _OTp& other, const _Tp& o) { \
912 typename _Tp::template Self<decltype(other op o[0])> res; \
913 for (size_t i = 0; i < _Tp::length; i++) res[i] = other op o[i]; \
928#undef __ITEM_OP_VEC_ON_OP_ENABLE
constexpr vec< _Tp, 2 > xw() const
constexpr bool every() const
Check if all elements satisfy a condition
constexpr const _Tp & z() const
Get the item at index 2 (const version)
constexpr const _Tp & operator[](size_t index) const
Access element at specified index (const version)
typename VecInfo< ItemType >::DataType DataType
Type of data stored in the vector
constexpr vec()
Construct a zero-initialized vector Notw: _Tp must be default constructible
constexpr const vec< _Tp, 3 > & xyz() const
constexpr _Tp angle(const vec< _Tp, _length > &other) const
Compute angle with another vector
constexpr const _Tp * begin() const
Get pointer to the beginning of the data array
constexpr vec< _Tp, _length > & operator=(const vec< _Tp, _length > &o)
Copy assignment operator
constexpr _Tp dot(const vec< _Tp, _length > &other) const
Compute Euclidean inner product
constexpr _Tp & x()
Get the item at index 0
constexpr bool all() const
Check universal quantification of components
constexpr vec(const T &fill_value)
Uniform value constructor
auto operator+() const
Unary plus operator
_Tp ItemType
Type of elements in the vector
constexpr const _Tp * end() const
Get pointer to the end of the data array
auto operator-() const
Component-wise additive inverse
constexpr const vec< _Tp, 3 > & yzw() const
constexpr vec(const std::initializer_list< ItemType > &list)
constexpr _Tp distance(const vec< _Tp, _length > &other) const
Compute distance to another vector
constexpr vec< _Tp, 2 > yw() const
constexpr vec(const vec< _Tp, _length > &other)
Copy constructor
constexpr vec< _Tp, 3 > & yzw()
__subVecHelper< size_t, __len, __lens... >::Type SubVec
constexpr vec< _Tp, 3 > & xyz()
constexpr _Tp & w()
Get the item at index 3
constexpr vec(const _Tp1 &arg1, const _T &... args)
Construct from component values
constexpr const _Tp & y() const
Get the item at index 1 (const version)
constexpr vec< _Tp, 2 > & yz()
auto & operator--(int)
Post-decrement operator
constexpr vec< _Tp, 2 > & zw()
constexpr const vec< _Tp, 2 > & zw() const
auto operator--()
Pre-decrement operator
constexpr const _Tp & x() const
Get the item at index 0 (const version)
constexpr vec< _Tp, 2 > & xy()
constexpr const vec< _Tp, 2 > & xy() const
constexpr _Tp mod() const
Calculate Euclidean norm (magnitude)
constexpr const vec< _Tp, 2 > & yz() const
constexpr vec< _Tp, _length > cross(const vec< _Tp, _length > &other) const
Compute 3D cross product
auto operator++()
Pre-increment operator
constexpr vec< _Tp, _length > & operator=(vec< _Tp, _length > &&o)
Move assignment operator
constexpr _Tp & y()
Get the item at index 1
constexpr _Tp & operator[](size_t index)
Access element at specified index
constexpr vec< _Tp, _length > normalize() const
Create unit vector in same direction
constexpr vec(vec< _Tp, _length > &&o)
Move constructor
constexpr _Tp & z()
Get the item at index 2
auto & operator++(int)
Post-increment operator
constexpr const _Tp & w() const
Get the item at index 3 (const version)
constexpr vec< _Tp, 2 > xz() const
constexpr bool any() const
Check if any element satisfies a condition
constexpr vec(const _Args &... args)
Construct from mixed scalars and vectors
Type requirement concept for vector types
Concept for valid vector component types
Declaration of vector, matrix, quaternion, and complex classes
Compiler-specific type information handling for MSVC
constexpr size_t VecConstructPackSize
Metafunction computing total size of vector constructor arguments
constexpr size_t VecConstructPackSize< Arg >
Metafunction computing total size of vector constructor arguments
Metaclassfor constructing a vector from a pack of arguments
vec< typename __batchHelper< T, lens... >::Type, len > Type
Type of the vector constructed from the arguments
Compile-time index sequence for vector slicing operations
static constexpr size_t dim
static constexpr auto Zero
static constexpr auto SubVecZero
decltype(SubVecZero< _Sl, _Sls... >) SubVec
decltype([]() { if constexpr(Vec< _Tp >) return VecInfo< typename _Tp::ItemType >::Zero DataType
Metafunction for type transformation
#define __VEC_OP_VEC_ON_EQ_LENGTH(op)
Macro generating component-wise vector operations
#define __VEC_OP_ITEM_ON_OP_ABLE(op)
Macro generating vector-scalar operations
#define __ITEM_OP_VEC_ON_OP_ENABLE(op)