#ifndef SPROUT_TUPLE_TUPLE_GET_HPP #define SPROUT_TUPLE_TUPLE_GET_HPP #include #include #include #include #include #include #include #include namespace sprout { namespace tuples { // // tuple_size // template struct tuple_size : public std::tuple_size {}; template struct tuple_size : public sprout::tuples::tuple_size {}; template struct tuple_size : public sprout::tuples::tuple_size {}; template struct tuple_size : public sprout::tuples::tuple_size {}; // // tuple_element // template struct tuple_element : public std::tuple_element {}; template struct tuple_element : public sprout::tuples::tuple_element {}; template struct tuple_element : public sprout::tuples::tuple_element {}; template struct tuple_element : public sprout::tuples::tuple_element {}; namespace detail { template inline SPROUT_CONSTEXPR typename std::add_lvalue_reference::type get_helper(sprout::tuples::detail::tuple_impl& t) SPROUT_NOEXCEPT { return sprout::tuples::detail::tuple_impl::head(t); } template inline SPROUT_CONSTEXPR typename std::add_lvalue_reference::type>::type get_helper(sprout::tuples::detail::tuple_impl const& t) SPROUT_NOEXCEPT { return sprout::tuples::detail::tuple_impl::head(t); } } // namespace detail // // get // template inline SPROUT_CONSTEXPR typename sprout::tuples::tuple_element >::type& get(sprout::tuples::tuple& t) SPROUT_NOEXCEPT { return sprout::tuples::detail::get_helper(t); } template inline SPROUT_CONSTEXPR typename sprout::tuples::tuple_element >::type&& get(sprout::tuples::tuple&& t) SPROUT_NOEXCEPT { return sprout::forward >::type&&>( sprout::tuples::get(t) ); } template inline SPROUT_CONSTEXPR typename sprout::tuples::tuple_element >::type const& get(sprout::tuples::tuple const& t) SPROUT_NOEXCEPT { return sprout::tuples::detail::get_helper(t); } } // namespace tuples using sprout::tuples::tuple_size; using sprout::tuples::tuple_element; using sprout::tuples::get; } // namespace sprout namespace sprout_adl { template sprout::not_found_via_adl tuple_get(...); } // namespace sprout_adl namespace sprout_tuple_detail { using sprout_adl::tuple_get; template struct has_adl_tuple_get_test { public: template< typename U = T, typename sprout::enabler_if< sprout::is_found_via_adl(std::declval()))>::value >::type = sprout::enabler > static std::true_type test(int); static std::false_type test(...); }; template struct has_adl_tuple_get : public decltype(sprout_tuple_detail::has_adl_tuple_get_test::test(0)) {}; template struct has_std_get_test { public: template< typename U = T, typename = decltype(std::get(std::declval())) > static std::true_type test(int); static std::false_type test(...); }; template struct has_std_get : public decltype(sprout_tuple_detail::has_std_get_test::test(0)) {}; template struct select_adl_tuple_get; template struct select_adl_tuple_get< I, T, typename std::enable_if::value>::type > : public std::true_type {}; template struct select_adl_tuple_get< I, T, typename std::enable_if::value>::type > : public std::false_type {}; template struct select_std_get; template struct select_std_get< I, T, typename std::enable_if< sprout_tuple_detail::has_std_get::value && !sprout_tuple_detail::has_adl_tuple_get::value >::type > : public std::true_type {}; template struct select_std_get< I, T, typename std::enable_if::value && !sprout_tuple_detail::has_adl_tuple_get::value )>::type > : public std::false_type {}; template struct noexcept_get; template struct noexcept_get::value>::type> : public std::integral_constant(std::declval()), false)> {}; template struct noexcept_get::value>::type> : public std::integral_constant(std::declval()), false)> {}; template struct get_result; template struct get_result::value>::type> { public: typedef decltype(tuple_get(std::declval())) type; }; template struct get_result::value>::type> { public: typedef decltype(std::get(std::declval())) type; }; template< std::size_t I, typename T, typename sprout::enabler_if::value>::type = sprout::enabler > inline SPROUT_CONSTEXPR typename sprout_tuple_detail::get_result::type get_impl(T&& t) SPROUT_NOEXCEPT_EXPR((sprout_tuple_detail::noexcept_get::value)) { return tuple_get(sprout::forward(t)); } template< std::size_t I, typename T, typename sprout::enabler_if::value>::type = sprout::enabler > inline SPROUT_CONSTEXPR typename sprout_tuple_detail::get_result::type get_impl(T&& t) SPROUT_NOEXCEPT_EXPR((sprout_tuple_detail::noexcept_get::value)) { return std::get(sprout::forward(t)); } } // namespace sprout_tuple_detail namespace sprout { namespace tuples { // // get // template inline SPROUT_CONSTEXPR typename sprout_tuple_detail::get_result::type get(T&& t) SPROUT_NOEXCEPT_EXPR((sprout_tuple_detail::noexcept_get::value)) { return sprout_tuple_detail::get_impl(sprout::forward(t)); } } // namespace tuples using sprout::tuples::get; } // namespace sprout #endif // #ifndef SPROUT_TUPLE_TUPLE_GET_HPP