|
|
|
|
|
|
|
|
|
|
|
|
|
#pragma once |
|
|
|
namespace unittest |
|
{ |
|
|
|
|
|
struct null_type {}; |
|
|
|
|
|
|
|
template<typename... Ts> |
|
struct type_list |
|
{ |
|
}; |
|
|
|
|
|
|
|
template<typename List, unsigned int i> |
|
struct get_type |
|
{ |
|
typedef null_type type; |
|
}; |
|
|
|
template<typename T, typename... Ts> |
|
struct get_type<type_list<T, Ts...>, 0> |
|
{ |
|
typedef T type; |
|
}; |
|
|
|
template<typename T, typename... Ts, unsigned int i> |
|
struct get_type<type_list<T, Ts...>, i> |
|
{ |
|
typedef typename get_type<type_list<Ts...>, i - 1>::type 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) |
|
{ |
|
|
|
Function<T> f; |
|
f(n); |
|
|
|
|
|
typedef typename get_type<TypeList,i+1>::type next_type; |
|
|
|
|
|
for_each_type<TypeList, Function, next_type, i + 1> loop; |
|
loop(n); |
|
} |
|
|
|
void operator()(void) |
|
{ |
|
|
|
Function<T> f; |
|
f(); |
|
|
|
|
|
typedef typename get_type<TypeList,i+1>::type next_type; |
|
|
|
|
|
for_each_type<TypeList, Function, next_type, i + 1> loop; |
|
loop(); |
|
} |
|
}; |
|
|
|
|
|
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) |
|
{ |
|
|
|
} |
|
|
|
void operator()(void) |
|
{ |
|
|
|
} |
|
}; |
|
|
|
|
|
|
|
|
|
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; |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
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; |
|
}; |
|
|
|
|
|
|
|
template<typename TypeList, |
|
template <typename> class Template> |
|
struct transform1; |
|
|
|
template<typename... Ts, |
|
template <typename> class Template> |
|
struct transform1<type_list<Ts...>, Template> |
|
{ |
|
typedef type_list<typename ApplyTemplate1<Template, Ts>::type...> type; |
|
}; |
|
|
|
template<typename TypeList1, |
|
typename TypeList2, |
|
template <typename,typename> class Template> |
|
struct transform2; |
|
|
|
template<typename... T1s, |
|
typename... T2s, |
|
template <typename,typename> class Template> |
|
struct transform2<type_list<T1s...>, type_list<T2s...>, Template> |
|
{ |
|
typedef type_list<typename ApplyTemplate2<Template, T1s, T2s>::type...> type; |
|
}; |
|
|
|
} |
|
|
|
|