Chris@102: // Boost.Varaint Chris@102: // Contains multivisitors that are implemented via variadic templates, std::tuple Chris@102: // and decltype(auto) Chris@102: // Chris@102: // See http://www.boost.org for most recent version, including documentation. Chris@102: // Chris@102: // Copyright Antony Polukhin, 2013-2014. Chris@102: // Chris@102: // Distributed under the Boost Chris@102: // Software License, Version 1.0. (See accompanying file Chris@102: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt). Chris@102: Chris@102: #ifndef BOOST_VARIANT_DETAIL_MULTIVISITORS_CPP14_BASED_HPP Chris@102: #define BOOST_VARIANT_DETAIL_MULTIVISITORS_CPP14_BASED_HPP Chris@102: Chris@102: #if defined(_MSC_VER) Chris@102: # pragma once Chris@102: #endif Chris@102: Chris@102: #include Chris@102: Chris@102: namespace boost { Chris@102: Chris@102: namespace detail { namespace variant { Chris@102: Chris@102: // Forward declaration Chris@102: template Chris@102: class one_by_one_visitor_and_value_referer_cpp14; Chris@102: Chris@102: template Chris@102: inline one_by_one_visitor_and_value_referer_cpp14 Chris@102: make_one_by_one_visitor_and_value_referer_cpp14( Chris@102: Visitor& visitor, Visitables visitables, std::tuple values Chris@102: ) Chris@102: { Chris@102: return one_by_one_visitor_and_value_referer_cpp14 ( Chris@102: visitor, visitables, values Chris@102: ); Chris@102: } Chris@102: Chris@102: template Chris@102: class one_by_one_visitor_and_value_referer_cpp14 Chris@102: { Chris@102: Visitor& visitor_; Chris@102: std::tuple values_; Chris@102: Visitables visitables_; Chris@102: Chris@102: public: // structors Chris@102: one_by_one_visitor_and_value_referer_cpp14( Chris@102: Visitor& visitor, Visitables visitables, std::tuple values Chris@102: ) BOOST_NOEXCEPT Chris@102: : visitor_(visitor) Chris@102: , values_(values) Chris@102: , visitables_(visitables) Chris@102: {} Chris@102: Chris@102: public: // visitor interfaces Chris@102: template Chris@102: decltype(auto) operator()(Value& value) const Chris@102: { Chris@102: return ::boost::apply_visitor( Chris@102: make_one_by_one_visitor_and_value_referer_cpp14( Chris@102: visitor_, Chris@102: tuple_tail(visitables_), Chris@102: std::tuple_cat(values_, std::tuple(value)) Chris@102: ) Chris@102: , std::get<0>(visitables_) // getting Head element Chris@102: ); Chris@102: } Chris@102: Chris@102: private: Chris@102: one_by_one_visitor_and_value_referer_cpp14& operator=(const one_by_one_visitor_and_value_referer_cpp14&); Chris@102: }; Chris@102: Chris@102: template Chris@102: class one_by_one_visitor_and_value_referer_cpp14, Values...> Chris@102: { Chris@102: Visitor& visitor_; Chris@102: std::tuple values_; Chris@102: Chris@102: public: Chris@102: one_by_one_visitor_and_value_referer_cpp14( Chris@102: Visitor& visitor, std::tuple<> /*visitables*/, std::tuple values Chris@102: ) BOOST_NOEXCEPT Chris@102: : visitor_(visitor) Chris@102: , values_(values) Chris@102: {} Chris@102: Chris@102: template Chris@102: decltype(auto) do_call(Tuple t, index_sequence) const { Chris@102: return visitor_(std::get(t)...); Chris@102: } Chris@102: Chris@102: template Chris@102: decltype(auto) operator()(Value& value) const Chris@102: { Chris@102: return do_call( Chris@102: std::tuple_cat(values_, std::tuple(value)), Chris@102: make_index_sequence() Chris@102: ); Chris@102: } Chris@102: }; Chris@102: Chris@102: }} // namespace detail::variant Chris@102: Chris@102: template Chris@102: inline decltype(auto) apply_visitor(const Visitor& visitor, T1& v1, T2& v2, T3& v3, TN&... vn, Chris@102: typename boost::disable_if< Chris@102: boost::detail::variant::has_result_type Chris@102: >::type* = 0) Chris@102: { Chris@102: return boost::apply_visitor( Chris@102: ::boost::detail::variant::make_one_by_one_visitor_and_value_referer_cpp14( Chris@102: visitor, Chris@102: ::boost::detail::variant::forward_as_tuple_simple(v2, v3, vn...), Chris@102: std::tuple<>() Chris@102: ), Chris@102: v1 Chris@102: ); Chris@102: } Chris@102: Chris@102: Chris@102: template Chris@102: inline decltype(auto) apply_visitor(Visitor& visitor, T1& v1, T2& v2, T3& v3, TN&... vn, Chris@102: typename boost::disable_if< Chris@102: boost::detail::variant::has_result_type Chris@102: >::type* = 0) Chris@102: { Chris@102: return ::boost::apply_visitor( Chris@102: ::boost::detail::variant::make_one_by_one_visitor_and_value_referer_cpp14( Chris@102: visitor, Chris@102: ::boost::detail::variant::forward_as_tuple_simple(v2, v3, vn...), Chris@102: std::tuple<>() Chris@102: ), Chris@102: v1 Chris@102: ); Chris@102: } Chris@102: Chris@102: } // namespace boost Chris@102: Chris@102: #endif // BOOST_VARIANT_DETAIL_MULTIVISITORS_CPP14_BASED_HPP Chris@102: