Search code examples
c++boostboost-test

Is there a way to test nontype templates using Boost Test?


I am using Boost Unit Test to perform unit test for my project. I need to test some non-type templates, however seems that using the macro BOOST_AUTO_TEST_CASE_TEMPLATE(test_case_name, formal_type_parameter_name, collection_of_types) I can test only typed templates. I want to use a collection_of_types not composed by { int, float, ...}, but {0,1,2, ...}.

Here an example of what I want to do:

#include <boost/test/included/unit_test.hpp>
#include <boost/mpl/list.hpp>

typedef boost::mpl::list<0, 1, 2, 4, 6> test_types;

BOOST_AUTO_TEST_CASE_TEMPLATE( my_test, T, test_types )
{
  test_template<T>* test_tmpl = new test_template<T>();

  // other code
}

Solution

  • You can always wrap static constants in a type. For integral types there is std::integral_constant or indeed the Boost MPL analog:

    Live On Coliru

    #define BOOST_TEST_MODULE sotest
    #define BOOST_TEST_MAIN
    
    #include <boost/mpl/list.hpp>
    #include <boost/test/included/unit_test.hpp>
    
    template <int> struct test_template {};
    
    typedef boost::mpl::list<
        boost::mpl::integral_c<int, 0>,
        boost::mpl::integral_c<int, 1>,
        boost::mpl::integral_c<int, 2>,
        boost::mpl::integral_c<int, 4>,
        boost::mpl::integral_c<int, 6>
    > test_types;
    
    BOOST_AUTO_TEST_CASE_TEMPLATE(my_test, T, test_types) {
        test_template<T::value>* test_tmpl = new test_template<T::value>();
    
        // other code
        delete test_tmpl;
    }
    

    Prints

    Running 5 test cases...
    
    *** No errors detected
    

    BONUS Tip

    To save on typing you can use a variadic template alias:

    template <typename T, T... vv> using vlist =
        boost::mpl::list<boost::mpl::integral_c<T, vv>... >;
    

    Now you can define the list as:

    Live On Coliru

    using test_types = vlist<int, 0, 1, 2, 4, 6>;