Selaa lähdekoodia

math: use a combination of ADL and enable_if black magic to get rid of macros.

undefined
Sam Hocevar 10 vuotta sitten
vanhempi
commit
f6dd334c1a
3 muutettua tiedostoa jossa 191 lisäystä ja 76 poistoa
  1. +4
    -10
      src/lol/math/matrix.h
  2. +2
    -2
      src/lol/math/transform.h
  3. +185
    -64
      src/lol/math/vector.h

+ 4
- 10
src/lol/math/matrix.h Näytä tiedosto

@@ -33,7 +33,7 @@ namespace lol
*/

template<typename T, int COLS, int ROWS>
struct mat_t
struct mat_t : public linear_ops::base
{
typedef mat_t<T,COLS,ROWS> type;

@@ -59,7 +59,7 @@ private:
*/

template <typename T>
struct mat_t<T, 2, 2>
struct mat_t<T, 2, 2> : public linear_ops::base
{
typedef mat_t<T,2,2> type;

@@ -124,7 +124,7 @@ private:
*/

template <typename T>
struct mat_t<T, 3, 3>
struct mat_t<T, 3, 3> : public linear_ops::base
{
typedef mat_t<T,3,3> type;

@@ -235,7 +235,7 @@ private:
*/

template <typename T>
struct mat_t<T, 4, 4>
struct mat_t<T, 4, 4> : public linear_ops::base
{
typedef mat_t<T,4,4> type;

@@ -427,12 +427,6 @@ static inline mat_t<T, COLS, ROWS> operator +(mat_t<T, COLS, ROWS> const &a,
return ret += b;
}

template<typename T, int COLS, int ROWS>
static inline mat_t<T, COLS, ROWS> operator +(mat_t<T, COLS, ROWS> const &m)
{
return m;
}

template<typename T, int COLS, int ROWS>
static inline mat_t<T, COLS, ROWS> &operator -=(mat_t<T, COLS, ROWS> &a,
mat_t<T, COLS, ROWS> const &b)


+ 2
- 2
src/lol/math/transform.h Näytä tiedosto

@@ -30,7 +30,7 @@ namespace lol
*/

template<typename T>
struct cmplx_t
struct cmplx_t : public linear_ops::base
{
typedef cmplx_t<T> type;

@@ -71,7 +71,7 @@ struct cmplx_t
*/

template<typename T>
struct quat_t
struct quat_t : public linear_ops::base
{
typedef quat_t<T> type;



+ 185
- 64
src/lol/math/vector.h Näytä tiedosto

@@ -17,6 +17,7 @@
#define __LOL_MATH_VECTOR_H__

#include <ostream>
#include <type_traits>

#include <lol/math/half.h>
#include <lol/math/real.h>
@@ -34,6 +35,169 @@ namespace lol
# define _____ /* */
#endif

/*
* Utility namespaces for traits
*/

namespace swizzle_ops
{



}


namespace linear_ops
{

struct base {};

/*
* Unary plus and minus
*/

template<typename V>
static inline typename std::enable_if<std::is_base_of<base, V>::value, V>::type
operator +(V const &v)
{
return v;
}

template<typename V>
static inline typename std::enable_if<std::is_base_of<base, V>::value, V>::type
operator -(V const &v)
{
V ret;
for (size_t i = 0; i < sizeof(ret) / sizeof(ret[0]); ++i)
ret[i] = -v[i];
return ret;
}

/*
* Addition and subtraction
*/

template<typename V>
static inline typename std::enable_if<std::is_base_of<base, V>::value, V>::type
operator +(V const &a, V const &b)
{
V ret;
for (size_t i = 0; i < sizeof(ret) / sizeof(ret[0]); ++i)
ret[i] = a[i] + b[i];
return ret;
}

template<typename V>
static inline typename std::enable_if<std::is_base_of<base, V>::value, V>::type
&operator +=(V &a, V const &b)
{
return a = a + b;
}

template<typename V>
static inline typename std::enable_if<std::is_base_of<base, V>::value, V>::type
operator -(V const &a, V const &b)
{
V ret;
for (size_t i = 0; i < sizeof(ret) / sizeof(ret[0]); ++i)
ret[i] = a[i] - b[i];
return ret;
}

template<typename V>
static inline typename std::enable_if<std::is_base_of<base, V>::value, V>::type
&operator -=(V &a, V const &b)
{
return a = a - b;
}

} /* namespace linear_ops */

namespace componentwise_ops
{

struct base {};

template<typename V>
static inline typename std::enable_if<std::is_base_of<base, V>::value, V>::type
operator *(V const &a, V const &b)
{
V ret;
for (size_t i = 0; i < sizeof(ret) / sizeof(ret[0]); ++i)
ret[i] = a[i] * b[i];
return ret;
}

template<typename V>
static inline typename std::enable_if<std::is_base_of<base, V>::value, V>::type
&operator *=(V &a, V const &b)
{
return a = a * b;
}

template<typename V>
static inline typename std::enable_if<std::is_base_of<base, V>::value, V>::type
operator /(V const &a, V const &b)
{
V ret;
for (size_t i = 0; i < sizeof(ret) / sizeof(ret[0]); ++i)
ret[i] = a[i] / b[i];
return ret;
}

template<typename V>
static inline typename std::enable_if<std::is_base_of<base, V>::value, V>::type
&operator /=(V &a, V const &b)
{
return a = a / b;
}

/*
* Comparisons
*/

template<typename V>
static inline typename std::enable_if<std::is_base_of<base, V>::value, bool>::type
operator <(V const &a, V const &b)
{
for (size_t i = 0; i < sizeof(a) / sizeof(a[0]); ++i)
if (!(a[i] < b[i]))
return false;
return true;
}

template<typename V>
static inline typename std::enable_if<std::is_base_of<base, V>::value, bool>::type
operator >(V const &a, V const &b)
{
for (size_t i = 0; i < sizeof(a) / sizeof(a[0]); ++i)
if (!(a[i] > b[i]))
return false;
return true;
}

template<typename V>
static inline typename std::enable_if<std::is_base_of<base, V>::value, bool>::type
operator <=(V const &a, V const &b)
{
for (size_t i = 0; i < sizeof(a) / sizeof(a[0]); ++i)
if (!(a[i] <= b[i]))
return false;
return true;
}

template<typename V>
static inline typename std::enable_if<std::is_base_of<base, V>::value, bool>::type
operator >=(V const &a, V const &b)
{
for (size_t i = 0; i < sizeof(a) / sizeof(a[0]); ++i)
if (!(a[i] >= b[i]))
return false;
return true;
}

} /* namespace componentwise_ops */

/*
* Magic vector swizzling (part 1/2)
* These vectors are empty, but thanks to static_cast we can take their
@@ -79,7 +243,9 @@ struct vec_t
/* The generic “vec_t” type, which is a fixed-size vector with no
* swizzling. There's an override for N=2, N=3, N=4 that has swizzling. */
template<typename T, int N>
struct vec_t<T, N, -1>
struct vec_t<T, N, FULL_SWIZZLE>
: public linear_ops::base,
public componentwise_ops::base
{
typedef vec_t<T,N> type;

@@ -94,21 +260,6 @@ private:
* Helper macros for vector type member functions
*/

#define LOL_V_VV_OP(op) \
friend inline type operator op(type const &a, type const &b) \
{ \
type ret; \
for (size_t i = 0; i < sizeof(type) / sizeof(T); ++i) \
ret[i] = a[i] op b[i]; \
return ret; \
}

#define LOL_V_VV_ASSIGN_OP(op) \
friend inline type &operator op##=(type &a, type const &b) \
{ \
return a = a op b; \
}

#define LOL_V_VS_OP(op) \
friend inline type operator op(type const &a, T const &val) \
{ \
@@ -148,30 +299,6 @@ private:
void printf() const; \
String tostring() const; \
\
/* vec_t -(vec_t)
* vec_t +(vec_t) */ \
friend inline type operator -(type const &a) \
{ \
type ret; \
for (size_t i = 0; i < sizeof(type) / sizeof(T); ++i) \
ret[i] = -a[i]; \
return ret; \
} \
\
friend inline type operator +(type const &a) \
{ \
return a; \
} \
\
/* vec_t +(vec_t, vec_t)
* vec_t -(vec_t, vec_t)
* vec_t +=(vec_t, vec_t)
* vec_t -=(vec_t, vec_t) */ \
LOL_V_VV_OP(+); \
LOL_V_VV_OP(-); \
LOL_V_VV_ASSIGN_OP(+); \
LOL_V_VV_ASSIGN_OP(-); \
\
/* vec_t *(vec_t, scalar)
* vec_t /(vec_t, scalar)
* vec_t *=(vec_t, scalar)
@@ -186,25 +313,6 @@ private:
LOL_B_VV_OP(==, ==, true) \
LOL_B_VV_OP(!=, ==, false)

#define LOL_VECTOR_MEMBER_OPS() \
/* vec_t *(vec_t, vec_t)
* vec_t /(vec_t, vec_t)
* vec_t *=(vec_t, vec_t)
* vec_t /=(vec_t, vec_t) */ \
LOL_V_VV_OP(*); \
LOL_V_VV_OP(/); \
LOL_V_VV_ASSIGN_OP(*); \
LOL_V_VV_ASSIGN_OP(/); \
\
/* bool >=(vec_t, vec_t)
* bool <=(vec_t, vec_t)
* bool >(vec_t, vec_t)
* bool <(vec_t, vec_t) */ \
LOL_B_VV_OP(<=, <=, true) \
LOL_B_VV_OP(>=, >=, true) \
LOL_B_VV_OP(<, <, true) \
LOL_B_VV_OP(>, >, true)

#define LOL_NONVECTOR_MEMBER_OPS() \
/* vec_t *(scalar, vec_t) (no division, it works differently) */ \
friend inline type operator *(T const &val, type const &a) \
@@ -221,6 +329,8 @@ private:

template <typename T>
struct vec_t<T,2>
: public linear_ops::base,
public componentwise_ops::base
{
typedef vec_t<T,2> type;

@@ -246,7 +356,6 @@ struct vec_t<T,2>
: x(X), y(X) {}

LOL_COMMON_MEMBER_OPS(x)
LOL_VECTOR_MEMBER_OPS()

static const vec_t<T,2> zero;
static const vec_t<T,2> axis_x;
@@ -302,6 +411,8 @@ struct vec_t<T,2>

template <typename T>
struct vec_t<T,3>
: public linear_ops::base,
public componentwise_ops::base
{
typedef vec_t<T,3> type;

@@ -331,7 +442,6 @@ struct vec_t<T,3>
: x(X), y(YZ.x), z(YZ.y) {}

LOL_COMMON_MEMBER_OPS(x)
LOL_VECTOR_MEMBER_OPS()

static vec_t<T,3> toeuler_xyx(quat_t<T> const &q);
static vec_t<T,3> toeuler_xzx(quat_t<T> const &q);
@@ -513,6 +623,8 @@ struct vec_t<T,3>

template <typename T>
struct vec_t<T,4>
: public linear_ops::base,
public componentwise_ops::base
{
typedef vec_t<T,4> type;

@@ -551,7 +663,6 @@ struct vec_t<T,4>
: x(X), y(YZW.x), z(YZW.y), w(YZW.z) {}

LOL_COMMON_MEMBER_OPS(x)
LOL_VECTOR_MEMBER_OPS()

static const vec_t<T,4> zero;
static const vec_t<T,4> axis_x;
@@ -939,13 +1050,23 @@ static inline bool operator !=(vec_t<T,N,SWIZZLE1> const &a,

#define LOL_SWIZZLE_V_VV_OP(op) \
template<typename T, int N, int SWIZZLE1, int SWIZZLE2> \
inline vec_t<T,N> operator op(vec_t<T,N,SWIZZLE1> const &a, \
vec_t<T,N,SWIZZLE2> const &b) \
inline typename std::enable_if<SWIZZLE1 != FULL_SWIZZLE \
|| SWIZZLE2 != FULL_SWIZZLE,vec_t<T,N>>::type \
operator op(vec_t<T,N,SWIZZLE1> const &a, \
vec_t<T,N,SWIZZLE2> const &b) \
{ \
return vec_t<T,N>(a) op vec_t<T,N>(b); \
} \
\
template<typename T, int N, int SWIZZLE> \
inline typename std::enable_if<SWIZZLE != FULL_SWIZZLE,vec_t<T,N>>::type & \
operator op##=(vec_t<T,N> &a, \
vec_t<T,N,SWIZZLE> const &b) \
{ \
return a op##= vec_t<T,N>(b); \
} \
\
template<typename T, int N, int SWIZZLE> \
inline vec_t<T,N> operator op(vec_t<T,N,SWIZZLE> a, T const &b) \
{ \
return vec_t<T,N>(a) op b; \


Ladataan…
Peruuta
Tallenna