Changeset 1158


Ignore:
Timestamp:
Mar 12, 2012, 2:57:11 AM (10 years ago)
Author:
sam
Message:

math: make sure magic swizzling vectors don't actually store data, and
do the swizzling by using their address rather than their members.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/lol/math/vector.h

    r1157 r1158  
    6161/*
    6262 * Magic vector swizzling (part 1/2)
     63 * These vectors are empty, but thanks to static_cast we can take their
     64 * address and access the vector of T's that they are union'ed with. We
     65 * use static_cast instead of reinterpret_cast because there is a stronger
     66 * guarantee (by the standard) that the address will stay the same across
     67 * casts.
    6368 */
    6469
     
    6772    inline Vec2<T> operator =(Vec2<T> const &that);
    6873
    69     static int const I = (N >> 4) & 3;
    70     static int const J = (N >> 0) & 3;
    71     T ptr[1 + (I > J ? I : J)];
     74    inline T& operator[](int n)
     75    {
     76        int i = (N >> (4 * (1 - n))) & 3;
     77        return static_cast<T*>(static_cast<void*>(this))[i];
     78    }
     79    inline T const& operator[](int n) const
     80    {
     81        int i = (N >> (4 * (1 - n))) & 3;
     82        return static_cast<T const*>(static_cast<void const *>(this))[i];
     83    }
    7284};
    7385
     
    7688    inline Vec3<T> operator =(Vec3<T> const &that);
    7789
    78     static int const I = (N >> 8) & 3;
    79     static int const J = (N >> 4) & 3;
    80     static int const K = (N >> 0) & 3;
    81     T ptr[1 + (I > J ? I > K ? I : K
    82                      : J > K ? J : K)];
     90    inline T& operator[](int n)
     91    {
     92        int i = (N >> (4 * (2 - n))) & 3;
     93        return static_cast<T*>(static_cast<void*>(this))[i];
     94    }
     95    inline T const& operator[](int n) const
     96    {
     97        int i = (N >> (4 * (2 - n))) & 3;
     98        return static_cast<T const*>(static_cast<void const *>(this))[i];
     99    }
    83100};
    84101
     
    87104    inline Vec4<T> operator =(Vec4<T> const &that);
    88105
    89     static int const I = (N >> 12) & 3;
    90     static int const J = (N >> 8) & 3;
    91     static int const K = (N >> 4) & 3;
    92     static int const L = (N >> 0) & 3;
    93     T ptr[1 + (I > J ? I > K ? I > L ? I : L : K > L ? K : L
    94                      : J > K ? J > L ? J : L : K > L ? K : L)];
     106    inline T& operator[](int n)
     107    {
     108        int i = (N >> (4 * (3 - n))) & 3;
     109        return static_cast<T*>(static_cast<void*>(this))[i];
     110    }
     111    inline T const& operator[](int n) const
     112    {
     113        int i = (N >> (4 * (3 - n))) & 3;
     114        return static_cast<T const*>(static_cast<void const *>(this))[i];
     115    }
    95116};
    96117
     
    201222    template<int N>
    202223    inline Vec2(XVec2<T, N> const &v)
    203       : BVec2<T>(v.ptr[v.I], v.ptr[v.J]) {}
     224      : BVec2<T>(v[0], v[1]) {}
    204225
    205226    template<typename U, int N>
    206227    explicit inline Vec2(XVec2<U, N> const &v)
    207       : BVec2<T>(v.ptr[v.I], v.ptr[v.J]) {}
     228      : BVec2<T>(v[0], v[1]) {}
    208229
    209230    DECLARE_MEMBER_OPS(Vec2)
     
    457478    template<int N>
    458479    inline Vec3(XVec3<T, N> const &v)
    459       : BVec3<T>(v.ptr[v.I], v.ptr[v.J], v.ptr[v.K]) {}
     480      : BVec3<T>(v[0], v[1], v[2]) {}
    460481
    461482    template<typename U, int N>
    462483    explicit inline Vec3(XVec3<U, N> const &v)
    463       : BVec3<T>(v.ptr[v.I], v.ptr[v.J], v.ptr[v.K]) {}
     484      : BVec3<T>(v[0], v[1], v[2]) {}
    464485
    465486    DECLARE_MEMBER_OPS(Vec3)
     
    869890    template<int N>
    870891    inline Vec4(XVec4<T, N> const &v)
    871       : BVec4<T>(v.ptr[v.I], v.ptr[v.J], v.ptr[v.K], v.ptr[v.L]) {}
     892      : BVec4<T>(v[0], v[1], v[2], v[3]) {}
    872893
    873894    template<typename U, int N>
    874895    explicit inline Vec4(XVec4<U, N> const &v)
    875       : BVec4<T>(v.ptr[v.I], v.ptr[v.J], v.ptr[v.K], v.ptr[v.L]) {}
     896      : BVec4<T>(v[0], v[1], v[2], v[3]) {}
    876897
    877898    DECLARE_MEMBER_OPS(Vec4)
     
    12381259inline Vec2<T> XVec2<T, N>::operator =(Vec2<T> const &that)
    12391260{
    1240     ptr[I] = that[0]; ptr[J] = that[1];
     1261    for (int i = 0; i < 2; i++)
     1262        *this[i] = that[i];
    12411263    return *this;
    12421264}
     
    12451267inline Vec3<T> XVec3<T, N>::operator =(Vec3<T> const &that)
    12461268{
    1247     ptr[I] = that[0]; ptr[J] = that[1]; ptr[K] = that[2];
     1269    for (int i = 0; i < 3; i++)
     1270        *this[i] = that[i];
    12481271    return *this;
    12491272}
     
    12521275inline Vec4<T> XVec4<T, N>::operator =(Vec4<T> const &that)
    12531276{
    1254     ptr[I] = that[0]; ptr[J] = that[1]; ptr[K] = that[2]; ptr[L] = that[3];
     1277    for (int i = 0; i < 4; i++)
     1278        *this[i] = that[i];
    12551279    return *this;
    12561280}
Note: See TracChangeset for help on using the changeset viewer.