Browse Source

math: add vectors of "half" to vector.h.

legacy
Sam Hocevar sam 12 years ago
parent
commit
33a3897b06
2 changed files with 102 additions and 53 deletions
  1. +59
    -18
      src/lol/math/half.h
  2. +43
    -35
      src/lol/math/vector.h

+ 59
- 18
src/lol/math/half.h View File

@@ -31,6 +31,7 @@ public:
inline half(int f) { *this = makefast((float)f); }
inline half(float f) { *this = makefast(f); }
inline half(double f) { *this = makefast((float)f); }
inline half(long double f) { *this = makefast((float)f); }

inline int is_nan() const
{
@@ -56,8 +57,19 @@ public:
inline half &operator =(int f) { return *this = makefast((float)f); }
inline half &operator =(float f) { return *this = makefast(f); }
inline half &operator =(double f) { return *this = makefast((float)f); }
inline operator int() const { return (int)tofloat(*this); }
inline half &operator =(long double f) { return *this = makefast((float)f); }
inline operator int8_t() const { return (int8_t)(float)*this; }
inline operator uint8_t() const { return (uint8_t)(float)*this; }
inline operator int16_t() const { return (int16_t)(float)*this; }
inline operator uint16_t() const { return (uint16_t)(float)*this; }
inline operator int32_t() const { return (int32_t)(float)*this; }
inline operator uint32_t() const { return (uint32_t)(float)*this; }
inline operator int64_t() const { return (int64_t)(float)*this; }
inline operator uint64_t() const { return (uint64_t)(float)*this; }

inline operator float() const { return tofloat(*this); }
inline operator double() const { return tofloat(*this); }
inline operator long double() const { return tofloat(*this); }

static float tofloat(half h);

@@ -78,19 +90,11 @@ public:

inline half operator -() const { return makebits(bits ^ 0x8000u); }
inline half operator +() const { return *this; }
inline half &operator +=(float f) { return (*this = (half)(*this + f)); }
inline half &operator -=(float f) { return (*this = (half)(*this - f)); }
inline half &operator *=(float f) { return (*this = (half)(*this * f)); }
inline half &operator /=(float f) { return (*this = (half)(*this / f)); }
inline half &operator +=(half h) { return (*this = (half)(*this + h)); }
inline half &operator -=(half h) { return (*this = (half)(*this - h)); }
inline half &operator *=(half h) { return (*this = (half)(*this * h)); }
inline half &operator /=(half h) { return (*this = (half)(*this / h)); }

inline float operator +(float f) const { return (float)*this + f; }
inline float operator -(float f) const { return (float)*this - f; }
inline float operator *(float f) const { return (float)*this * f; }
inline float operator /(float f) const { return (float)*this / f; }
inline float operator +(half h) const { return (float)*this + (float)h; }
inline float operator -(half h) const { return (float)*this - (float)h; }
inline float operator *(half h) const { return (float)*this * (float)h; }
@@ -110,15 +114,52 @@ public:
uint16_t bits;
};

inline float &operator +=(float &f, half h) { return f += (float)h; }
inline float &operator -=(float &f, half h) { return f -= (float)h; }
inline float &operator *=(float &f, half h) { return f *= (float)h; }
inline float &operator /=(float &f, half h) { return f /= (float)h; }

inline float operator +(float f, half h) { return f + (float)h; }
inline float operator -(float f, half h) { return f - (float)h; }
inline float operator *(float f, half h) { return f * (float)h; }
inline float operator /(float f, half h) { return f / (float)h; }
#define DECLARE_COERCE_HALF_NUMERIC_OPS(op, type, ret, x2, h2) \
inline ret operator op(type x, half h) { return x2 op h2; } \
inline ret operator op(half h, type x) { return h2 op x2; } \
inline type &operator op##=(type &x, half h) { return x = x op h2; } \
inline half &operator op##=(half &h, type x) { return h = h op x2; }

#define DECLARE_COERCE_HALF_BOOL_OPS(op, type, x2, h2) \
inline bool operator op(type x, half h) { return x2 op h2; } \
inline bool operator op(half h, type x) { return h2 op x2; }

#define DECLARE_COERCE_HALF_OPS(type, ret, x2, h2) \
DECLARE_COERCE_HALF_NUMERIC_OPS(+, type, ret, x2, h2) \
DECLARE_COERCE_HALF_NUMERIC_OPS(-, type, ret, x2, h2) \
DECLARE_COERCE_HALF_NUMERIC_OPS(*, type, ret, x2, h2) \
DECLARE_COERCE_HALF_NUMERIC_OPS(/, type, ret, x2, h2) \
\
DECLARE_COERCE_HALF_BOOL_OPS(==, type, x2, h2) \
DECLARE_COERCE_HALF_BOOL_OPS(!=, type, x2, h2) \
DECLARE_COERCE_HALF_BOOL_OPS(>=, type, x2, h2) \
DECLARE_COERCE_HALF_BOOL_OPS(<=, type, x2, h2) \
DECLARE_COERCE_HALF_BOOL_OPS(>, type, x2, h2) \
DECLARE_COERCE_HALF_BOOL_OPS(<, type, x2, h2)

