/*! \file meta.h * \brief Defines template classes * for metaprogramming in the * unit tests. */ #pragma once namespace unittest { // mark the absence of a type struct null_type {}; // this type encapsulates a list of // types template struct type_list { }; // this type provides a way of indexing // into a type_list template struct get_type { typedef null_type type; }; template struct get_type, 0> { typedef T type; }; template struct get_type, i> { typedef typename get_type, i - 1>::type type; }; // this type and its specialization provides a way to // iterate over a type_list, and // applying a unary function to each type template class Function, typename T, unsigned int i = 0> struct for_each_type { template void operator()(U n) { // run the function on type T Function f; f(n); // get the next type typedef typename get_type::type next_type; // recurse to i + 1 for_each_type loop; loop(n); } void operator()(void) { // run the function on type T Function f; f(); // get the next type typedef typename get_type::type next_type; // recurse to i + 1 for_each_type loop; loop(); } }; // terminal case: do nothing when encountering null_type template class Function, unsigned int i> struct for_each_type { template void operator()(U) { // no-op } void operator()(void) { // no-op } }; // this type and its specialization instantiates // a template by applying T to Template. // if T == null_type, then its result is also null_type template