Procházet zdrojové kódy

math: make sure magic swizzling vectors don't actually store data, and

do the swizzling by using their address rather than their members.
legacy
Sam Hocevar sam před 13 roky
rodič
revize
7723d892f7
1 změnil soubory, kde provedl 47 přidání a 23 odebrání
  1. +47
    -23
      src/lol/math/vector.h

+ 47
- 23
src/lol/math/vector.h Zobrazit soubor

@@ -60,38 +60,59 @@ DECLARE_VECTOR_TYPEDEFS(Mat4, mat4)

/*
* Magic vector swizzling (part 1/2)
* These vectors are empty, but thanks to static_cast we can take their
* address and access the vector of T's that they are union'ed with. We
* use static_cast instead of reinterpret_cast because there is a stronger
* guarantee (by the standard) that the address will stay the same across
* casts.
*/

template<typename T, int N> struct XVec2
{
inline Vec2<T> operator =(Vec2<T> const &that);

static int const I = (N >> 4) & 3;
static int const J = (N >> 0) & 3;
T ptr[1 + (I > J ? I : J)];
inline T& operator[](int n)
{
int i = (N >> (4 * (1 - n))) & 3;
return static_cast<T*>(static_cast<void*>(this))[i];
}
inline T const& operator[](int n) const
{
int i = (N >> (4 * (1 - n))) & 3;
return static_cast<T const*>(static_cast<void const *>(this))[i];
}
};

template<typename T, int N> struct XVec3
{
inline Vec3<T> operator =(Vec3<T> const &that);

static int const I = (N >> 8) & 3;
static int const J = (N >> 4) & 3;
static int const K = (N >> 0) & 3;
T ptr[1 + (I > J ? I > K ? I : K
: J > K ? J : K)];
inline T& operator[](int n)
{
int i = (N >> (4 * (2 - n))) & 3;
return static_cast<T*>(static_cast<void*>(this))[i];
}
inline T const& operator[](int n) const
{
int i = (N >> (4 * (2 - n))) & 3;
return static_cast<T const*>(static_cast<void const *>(this))[i];
}
};

template<typename T, int N> struct XVec4
{
inline Vec4<T> operator =(Vec4<T> const &that);

static int const I = (N >> 12) & 3;
static int const J = (N >> 8) & 3;
static int const K = (N >> 4) & 3;
static int const L = (N >> 0) & 3;
T ptr[1 + (I > J ? I > K ? I > L ? I : L : K > L ? K : L
: J > K ? J > L ? J : L : K > L ? K : L)];
inline T& operator[](int n)
{
int i = (N >> (4 * (3 - n))) & 3;
return static_cast<T*>(static_cast<void*>(this))[i];
}
inline T const& operator[](int n) const
{
int i = (N >> (4 * (3 - n))) & 3;
return static_cast<T const*>(static_cast<void const *>(this))[i];
}
};

/*
@@ -200,11 +221,11 @@ template <typename T> struct Vec2 : BVec2<T>

template<int N>
inline Vec2(XVec2<T, N> const &v)
: BVec2<T>(v.ptr[v.I], v.ptr[v.J]) {}
: BVec2<T>(v[0], v[1]) {}

template<typename U, int N>
explicit inline Vec2(XVec2<U, N> const &v)
: BVec2<T>(v.ptr[v.I], v.ptr[v.J]) {}
: BVec2<T>(v[0], v[1]) {}

DECLARE_MEMBER_OPS(Vec2)

@@ -456,11 +477,11 @@ template <typename T> struct Vec3 : BVec3<T>

template<int N>
inline Vec3(XVec3<T, N> const &v)
: BVec3<T>(v.ptr[v.I], v.ptr[v.J], v.ptr[v.K]) {}
: BVec3<T>(v[0], v[1], v[2]) {}

template<typename U, int N>
explicit inline Vec3(XVec3<U, N> const &v)
: BVec3<T>(v.ptr[v.I], v.ptr[v.J], v.ptr[v.K]) {}
: BVec3<T>(v[0], v[1], v[2]) {}

DECLARE_MEMBER_OPS(Vec3)

@@ -868,11 +889,11 @@ template <typename T> struct Vec4 : BVec4<T>

template<int N>
inline Vec4(XVec4<T, N> const &v)
: BVec4<T>(v.ptr[v.I], v.ptr[v.J], v.ptr[v.K], v.ptr[v.L]) {}
: BVec4<T>(v[0], v[1], v[2], v[3]) {}

template<typename U, int N>
explicit inline Vec4(XVec4<U, N> const &v)
: BVec4<T>(v.ptr[v.I], v.ptr[v.J], v.ptr[v.K], v.ptr[v.L]) {}
: BVec4<T>(v[0], v[1], v[2], v[3]) {}

DECLARE_MEMBER_OPS(Vec4)

@@ -1237,21 +1258,24 @@ DECLARE_ALL_VECTOR_COERCE_OPS(Vec4)
template<typename T, int N>
inline Vec2<T> XVec2<T, N>::operator =(Vec2<T> const &that)
{
ptr[I] = that[0]; ptr[J] = that[1];
for (int i = 0; i < 2; i++)
*this[i] = that[i];
return *this;
}

template<typename T, int N>
inline Vec3<T> XVec3<T, N>::operator =(Vec3<T> const &that)
{
ptr[I] = that[0]; ptr[J] = that[1]; ptr[K] = that[2];
for (int i = 0; i < 3; i++)
*this[i] = that[i];
return *this;
}

template<typename T, int N>
inline Vec4<T> XVec4<T, N>::operator =(Vec4<T> const &that)
{
ptr[I] = that[0]; ptr[J] = that[1]; ptr[K] = that[2]; ptr[L] = that[3];
for (int i = 0; i < 4; i++)
*this[i] = that[i];
return *this;
}



Načítá se…
Zrušit
Uložit