#define DECLARE_COERCE_TO_HALF_OPS(type) \
DECLARE_COERCE_HALF_OPS(type, half, (half)(int)x, h)

#define DECLARE_COERCE_FROM_HALF_OPS(type) \
DECLARE_COERCE_HALF_OPS(type, type, x, (type)h)

DECLARE_COERCE_TO_HALF_OPS(int8_t)
DECLARE_COERCE_TO_HALF_OPS(uint8_t)
DECLARE_COERCE_TO_HALF_OPS(int16_t)
DECLARE_COERCE_TO_HALF_OPS(uint16_t)
DECLARE_COERCE_TO_HALF_OPS(int32_t)
DECLARE_COERCE_TO_HALF_OPS(uint32_t)
DECLARE_COERCE_TO_HALF_OPS(int64_t)
DECLARE_COERCE_TO_HALF_OPS(uint64_t)

DECLARE_COERCE_FROM_HALF_OPS(float)
DECLARE_COERCE_FROM_HALF_OPS(double)
DECLARE_COERCE_FROM_HALF_OPS(long double)

#undef DECLARE_COERCE_HALF_NUMERIC_OPS
#undef DECLARE_COERCE_HALF_OPS
#undef DECLARE_COERCE_TO_HALF_OPS
#undef DECLARE_COERCE_FROM_HALF_OPS

} /* namespace lol */



+ 43
- 35
src/lol/math/vector.h View File

@@ -1123,7 +1123,7 @@ static inline Quat<T> operator /(Quat<T> x, Quat<T> const &y)
\
DECLARE_VEC_3_COERCE_OPS(Vec3, static, type, type, type)

#define DECLARE_ALL_VECTOR_COERCE_OPS_INNER(tname, tlow, thigh) \
#define DECLARE_VEC_ANY_COERCE_OPS(tname, tlow, thigh) \
DECLARE_BINARY_COERCE_OPS(tname, static, tlow, thigh, thigh) \
DECLARE_BINARY_COERCE_OPS(tname, static, thigh, tlow, thigh) \
\
@@ -1131,22 +1131,22 @@ static inline Quat<T> operator /(Quat<T> x, Quat<T> const &y)
DECLARE_VECTOR_COERCE_OPS(tname, static, thigh, tlow, thigh)

#define DECLARE_ALL_VECTOR_COERCE_OPS(tlow, thigh) \
DECLARE_ALL_VECTOR_COERCE_OPS_INNER(Vec2, tlow, thigh) \
DECLARE_ALL_VECTOR_COERCE_OPS_INNER(Vec3, tlow, thigh) \
DECLARE_ALL_VECTOR_COERCE_OPS_INNER(Vec4, tlow, thigh) \
DECLARE_VEC_ANY_COERCE_OPS(Vec2, tlow, thigh) \
DECLARE_VEC_ANY_COERCE_OPS(Vec3, tlow, thigh) \
DECLARE_VEC_ANY_COERCE_OPS(Vec4, tlow, thigh) \
\
DECLARE_VEC_3_COERCE_OPS(Vec3, static, tlow, thigh, thigh) \
DECLARE_VEC_3_COERCE_OPS(Vec3, static, thigh, tlow, thigh)

DECLARE_ALL_NONVECTOR_OPS(Cmplx)
DECLARE_ALL_NONVECTOR_OPS(Quat)

/* Disable warning about unary operator applied to unsigned type */
#if defined _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4146)
#endif

DECLARE_ALL_NONVECTOR_OPS(Cmplx)
DECLARE_ALL_NONVECTOR_OPS(Quat)

DECLARE_ALL_VECTOR_OPS(half)
DECLARE_ALL_VECTOR_OPS(float)
DECLARE_ALL_VECTOR_OPS(double)
@@ -1178,10 +1178,9 @@ DECLARE_ALL_VECTOR_OPS(uint64_t)
# pragma warning(disable: 4018)
#endif

