Skip to content

Instantly share code, notes, and snippets.

@tejacques
Created September 5, 2016 20:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tejacques/2a646c9a8e3948a2245534e932c70370 to your computer and use it in GitHub Desktop.
Save tejacques/2a646c9a8e3948a2245534e932c70370 to your computer and use it in GitHub Desktop.
#include <type_traits>
template <typename...TArgs>
struct TypeList {};
// Assume TElement is not in the list unless proven otherwise
template < typename TElement, typename TList >
struct ContainsType {
static constexpr bool value = false;
};
// If it matches the first type, it is definitely in the list
template < typename TElement, typename... TTail >
struct ContainsType < TElement, TypeList < TElement, TTail... > >
{
static constexpr bool value = true;
};
// If it is not the first element, check the remaining list
template < typename TElement, typename THead, typename... TTail >
struct ContainsType < TElement, TypeList < THead, TTail... > >
{
static constexpr bool value = (ContainsType < TElement, TypeList < TTail... > >::value);
};
template <typename ...Types>
struct TypeAdder;
template<class ...Types>
struct BuilderType {};
template<typename ...Types>
struct BuilderType<TypeList<Types...> > {
typedef TypeAdder<Types...> TypeAdder;
};
template<typename T, typename TList>
struct AddType;
template<typename T, typename ... TArgs>
struct AddType< T, TypeList<TArgs...> >
{
typedef typename std::conditional<
ContainsType<T, TypeList<TArgs...> >::value,
TypeList<TArgs... >,
TypeList<T, TArgs... >
>::type type;
};
template <typename ...Types>
struct TypeAdder
{
template <typename T>
using with = typename BuilderType<typename AddType<T, TypeList<Types...> >::type>::TypeAdder;
int value;
};
struct A {
int a;
};
struct B {
int b;
};
int main()
{
TypeAdder<>
::with<A>
::with<B> b;
b.value = 0;
return b.value;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment