meta: Change complexity of typelist<>::times<> from O(N) to O(logN)

This commit is contained in:
Christos Houtouridis 2019-10-13 19:54:08 +03:00
parent e974b9d43d
commit 899efcc2d6

View File

@ -76,17 +76,29 @@ namespace meta {
} }
// ======= times utility ======= // ======= times utility =======
private: private:
template<size_t N, typename L, typename ...T> template <typename... > struct cat_ { };
struct times_ { }; template <typename... L1, typename... L2>
struct cat_<typelist<L1...>, typelist<L2...>> {
using type = typelist<L1..., L2...>;
};
template<size_t N, typename ...L> template <size_t N, typename ...T>
struct times_<N, typelist<L...>, Ts...> { struct times_ {
// append one and recurse //static_assert( N >= 0, "Cannot make typelist of negative length" );
using type = type_< using type = eval<
if_c <N != 0, cat_<
times_<N-1, typelist<L..., Ts...>, Ts...>, eval<times_<N/2, T...>>,
typelist<L...> eval<times_<N - N/2, T...>>
>>; >
>;
};
template <typename ...T>
struct times_<1, T...> {
using type = typelist<T...>;
};
template <typename ...T>
struct times_<0, T...> {
using type = typelist<>;
}; };
public: public:
/*! /*!
@ -98,11 +110,11 @@ namespace meta {
* typelist<int, char, int, char> * typelist<int, char, int, char>
* >, "" ); * >, "" );
* \endcode * \endcode
* complexity \f$ O(N) \f$ * complexity \f$ O(logN) \f$
*/ */
template<size_t N> template<size_t N>
using times = type_< using times = eval<
times_<N, typelist<>, Ts...> times_<N, Ts...>
>; >;
}; };
@ -226,7 +238,7 @@ namespace meta {
/*! /*!
* Return the \p N th element in the \c meta::typelist \p List. * Return the \p N th element in the \c meta::typelist \p List.
* *
* Complexity \f$ O(N) \f$. * Complexity \f$ O(logN) \f$.
*/ */
template <typename List, index_t N> template <typename List, index_t N>
using at_c = eval< using at_c = eval<