The post is follow up to my previous Typelist with extractor. The type_list and extraction feature code is identical to the accepted answer (from user2296177). The idea is to provide a type list with fundamental features that users could built something specialized upon that.List of features, by order of appearance in the code:type_list itself.type_list_extract, extracts Nth type (0 indexed) from theprovided type_list.type_list_concat, concatenates 2 type_lists, adding second to the end of the first.type_list_expand, expansion of the type_list into std::tuple, supporting extraction by supplied indexes.utility first_index_holder, which helps to extract first index from the index interval.utility reverse_index_interval, which reverses interval N ... M to M ... N, code has undefined behavior if the interval is not contiguous.type_list_reverse, reversion of the type_list.The code also provides convenient xxx_t aliases for all operations, except for first_index_holder and reverse_index_interval.My particular concerns are naming in all parts of the code and optimization (in terms of instantiations) and compile-time (not sure how I could measure this though) of type_list_reverse.#include <cstddef>#include <tuple>#include <utility>#include <cassert>template <class ... Types>class type_list {};template <std::size_t idx, class... Types>class extract{    static_assert(idx < sizeof...(Types), index out of bounds);    template <std::size_t i, std::size_t n, class... Rest>    struct extract_impl;    template <std::size_t i, std::size_t n, class T, class... Rest>    struct extract_impl<i, n, T, Rest...>    {        using type = typename extract_impl<i + 1, n, Rest...>::type;    };    template <std::size_t n, class T, class... Rest>    struct extract_impl<n, n, T, Rest...>    {        using type = T;    };public:    using type = typename extract_impl<0, idx, Types...>::type;};template <std::size_t idx, class TypeList>struct type_list_extract;template <std::size_t idx, template <class...> class TypeList, class... Types>struct type_list_extract<idx, TypeList<Types...>>{    using type = typename extract<idx, Types...>::type;};template <std::size_t idx, class TypeList>using type_list_extract_t = typename type_list_extract<idx, TypeList>::type;template <class FirstTypeList, class SecondTypeList>struct type_list_concat;template <template <class ...> class TypeList, class ... FirstTypesPack, class ... SecondTypesPack>struct type_list_concat<TypeList<FirstTypesPack...>, TypeList<SecondTypesPack...> >{    using type = TypeList<FirstTypesPack..., SecondTypesPack...>;};template <class FirstTypeList, class SecondTypeList>using type_list_concat_t = typename type_list_concat<FirstTypeList, SecondTypeList>::type;template <class TypeList, size_t ... indexes>struct type_list_expand{    using type = std::tuple<typename type_list_extract<indexes, TypeList>::type...>;};template < template <class...> class TypeList, class ... Types>struct type_list_expand< TypeList<Types...>>{    using type = std::tuple<Types...>;};template <class TypeList, size_t ... indexes>using type_list_expand_t = typename type_list_expand<TypeList, indexes...>::type;template <std::size_t ... indexes>struct first_index_holder;template <std::size_t head, std::size_t ... remainder>struct first_index_holder<head, remainder...>{    static const std::size_t value = head;};template <class IndexInterval>class reverse_index_interval;template <template <typename T, T ...> class IndexInterval, std::size_t ... indexes>class reverse_index_interval < IndexInterval<std::size_t, indexes...>>{    static const std::size_t size = sizeof...(indexes)-1;    static const std::size_t head = first_index_holder<indexes...>::value;public:    using type = IndexInterval<std::size_t, (size + head - indexes + head)... >;};template <class TypeList>class type_list_reverse;template <template <class ... > class TypeList, class ... Types>class type_list_reverse<TypeList<Types...> >{    template <class integer_sequence, class TList>    struct typelist_reverse_impl;    template <template <typename T, T ...> class Sequence, std::size_t ... indexes, template<class ...> class TList, class ... Ts>    struct typelist_reverse_impl<Sequence<std::size_t, indexes...>, TList<Ts...>>    {        using type = TList<type_list_extract_t<indexes, TList<Ts...>>...>;    };public:    using type = typename typelist_reverse_impl<typename reverse_index_interval<std::make_index_sequence<sizeof...(Types)> >::type, TypeList<Types...>>::type;};template <class TypeList>using type_list_reverse_t = typename type_list_reverse<TypeList>::type;Example usage:#include <utility>#include <cassert>#include typelist.h//just to populate with some typesstruct String;struct Condition;struct Opinion;int main(){    using MyList = type_list<int, char, bool>;    using First = type_list_extract_t<0, MyList>;    static_assert(std::is_same<First, int>::value, !);    using SecondList = type_list<String, Condition, Opinion>;    using Concat = type_list_concat_t<MyList, SecondList>;    static_assert(std::is_same<type_list<int, char, bool, String, Condition, Opinion>, Concat>::value, !);    using Expansion = type_list_expand_t<MyList>;    static_assert(std::is_same<std::tuple<int, char, bool>, Expansion>::value, !);    using PartialExpansion = type_list_expand_t<MyList, 0, 2>; //int, bool    static_assert(std::is_same<std::tuple<int, bool>, PartialExpansion>::value, !);    constexpr std::size_t sz = first_index_holder<2, 3, 4>::value;    static_assert(sz == 2, !);    using Seq = std::index_sequence<2, 3, 4>;    using ReversedSeq = reverse_index_interval<Seq>::type;    static_assert(std::is_same<ReversedSeq, std::index_sequence<4, 3, 2> >::value, !);    using Rev = type_list_reverse_t<MyList>;    static_assert(std::is_same<type_list<bool, char, int>, Rev>::value, !);}Note:The code doesn't compile in VC++14 (it argues that > is missing before alias named type which belongs to reverse_index_interval), but does compile on Ideone and c++ shell (GCC 4.9.2). I believe my code is standard conformant.
type_list with utilities
c++;c++14;template meta programming