/* Apply the same coercion rules as in the C++ standard. However, */
/* instead of promoting int8_t etc. to int, we apply our own rules. */
/* FIXME: "half" and "real" are deactivated for now, because we do */
/* not implement all combinations of operators for these types yet. */
/* Apply the same coercion rules as in the C++ standard. However, instead
* of always promoting smaller types to int, we allow int8_t op int16_t to
* return an int16_t. */
DECLARE_ALL_VECTOR_COERCE_OPS(int8_t, uint8_t)
DECLARE_ALL_VECTOR_COERCE_OPS(int8_t, int16_t)
DECLARE_ALL_VECTOR_COERCE_OPS(int8_t, uint16_t)
@@ -1189,11 +1188,9 @@ DECLARE_ALL_VECTOR_COERCE_OPS(int8_t, int32_t)
DECLARE_ALL_VECTOR_COERCE_OPS(int8_t, uint32_t)
DECLARE_ALL_VECTOR_COERCE_OPS(int8_t, int64_t)
DECLARE_ALL_VECTOR_COERCE_OPS(int8_t, uint64_t)
/* DECLARE_ALL_VECTOR_COERCE_OPS(int8_t, half) */
DECLARE_ALL_VECTOR_COERCE_OPS(int8_t, float)
DECLARE_ALL_VECTOR_COERCE_OPS(int8_t, double)
DECLARE_ALL_VECTOR_COERCE_OPS(int8_t, long double)
/* DECLARE_ALL_VECTOR_COERCE_OPS(int8_t, real) */

DECLARE_ALL_VECTOR_COERCE_OPS(uint8_t, int16_t)
DECLARE_ALL_VECTOR_COERCE_OPS(uint8_t, uint16_t)
@@ -1201,76 +1198,87 @@ DECLARE_ALL_VECTOR_COERCE_OPS(uint8_t, int32_t)
DECLARE_ALL_VECTOR_COERCE_OPS(uint8_t, uint32_t)
DECLARE_ALL_VECTOR_COERCE_OPS(uint8_t, int64_t)
DECLARE_ALL_VECTOR_COERCE_OPS(uint8_t, uint64_t)
/* DECLARE_ALL_VECTOR_COERCE_OPS(uint8_t, half) */
DECLARE_ALL_VECTOR_COERCE_OPS(uint8_t, float)
DECLARE_ALL_VECTOR_COERCE_OPS(uint8_t, double)
DECLARE_ALL_VECTOR_COERCE_OPS(uint8_t, long double)
/* DECLARE_ALL_VECTOR_COERCE_OPS(uint8_t, real) */

DECLARE_ALL_VECTOR_COERCE_OPS(int16_t, uint16_t)
DECLARE_ALL_VECTOR_COERCE_OPS(int16_t, int32_t)
DECLARE_ALL_VECTOR_COERCE_OPS(int16_t, uint32_t)
DECLARE_ALL_VECTOR_COERCE_OPS(int16_t, int64_t)
DECLARE_ALL_VECTOR_COERCE_OPS(int16_t, uint64_t)
/* DECLARE_ALL_VECTOR_COERCE_OPS(int16_t, half) */
DECLARE_ALL_VECTOR_COERCE_OPS(int16_t, float)
DECLARE_ALL_VECTOR_COERCE_OPS(int16_t, double)
DECLARE_ALL_VECTOR_COERCE_OPS(int16_t, long double)
/* DECLARE_ALL_VECTOR_COERCE_OPS(int16_t, real) */

DECLARE_ALL_VECTOR_COERCE_OPS(uint16_t, int32_t)
DECLARE_ALL_VECTOR_COERCE_OPS(uint16_t, uint32_t)
DECLARE_ALL_VECTOR_COERCE_OPS(uint16_t, int64_t)
DECLARE_ALL_VECTOR_COERCE_OPS(uint16_t, uint64_t)
/* DECLARE_ALL_VECTOR_COERCE_OPS(uint16_t, half) */
DECLARE_ALL_VECTOR_COERCE_OPS(uint16_t, float)
DECLARE_ALL_VECTOR_COERCE_OPS(uint16_t, double)
DECLARE_ALL_VECTOR_COERCE_OPS(uint16_t, long double)
/* DECLARE_ALL_VECTOR_COERCE_OPS(uint16_t, real) */

DECLARE_ALL_VECTOR_COERCE_OPS(int32_t, uint32_t)
DECLARE_ALL_VECTOR_COERCE_OPS(int32_t, int64_t)
DECLARE_ALL_VECTOR_COERCE_OPS(int32_t, uint64_t)
/* DECLARE_ALL_VECTOR_COERCE_OPS(int32_t, half) */
DECLARE_ALL_VECTOR_COERCE_OPS(int32_t, float)
DECLARE_ALL_VECTOR_COERCE_OPS(int32_t, double)
DECLARE_ALL_VECTOR_COERCE_OPS(int32_t, long double)
/* DECLARE_ALL_VECTOR_COERCE_OPS(int32_t, real) */

DECLARE_ALL_VECTOR_COERCE_OPS(uint32_t, int64_t)
DECLARE_ALL_VECTOR_COERCE_OPS(uint32_t, uint64_t)
/* DECLARE_ALL_VECTOR_COERCE_OPS(uint32_t, half) */
DECLARE_ALL_VECTOR_COERCE_OPS(uint32_t, float)
DECLARE_ALL_VECTOR_COERCE_OPS(uint32_t, double)
DECLARE_ALL_VECTOR_COERCE_OPS(uint32_t, long double)
/* DECLARE_ALL_VECTOR_COERCE_OPS(uint32_t, real) */

DECLARE_ALL_VECTOR_COERCE_OPS(int64_t, uint64_t)
/* DECLARE_ALL_VECTOR_COERCE_OPS(int64_t, half) */
DECLARE_ALL_VECTOR_COERCE_OPS(int64_t, float)
DECLARE_ALL_VECTOR_COERCE_OPS(int64_t, double)
DECLARE_ALL_VECTOR_COERCE_OPS(int64_t, long double)
/* DECLARE_ALL_VECTOR_COERCE_OPS(int64_t, real) */

/* DECLARE_ALL_VECTOR_COERCE_OPS(uint64_t, half) */
DECLARE_ALL_VECTOR_COERCE_OPS(uint64_t, float)
DECLARE_ALL_VECTOR_COERCE_OPS(uint64_t, double)
DECLARE_ALL_VECTOR_COERCE_OPS(uint64_t, long double)
/* DECLARE_ALL_VECTOR_COERCE_OPS(uint64_t, real) */

/* DECLARE_ALL_VECTOR_COERCE_OPS(half, float) */
/* DECLARE_ALL_VECTOR_COERCE_OPS(half, double) */
/* DECLARE_ALL_VECTOR_COERCE_OPS(half, long double) */
/* DECLARE_ALL_VECTOR_COERCE_OPS(half, real) */

DECLARE_ALL_VECTOR_COERCE_OPS(float, double)
DECLARE_ALL_VECTOR_COERCE_OPS(float, long double)
/* DECLARE_ALL_VECTOR_COERCE_OPS(float, real) */

DECLARE_ALL_VECTOR_COERCE_OPS(double, long double)
/* DECLARE_ALL_VECTOR_COERCE_OPS(double, real) */

/* DECLARE_ALL_VECTOR_COERCE_OPS(long double, real) */
/* All integer types are promoted to half; all floating point types
* cause half to be promoted. */
DECLARE_ALL_VECTOR_COERCE_OPS(int8_t, half)
DECLARE_ALL_VECTOR_COERCE_OPS(uint8_t, half)
DECLARE_ALL_VECTOR_COERCE_OPS(int16_t, half)
DECLARE_ALL_VECTOR_COERCE_OPS(uint16_t, half)
DECLARE_ALL_VECTOR_COERCE_OPS(int32_t, half)
DECLARE_ALL_VECTOR_COERCE_OPS(uint32_t, half)
DECLARE_ALL_VECTOR_COERCE_OPS(int64_t, half)
DECLARE_ALL_VECTOR_COERCE_OPS(uint64_t, half)

DECLARE_ALL_VECTOR_COERCE_OPS(half, float)
DECLARE_ALL_VECTOR_COERCE_OPS(half, double)
DECLARE_ALL_VECTOR_COERCE_OPS(half, long double)

/* FIXME: vectors of "real" are deactivated for now, because we do
* not implement all combinations of operators for these types yet. */

#if 0
/* All types are promoted to real */
DECLARE_ALL_VECTOR_COERCE_OPS(int8_t, real)
DECLARE_ALL_VECTOR_COERCE_OPS(uint8_t, real)
DECLARE_ALL_VECTOR_COERCE_OPS(int16_t, real)
DECLARE_ALL_VECTOR_COERCE_OPS(uint16_t, real)
DECLARE_ALL_VECTOR_COERCE_OPS(int32_t, real)
DECLARE_ALL_VECTOR_COERCE_OPS(uint32_t, real)
DECLARE_ALL_VECTOR_COERCE_OPS(int64_t, real)
DECLARE_ALL_VECTOR_COERCE_OPS(uint64_t, real)
DECLARE_ALL_VECTOR_COERCE_OPS(half, real)
DECLARE_ALL_VECTOR_COERCE_OPS(float, real)
DECLARE_ALL_VECTOR_COERCE_OPS(double, real)
DECLARE_ALL_VECTOR_COERCE_OPS(long double, real)
#endif

#if defined __GNUC__ && (__GNUC__ >= 4)
# pragma GCC diagnostic pop


Loading…
Cancel
Save