More constexpr experiments
This commit is contained in:
parent
5ddfa3f8a9
commit
c5386c05f9
@ -30,7 +30,7 @@ namespace glm
|
|||||||
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
|
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
|
||||||
/// @see qualifier
|
/// @see qualifier
|
||||||
template<typename genType>
|
template<typename genType>
|
||||||
GLM_FUNC_DECL genType abs(genType x);
|
GLM_FUNC_DECL GLM_CONSTEXPR_CXX11 genType abs(genType x);
|
||||||
|
|
||||||
/// Returns x if x >= 0; otherwise, it returns -x.
|
/// Returns x if x >= 0; otherwise, it returns -x.
|
||||||
///
|
///
|
||||||
@ -41,7 +41,7 @@ namespace glm
|
|||||||
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/abs.xml">GLSL abs man page</a>
|
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/abs.xml">GLSL abs man page</a>
|
||||||
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
|
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
|
||||||
template<length_t L, typename T, qualifier Q>
|
template<length_t L, typename T, qualifier Q>
|
||||||
GLM_FUNC_DECL vec<L, T, Q> abs(vec<L, T, Q> const& x);
|
GLM_FUNC_DECL GLM_CONSTEXPR_CXX11 vec<L, T, Q> abs(vec<L, T, Q> const& x);
|
||||||
|
|
||||||
/// Returns 1.0 if x > 0, 0.0 if x == 0, or -1.0 if x < 0.
|
/// Returns 1.0 if x > 0, 0.0 if x == 0, or -1.0 if x < 0.
|
||||||
///
|
///
|
||||||
|
@ -17,7 +17,7 @@ namespace detail
|
|||||||
template<typename R, typename T, qualifier Q>
|
template<typename R, typename T, qualifier Q>
|
||||||
struct functor1<1, R, T, Q>
|
struct functor1<1, R, T, Q>
|
||||||
{
|
{
|
||||||
GLM_FUNC_QUALIFIER static vec<1, R, Q> call(R (*Func) (T x), vec<1, T, Q> const& v)
|
GLM_FUNC_QUALIFIER GLM_CONSTEXPR_CXX11 static vec<1, R, Q> call(R (*Func) (T x), vec<1, T, Q> const& v)
|
||||||
{
|
{
|
||||||
return vec<1, R, Q>(Func(v.x));
|
return vec<1, R, Q>(Func(v.x));
|
||||||
}
|
}
|
||||||
@ -26,7 +26,7 @@ namespace detail
|
|||||||
template<typename R, typename T, qualifier Q>
|
template<typename R, typename T, qualifier Q>
|
||||||
struct functor1<2, R, T, Q>
|
struct functor1<2, R, T, Q>
|
||||||
{
|
{
|
||||||
GLM_FUNC_QUALIFIER static vec<2, R, Q> call(R (*Func) (T x), vec<2, T, Q> const& v)
|
GLM_FUNC_QUALIFIER GLM_CONSTEXPR_CXX11 static vec<2, R, Q> call(R (*Func) (T x), vec<2, T, Q> const& v)
|
||||||
{
|
{
|
||||||
return vec<2, R, Q>(Func(v.x), Func(v.y));
|
return vec<2, R, Q>(Func(v.x), Func(v.y));
|
||||||
}
|
}
|
||||||
@ -35,7 +35,7 @@ namespace detail
|
|||||||
template<typename R, typename T, qualifier Q>
|
template<typename R, typename T, qualifier Q>
|
||||||
struct functor1<3, R, T, Q>
|
struct functor1<3, R, T, Q>
|
||||||
{
|
{
|
||||||
GLM_FUNC_QUALIFIER static vec<3, R, Q> call(R (*Func) (T x), vec<3, T, Q> const& v)
|
GLM_FUNC_QUALIFIER GLM_CONSTEXPR_CXX11 static vec<3, R, Q> call(R (*Func) (T x), vec<3, T, Q> const& v)
|
||||||
{
|
{
|
||||||
return vec<3, R, Q>(Func(v.x), Func(v.y), Func(v.z));
|
return vec<3, R, Q>(Func(v.x), Func(v.y), Func(v.z));
|
||||||
}
|
}
|
||||||
@ -44,7 +44,7 @@ namespace detail
|
|||||||
template<typename R, typename T, qualifier Q>
|
template<typename R, typename T, qualifier Q>
|
||||||
struct functor1<4, R, T, Q>
|
struct functor1<4, R, T, Q>
|
||||||
{
|
{
|
||||||
GLM_FUNC_QUALIFIER static vec<4, R, Q> call(R (*Func) (T x), vec<4, T, Q> const& v)
|
GLM_FUNC_QUALIFIER GLM_CONSTEXPR_CXX11 static vec<4, R, Q> call(R (*Func) (T x), vec<4, T, Q> const& v)
|
||||||
{
|
{
|
||||||
return vec<4, R, Q>(Func(v.x), Func(v.y), Func(v.z), Func(v.w));
|
return vec<4, R, Q>(Func(v.x), Func(v.y), Func(v.z), Func(v.w));
|
||||||
}
|
}
|
||||||
|
60
glm/detail/compute_common.hpp
Normal file
60
glm/detail/compute_common.hpp
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "setup.hpp"
|
||||||
|
#include <cstring>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
namespace glm{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template<typename genFIType, bool /*signed*/>
|
||||||
|
struct compute_abs
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<typename genFIType>
|
||||||
|
struct compute_abs<genFIType, true>
|
||||||
|
{
|
||||||
|
GLM_FUNC_QUALIFIER GLM_CONSTEXPR_CXX11 static genFIType call(genFIType x)
|
||||||
|
{
|
||||||
|
GLM_STATIC_ASSERT(
|
||||||
|
std::numeric_limits<genFIType>::is_iec559 || std::numeric_limits<genFIType>::is_signed || GLM_UNRESTRICTED_GENTYPE,
|
||||||
|
"'abs' only accept floating-point and integer scalar or vector inputs");
|
||||||
|
|
||||||
|
return x >= genFIType(0) ? x : -x;
|
||||||
|
// TODO, perf comp with: *(((int *) &x) + 1) &= 0x7fffffff;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#if GLM_COMPILER & GLM_COMPILER_CUDA
|
||||||
|
template<>
|
||||||
|
struct compute_abs<float, true>
|
||||||
|
{
|
||||||
|
GLM_FUNC_QUALIFIER GLM_CONSTEXPR_CXX11 static float call(float x)
|
||||||
|
{
|
||||||
|
return fabsf(x);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<typename genFIType>
|
||||||
|
struct compute_abs<genFIType, false>
|
||||||
|
{
|
||||||
|
GLM_FUNC_QUALIFIER GLM_CONSTEXPR_CXX11 static genFIType call(genFIType x)
|
||||||
|
{
|
||||||
|
GLM_STATIC_ASSERT(
|
||||||
|
(!std::numeric_limits<genFIType>::is_signed && std::numeric_limits<genFIType>::is_integer) || GLM_UNRESTRICTED_GENTYPE,
|
||||||
|
"'abs' only accept floating-point and integer scalar or vector inputs");
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<length_t L, typename T, qualifier Q, bool Aligned>
|
||||||
|
struct compute_abs_vector
|
||||||
|
{
|
||||||
|
GLM_FUNC_QUALIFIER GLM_CONSTEXPR_CXX11 static vec<L, T, Q> call(vec<L, T, Q> const& x)
|
||||||
|
{
|
||||||
|
return detail::functor1<L, T, T, Q>::call(abs, x);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}//namespace detail
|
||||||
|
}//namespace glm
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "compute_common.hpp"
|
||||||
#include "setup.hpp"
|
#include "setup.hpp"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
@ -10,7 +11,7 @@ namespace detail
|
|||||||
template <typename T, bool isFloat = std::numeric_limits<T>::is_iec559>
|
template <typename T, bool isFloat = std::numeric_limits<T>::is_iec559>
|
||||||
struct compute_equal
|
struct compute_equal
|
||||||
{
|
{
|
||||||
GLM_FUNC_QUALIFIER static bool call(T a, T b)
|
GLM_FUNC_QUALIFIER GLM_CONSTEXPR_CXX11 static bool call(T a, T b)
|
||||||
{
|
{
|
||||||
return a == b;
|
return a == b;
|
||||||
}
|
}
|
||||||
@ -19,9 +20,10 @@ namespace detail
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
struct compute_equal<T, true>
|
struct compute_equal<T, true>
|
||||||
{
|
{
|
||||||
GLM_FUNC_QUALIFIER static bool call(T a, T b)
|
GLM_FUNC_QUALIFIER GLM_CONSTEXPR_CXX11 static bool call(T a, T b)
|
||||||
{
|
{
|
||||||
return std::memcmp(&a, &b, sizeof(T)) == 0;
|
return detail::compute_abs<T, std::numeric_limits<T>::is_signed>::call(b - a) <= static_cast<T>(0);
|
||||||
|
//return std::memcmp(&a, &b, sizeof(T)) == 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}//namespace detail
|
}//namespace detail
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
/// @file glm/detail/func_common.inl
|
/// @file glm/detail/func_common.inl
|
||||||
|
|
||||||
#include "../vector_relational.hpp"
|
#include "../vector_relational.hpp"
|
||||||
|
#include "compute_common.hpp"
|
||||||
#include "type_vec2.hpp"
|
#include "type_vec2.hpp"
|
||||||
#include "type_vec3.hpp"
|
#include "type_vec3.hpp"
|
||||||
#include "type_vec4.hpp"
|
#include "type_vec4.hpp"
|
||||||
@ -66,56 +67,6 @@ namespace glm
|
|||||||
namespace glm{
|
namespace glm{
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
template<typename genFIType, bool /*signed*/>
|
|
||||||
struct compute_abs
|
|
||||||
{};
|
|
||||||
|
|
||||||
template<typename genFIType>
|
|
||||||
struct compute_abs<genFIType, true>
|
|
||||||
{
|
|
||||||
GLM_FUNC_QUALIFIER static genFIType call(genFIType x)
|
|
||||||
{
|
|
||||||
GLM_STATIC_ASSERT(
|
|
||||||
std::numeric_limits<genFIType>::is_iec559 || std::numeric_limits<genFIType>::is_signed || GLM_UNRESTRICTED_GENTYPE,
|
|
||||||
"'abs' only accept floating-point and integer scalar or vector inputs");
|
|
||||||
|
|
||||||
return x >= genFIType(0) ? x : -x;
|
|
||||||
// TODO, perf comp with: *(((int *) &x) + 1) &= 0x7fffffff;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#if GLM_COMPILER & GLM_COMPILER_CUDA
|
|
||||||
template<>
|
|
||||||
struct compute_abs<float, true>
|
|
||||||
{
|
|
||||||
GLM_FUNC_QUALIFIER static float call(float x)
|
|
||||||
{
|
|
||||||
return fabsf(x);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename genFIType>
|
|
||||||
struct compute_abs<genFIType, false>
|
|
||||||
{
|
|
||||||
GLM_FUNC_QUALIFIER static genFIType call(genFIType x)
|
|
||||||
{
|
|
||||||
GLM_STATIC_ASSERT(
|
|
||||||
(!std::numeric_limits<genFIType>::is_signed && std::numeric_limits<genFIType>::is_integer) || GLM_UNRESTRICTED_GENTYPE,
|
|
||||||
"'abs' only accept floating-point and integer scalar or vector inputs");
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<length_t L, typename T, qualifier Q, bool Aligned>
|
|
||||||
struct compute_abs_vector
|
|
||||||
{
|
|
||||||
GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& x)
|
|
||||||
{
|
|
||||||
return detail::functor1<L, T, T, Q>::call(abs, x);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<length_t L, typename T, typename U, qualifier Q, bool Aligned>
|
template<length_t L, typename T, typename U, qualifier Q, bool Aligned>
|
||||||
struct compute_mix_vector
|
struct compute_mix_vector
|
||||||
{
|
{
|
||||||
@ -306,13 +257,13 @@ namespace detail
|
|||||||
}//namespace detail
|
}//namespace detail
|
||||||
|
|
||||||
template<typename genFIType>
|
template<typename genFIType>
|
||||||
GLM_FUNC_QUALIFIER genFIType abs(genFIType x)
|
GLM_FUNC_QUALIFIER GLM_CONSTEXPR_CXX11 genFIType abs(genFIType x)
|
||||||
{
|
{
|
||||||
return detail::compute_abs<genFIType, std::numeric_limits<genFIType>::is_signed>::call(x);
|
return detail::compute_abs<genFIType, std::numeric_limits<genFIType>::is_signed>::call(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<length_t L, typename T, qualifier Q>
|
template<length_t L, typename T, qualifier Q>
|
||||||
GLM_FUNC_QUALIFIER vec<L, T, Q> abs(vec<L, T, Q> const& x)
|
GLM_FUNC_QUALIFIER GLM_CONSTEXPR_CXX11 vec<L, T, Q> abs(vec<L, T, Q> const& x)
|
||||||
{
|
{
|
||||||
return detail::compute_abs_vector<L, T, Q, detail::is_aligned<Q>::value>::call(x);
|
return detail::compute_abs_vector<L, T, Q, detail::is_aligned<Q>::value>::call(x);
|
||||||
}
|
}
|
||||||
|
@ -409,7 +409,7 @@ namespace glm
|
|||||||
GLM_FUNC_DECL GLM_CONSTEXPR_CXX11 bool operator==(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2);
|
GLM_FUNC_DECL GLM_CONSTEXPR_CXX11 bool operator==(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2);
|
||||||
|
|
||||||
template<typename T, qualifier Q>
|
template<typename T, qualifier Q>
|
||||||
GLM_FUNC_DECL bool operator!=(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2);
|
GLM_FUNC_DECL GLM_CONSTEXPR_CXX11 bool operator!=(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2);
|
||||||
|
|
||||||
template<qualifier Q>
|
template<qualifier Q>
|
||||||
GLM_FUNC_DECL vec<3, bool, Q> operator&&(vec<3, bool, Q> const& v1, vec<3, bool, Q> const& v2);
|
GLM_FUNC_DECL vec<3, bool, Q> operator&&(vec<3, bool, Q> const& v1, vec<3, bool, Q> const& v2);
|
||||||
|
@ -1023,17 +1023,14 @@ namespace glm
|
|||||||
template<typename T, qualifier Q>
|
template<typename T, qualifier Q>
|
||||||
GLM_FUNC_QUALIFIER GLM_CONSTEXPR_CXX11 bool operator==(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2)
|
GLM_FUNC_QUALIFIER GLM_CONSTEXPR_CXX11 bool operator==(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2)
|
||||||
{
|
{
|
||||||
return v1.x == v2.x && v1.y == v2.y && v1.z == v2.z;
|
|
||||||
/*
|
|
||||||
return
|
return
|
||||||
detail::compute_equal<T>::call(v1.x, v2.x) &&
|
detail::compute_equal<T>::call(v1.x, v2.x) &&
|
||||||
detail::compute_equal<T>::call(v1.y, v2.y) &&
|
detail::compute_equal<T>::call(v1.y, v2.y) &&
|
||||||
detail::compute_equal<T>::call(v1.z, v2.z);
|
detail::compute_equal<T>::call(v1.z, v2.z);
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, qualifier Q>
|
template<typename T, qualifier Q>
|
||||||
GLM_FUNC_QUALIFIER bool operator!=(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2)
|
GLM_FUNC_QUALIFIER GLM_CONSTEXPR_CXX11 bool operator!=(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2)
|
||||||
{
|
{
|
||||||
return !(v1 == v2);
|
return !(v1 == v2);
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ namespace glm
|
|||||||
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
struct { T x, y, z, w;};
|
struct { T x, y, z, w; };
|
||||||
struct { T r, g, b, a; };
|
struct { T r, g, b, a; };
|
||||||
struct { T s, t, p, q; };
|
struct { T s, t, p, q; };
|
||||||
|
|
||||||
|
@ -1289,10 +1289,19 @@ namespace ldexp_
|
|||||||
}
|
}
|
||||||
}//namespace ldexp_
|
}//namespace ldexp_
|
||||||
|
|
||||||
|
static int test_constexpr()
|
||||||
|
{
|
||||||
|
static_assert(glm::abs(1.0f) > 0.0f, "GLM: Failed constexpr");
|
||||||
|
static_assert(glm::abs(glm::vec3(1.0f)) != glm::vec3(0.0f), "GLM: Failed constexpr");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
int Error = 0;
|
int Error = 0;
|
||||||
|
|
||||||
|
Error += test_constexpr();
|
||||||
Error += sign::test();
|
Error += sign::test();
|
||||||
Error += floor_::test();
|
Error += floor_::test();
|
||||||
Error += mod_::test();
|
Error += mod_::test();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user