#ifndef SPROUT_TUPLE_TUPLE_MAKE_TUPLE_HPP #define SPROUT_TUPLE_TUPLE_MAKE_TUPLE_HPP #include #include #include #include #include #include namespace sprout { namespace tuples { // // make_tuple // template inline SPROUT_CONSTEXPR sprout::tuples::tuple::type...> make_tuple(Types&&... args) { return sprout::tuples::tuple::type...>(sprout::forward(args)...); } // // forward_as_tuple // template inline SPROUT_CONSTEXPR sprout::tuples::tuple forward_as_tuple(Types&&... args) SPROUT_NOEXCEPT { return sprout::tuples::tuple(sprout::forward(args)...); } // // tie // template inline sprout::tuples::tuple tie(Types&... args) SPROUT_NOEXCEPT { return sprout::tuples::tuple(args...); } namespace result_of { namespace detail { template struct tuple_cat_impl; template<> struct tuple_cat_impl<> { typedef sprout::tuples::tuple<> type; }; template struct tuple_cat_impl { private: template struct make; template struct make > { public: typedef sprout::tuples::tuple::type...> type; }; public: typedef typename make< Tuple, typename sprout::index_range<0, sprout::tuples::tuple_size::value>::type >::type type; }; template struct tuple_cat_impl { private: template struct make; template struct make, Tup2, sprout::index_tuple > { public: typedef sprout::tuples::tuple< typename sprout::tuples::tuple_element::type..., typename sprout::tuples::tuple_element::type... > type; }; public: typedef typename sprout::tuples::result_of::detail::tuple_cat_impl< typename make< T, typename sprout::index_range<0, sprout::tuples::tuple_size::value>::type, U, typename sprout::index_range<0, sprout::tuples::tuple_size::value>::type >::type, Tuples... >::type type; }; } // namespace detail // // tuple_cat // template struct tuple_cat : public sprout::tuples::result_of::detail::tuple_cat_impl< typename std::decay::type... > {}; } // namespace result_of namespace detail { template struct tuple_cat_1st_indexes; template<> struct tuple_cat_1st_indexes<> { public: typedef sprout::index_tuple<> type; }; template struct tuple_cat_1st_indexes { public: typedef typename sprout::index_range< 0, sprout::tuples::tuple_size::type>::value >::type type; }; template struct tuple_cat_impl; template struct tuple_cat_impl > { public: template static SPROUT_CONSTEXPR Result call(Args&&... args) { return Result(sprout::forward(args)...); } }; template struct tuple_cat_impl, Head, Tail...> { public: template static SPROUT_CONSTEXPR Result call(T&& t, Args&&... args) { return sprout::tuples::detail::tuple_cat_impl< Result, typename sprout::tuples::detail::tuple_cat_1st_indexes::type, Tail... >::call( sprout::forward(args)..., sprout::tuples::get(sprout::forward(t))... ); } }; } // namespace detail // // tuple_cat // template inline SPROUT_CONSTEXPR typename sprout::tuples::result_of::tuple_cat::type tuple_cat(Tuples&&... tuples) { return sprout::tuples::detail::tuple_cat_impl< typename sprout::tuples::result_of::tuple_cat::type, typename sprout::tuples::detail::tuple_cat_1st_indexes::type, Tuples... >::call(sprout::forward(tuples)...); } } // namespace tuples namespace result_of { using sprout::tuples::result_of::tuple_cat; } // namespace result_of using sprout::tuples::make_tuple; using sprout::tuples::forward_as_tuple; using sprout::tuples::tie; using sprout::tuples::tuple_cat; } // namespace sprout #endif // #ifndef SPROUT_TUPLE_TUPLE_MAKE_TUPLE_HPP