Skip to content

Instantly share code, notes, and snippets.

@ShaderManager
Created November 9, 2015 17:49
Show Gist options
  • Save ShaderManager/2494d775423218fabe54 to your computer and use it in GitHub Desktop.
Save ShaderManager/2494d775423218fabe54 to your computer and use it in GitHub Desktop.
Check if types are unique among sequence of types of variadic templates
namespace detail
{
template<typename Selector, typename A, typename B> using choose = typename std::conditional<Selector::value, A, B>::type;
struct empty {};
template<typename T> struct id {};
template<typename A, typename B> struct base : A, B {};
// Check if id<Head> is base class for type B. If it's true, then we have already instantiated Head type somewhere before this step
// In other case, we construct base type with base classes B and id<Head> and do recursive descend, while we have types to iterate
// Helper id<T> class is needed to support classes with multiple inheritance.
template<typename B, typename...> struct is_unique_impl;
template<typename B> struct is_unique_impl<B> : std::true_type {};
template<typename B, typename Head, typename... Rest> struct is_unique_impl<B, Head, Rest...> : choose<std::is_base_of<id<Head>, B>, std::false_type, is_unique_impl<base<B, id<Head>>, Rest...>>{};
template<typename InType, typename...> struct contains_impl;
template<typename InType> struct contains_impl<InType> : std::false_type{};
template<typename InType, typename Head, typename... Rest> struct contains_impl<InType, Head, Rest...> : choose<std::is_same<InType, Head>, std::true_type, contains_impl<InType, Rest...>>{};
}
template<typename... Types> struct is_unique: detail::is_unique_impl<detail::empty, Types...> {};
template<typename InType, typename... Types> struct contains : detail::contains_impl<InType, Types...> {};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment