diff --git a/sprout/type/type_tuple.hpp b/sprout/type/type_tuple.hpp index 71170fbb..5b5c0cee 100644 --- a/sprout/type/type_tuple.hpp +++ b/sprout/type/type_tuple.hpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -51,21 +52,21 @@ namespace sprout { }; namespace detail { - template + template struct head_element; template struct head_element > : public sprout::identity {}; - template + template struct tuple_head; template struct tuple_head > : public sprout::identity > {}; - template + template struct tuple_tail; template struct tuple_tail > @@ -74,7 +75,14 @@ namespace sprout { template struct dummy_index - : sprout::identity + : public sprout::identity + {}; + + template + struct tuple_cat; + template + struct tuple_cat, sprout::types::type_tuple > + : public sprout::identity > {}; template @@ -85,58 +93,47 @@ namespace sprout { static sprout::types::type_tuple eval(typename sprout::types::detail::dummy_index::type*..., Types*...); }; - template + template struct tuple_drop_impl; template struct tuple_drop_impl > : public sprout::identity::type>::eval( - static_cast*>(0)... - ) + sprout::types::detail::tuple_drop_helper::type> + ::eval(static_cast*>(0)...) )>::type {}; - template + template struct tuple_drop; template struct tuple_drop > : public sprout::types::detail::tuple_drop_impl > {}; -// template -// struct tuple_drop_impl; -// template -// struct tuple_drop_impl< -// I, N, sprout::types::type_tuple, -// typename std::enable_if<(I == 0)>::type -// > -// : public sprout::identity > -// {}; -// template -// struct tuple_drop_impl< -// I, N, sprout::types::type_tuple, -// typename std::enable_if<(I != 0 && I < N / 2)>::type -// > -// : public sprout::types::detail::tuple_drop_impl< -// I - 1, N / 2 - 1, -// sprout::types::type_tuple -// > -// {}; -// template -// struct tuple_drop_impl< -// I, N, sprout::types::type_tuple, -// typename std::enable_if<(I != 0 && I >= N / 2)>::type -// > -// : public sprout::types::detail::tuple_drop_impl< -// I - N / 2, N - N / 2, -// typename sprout::types::detail::tuple_drop_impl >::type -// > -// {}; -// template -// struct tuple_drop; -// template -// struct tuple_drop > -// : public sprout::types::detail::tuple_drop_impl > -// {}; + template + struct tuple_element; + template + struct tuple_element > + : public sprout::types::detail::head_element< + typename sprout::types::detail::tuple_drop >::type + > + {}; + + template + struct tuple_take_impl; + template + struct tuple_take_impl, sprout::index_tuple > + : public sprout::identity< + sprout::types::type_tuple< + typename sprout::types::detail::tuple_element >::type... + > + >::type + {}; + template + struct tuple_take; + template + struct tuple_take > + : public sprout::types::detail::tuple_take_impl, typename sprout::make_index_tuple::type> + {}; } // namespace detail } // namespace types @@ -162,9 +159,7 @@ namespace std { // template struct tuple_element > - : public sprout::types::detail::head_element< - typename sprout::types::detail::tuple_drop >::type - > + : public sprout::types::detail::tuple_element > {}; #if defined(__clang__) # pragma clang diagnostic pop diff --git a/sprout/utility/pack.hpp b/sprout/utility/pack.hpp index 5df9ef2d..df38dc1f 100644 --- a/sprout/utility/pack.hpp +++ b/sprout/utility/pack.hpp @@ -36,30 +36,44 @@ namespace sprout { // pack_get // namespace detail { - template< - std::size_t I, typename R, typename Head, typename... Tail, - typename sprout::enabler_if::type = sprout::enabler - > - inline SPROUT_CONSTEXPR R - pack_get_impl(Head&& head, Tail&&...) { - return sprout::forward(head); - } - template< - std::size_t I, typename R, typename Head, typename... Tail, - typename sprout::enabler_if::type = sprout::enabler - > - inline SPROUT_CONSTEXPR R - pack_get_impl(Head&&, Tail&&... tail) { - return sprout::detail::pack_get_impl(sprout::forward(tail)...); - } +// template< +// std::size_t I, typename R, typename Head, typename... Tail, +// typename sprout::enabler_if::type = sprout::enabler +// > +// inline SPROUT_CONSTEXPR R +// pack_get_impl(Head&& head, Tail&&...) { +// return sprout::forward(head); +// } +// template< +// std::size_t I, typename R, typename Head, typename... Tail, +// typename sprout::enabler_if::type = sprout::enabler +// > +// inline SPROUT_CONSTEXPR R +// pack_get_impl(Head&&, Tail&&... tail) { +// return sprout::detail::pack_get_impl(sprout::forward(tail)...); +// } + + template + struct pack_get_helper; + template + struct pack_get_helper > { + template + static SPROUT_CONSTEXPR T&& + eval(Args&&..., T&& t, ...) { + return sprout::forward(t); + } + }; } // namespace detail template inline SPROUT_CONSTEXPR typename sprout::pack_element::type pack_get(Args&&... args) { - return sprout::detail::pack_get_impl< - I, - typename sprout::pack_element::type - >(sprout::forward(args)...); + return sprout::detail::pack_get_helper< + typename sprout::types::detail::tuple_take >::type + >::eval(sprout::forward(args)...); +// return sprout::detail::pack_get_impl< +// I, +// typename sprout::pack_element::type +// >(sprout::forward(args)...); } } // namespace sprout