#ifndef TMP_PACK_H #define TMP_PACK_H #include "utility.h" namespace tmp { /** * Pack */ template struct Pack { static constexpr Size size = sizeof...(Ts); }; /** * PackHead */ template struct PackHeadImpl; template struct PackHeadImpl> { using type = T; }; template using PackHead = typename PackHeadImpl::type; /** * PackTrail */ template struct PackTrailImpl; template struct PackTrailImpl> { using type = Pack; }; template using PackTrail = typename PackTrailImpl::type; /** * PackGet */ template struct PackGetImpl; template struct PackGetImpl, I> { using type = typename PackGetImpl, I-1>::type; }; template struct PackGetImpl, 0> { using type = T; }; template using PackGet = typename PackGetImpl::type; /** * PackPushFront */ template struct PackPushFrontImpl; template struct PackPushFrontImpl, T> { using type = Pack; }; template using PackPushFront = typename PackPushFrontImpl::type; /** * PackPushBack */ template struct PackPushBackImpl; template struct PackPushBackImpl, T> { using type = Pack; }; template using PackPushBack = typename PackPushBackImpl::type; /** * PackCat */ template struct PackCatImpl; template struct PackCatImpl, Pack, Packs...> { using type = typename PackCatImpl, Packs...>::type; }; template struct PackCatImpl> { using type = Pack; }; template<> struct PackCatImpl<> { using type = Pack<>; }; template using PackCat = typename PackCatImpl::type; /** * PackReverse */ template struct PackReverseImpl; template struct PackReverseImpl> { using type = PackPushBack>::type, T>; }; template<> struct PackReverseImpl> { using type = Pack<>; }; template using PackReverse = typename PackReverseImpl

::type; /** * PackReplace */ template struct PackReplaceImpl; template struct PackReplaceImpl, Before, After> { using type = PackCat, typename PackReplaceImpl, Before, After>::type>; }; template struct PackReplaceImpl, Before, After> { using type = PackCat, typename PackReplaceImpl, Before, After>::type>; }; template struct PackReplaceImpl, Before, After> { using type = Pack<>; }; template using PackReplace = typename PackReplaceImpl::type; /** * Repack */ template class, typename> struct RepackImpl; template class Out, template class In, typename... Ts> struct RepackImpl> { using type = Out; }; template class Out, typename In> using Repack = typename RepackImpl::type; /** * AsPack */ template using AsPack = Repack; } #endif