Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Repeatedly calling a function with a non-type template parameter

I have a function with a non-type template parameter of type int, like so:

template <int N>
int foo() { /*...*/ }

I would like to unit test this function for all values of N from 0 to 32. I have a function int expected(int n) that takes the same N value and returns the expected value. Effectively, I want:

if (foo<0>() != expected(0)) { /* fail... */ }
if (foo<1>() != expected(1)) { /* fail... */ }
if (foo<2>() != expected(2)) { /* fail... */ }
// 30 more lines

I don't want to write out all 33 test cases by hand, and I can't easily use a runtime loop because N is compile time.

How can I get the compiler to generate the test cases for me in a simple way, without BOOST_PP_REPEAT-style tricks or code generation, in C++11?

like image 995
BeeOnRope Avatar asked Jan 26 '23 22:01

BeeOnRope


2 Answers

You can write a recursive function template with full specialization to perform the test. e.g.

template <int N>
void test() {
    test<N-1>();
    if (foo<N>() != expected(N)) { /* fail... */ }
}

template <>
void test<-1>() {
    // do nothing
}

and run it like

test<32>();
like image 122
songyuanyao Avatar answered Jan 31 '23 23:01

songyuanyao


In c++14 you can do something like this

#include <type_traits>

template <int beg, int end> struct static_for {
    template <typename Fn> void operator()(Fn const& fn) const {
        if (beg < end) {
            fn(std::integral_constant<int, beg>());
            static_for<beg + 1, end>()(fn);
        }
    }
};

template <int n> struct static_for<n, n> {
    template <typename Fn> void operator()(Fn const& fn) const {}
};

template <int N> int foo() { /*...*/
    return N;
}

int main() {
    static_for<0, 32>()([&](auto i) {
        if (foo<i>() != i) { /* fail... */
        }
    });
    return 0;
}
like image 25
Amos Avatar answered Jan 31 '23 21:01

Amos