diff --git a/glm/ext/vector_integer.hpp b/glm/ext/vector_integer.hpp index c5df1b81..d7ada3c0 100644 --- a/glm/ext/vector_integer.hpp +++ b/glm/ext/vector_integer.hpp @@ -101,7 +101,7 @@ namespace glm /// @param v Source values to which is applied the function /// @param Multiple Must be a null or positive value template - GLM_FUNC_DECL vec prevMultiple(vec const& v, T const& Multiple); + GLM_FUNC_DECL vec prevMultiple(vec const& v, T Multiple); /// Lower multiple number of Source. /// diff --git a/glm/ext/vector_integer.inl b/glm/ext/vector_integer.inl index 0d4d7d67..4da314b6 100644 --- a/glm/ext/vector_integer.inl +++ b/glm/ext/vector_integer.inl @@ -1,223 +1,7 @@ -/// @ref gtc_round +#include "scalar_integer.hpp" -#include "../integer.hpp" - -namespace glm{ -namespace detail +namespace glm { - template - struct compute_ceilShift - { - GLM_FUNC_QUALIFIER static vec call(vec const& v, T) - { - return v; - } - }; - - template - struct compute_ceilShift - { - GLM_FUNC_QUALIFIER static vec call(vec const& v, T Shift) - { - return v | (v >> Shift); - } - }; - - template - struct compute_ceilPowerOfTwo - { - GLM_FUNC_QUALIFIER static vec call(vec const& x) - { - GLM_STATIC_ASSERT(!std::numeric_limits::is_iec559, "'ceilPowerOfTwo' only accept integer scalar or vector inputs"); - - vec const Sign(sign(x)); - - vec v(abs(x)); - - v = v - static_cast(1); - v = v | (v >> static_cast(1)); - v = v | (v >> static_cast(2)); - v = v | (v >> static_cast(4)); - v = compute_ceilShift= 2>::call(v, 8); - v = compute_ceilShift= 4>::call(v, 16); - v = compute_ceilShift= 8>::call(v, 32); - return (v + static_cast(1)) * Sign; - } - }; - - template - struct compute_ceilPowerOfTwo - { - GLM_FUNC_QUALIFIER static vec call(vec const& x) - { - GLM_STATIC_ASSERT(!std::numeric_limits::is_iec559, "'ceilPowerOfTwo' only accept integer scalar or vector inputs"); - - vec v(x); - - v = v - static_cast(1); - v = v | (v >> static_cast(1)); - v = v | (v >> static_cast(2)); - v = v | (v >> static_cast(4)); - v = compute_ceilShift= 2>::call(v, 8); - v = compute_ceilShift= 4>::call(v, 16); - v = compute_ceilShift= 8>::call(v, 32); - return v + static_cast(1); - } - }; - - template - struct compute_ceilMultiple{}; - - template<> - struct compute_ceilMultiple - { - template - GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple) - { - if(Source > genType(0)) - return Source + (Multiple - std::fmod(Source, Multiple)); - else - return Source + std::fmod(-Source, Multiple); - } - }; - - template<> - struct compute_ceilMultiple - { - template - GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple) - { - genType Tmp = Source - genType(1); - return Tmp + (Multiple - (Tmp % Multiple)); - } - }; - - template<> - struct compute_ceilMultiple - { - template - GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple) - { - if(Source > genType(0)) - { - genType Tmp = Source - genType(1); - return Tmp + (Multiple - (Tmp % Multiple)); - } - else - return Source + (-Source % Multiple); - } - }; - - template - struct compute_floorMultiple{}; - - template<> - struct compute_floorMultiple - { - template - GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple) - { - if(Source >= genType(0)) - return Source - std::fmod(Source, Multiple); - else - return Source - std::fmod(Source, Multiple) - Multiple; - } - }; - - template<> - struct compute_floorMultiple - { - template - GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple) - { - if(Source >= genType(0)) - return Source - Source % Multiple; - else - { - genType Tmp = Source + genType(1); - return Tmp - Tmp % Multiple - Multiple; - } - } - }; - - template<> - struct compute_floorMultiple - { - template - GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple) - { - if(Source >= genType(0)) - return Source - Source % Multiple; - else - { - genType Tmp = Source + genType(1); - return Tmp - Tmp % Multiple - Multiple; - } - } - }; - - template - struct compute_roundMultiple{}; - - template<> - struct compute_roundMultiple - { - template - GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple) - { - if(Source >= genType(0)) - return Source - std::fmod(Source, Multiple); - else - { - genType Tmp = Source + genType(1); - return Tmp - std::fmod(Tmp, Multiple) - Multiple; - } - } - }; - - template<> - struct compute_roundMultiple - { - template - GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple) - { - if(Source >= genType(0)) - return Source - Source % Multiple; - else - { - genType Tmp = Source + genType(1); - return Tmp - Tmp % Multiple - Multiple; - } - } - }; - - template<> - struct compute_roundMultiple - { - template - GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple) - { - if(Source >= genType(0)) - return Source - Source % Multiple; - else - { - genType Tmp = Source + genType(1); - return Tmp - Tmp % Multiple - Multiple; - } - } - }; -}//namespace detail - - //////////////// - // isPowerOfTwo - - template - GLM_FUNC_QUALIFIER bool isPowerOfTwo(genType Value) - { - genType const Result = glm::abs(Value); - return !(Result & (Result - 1)); - } - template GLM_FUNC_QUALIFIER vec isPowerOfTwo(vec const& Value) { @@ -225,63 +9,16 @@ namespace detail return equal(Result & (Result - 1), vec(0)); } - ////////////////// - // ceilPowerOfTwo - - template - GLM_FUNC_QUALIFIER genType ceilPowerOfTwo(genType value) - { - return detail::compute_ceilPowerOfTwo<1, genType, defaultp, std::numeric_limits::is_signed>::call(vec<1, genType, defaultp>(value)).x; - } - template - GLM_FUNC_QUALIFIER vec ceilPowerOfTwo(vec const& v) + GLM_FUNC_QUALIFIER vec nextPowerOfTwo(vec const& v) { return detail::compute_ceilPowerOfTwo::is_signed>::call(v); } - /////////////////// - // floorPowerOfTwo - - template - GLM_FUNC_QUALIFIER genType floorPowerOfTwo(genType value) - { - return isPowerOfTwo(value) ? value : static_cast(1) << findMSB(value); - } - template - GLM_FUNC_QUALIFIER vec floorPowerOfTwo(vec const& v) + GLM_FUNC_QUALIFIER vec prevPowerOfTwo(vec const& v) { - return detail::functor1::call(floorPowerOfTwo, v); - } - - /////////////////// - // roundPowerOfTwo - - template - GLM_FUNC_QUALIFIER genIUType roundPowerOfTwo(genIUType value) - { - if(isPowerOfTwo(value)) - return value; - - genIUType const prev = static_cast(1) << findMSB(value); - genIUType const next = prev << static_cast(1); - return (next - value) < (value - prev) ? next : prev; - } - - template - GLM_FUNC_QUALIFIER vec roundPowerOfTwo(vec const& v) - { - return detail::functor1::call(roundPowerOfTwo, v); - } - - //////////////// - // isMultiple - - template - GLM_FUNC_QUALIFIER bool isMultiple(genType Value, genType Multiple) - { - return isMultiple(vec<1, genType>(Value), vec<1, genType>(Multiple)).x; + return detail::functor1::call(prevPowerOfTwo, v); } template @@ -296,48 +33,27 @@ namespace detail return (Value % Multiple) == vec(0); } - ////////////////////// - // ceilMultiple - - template - GLM_FUNC_QUALIFIER genType ceilMultiple(genType Source, genType Multiple) + template + GLM_FUNC_QUALIFIER vec nextMultiple(vec const& Source, T Multiple) { - return detail::compute_ceilMultiple::is_iec559, std::numeric_limits::is_signed>::call(Source, Multiple); + return detail::functor2::call(nextMultiple, Source, vec(Multiple)); } template - GLM_FUNC_QUALIFIER vec ceilMultiple(vec const& Source, vec const& Multiple) + GLM_FUNC_QUALIFIER vec nextMultiple(vec const& Source, vec const& Multiple) { - return detail::functor2::call(ceilMultiple, Source, Multiple); - } - - ////////////////////// - // floorMultiple - - template - GLM_FUNC_QUALIFIER genType floorMultiple(genType Source, genType Multiple) - { - return detail::compute_floorMultiple::is_iec559, std::numeric_limits::is_signed>::call(Source, Multiple); + return detail::functor2::call(nextMultiple, Source, Multiple); } template - GLM_FUNC_QUALIFIER vec floorMultiple(vec const& Source, vec const& Multiple) + GLM_FUNC_QUALIFIER vec prevMultiple(vec const& Source, T Multiple) { - return detail::functor2::call(floorMultiple, Source, Multiple); - } - - ////////////////////// - // roundMultiple - - template - GLM_FUNC_QUALIFIER genType roundMultiple(genType Source, genType Multiple) - { - return detail::compute_roundMultiple::is_iec559, std::numeric_limits::is_signed>::call(Source, Multiple); + return detail::functor2::call(prevMultiple, Source, vec(Multiple)); } template - GLM_FUNC_QUALIFIER vec roundMultiple(vec const& Source, vec const& Multiple) + GLM_FUNC_QUALIFIER vec prevMultiple(vec const& Source, vec const& Multiple) { - return detail::functor2::call(roundMultiple, Source, Multiple); + return detail::functor2::call(prevMultiple, Source, Multiple); } }//namespace glm diff --git a/test/ext/ext_vector_integer.cpp b/test/ext/ext_vector_integer.cpp index 642499f7..278379a6 100644 --- a/test/ext/ext_vector_integer.cpp +++ b/test/ext/ext_vector_integer.cpp @@ -1,211 +1,309 @@ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include -template -static int test_operators() +namespace isPowerOfTwo { - int Error = 0; - + template + struct type { - genType const A(1); - genType const B(1); + genType Value; + bool Return; + }; - bool const R = A != B; - bool const S = A == B; - Error += (S && !R) ? 0 : 1; + int test_int16() + { + type const Data[] = + { + { 0x0001, true }, + { 0x0002, true }, + { 0x0004, true }, + { 0x0080, true }, + { 0x0000, true }, + { 0x0003, false } + }; + + int Error = 0; + + for (std::size_t i = 0, n = sizeof(Data) / sizeof(type); i < n; ++i) + { + bool Result = glm::isPowerOfTwo(Data[i].Value); + Error += Data[i].Return == Result ? 0 : 1; + } + + return Error; } + int test_uint16() { - genType const A(1); - genType const B(1); + type const Data[] = + { + { 0x0001, true }, + { 0x0002, true }, + { 0x0004, true }, + { 0x0000, true }, + { 0x0000, true }, + { 0x0003, false } + }; - genType const C = A + B; - Error += C == genType(2) ? 0 : 1; + int Error = 0; - genType const D = A - B; - Error += D == genType(0) ? 0 : 1; + for (std::size_t i = 0, n = sizeof(Data) / sizeof(type); i < n; ++i) + { + bool Result = glm::isPowerOfTwo(Data[i].Value); + Error += Data[i].Return == Result ? 0 : 1; + } - genType const E = A * B; - Error += E == genType(1) ? 0 : 1; - - genType const F = A / B; - Error += F == genType(1) ? 0 : 1; + return Error; } + int test_int32() { - genType const A(3); - genType const B(2); + type const Data[] = + { + { 0x00000001, true }, + { 0x00000002, true }, + { 0x00000004, true }, + { 0x0000000f, false }, + { 0x00000000, true }, + { 0x00000003, false } + }; - genType const C = A % B; - Error += C == genType(1) ? 0 : 1; + int Error = 0; + + for (std::size_t i = 0, n = sizeof(Data) / sizeof(type); i < n; ++i) + { + bool Result = glm::isPowerOfTwo(Data[i].Value); + Error += Data[i].Return == Result ? 0 : 1; + } + + return Error; } + int test_uint32() { - genType const A(1); - genType const B(1); - genType const C(0); + type const Data[] = + { + { 0x00000001, true }, + { 0x00000002, true }, + { 0x00000004, true }, + { 0x80000000, true }, + { 0x00000000, true }, + { 0x00000003, false } + }; - genType const I = A & B; - Error += I == genType(1) ? 0 : 1; - genType const D = A & C; - Error += D == genType(0) ? 0 : 1; + int Error = 0; - genType const E = A | B; - Error += E == genType(1) ? 0 : 1; - genType const F = A | C; - Error += F == genType(1) ? 0 : 1; + for (std::size_t i = 0, n = sizeof(Data) / sizeof(type); i < n; ++i) + { + bool Result = glm::isPowerOfTwo(Data[i].Value); + Error += Data[i].Return == Result ? 0 : 1; + } - genType const G = A ^ B; - Error += G == genType(0) ? 0 : 1; - genType const H = A ^ C; - Error += H == genType(1) ? 0 : 1; + return Error; } + int test() { - genType const A(0); - genType const B(1); - genType const C(2); + int Error = 0; - genType const D = B << B; - Error += D == genType(2) ? 0 : 1; - genType const E = C >> B; - Error += E == genType(1) ? 0 : 1; + Error += test_int16(); + Error += test_uint16(); + Error += test_int32(); + Error += test_uint32(); + + return Error; + } +}//isPowerOfTwo + +namespace prevPowerOfTwo +{ + template + int run() + { + int Error = 0; + + T const A = glm::prevPowerOfTwo(static_cast(7)); + Error += A == static_cast(4) ? 0 : 1; + + T const B = glm::prevPowerOfTwo(static_cast(15)); + Error += B == static_cast(8) ? 0 : 1; + + T const C = glm::prevPowerOfTwo(static_cast(31)); + Error += C == static_cast(16) ? 0 : 1; + + T const D = glm::prevPowerOfTwo(static_cast(32)); + Error += D == static_cast(32) ? 0 : 1; + + return Error; } - return Error; -} + int test() + { + int Error = 0; -template -static int test_ctor() + Error += run(); + Error += run(); + Error += run(); + Error += run(); + + Error += run(); + Error += run(); + Error += run(); + Error += run(); + + return Error; + } +}//namespace prevPowerOfTwo + +namespace nextPowerOfTwo { - typedef typename genType::value_type T; - - int Error = 0; + template + int run() + { + int Error = 0; - genType const A = genType(1); + T const A = glm::nextPowerOfTwo(static_cast(7)); + Error += A == static_cast(8) ? 0 : 1; - genType const E(genType(1)); - Error += A == E ? 0 : 1; + T const B = glm::nextPowerOfTwo(static_cast(15)); + Error += B == static_cast(16) ? 0 : 1; - genType const F(E); - Error += A == F ? 0 : 1; + T const C = glm::nextPowerOfTwo(static_cast(31)); + Error += C == static_cast(32) ? 0 : 1; - genType const B = genType(1); - genType const G(glm::vec<2, T>(1)); - Error += B == G ? 0 : 1; + T const D = glm::nextPowerOfTwo(static_cast(32)); + Error += D == static_cast(32) ? 0 : 1; - genType const H(glm::vec<3, T>(1)); - Error += B == H ? 0 : 1; + return Error; + } - genType const I(glm::vec<4, T>(1)); - Error += B == I ? 0 : 1; + int test() + { + int Error = 0; - return Error; -} + Error += run(); + Error += run(); + Error += run(); + Error += run(); -template -static int test_size() + Error += run(); + Error += run(); + Error += run(); + Error += run(); + + return Error; + } +}//namespace nextPowerOfTwo + +namespace prevMultiple { - int Error = 0; + template + struct type + { + genIUType Source; + genIUType Multiple; + genIUType Return; + }; - Error += sizeof(typename genType::value_type) == sizeof(genType) ? 0 : 1; - Error += genType().length() == 1 ? 0 : 1; - Error += genType::length() == 1 ? 0 : 1; + template + int run() + { + type const Data[] = + { + { 8, 3, 6 }, + { 7, 7, 7 } + }; - return Error; -} + int Error = 0; -template -static int test_relational() + for (std::size_t i = 0, n = sizeof(Data) / sizeof(type); i < n; ++i) + { + glm::vec<4, T> const Result = glm::prevMultiple(glm::vec<4, T>(Data[i].Source), Data[i].Multiple); + Error += glm::vec<4, T>(Data[i].Return) == Result ? 0 : 1; + } + + return Error; + } + + int test() + { + int Error = 0; + + Error += run(); + Error += run(); + Error += run(); + Error += run(); + + Error += run(); + Error += run(); + Error += run(); + Error += run(); + + return Error; + } +}//namespace prevMultiple + +namespace nextMultiple { - int Error = 0; + template + struct type + { + genIUType Source; + genIUType Multiple; + genIUType Return; + }; - genType const A(1); - genType const B(1); - genType const C(0); + template + int run() + { + type const Data[] = + { + { 8, 3, 6 }, + { 7, 7, 7 } + }; - Error += A == B ? 0 : 1; - Error += A != C ? 0 : 1; - Error += all(equal(A, B)) ? 0 : 1; - Error += any(notEqual(A, C)) ? 0 : 1; + int Error = 0; - return Error; -} + for (std::size_t i = 0, n = sizeof(Data) / sizeof(type); i < n; ++i) + { + glm::vec<4, T> const Result = glm::nextMultiple(glm::vec<4, T>(Data[i].Source), Data[i].Multiple); + Error += glm::vec<4, T>(Data[i].Return) == Result ? 0 : 1; + } -template -static int test_constexpr() -{ -# if GLM_CONFIG_CONSTEXP == GLM_ENABLE - static_assert(genType::length() == 1, "GLM: Failed constexpr"); - static_assert(genType(1)[0] == 1, "GLM: Failed constexpr"); - static_assert(genType(1) == genType(1), "GLM: Failed constexpr"); - static_assert(genType(1) != genType(0), "GLM: Failed constexpr"); -# endif + return Error; + } - return 0; -} + int test() + { + int Error = 0; + + Error += run(); + Error += run(); + Error += run(); + Error += run(); + + Error += run(); + Error += run(); + Error += run(); + Error += run(); + + return Error; + } +}//namespace nextMultiple int main() { int Error = 0; - Error += test_operators(); - Error += test_operators(); - Error += test_operators(); - Error += test_operators(); + Error += isPowerOfTwo::test(); + Error += prevPowerOfTwo::test(); + Error += nextPowerOfTwo::test(); + Error += prevMultiple::test(); + Error += nextMultiple::test(); - Error += test_ctor(); - Error += test_ctor(); - Error += test_ctor(); - Error += test_ctor(); - - Error += test_size(); - Error += test_size(); - Error += test_size(); - Error += test_size(); - - Error += test_relational(); - Error += test_relational(); - Error += test_relational(); - Error += test_relational(); - - Error += test_constexpr(); - Error += test_constexpr(); - Error += test_constexpr(); - Error += test_constexpr(); - - Error += test_operators(); - Error += test_operators(); - Error += test_operators(); - Error += test_operators(); - - Error += test_ctor(); - Error += test_ctor(); - Error += test_ctor(); - Error += test_ctor(); - - Error += test_size(); - Error += test_size(); - Error += test_size(); - Error += test_size(); - - Error += test_relational(); - Error += test_relational(); - Error += test_relational(); - Error += test_relational(); - - Error += test_constexpr(); - Error += test_constexpr(); - Error += test_constexpr(); - Error += test_constexpr(); - return Error; } diff --git a/test/ext/ext_vector_integer_sized.cpp b/test/ext/ext_vector_integer_sized.cpp index 39f11086..4793646c 100644 --- a/test/ext/ext_vector_integer_sized.cpp +++ b/test/ext/ext_vector_integer_sized.cpp @@ -1,14 +1,8 @@ +#include #include #include -#include -#include -#include #include #include -#include -#include -#include -#include template static int test_operators()