8 #include "../Common/Definitions.hpp" 9 #include "../Common/Traits.hpp" 10 #include "../SIMD/Simd.hpp" 11 #include "../Common/MathUtil.hpp" 17 #include <type_traits> 34 template <
class T,
int... Indices>
36 static constexpr
int IndexTable[] = { Indices... };
37 static constexpr
int Dim =
sizeof...(Indices);
38 T* data() {
return reinterpret_cast<T*
>(
this); }
39 const T* data()
const {
return reinterpret_cast<const T*
>(
this); }
43 operator Vector<T,
sizeof...(Indices),
false>()
const;
45 operator Vector<T,
sizeof...(Indices),
true>()
const;
52 Swizzle&
operator=(
const Vector<T,
sizeof...(Indices),
false>& rhs);
58 Swizzle&
operator=(
const Vector<T,
sizeof...(Indices),
true>& rhs);
65 template <
class T2,
int... Indices2,
typename std::enable_if<
sizeof...(Indices) ==
sizeof...(Indices2),
int>::type = 0>
67 *
this =
Vector<T,
sizeof...(Indices2),
false>(rhs);
74 return data()[IndexTable[idx]];
79 return data()[IndexTable[idx]];
85 return data()[IndexTable[idx]];
90 return data()[IndexTable[idx]];
94 template <
bool Packed = false>
100 template <
int... Rest,
class =
typename std::enable_if<
sizeof...(Rest) == 0>::type>
101 void Assign(
const T*) {}
103 template <
int Index,
int... Rest>
104 void Assign(
const T* rhs) {
105 data()[Index] = *rhs;
106 return Assign<Rest...>(rhs + 1);
110 template <
class T,
int... Indices>
111 constexpr
int Swizzle<T, Indices...>::IndexTable[];
119 template <
class T,
int Dim,
bool Packed>
128 template <
class T,
bool Packed>
129 class VectorData<T, 2, Packed> {
134 VectorData(
const VectorData& rhs) {
135 for (
int i = 0; i < 2; ++i) {
136 data[i] = rhs.data[i];
139 VectorData&
operator=(
const VectorData& rhs) {
140 for (
int i = 0; i < 2; ++i) {
141 data[i] = rhs.data[i];
151 #include "../Swizzle/Swizzle_2.inc.hpp" 155 template <
class T,
bool Packed>
156 class VectorData<T, 3, Packed> {
161 VectorData(
const VectorData& rhs) {
162 for (
int i = 0; i < 3; ++i) {
163 data[i] = rhs.data[i];
166 VectorData&
operator=(
const VectorData& rhs) {
167 for (
int i = 0; i < 3; ++i) {
168 data[i] = rhs.data[i];
178 #include "../Swizzle/Swizzle_3.inc.hpp" 182 template <
class T,
bool Packed>
183 class VectorData<T, 4, Packed> {
188 VectorData(
const VectorData& rhs) {
189 for (
int i = 0; i < 4; ++i) {
190 data[i] = rhs.data[i];
193 VectorData&
operator=(
const VectorData& rhs) {
194 for (
int i = 0; i < 4; ++i) {
195 data[i] = rhs.data[i];
205 #include "../Swizzle/Swizzle_4.inc.hpp" 212 class VectorData<float, 2, false> {
217 VectorData(
const VectorData& rhs) { simd = rhs.simd; }
218 VectorData&
operator=(
const VectorData& rhs) {
230 #include "../Swizzle/Swizzle_2.inc.hpp" 235 class VectorData<float, 3, false> {
240 VectorData(
const VectorData& rhs) { simd = rhs.simd; }
241 VectorData&
operator=(
const VectorData& rhs) {
253 #include "../Swizzle/Swizzle_3.inc.hpp" 258 class VectorData<float, 4, false> {
263 VectorData(
const VectorData& rhs) { simd = rhs.simd; }
264 VectorData&
operator=(
const VectorData& rhs) {
276 #include "../Swizzle/Swizzle_4.inc.hpp" 281 class VectorData<float, 8, false> {
284 VectorData(
const VectorData& rhs) { simd = rhs.simd; }
285 VectorData&
operator=(
const VectorData& rhs) {
300 class VectorData<double, 2, false> {
305 VectorData(
const VectorData& rhs) { simd = rhs.simd; }
306 VectorData&
operator=(
const VectorData& rhs) {
318 #include "../Swizzle/Swizzle_2.inc.hpp" 323 class VectorData<double, 3, false> {
328 VectorData(
const VectorData& rhs) { simd = rhs.simd; }
329 VectorData&
operator=(
const VectorData& rhs) {
341 #include "../Swizzle/Swizzle_3.inc.hpp" 346 class VectorData<double, 4, false> {
351 VectorData(
const VectorData& rhs) { simd = rhs.simd; }
352 VectorData&
operator=(
const VectorData& rhs) {
364 #include "../Swizzle/Swizzle_4.inc.hpp" 390 template <
class T,
int Dim,
bool Packed = false>
391 class Vector :
public VectorData<T, Dim, Packed> {
392 static_assert(Dim >= 1,
"Dimension must be positive integer.");
395 using VectorData<T, Dim, Packed>::data;
418 for (
auto& v : *
this) {
423 using SimdT = decltype(VectorData<T, Dim, Packed>::simd);
424 this->simd = SimdT::spread(all);
432 for (
int i = 0; i < Dim; ++i) {
433 this->data[i] = data[i];
442 template <
class T2,
bool Packed2,
class =
typename std::enable_if<(Dim >= 2), T2>::type>
446 template <
class T2,
bool Packed2>
460 Vector(H1 h1, H2 h2, Scalars... scalars) {
461 Assign(0, h1, h2, scalars...);
468 Vector(
const H1& h1,
const Mixed&... mixed) {
469 Assign(0, h1, mixed...);
475 template <
class... Scalars,
typename std::enable_if<((
sizeof...(Scalars) > 1) &&
traits::All<traits::IsScalar, Scalars...>::value),
int>::type = 0>
478 Assign(0, scalars...);
485 template <
class... Mixed,
typename std::enable_if<(
sizeof...(Mixed) > 0) &&
traits::Any<traits::IsVectorOrSwizzle, Mixed...>::value,
int>::type = 0>
499 assert(idx < Dimension());
504 assert(idx < Dimension());
510 assert(idx < Dimension());
515 assert(idx < Dimension());
560 struct GetVectorElement {
561 static U Get(
const U& u,
int idx) {
return u; }
563 template <
class T2,
int D2,
bool P2>
564 struct GetVectorElement<Vector<T2, D2, P2>> {
567 template <
class U,
int... Indices>
568 struct GetVectorElement<Swizzle<U, Indices...>> {
574 template <
class Head,
class... Scalars,
typename std::enable_if<
traits::All<traits::IsScalar, Head, Scalars...>::value,
int>::type = 0>
575 void Assign(
int idx, Head head, Scalars... scalars) {
577 Assign(idx + 1, scalars...);
581 template <
class Head,
class... Mixed,
typename std::enable_if<
traits::Any<traits::IsVectorOrSwizzle, Head, Mixed...>::value,
int>::type = 0>
582 void Assign(
int idx,
const Head& head,
const Mixed&... mixed) {
583 for (
int i = 0; i < traits::DimensionOf<Head>::value; ++i) {
584 data[idx] = (T)GetVectorElement<Head>::Get(head, i);
587 Assign(idx, mixed...);
591 void Assign(
int idx) {
592 for (; idx < Dim; idx++) {
599 template <
class T,
int... Indices>
600 Swizzle<T, Indices...>::operator
Vector<T,
sizeof...(Indices),
false>()
const {
601 return Vector<T,
sizeof...(Indices),
false>(data()[Indices]...);
603 template <
class T,
int... Indices>
604 Swizzle<T, Indices...>::operator
Vector<T,
sizeof...(Indices),
true>()
const {
605 return Vector<T,
sizeof...(Indices),
true>(data()[Indices]...);
608 template <
class T,
int... Indices>
610 if (data() != rhs.data) {
611 Assign<Indices...>(rhs.data);
614 Vector<T,
sizeof...(Indices),
false> tmp = rhs;
619 template <
class T,
int... Indices>
621 if (data() != rhs.data) {
622 Assign<Indices...>(rhs.data);
625 Vector<T,
sizeof...(Indices),
false> tmp = rhs;
const T * end() const
Returns an iterator to the end of the vector (works like STL).
Definition: VectorImpl.hpp:536
Swizzle & operator=(const Swizzle< T2, Indices2... > &rhs)
Sets the parent vector's elements from the right-side argument.
Definition: VectorImpl.hpp:66
Definition: Simd_SSE2.hpp:115
Vector(const H1 &h1, const Mixed &... mixed)
Initializes the vector by concatenating given scalar and vector arguments.
Definition: VectorImpl.hpp:468
T * end()
Returns an iterator to the end of the vector (works like STL).
Definition: VectorImpl.hpp:540
T & operator[](int idx)
Returns the nth element of the vector.
Definition: VectorImpl.hpp:503
Represents a vector in N-dimensional space.
Definition: Definitions.hpp:57
Enables element swizzling (reordering elements) for vectors.
Definition: Definitions.hpp:60
T & operator()(int idx)
Returns the nth element of the swizzled vector. Example: v.zxy(2) returns y.
Definition: VectorImpl.hpp:83
const auto ToVector() const
Builds the swizzled vector object.
Definition: VectorImpl.hpp:95
Vector & Set(Scalars... scalars)
Sets the vector's elements to the given scalars.
Definition: VectorImpl.hpp:476
Definition: Simd_SSE2.hpp:249
Vector & Set(const Mixed &... mixed)
Sets the vector's elements by concatenating given scalar and vector arguments.
Definition: VectorImpl.hpp:486
Swizzle & operator=(const Vector< T, sizeof...(Indices), false > &rhs)
Sets the parent vector's elements from the right-side argument.
Definition: VectorImpl.hpp:609
Definition: Traits.hpp:66
Definition: Approx.hpp:11
Vector(const U *data)
Constructs the vector from an array of elements.
Definition: VectorImpl.hpp:431
T & operator()(int idx)
Returns the nth element of the vector.
Definition: VectorImpl.hpp:514
Definition: Traits.hpp:139
Vector(T all)
Sets all elements to the same value.
Definition: VectorImpl.hpp:416
Vector(H1 h1, H2 h2, Scalars... scalars)
Initializes the vector to the given scalar elements.
Definition: VectorImpl.hpp:460
T * Data()
Returns a pointer to the underlying array of elements.
Definition: VectorImpl.hpp:549
const T * Data() const
Returns a pointer to the underlying array of elements.
Definition: VectorImpl.hpp:545
T operator[](int idx) const
Returns the nth element of the swizzled vector. Example: v.zxy[2] returns y.
Definition: VectorImpl.hpp:77
T * begin()
Returns an iterator to the first element.
Definition: VectorImpl.hpp:528
const T * cend() const
Returns an iterator to the end of the vector (works like STL).
Definition: VectorImpl.hpp:532
Definition: Simd_SSE2.hpp:347
T operator[](int idx) const
Returns the nth element of the vector.
Definition: VectorImpl.hpp:498
Definition: Traits.hpp:184
Definition: Traits.hpp:204
Definition: Traits.hpp:80
Vector(const Vector< T2, Dim+1, Packed2 > &rhs)
Truncates last coordinate of homogenous vector to create non-homogeneous.
Definition: VectorImpl.hpp:447
Vector(const Vector< T2, Dim - 1, Packed2 > &rhs)
Creates a homogeneous vector by appending a 1.
Definition: VectorImpl.hpp:443
constexpr int Dimension() const
Returns the number of dimensions of the vector.
Definition: VectorImpl.hpp:402
T operator()(int idx) const
Returns the nth element of the swizzled vector. Example: v.zxy(2) returns y.
Definition: VectorImpl.hpp:88
2,4 or 8 dimension float or double parameters accepted. Uses SSE2 or AVX acceleration if enabled in t...
Definition: Simd.hpp:22
T operator()(int idx) const
Returns the nth element of the vector.
Definition: VectorImpl.hpp:509
const T * cbegin() const
Returns an iterator to the first element.
Definition: VectorImpl.hpp:520
Definition: Simd_SSE2.hpp:17
Definition: Traits.hpp:218
T & operator[](int idx)
Returns the nth element of the swizzled vector. Example: v.zxy[2] returns y.
Definition: VectorImpl.hpp:72
const T * begin() const
Returns an iterator to the first element.
Definition: VectorImpl.hpp:524