Spaces:
Runtime error
Runtime error
/*! \file meta.h | |
* \brief Defines template classes | |
* for metaprogramming in the | |
* unit tests. | |
*/ | |
namespace unittest | |
{ | |
// mark the absence of a type | |
struct null_type {}; | |
// this type encapsulates a list of | |
// up to 10 types | |
template<typename T0 = null_type, | |
typename T1 = null_type, | |
typename T2 = null_type, | |
typename T3 = null_type, | |
typename T4 = null_type, | |
typename T5 = null_type, | |
typename T6 = null_type, | |
typename T7 = null_type, | |
typename T8 = null_type, | |
typename T9 = null_type, | |
typename T10 = null_type, | |
typename T11 = null_type, | |
typename T12 = null_type, | |
typename T13 = null_type, | |
typename T14 = null_type, | |
typename T15 = null_type, | |
typename T16 = null_type, | |
typename T17 = null_type, | |
typename T18 = null_type, | |
typename T19 = null_type> | |
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<typename List, unsigned int i> | |
struct get_type | |
{ | |
typedef null_type type; | |
}; | |
template<typename List> struct get_type<List,0> { typedef typename List::type_0 type; }; | |
template<typename List> struct get_type<List,1> { typedef typename List::type_1 type; }; | |
template<typename List> struct get_type<List,2> { typedef typename List::type_2 type; }; | |
template<typename List> struct get_type<List,3> { typedef typename List::type_3 type; }; | |
template<typename List> struct get_type<List,4> { typedef typename List::type_4 type; }; | |
template<typename List> struct get_type<List,5> { typedef typename List::type_5 type; }; | |
template<typename List> struct get_type<List,6> { typedef typename List::type_6 type; }; | |
template<typename List> struct get_type<List,7> { typedef typename List::type_7 type; }; | |
template<typename List> struct get_type<List,8> { typedef typename List::type_8 type; }; | |
template<typename List> struct get_type<List,9> { typedef typename List::type_9 type; }; | |
template<typename List> struct get_type<List,10> { typedef typename List::type_10 type; }; | |
template<typename List> struct get_type<List,11> { typedef typename List::type_11 type; }; | |
template<typename List> struct get_type<List,12> { typedef typename List::type_12 type; }; | |
template<typename List> struct get_type<List,13> { typedef typename List::type_13 type; }; | |
template<typename List> struct get_type<List,14> { typedef typename List::type_14 type; }; | |
template<typename List> struct get_type<List,15> { typedef typename List::type_15 type; }; | |
template<typename List> struct get_type<List,16> { typedef typename List::type_16 type; }; | |
template<typename List> struct get_type<List,17> { typedef typename List::type_17 type; }; | |
template<typename List> struct get_type<List,18> { typedef typename List::type_18 type; }; | |
template<typename List> struct get_type<List,19> { 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<typename TypeList, | |
template <typename> class Function, | |
typename T, | |
unsigned int i = 0> | |
struct for_each_type | |
{ | |
template<typename U> | |
void operator()(U n) | |
{ | |
// run the function on type T | |
Function<T> f; | |
f(n); | |
// get the next type | |
typedef typename get_type<TypeList,i+1>::type next_type; | |
// recurse to i + 1 | |
for_each_type<TypeList, Function, next_type, i + 1> loop; | |
loop(n); | |
} | |
void operator()(void) | |
{ | |
// run the function on type T | |
Function<T> f; | |
f(); | |
// get the next type | |
typedef typename get_type<TypeList,i+1>::type next_type; | |
// recurse to i + 1 | |
for_each_type<TypeList, Function, next_type, i + 1> loop; | |
loop(); | |
} | |
}; | |
// terminal case: do nothing when encountering null_type | |
template<typename TypeList, | |
template <typename> class Function, | |
unsigned int i> | |
struct for_each_type<TypeList, Function, null_type, i> | |
{ | |
template<typename U> | |
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<template <typename> class Template, | |
typename T> | |
struct ApplyTemplate1 | |
{ | |
typedef Template<T> type; | |
}; | |
template<template <typename> class Template> | |
struct ApplyTemplate1<Template, null_type> | |
{ | |
typedef null_type type; | |
}; | |
// this type and its specializations instantiates | |
// a template by applying T1 & T2 to Template. | |
// if either T1 or T2 == null_type, then its result | |
// is also null_type | |
template<template <typename,typename> class Template, | |
typename T1, | |
typename T2> | |
struct ApplyTemplate2 | |
{ | |
typedef Template<T1,T2> type; | |
}; | |
template<template <typename,typename> class Template, | |
typename T> | |
struct ApplyTemplate2<Template, T, null_type> | |
{ | |
typedef null_type type; | |
}; | |
template<template <typename,typename> class Template, | |
typename T> | |
struct ApplyTemplate2<Template, null_type, T> | |
{ | |
typedef null_type type; | |
}; | |
template<template <typename,typename> class Template> | |
struct ApplyTemplate2<Template, null_type, null_type> | |
{ | |
typedef null_type type; | |
}; | |
// this type creates a new type_list by applying a Template to each of | |
// the Type_list's types | |
template<typename TypeList, | |
template <typename> class Template> | |
struct transform1 | |
{ | |
typedef typename ApplyTemplate1<Template, typename get_type<TypeList,0>::type>::type type_0; | |
typedef typename ApplyTemplate1<Template, typename get_type<TypeList,1>::type>::type type_1; | |
typedef typename ApplyTemplate1<Template, typename get_type<TypeList,2>::type>::type type_2; | |
typedef typename ApplyTemplate1<Template, typename get_type<TypeList,3>::type>::type type_3; | |
typedef typename ApplyTemplate1<Template, typename get_type<TypeList,4>::type>::type type_4; | |
typedef typename ApplyTemplate1<Template, typename get_type<TypeList,5>::type>::type type_5; | |
typedef typename ApplyTemplate1<Template, typename get_type<TypeList,6>::type>::type type_6; | |
typedef typename ApplyTemplate1<Template, typename get_type<TypeList,7>::type>::type type_7; | |
typedef typename ApplyTemplate1<Template, typename get_type<TypeList,8>::type>::type type_8; | |
typedef typename ApplyTemplate1<Template, typename get_type<TypeList,9>::type>::type type_9; | |
typedef typename ApplyTemplate1<Template, typename get_type<TypeList,10>::type>::type type_10; | |
typedef typename ApplyTemplate1<Template, typename get_type<TypeList,11>::type>::type type_11; | |
typedef typename ApplyTemplate1<Template, typename get_type<TypeList,12>::type>::type type_12; | |
typedef typename ApplyTemplate1<Template, typename get_type<TypeList,13>::type>::type type_13; | |
typedef typename ApplyTemplate1<Template, typename get_type<TypeList,14>::type>::type type_14; | |
typedef typename ApplyTemplate1<Template, typename get_type<TypeList,15>::type>::type type_15; | |
typedef typename ApplyTemplate1<Template, typename get_type<TypeList,16>::type>::type type_16; | |
typedef typename ApplyTemplate1<Template, typename get_type<TypeList,17>::type>::type type_17; | |
typedef typename ApplyTemplate1<Template, typename get_type<TypeList,18>::type>::type type_18; | |
typedef typename ApplyTemplate1<Template, typename get_type<TypeList,19>::type>::type type_19; | |
typedef type_list<type_0, type_1, type_2, type_3, type_4, type_5, type_6, type_7, type_8, type_9, | |
type_10, type_11, type_12, type_13, type_14, type_15, type_16, type_17, type_18, type_19> type; | |
}; | |
// this type creates a new type_list by applying a Template to each of | |
// two type_list's types | |
template<typename TypeList1, | |
typename TypeList2, | |
template <typename,typename> class Template> | |
struct transform2 | |
{ | |
typedef typename ApplyTemplate2<Template, typename get_type<TypeList1,0>::type, typename get_type<TypeList2,0>::type>::type type_0; | |
typedef typename ApplyTemplate2<Template, typename get_type<TypeList1,1>::type, typename get_type<TypeList2,1>::type>::type type_1; | |
typedef typename ApplyTemplate2<Template, typename get_type<TypeList1,2>::type, typename get_type<TypeList2,2>::type>::type type_2; | |
typedef typename ApplyTemplate2<Template, typename get_type<TypeList1,3>::type, typename get_type<TypeList2,3>::type>::type type_3; | |
typedef typename ApplyTemplate2<Template, typename get_type<TypeList1,4>::type, typename get_type<TypeList2,4>::type>::type type_4; | |
typedef typename ApplyTemplate2<Template, typename get_type<TypeList1,5>::type, typename get_type<TypeList2,5>::type>::type type_5; | |
typedef typename ApplyTemplate2<Template, typename get_type<TypeList1,6>::type, typename get_type<TypeList2,6>::type>::type type_6; | |
typedef typename ApplyTemplate2<Template, typename get_type<TypeList1,7>::type, typename get_type<TypeList2,7>::type>::type type_7; | |
typedef typename ApplyTemplate2<Template, typename get_type<TypeList1,8>::type, typename get_type<TypeList2,8>::type>::type type_8; | |
typedef typename ApplyTemplate2<Template, typename get_type<TypeList1,9>::type, typename get_type<TypeList2,9>::type>::type type_9; | |
typedef typename ApplyTemplate2<Template, typename get_type<TypeList1,10>::type, typename get_type<TypeList2,10>::type>::type type_10; | |
typedef typename ApplyTemplate2<Template, typename get_type<TypeList1,11>::type, typename get_type<TypeList2,11>::type>::type type_11; | |
typedef typename ApplyTemplate2<Template, typename get_type<TypeList1,12>::type, typename get_type<TypeList2,12>::type>::type type_12; | |
typedef typename ApplyTemplate2<Template, typename get_type<TypeList1,13>::type, typename get_type<TypeList2,13>::type>::type type_13; | |
typedef typename ApplyTemplate2<Template, typename get_type<TypeList1,14>::type, typename get_type<TypeList2,14>::type>::type type_14; | |
typedef typename ApplyTemplate2<Template, typename get_type<TypeList1,15>::type, typename get_type<TypeList2,15>::type>::type type_15; | |
typedef typename ApplyTemplate2<Template, typename get_type<TypeList1,16>::type, typename get_type<TypeList2,16>::type>::type type_16; | |
typedef typename ApplyTemplate2<Template, typename get_type<TypeList1,17>::type, typename get_type<TypeList2,17>::type>::type type_17; | |
typedef typename ApplyTemplate2<Template, typename get_type<TypeList1,18>::type, typename get_type<TypeList2,18>::type>::type type_18; | |
typedef typename ApplyTemplate2<Template, typename get_type<TypeList1,19>::type, typename get_type<TypeList2,19>::type>::type type_19; | |
typedef type_list<type_0, type_1, type_2, type_3, type_4, type_5, type_6, type_7, type_8, type_9, | |
type_10, type_11, type_12, type_13, type_14, type_15, type_16, type_17, type_18, type_19> type; | |
}; | |
} // end unittest | |