/*! \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 // up to 10 types template struct type_list { typedef T0 type_0; typedef T1 type_1; typedef T2 type_2; typedef T3 type_3; typedef T4 type_4; typedef T5 type_5; typedef T6 type_6; typedef T7 type_7; typedef T8 type_8; typedef T9 type_9; typedef T10 type_10; typedef T11 type_11; typedef T12 type_12; typedef T13 type_13; typedef T14 type_14; typedef T15 type_15; typedef T16 type_16; typedef T17 type_17; typedef T18 type_18; typedef T19 type_19; }; // this type provides a way of indexing // into a type_list template struct get_type { typedef null_type type; }; template struct get_type { typedef typename List::type_0 type; }; template struct get_type { typedef typename List::type_1 type; }; template struct get_type { typedef typename List::type_2 type; }; template struct get_type { typedef typename List::type_3 type; }; template struct get_type { typedef typename List::type_4 type; }; template struct get_type { typedef typename List::type_5 type; }; template struct get_type { typedef typename List::type_6 type; }; template struct get_type { typedef typename List::type_7 type; }; template struct get_type { typedef typename List::type_8 type; }; template struct get_type { typedef typename List::type_9 type; }; template struct get_type { typedef typename List::type_10 type; }; template struct get_type { typedef typename List::type_11 type; }; template struct get_type { typedef typename List::type_12 type; }; template struct get_type { typedef typename List::type_13 type; }; template struct get_type { typedef typename List::type_14 type; }; template struct get_type { typedef typename List::type_15 type; }; template struct get_type { typedef typename List::type_16 type; }; template struct get_type { typedef typename List::type_17 type; }; template struct get_type { typedef typename List::type_18 type; }; template struct get_type { typedef typename List::type_19 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