From c1be8bf0089d15c2a2bb6c6fe68545f4f8942958 Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Tue, 7 Aug 2018 23:52:57 +0200 Subject: [PATCH] Fixed constexpr relational function and added tests --- glm/detail/func_vector_relational.inl | 248 ++++++-------------------- glm/detail/type_vec1.inl | 4 +- glm/detail/type_vec2.inl | 18 +- glm/detail/type_vec3.inl | 22 ++- glm/detail/type_vec4.inl | 26 ++- glm/ext/matrix_relational.inl | 74 ++------ glm/ext/vector_relational.inl | 16 +- test/core/core_cpp_constexpr.cpp | 66 +++++++ 8 files changed, 197 insertions(+), 277 deletions(-) diff --git a/glm/detail/func_vector_relational.inl b/glm/detail/func_vector_relational.inl index 5d7fc597..11446636 100644 --- a/glm/detail/func_vector_relational.inl +++ b/glm/detail/func_vector_relational.inl @@ -2,170 +2,68 @@ #include "compute_vector_relational.hpp" -// Bug #782: Warning C4701: potentially uninitialized local variable 'Result' used -#if ((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC12)) -# define GLM_BUG_VC_INIT (false) -#else -# define GLM_BUG_VC_INIT -#endif - -namespace glm{ -namespace detail +namespace glm { - enum relational_type + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec lessThan(vec const& x, vec const& y) { - EQUAL, - NOT_EQUAL, - LESS, - LESS_EQUAL, - GREATER, - GREATER_EQUAL, - ANY, - ALL, - NOT - }; + vec Result(true); + for(length_t i = 0; i < L; ++i) + Result[i] = x[i] < y[i]; + return Result; + } - template - struct relational + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec lessThanEqual(vec const& x, vec const& y) { - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(T Src0, T Src1); - }; + vec Result(true); + for(length_t i = 0; i < L; ++i) + Result[i] = x[i] <= y[i]; + return Result; + } - template <> - struct relational + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec greaterThan(vec const& x, vec const& y) { - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(T Src0, T Src1) - { - return Src0 == Src1; - } - }; + vec Result(true); + for(length_t i = 0; i < L; ++i) + Result[i] = x[i] > y[i]; + return Result; + } - template <> - struct relational + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec greaterThanEqual(vec const& x, vec const& y) { - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(T Src0, T Src1) - { - return Src0 != Src1; - } - }; + vec Result(true); + for(length_t i = 0; i < L; ++i) + Result[i] = x[i] >= y[i]; + return Result; + } - template <> - struct relational + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec equal(vec const& x, vec const& y) { - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(T Src0, T Src1) - { - return Src0 < Src1; - } - }; + vec Result(true); + for(length_t i = 0; i < L; ++i) + Result[i] = x[i] == y[i]; + return Result; + } - template <> - struct relational + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec notEqual(vec const& x, vec const& y) { - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(T Src0, T Src1) - { - return Src0 <= Src1; - } - }; - - template <> - struct relational - { - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(T Src0, T Src1) - { - return Src0 > Src1; - } - }; - - template <> - struct relational - { - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(T Src0, T Src1) - { - return Src0 >= Src1; - } - }; - - template <> - struct relational - { - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(T Src0, T Src1) - { - return Src0 || Src1; - } - }; - - template <> - struct relational - { - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(T Src0, T Src1) - { - return Src0 && Src1; - } - }; - - template <> - struct relational - { - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(T Src0, T) - { - return !Src0; - } - }; - - template - struct loop_relational - { - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static void call(vecBType& Dst, vecType const& Src0, vecType const& Src1) - { - Dst[I] = relational::call(Src0[I], Src1[I]); - loop_relational::call(Dst, Src0, Src1); - } - }; - - template - struct loop_relational - { - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static void call(vecBType&, vecType const&, vecType const&) - {} - }; - - template - struct reduce_relational - { - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static void call(bool& Dst, vecType const& Src) - { - Dst = relational::call(Dst, Src[I]); - reduce_relational::call(Dst, Src); - } - }; - - template - struct reduce_relational - { - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static void call(bool&, vecType const&) - {} - }; -}//namespace detail + vec Result(true); + for(length_t i = 0; i < L; ++i) + Result[i] = x[i] != y[i]; + return Result; + } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool any(vec const& v) { bool Result = false; - detail::reduce_relational<0, L, detail::ANY>::call(Result, v); + for(length_t i = 0; i < L; ++i) + Result = Result || v[i]; return Result; } @@ -173,63 +71,17 @@ namespace detail GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool all(vec const& v) { bool Result = true; - detail::reduce_relational<0, L, detail::ALL>::call(Result, v); + for(length_t i = 0; i < L; ++i) + Result = Result && v[i]; return Result; } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec not_(vec const& v) { - vec Result; - detail::loop_relational<0, L, detail::NOT>::call(Result, v, v); - return Result; - } - - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec lessThan(vec const& x, vec const& y) - { - vec Result GLM_BUG_VC_INIT; - detail::loop_relational<0, L, detail::LESS>::call(Result, x, y); - return Result; - } - - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec lessThanEqual(vec const& x, vec const& y) - { - vec Result GLM_BUG_VC_INIT; - detail::loop_relational<0, L, detail::LESS_EQUAL>::call(Result, x, y); - return Result; - } - - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec greaterThan(vec const& x, vec const& y) - { - vec Result GLM_BUG_VC_INIT; - detail::loop_relational<0, L, detail::GREATER>::call(Result, x, y); - return Result; - } - - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec greaterThanEqual(vec const& x, vec const& y) - { - vec Result GLM_BUG_VC_INIT; - detail::loop_relational<0, L, detail::GREATER_EQUAL>::call(Result, x, y); - return Result; - } - - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec equal(vec const& x, vec const& y) - { - vec Result GLM_BUG_VC_INIT; - detail::loop_relational<0, L, detail::EQUAL>::call(Result, x, y); - return Result; - } - - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec notEqual(vec const& x, vec const& y) - { - vec Result GLM_BUG_VC_INIT; - detail::loop_relational<0, L, detail::NOT_EQUAL>::call(Result, x, y); + vec Result(true); + for(length_t i = 0; i < L; ++i) + Result[i] = !v[i]; return Result; } }//namespace glm diff --git a/glm/detail/type_vec1.inl b/glm/detail/type_vec1.inl index 53002473..4be64d0b 100644 --- a/glm/detail/type_vec1.inl +++ b/glm/detail/type_vec1.inl @@ -65,14 +65,14 @@ namespace glm GLM_FUNC_QUALIFIER GLM_CONSTEXPR T & vec<1, T, Q>::operator[](typename vec<1, T, Q>::length_type i) { assert(i >= 0 && i < this->length()); - return (&x)[i]; + return x; } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR T const& vec<1, T, Q>::operator[](typename vec<1, T, Q>::length_type i) const { assert(i >= 0 && i < this->length()); - return (&x)[i]; + return x; } // -- Unary arithmetic operators -- diff --git a/glm/detail/type_vec2.inl b/glm/detail/type_vec2.inl index b8099806..f5414bad 100644 --- a/glm/detail/type_vec2.inl +++ b/glm/detail/type_vec2.inl @@ -104,14 +104,28 @@ namespace glm GLM_FUNC_QUALIFIER GLM_CONSTEXPR T & vec<2, T, Q>::operator[](typename vec<2, T, Q>::length_type i) { assert(i >= 0 && i < this->length()); - return (&x)[i]; + switch(i) + { + default: + case 0: + return x; + case 1: + return y; + } } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR T const& vec<2, T, Q>::operator[](typename vec<2, T, Q>::length_type i) const { assert(i >= 0 && i < this->length()); - return (&x)[i]; + switch(i) + { + default: + case 0: + return x; + case 1: + return y; + } } // -- Unary arithmetic operators -- diff --git a/glm/detail/type_vec3.inl b/glm/detail/type_vec3.inl index 5f33e806..40c31618 100644 --- a/glm/detail/type_vec3.inl +++ b/glm/detail/type_vec3.inl @@ -168,14 +168,32 @@ namespace glm GLM_FUNC_QUALIFIER GLM_CONSTEXPR T & vec<3, T, Q>::operator[](typename vec<3, T, Q>::length_type i) { assert(i >= 0 && i < this->length()); - return (&x)[i]; + switch(i) + { + default: + case 0: + return x; + case 1: + return y; + case 2: + return z; + } } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR T const& vec<3, T, Q>::operator[](typename vec<3, T, Q>::length_type i) const { assert(i >= 0 && i < this->length()); - return (&x)[i]; + switch(i) + { + default: + case 0: + return x; + case 1: + return y; + case 2: + return z; + } } // -- Unary arithmetic operators -- diff --git a/glm/detail/type_vec4.inl b/glm/detail/type_vec4.inl index 6e7d6f3d..9f3142d6 100644 --- a/glm/detail/type_vec4.inl +++ b/glm/detail/type_vec4.inl @@ -507,14 +507,36 @@ namespace detail GLM_FUNC_QUALIFIER GLM_CONSTEXPR T& vec<4, T, Q>::operator[](typename vec<4, T, Q>::length_type i) { assert(i >= 0 && i < this->length()); - return (&x)[i]; + switch(i) + { + default: + case 0: + return x; + case 1: + return y; + case 2: + return z; + case 3: + return w; + } } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR T const& vec<4, T, Q>::operator[](typename vec<4, T, Q>::length_type i) const { assert(i >= 0 && i < this->length()); - return (&x)[i]; + switch(i) + { + default: + case 0: + return x; + case 1: + return y; + case 2: + return z; + case 3: + return w; + } } // -- Unary arithmetic operators -- diff --git a/glm/ext/matrix_relational.inl b/glm/ext/matrix_relational.inl index ca3383e2..d6054f33 100644 --- a/glm/ext/matrix_relational.inl +++ b/glm/ext/matrix_relational.inl @@ -5,62 +5,8 @@ #include "../ext/vector_relational.hpp" #include "../common.hpp" -namespace glm{ -namespace detail +namespace glm { - enum matrix_relational_type - { - MAT_EQUAL, - MAT_NOT_EQUAL - }; - - template - struct matrix_relational - { - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(vecType const& Src0, vecType const& Src1, T Epsilon); - }; - - template <> - struct matrix_relational - { - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(vecType const& Src0, vecType const& Src1, T Epsilon) - { - return all(equal(Src0, Src1, Epsilon)); - } - }; - - template <> - struct matrix_relational - { - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(vecType const& Src0, vecType const& Src1, T Epsilon) - { - return any(notEqual(Src0, Src1, Epsilon)); - } - }; - - template - struct loop_matrix_relational - { - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static void call(vecBType& Dst, matType const& Src0, matType const& Src1, vecType const& Epsilon) - { - Dst[I] = matrix_relational::call(Src0[I], Src1[I], Epsilon[I]); - loop_matrix_relational::call(Dst, Src0, Src1, Epsilon); - } - }; - - template - struct loop_matrix_relational - { - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static void call(vecBType&, matType const&, matType const&, vecType const&) - {} - }; -}//namespace detail - template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec equal(mat const& a, mat const& b) { @@ -68,16 +14,17 @@ namespace detail } template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec equal(mat const& a, mat const& b, T epsilon) + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec equal(mat const& a, mat const& b, T Epsilon) { - return equal(a, b, vec(epsilon)); + return equal(a, b, vec(Epsilon)); } template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec equal(mat const& a, mat const& b, vec const& epsilon) + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec equal(mat const& a, mat const& b, vec const& Epsilon) { vec Result; - detail::loop_matrix_relational<0, C, detail::EQUAL>::call(Result, a, b, epsilon); + for(length_t i = 0; i < C; ++i) + Result[i] = all(equal(a[i], b[i], Epsilon[i])); return Result; } @@ -88,16 +35,17 @@ namespace detail } template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec notEqual(mat const& x, mat const& y, T epsilon) + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec notEqual(mat const& x, mat const& y, T Epsilon) { - return notEqual(x, y, vec(epsilon)); + return notEqual(x, y, vec(Epsilon)); } template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec notEqual(mat const& a, mat const& b, vec const& epsilon) + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec notEqual(mat const& a, mat const& b, vec const& Epsilon) { vec Result; - detail::loop_matrix_relational<0, C, detail::NOT_EQUAL>::call(Result, a, b, epsilon); + for(length_t i = 0; i < C; ++i) + Result[i] = any(notEqual(a[i], b[i], Epsilon[i])); return Result; } }//namespace glm diff --git a/glm/ext/vector_relational.inl b/glm/ext/vector_relational.inl index 49792be5..f38a97af 100644 --- a/glm/ext/vector_relational.inl +++ b/glm/ext/vector_relational.inl @@ -8,26 +8,26 @@ namespace glm { template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec equal(vec const& x, vec const& y, T epsilon) + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec equal(vec const& x, vec const& y, T Epsilon) { - return equal(x, y, vec(epsilon)); + return equal(x, y, vec(Epsilon)); } template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec equal(vec const& x, vec const& y, vec const& epsilon) + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec equal(vec const& x, vec const& y, vec const& Epsilon) { - return lessThanEqual(abs(x - y), epsilon); + return lessThanEqual(abs(x - y), Epsilon); } template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec notEqual(vec const& x, vec const& y, T epsilon) + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec notEqual(vec const& x, vec const& y, T Epsilon) { - return notEqual(x, y, vec(epsilon)); + return notEqual(x, y, vec(Epsilon)); } template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec notEqual(vec const& x, vec const& y, vec const& epsilon) + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec notEqual(vec const& x, vec const& y, vec const& Epsilon) { - return greaterThan(abs(x - y), epsilon); + return greaterThan(abs(x - y), Epsilon); } }//namespace glm diff --git a/test/core/core_cpp_constexpr.cpp b/test/core/core_cpp_constexpr.cpp index 3c2fa3d5..3dc0a92b 100644 --- a/test/core/core_cpp_constexpr.cpp +++ b/test/core/core_cpp_constexpr.cpp @@ -7,12 +7,30 @@ #include #include #include +#include #include +#include static int test_vec1() { int Error = 0; + { + constexpr glm::bvec1 B(true); + constexpr bool A = glm::all(B); + static_assert(A, "GLM: Failed constexpr"); + + constexpr glm::bvec1 D(true); + constexpr bool C = glm::any(D); + static_assert(C, "GLM: Failed constexpr"); + } + + { + constexpr glm::bvec2 C(true); + constexpr glm::bvec2 B(true); + static_assert(glm::any(glm::equal(C, B)), "GLM: Failed constexpr"); + } + { constexpr glm::ivec1 O(glm::ivec1(1)); static_assert(glm::ivec1(1) == O, "GLM: Failed constexpr"); @@ -154,6 +172,22 @@ static int test_vec2() { int Error = 0; + { + constexpr glm::bvec2 B(true); + constexpr bool A = glm::all(B); + static_assert(A, "GLM: Failed constexpr"); + + constexpr glm::bvec2 D(true, false); + constexpr bool C = glm::any(D); + static_assert(C, "GLM: Failed constexpr"); + } + + { + constexpr glm::bvec2 C(true); + constexpr glm::bvec2 B(true, false); + static_assert(glm::any(glm::equal(C, B)), "GLM: Failed constexpr"); + } + { constexpr glm::ivec2 O(glm::ivec1(1)); static_assert(glm::ivec2(1) == O, "GLM: Failed constexpr"); @@ -311,6 +345,22 @@ static int test_vec3() { int Error = 0; + { + constexpr glm::bvec3 B(true); + constexpr bool A = glm::all(B); + static_assert(A, "GLM: Failed constexpr"); + + constexpr glm::bvec3 D(true, false, true); + constexpr bool C = glm::any(D); + static_assert(C, "GLM: Failed constexpr"); + } + + { + constexpr glm::bvec3 C(true); + constexpr glm::bvec3 B(true, false, true); + static_assert(glm::any(glm::equal(C, B)), "GLM: Failed constexpr"); + } + { constexpr glm::ivec3 O(glm::ivec1(1)); static_assert(glm::ivec3(1) == O, "GLM: Failed constexpr"); @@ -487,6 +537,22 @@ static int test_vec3() static int test_vec4() { int Error = 0; + + { + constexpr glm::bvec4 B(true); + constexpr bool A = glm::all(B); + static_assert(A, "GLM: Failed constexpr"); + + constexpr glm::bvec4 D(true, false, true, false); + constexpr bool C = glm::any(D); + static_assert(C, "GLM: Failed constexpr"); + } + + { + constexpr glm::bvec4 C(true); + constexpr glm::bvec4 B(true, false, true, false); + static_assert(glm::any(glm::equal(C, B)), "GLM: Failed constexpr"); + } { constexpr glm::ivec4 O(glm::ivec4(1));