Template code trimming

I’ve been talking about recursive templates and how to control code generation in the last three posts, and I thought of another technique. This shows how to use a separate template param to trim generated code for special cases. In this example the special case is caught by specializing the check_bounds<false> struct.

As usual I use the factorial function to illustrate. This is just an outline for a technique, so I did not pretty it up with namespaces and asserts.

# include <boost/cstdint.hpp>

typedef boost::uint_fast64_t uint_v;
const int max_n = 20;

template< bool XXX >
struct check_bounds {
    template< int N >
    static uint_v calc( ) { return calc< N - 1 >( ) * N; }

    template<>
    static uint_v calc< 0 >( ) { return 1; }
};

template<>
struct check_bounds< false > {
    template< int N >
    static uint_v calc( ) { return 0; }
};

template< int N >
uint_v factorial( )
{
    return
        check_bounds< (0 <= N) && (N <= max_n) >::calc< N >( );
}

This correctly calculates factorials 0..20, returns zero for all other values, and the compiler has no trouble with expressions like factorial< 1000000 >( ) and factorial< -1000000 >( ). It trims the code and avoids huge expansions. I talk about this more in yesterday’s Template recursion post.

Comments

Leave a Reply