瀏覽代碼

math: try to get proper EBCO from that fucking Visual Studio piece of shit.

undefined
Sam Hocevar 10 年之前
父節點
當前提交
52f3fc7eb0
共有 2 個文件被更改,包括 40 次插入26 次删除
  1. +36
    -15
      src/lol/math/ops.h
  2. +4
    -11
      src/lol/math/vector.h

+ 36
- 15
src/lol/math/ops.h 查看文件

@@ -22,14 +22,45 @@
#include <lol/math/half.h>
#include <lol/math/real.h>

namespace lol
{

/*
* Utility namespaces for traits -- this file uses a combination of
* ADL black magic and enable_if to ensure that only the expected type
* conversions are done.
*
* vec_t (swizzle) needs swizzle_ops
* vec_t (generic) needs linear_ops + componentwise_ops
* vec_t (specialisation) needs swizzle_ops + linear_ops + componentwise_ops
* mat_t (all) needs linear_ops
* cmplx_t quat_t need linear_ops
*
* We can only inherit from one class, because Visual Studio will not
* perform EBCO (empty base class optimisation) when there is multiple
* inheritance.
*/

namespace lol
namespace linear_ops
{
template<typename T>
struct base {};
}

namespace componentwise_ops
{
template<typename T>
struct base : public linear_ops::base<T> {};
}

namespace swizzle_ops
{
template<typename T, int SWIZZLE = FULL_SWIZZLE>
struct base {};

template<typename T>
struct base<T, FULL_SWIZZLE> : public componentwise_ops::base<T> {};
}

/*
* Operators for swizzled vectors. Since template deduction cannot be
@@ -40,20 +71,16 @@ namespace lol
namespace swizzle_ops
{

template<typename T, int SWIZZLE = FULL_SWIZZLE>
struct base {};


template<typename T, int N, int SWIZZLE1, int SWIZZLE2>
static inline typename std::enable_if<SWIZZLE1 != FULL_SWIZZLE || SWIZZLE2 != FULL_SWIZZLE, bool>::type operator ==(vec_t<T,N,SWIZZLE1> const &a,
vec_t<T,N,SWIZZLE2> const &b)
static inline typename std::enable_if<SWIZZLE1 != FULL_SWIZZLE || SWIZZLE2 != FULL_SWIZZLE, bool>::type
operator ==(vec_t<T,N,SWIZZLE1> const &a, vec_t<T,N,SWIZZLE2> const &b)
{
return vec_t<T,N>(a) == vec_t<T,N>(b);
}

template<typename T, int N, int SWIZZLE1, int SWIZZLE2>
static inline typename std::enable_if<SWIZZLE1 != FULL_SWIZZLE || SWIZZLE2 != FULL_SWIZZLE, bool>::type operator !=(vec_t<T,N,SWIZZLE1> const &a,
vec_t<T,N,SWIZZLE2> const &b)
static inline typename std::enable_if<SWIZZLE1 != FULL_SWIZZLE || SWIZZLE2 != FULL_SWIZZLE, bool>::type
operator !=(vec_t<T,N,SWIZZLE1> const &a, vec_t<T,N,SWIZZLE2> const &b)
{
return vec_t<T,N>(a) != vec_t<T,N>(b);
}
@@ -105,9 +132,6 @@ LOL_SWIZZLE_V_VV_OP(/)
namespace linear_ops
{

template<typename T>
struct base {};

/*
* Comparisons
*/
@@ -255,9 +279,6 @@ operator /=(V &a, typename V::element const &val)
namespace componentwise_ops
{

template<typename T>
struct base {};

template<typename V>
static inline typename std::enable_if<std::is_base_of<base<typename V::element>, V>::value, typename V::type>::type
operator *(V const &a, V const &b)


+ 4
- 11
src/lol/math/vector.h 查看文件

@@ -102,8 +102,7 @@ struct vec_t
* 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, FULL_SWIZZLE>
: public linear_ops::base<T>,
public componentwise_ops::base<T>
: public componentwise_ops::base<T>
{
static int const count = N;
typedef T element;
@@ -176,9 +175,7 @@ private:

template <typename T>
struct vec_t<T,2>
: public swizzle_ops::base<T>,
public linear_ops::base<T>,
public componentwise_ops::base<T>
: public swizzle_ops::base<T>
{
static int const count = 2;
typedef T element;
@@ -285,9 +282,7 @@ static_assert(sizeof(dvec2) == 16, "sizeof(dvec2) == 16");

template <typename T>
struct vec_t<T,3>
: public swizzle_ops::base<T>,
public linear_ops::base<T>,
public componentwise_ops::base<T>
: public swizzle_ops::base<T>
{
static int const count = 3;
typedef T element;
@@ -524,9 +519,7 @@ static_assert(sizeof(dvec3) == 24, "sizeof(dvec3) == 24");

template <typename T>
struct vec_t<T,4>
: public swizzle_ops::base<T>,
public linear_ops::base<T>,
public componentwise_ops::base<T>
: public swizzle_ops::base<T>
{
static int const count = 4;
typedef T element;


Loading…
取消
儲存