Search code examples
c++variadic-templatestemplate-meta-programmingc++20parameter-pack

Filter types in a parameter pack


Im trying create a filtered type of a variadic template/parameter pack and also preserve ordering.

// example what im trying to accomplish
template<typename... Args>
struct query
{
    using filtered = typename filtered<std::is_integral_v, Args...>
}

In this example filtered would filter all integral types eg.

query<int, A, B>::filtered == query<A, B>::filtered

How can I create a util like this or something that would achieve the same results


Solution

  • Comment by @Jarod42 has demo with working code

    #include <tuple>
    #include <type_traits>
    
    template<template<class> class, template<class...> class, class...>
    struct filter;
    template<template<class> class Pred, template<class...> class Variadic>
    struct filter<Pred, Variadic>
    {
        using type = Variadic<>;
    };
    
    template<template<class> class Pred,
             template<class...> class Variadic,
             class T,
             class... Ts>
    struct filter<Pred, Variadic, T, Ts...>
    {
        template<class, class>
        struct Cons;
        template<class Head, class... Tail>
        struct Cons<Head, Variadic<Tail...>>
        {
            using type = Variadic<Head, Tail...>;
        };
    
        using type = typename std::conditional<
          Pred<T>::value,
          typename Cons<T, typename filter<Pred, Variadic, Ts...>::type>::type,
          typename filter<Pred, Variadic, Ts...>::type>::type;
    };
    

    And integration with my example

    
    template<typename... Args>
    struct query
    {
        using filtered = filter<std::is_integral, std::tuple, Args...>::type
    }