#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;
};
int main() {
static_assert(std::is_same<
filter<std::is_integral, std::tuple, int, float, long>::type,
std::tuple<int, long> >::value, "");
}
I2luY2x1ZGUgPHR1cGxlPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CgogICAgdGVtcGxhdGUgPHRlbXBsYXRlIDxjbGFzcz4gY2xhc3MsCiAgICAgICAgICAgICAgdGVtcGxhdGUgPGNsYXNzLi4uPiBjbGFzcywKICAgICAgICAgICAgICBjbGFzcy4uLj4KICAgIHN0cnVjdCBmaWx0ZXI7CiAgICB0ZW1wbGF0ZSA8dGVtcGxhdGUgPGNsYXNzPiBjbGFzcyBQcmVkLCB0ZW1wbGF0ZSA8Y2xhc3MuLi4+IGNsYXNzIFZhcmlhZGljPgogICAgc3RydWN0IGZpbHRlcjxQcmVkLCBWYXJpYWRpYz4KICAgIHsKICAgICAgICB1c2luZyB0eXBlID0gVmFyaWFkaWM8PjsKICAgIH07CgogICAgdGVtcGxhdGUgPHRlbXBsYXRlIDxjbGFzcz4gY2xhc3MgUHJlZCwKICAgICAgICAgICAgICB0ZW1wbGF0ZSA8Y2xhc3MuLi4+IGNsYXNzIFZhcmlhZGljLAogICAgICAgICAgICAgIGNsYXNzIFQsIGNsYXNzLi4uIFRzPgogICAgc3RydWN0IGZpbHRlcjxQcmVkLCBWYXJpYWRpYywgVCwgVHMuLi4+CiAgICB7CiAgICAgICAgdGVtcGxhdGUgPGNsYXNzLCBjbGFzcz4gc3RydWN0IENvbnM7CiAgICAgICAgdGVtcGxhdGUgPGNsYXNzIEhlYWQsIGNsYXNzLi4uIFRhaWw+CiAgICAgICAgc3RydWN0IENvbnM8SGVhZCwgVmFyaWFkaWM8VGFpbC4uLj4gPgogICAgICAgIHsKICAgICAgICAgICAgdXNpbmcgdHlwZSA9IFZhcmlhZGljPEhlYWQsIFRhaWwuLi4+OwogICAgICAgIH07CiAgICAgICAgCiAgICAgICAgdXNpbmcgdHlwZSA9IHR5cGVuYW1lIHN0ZDo6Y29uZGl0aW9uYWw8CiAgICAgICAgICAgIFByZWQ8VD46OnZhbHVlLAogICAgICAgICAgICB0eXBlbmFtZSBDb25zPFQsIHR5cGVuYW1lIGZpbHRlcjxQcmVkLCBWYXJpYWRpYywgVHMuLi4+Ojp0eXBlPjo6dHlwZSwKICAgICAgICAgICAgdHlwZW5hbWUgZmlsdGVyPFByZWQsIFZhcmlhZGljLCBUcy4uLj46OnR5cGUgPjo6dHlwZTsKICAgIH07CgppbnQgbWFpbigpIHsKCSAgICBzdGF0aWNfYXNzZXJ0KHN0ZDo6aXNfc2FtZTwKICAgICAgICAgICAgICAgICAgZmlsdGVyPHN0ZDo6aXNfaW50ZWdyYWwsIHN0ZDo6dHVwbGUsIGludCwgZmxvYXQsIGxvbmc+Ojp0eXBlLAogICAgICAgICAgICAgICAgICBzdGQ6OnR1cGxlPGludCwgbG9uZz4gPjo6dmFsdWUsICIiKTsKfQ==