Behold, the power of C++!

`#include <type_traits>`

template <typename ...Ts>

struct List;

template <typename T, typename ...Ts>

struct List<T, Ts...>

{

constexpr static

unsigned size = 1 + List<Ts...>::size;

using Head = T;

using Tail = List<Ts...>;

};

template <>

struct List<>

{

constexpr static

unsigned size = 0;

};

template <typename T, typename ...Ts>

auto consHelper(List<Ts...>)

{

return List<T, Ts...>{};

}

template <typename T, typename L>

using Cons = decltype(consHelper<T>(L{}));

template <typename Fn>

auto mapHelper(List<> = {})

{

return List<>{};

}

template <typename Fn, typename T, typename ...Ts>

auto mapHelper(List<T, Ts...> = {})

{

return Cons<

typename Fn::template Template<T>,

decltype(mapHelper<Fn, Ts...>())

>{};

}

template <typename Fn, typename L>

using Map = decltype(mapHelper<Fn>(L{}));

struct AddPtr

{

template <typename T>

using Template = T*;

};

using PtrList = Map<AddPtr, List<int, void, char, double>>;

void f(PtrList)

{}

template <typename Fn>

auto filterHelper(List<> = {})

{

return List<>{};

}

template <typename Fn, typename T, typename ...Ts>

auto filterHelper(List<T, Ts...> = {})

{

return std::conditional_t<

Fn::template Template<T>,

Cons<T, decltype(filterHelper<Fn, Ts...>())>,

decltype(filterHelper<Fn,Ts...>())

>{};

}

template <typename Fn, typename L>

using Filter = decltype(filterHelper<Fn>(L{}));

struct IsInteger

{

template <typename T>

constexpr static

bool Template = std::is_integral_v<T>;

};

using IntegerList = Filter<IsInteger, List<int, char, void, IsInteger, bool>>;

void f(IntegerList)

{}