diff --git a/src/Magnum/Math/Functions.h b/src/Magnum/Math/Functions.h index 284f09f72..eb62de90d 100644 --- a/src/Magnum/Math/Functions.h +++ b/src/Magnum/Math/Functions.h @@ -50,30 +50,13 @@ namespace Implementation { template<> struct Pow<0> { Pow() = delete; - template constexpr static T pow(T) { return 1; } + template constexpr static T pow(T) { return T(1); } }; template struct IsBoolVector: std::false_type {}; template struct IsBoolVector>: std::true_type {}; } -/** -@brief Integral power - -Returns integral power of base to the exponent. -*/ -template constexpr T pow(T base) { - return Implementation::Pow::pow(base); -} - -/** -@brief Power - -Returns power of @p base to the @p exponent. -@see @ref pow(T), @ref exp() -*/ -template T pow(T base, T exponent) { return std::pow(base, exponent); } - /** @brief Integral logarithm @@ -195,6 +178,46 @@ versions function exactly as their possible STL equivalents, vector overloads perform the operations component-wise. */ +/** +@brief Integral power + +Returns integral power of base to the exponent. +@see @ref pow(T, T) +*/ +#ifdef DOXYGEN_GENERATING_OUTPUT +template constexpr T pow(T base); +#else +template constexpr typename std::enable_if::value, T>::type pow(T base) { + return Implementation::Pow::pow(base); +} +template Vector pow(const Vector& base) { + Vector out{NoInit}; + for(std::size_t i = 0; i != size; ++i) + out[i] = Implementation::Pow::pow(base[i]); + return out; +} +#endif + +/** +@brief Power + +Returns power of @p base to the @p exponent. +@see @ref pow(T), @ref exp() +*/ +#ifdef DOXYGEN_GENERATING_OUTPUT +template T pow(T base, T exponent); +#else +template typename std::enable_if::value, T>::type pow(T base, T exponent) { + return std::pow(base, exponent); +} +template inline Vector pow(const Vector& base, T exponent) { + Vector out{NoInit}; + for(std::size_t i = 0; i != size; ++i) + out[i] = std::pow(base[i], exponent); + return out; +} +#endif + /** @brief Minimum diff --git a/src/Magnum/Math/Test/FunctionsTest.cpp b/src/Magnum/Math/Test/FunctionsTest.cpp index 12ed46427..2dd2c7eff 100644 --- a/src/Magnum/Math/Test/FunctionsTest.cpp +++ b/src/Magnum/Math/Test/FunctionsTest.cpp @@ -34,6 +34,9 @@ namespace Magnum { namespace Math { namespace Test { struct FunctionsTest: Corrade::TestSuite::Tester { explicit FunctionsTest(); + void powIntegral(); + void pow(); + void min(); void minList(); void max(); @@ -64,8 +67,6 @@ struct FunctionsTest: Corrade::TestSuite::Tester { void normalizeTypeDeduction(); - void powIntegral(); - void pow(); void logIntegral(); void log2(); void log(); @@ -85,7 +86,10 @@ typedef Math::Vector3 Vector3b; typedef Math::Vector3 Vector3i; FunctionsTest::FunctionsTest() { - addTests({&FunctionsTest::min, + addTests({&FunctionsTest::powIntegral, + &FunctionsTest::pow, + + &FunctionsTest::min, &FunctionsTest::minList, &FunctionsTest::max, &FunctionsTest::maxList, @@ -115,8 +119,6 @@ FunctionsTest::FunctionsTest() { &FunctionsTest::normalizeTypeDeduction, - &FunctionsTest::powIntegral, - &FunctionsTest::pow, &FunctionsTest::logIntegral, &FunctionsTest::log2, &FunctionsTest::log, @@ -126,6 +128,23 @@ FunctionsTest::FunctionsTest() { &FunctionsTest::trigonometricWithBase}); } +void FunctionsTest::powIntegral() { + CORRADE_COMPARE(Math::pow<10>(2ul), 1024ul); + CORRADE_COMPARE(Math::pow<0>(3ul), 1ul); + CORRADE_COMPARE(Math::pow<2>(2.0f), 4.0f); + + /* Constant expression */ + constexpr Int a = Math::pow<3>(5); + CORRADE_COMPARE(a, 125); + + CORRADE_COMPARE(Math::pow<2>(Vector3{2.0f, -3.0f, 1.5f}), (Vector3{4.0f, 9.0f, 2.25f})); +} + +void FunctionsTest::pow() { + CORRADE_COMPARE(Math::pow(2.0f, 0.5f), 1.414213562f); + CORRADE_COMPARE(Math::pow(Vector3{2.0f, 9.0f, 25.0f}, 0.5f), (Vector3{1.414213562f, 3.0f, 5.0f})); +} + void FunctionsTest::min() { CORRADE_COMPARE(Math::min(5, 9), 5); CORRADE_COMPARE(Math::min(Vector3i(5, -3, 2), Vector3i(9, -5, 18)), Vector3i(5, -5, 2)); @@ -437,20 +456,6 @@ void FunctionsTest::normalizeTypeDeduction() { CORRADE_COMPARE((Math::normalize('\x7F')), 1.0f); } -void FunctionsTest::powIntegral() { - CORRADE_COMPARE(Math::pow<10>(2ul), 1024ul); - CORRADE_COMPARE(Math::pow<0>(3ul), 1ul); - CORRADE_COMPARE(Math::pow<2>(2.0f), 4.0f); - - /* Constant expression */ - constexpr Int a = Math::pow<3>(5); - CORRADE_COMPARE(a, 125); -} - -void FunctionsTest::pow() { - CORRADE_COMPARE(Math::pow(2.0f, 0.5f), 1.414213562f); -} - void FunctionsTest::logIntegral() { CORRADE_COMPARE(Math::log(2, 256), 8ul); CORRADE_COMPARE(Math::log(256, 2), 0ul);