From f87ff27d852627e634c8aee05b6de3283bca8e92 Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Fri, 8 Aug 2014 12:55:36 +0300 Subject: [PATCH] [test][util] add unit test for the ipower metafunction in the util namespace --- test/util/ipower.cpp | 145 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 test/util/ipower.cpp diff --git a/test/util/ipower.cpp b/test/util/ipower.cpp new file mode 100644 index 000000000..b8c85174c --- /dev/null +++ b/test/util/ipower.cpp @@ -0,0 +1,145 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) +// Unit Test + +// Copyright (c) 2014, Oracle and/or its affiliates. + +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle + +// Licensed under the Boost Software License version 1.0. +// http://www.boost.org/users/license.html + +#if defined(DO_NOT_USE_BOOST_TEST) +# include +#else +# ifndef BOOST_TEST_MODULE +# define BOOST_TEST_MODULE test_mpl_ipower +# endif +# include +#endif // DO_NOT_USE_BOOST_TEST + + +#include + +#include +#include + +#include +#include +#include + +namespace bg = boost::geometry; + + +// this is the function implemented with MPL (in non-recursive form) +template +T ipower(const T& x, std::size_t n) +{ + T z(1); + if ( n == 0 ) { return z; } + + T y = x; + + while (n > 1) + { + if ( n % 2 == 1 ) + { + z *= y; + } + y *= y; + n /= 2; + } + + return z * y; +} + + +template +struct test_power +{ + static inline void apply() + { + typedef typename T::value_type value_type; + + value_type const value = T::value; + + value_type result_from_mpl = bg::util::ipower::value; + value_type result_from_function = ::ipower(value, Power); + +#ifdef BOOST_GEOMETRY_TEST_DEBUG + std::cout << "pow[function](" << value << ", " << Power << ") = " + << result_from_function + << std::endl; + + std::cout << "pow[mpl](" << value << ", " << Power << ") = " + << result_from_mpl + << std::endl; + std::cout << std::endl; +#endif + +#if defined(DO_NOT_USE_BOOST_TEST) + assert( result_from_mpl == result_from_function ); +#else + BOOST_CHECK( result_from_mpl == result_from_function ); +#endif // DO_NOT_USE_BOOST_TEST + } +}; + +void test_ipower() +{ + typedef boost::mpl::int_<-1> negative_one; + typedef boost::mpl::size_t<2> two; + typedef boost::mpl::long_<4> four; + + test_power::apply(); + test_power::apply(); + test_power::apply(); + test_power::apply(); + test_power::apply(); + test_power::apply(); + test_power::apply(); + test_power::apply(); + test_power::apply(); + + test_power::apply(); + test_power::apply(); + +#ifdef BOOST_GEOMETRY_TEST_DEBUG + // print out the max possible value for std::size_t + std::cout << "max value for std::size_t = " + << std::numeric_limits::max() << std::endl; + std::cout << std::endl; +#endif + + test_power::apply(); + + test_power::apply(); +#if defined(DO_NOT_USE_BOOST_TEST) + // test for very high power value; the template depth should not + // be a problem as we only require log2(exponent) nested templates + // + // b2 takes forever to compile the ones below; however, both g++ + // and clang++ when invoked from the command line just do it + test_power::apply(); + test_power::apply(); + test_power::apply(); +#endif // DO_NOT_USE_BOOST_TEST + +#if false + // the following does not compile as expected + test_power, 0>::apply(); +#endif +} + + +#if defined(DO_NOT_USE_BOOST_TEST) +int main() +{ + test_ipower(); + return 0; +} +#else +BOOST_AUTO_TEST_CASE( test_ipower_all ) +{ + test_ipower(); +} +#endif // DO_NOT_USE_BOOST_TEST