Chris@16: //----------------------------------------------------------------------------- Chris@16: // boost variant/detail/apply_visitor_binary.hpp header file Chris@16: // See http://www.boost.org for updates, documentation, and revision history. Chris@16: //----------------------------------------------------------------------------- Chris@16: // Chris@101: // Copyright (c) 2002-2003 Eric Friedman Chris@101: // Copyright (c) 2014 Antony Polukhin Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_VARIANT_DETAIL_APPLY_VISITOR_BINARY_HPP Chris@16: #define BOOST_VARIANT_DETAIL_APPLY_VISITOR_BINARY_HPP Chris@16: Chris@16: #include "boost/config.hpp" Chris@16: #include "boost/detail/workaround.hpp" Chris@16: #include "boost/variant/detail/generic_result_type.hpp" Chris@16: Chris@16: #include "boost/variant/detail/apply_visitor_unary.hpp" Chris@16: Chris@16: #if BOOST_WORKAROUND(__EDG__, BOOST_TESTED_AT(302)) Chris@16: #include "boost/utility/enable_if.hpp" Chris@16: #include "boost/mpl/not.hpp" Chris@16: #include "boost/type_traits/is_const.hpp" Chris@16: #endif Chris@16: Chris@101: Chris@101: #if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276) Chris@101: # include "boost/variant/detail/has_result_type.hpp" Chris@101: #endif Chris@101: Chris@16: namespace boost { Chris@16: Chris@16: ////////////////////////////////////////////////////////////////////////// Chris@16: // function template apply_visitor(visitor, visitable1, visitable2) Chris@16: // Chris@16: // Visits visitable1 and visitable2 such that their values (which we Chris@16: // shall call x and y, respectively) are used as arguments in the Chris@16: // expression visitor(x, y). Chris@16: // Chris@16: Chris@16: namespace detail { namespace variant { Chris@16: Chris@16: template Chris@16: class apply_visitor_binary_invoke Chris@16: { Chris@16: public: // visitor typedefs Chris@16: Chris@16: typedef typename Visitor::result_type Chris@16: result_type; Chris@16: Chris@16: private: // representation Chris@16: Chris@16: Visitor& visitor_; Chris@16: Value1& value1_; Chris@16: Chris@16: public: // structors Chris@16: Chris@101: apply_visitor_binary_invoke(Visitor& visitor, Value1& value1) BOOST_NOEXCEPT Chris@16: : visitor_(visitor) Chris@16: , value1_(value1) Chris@16: { Chris@16: } Chris@16: Chris@16: public: // visitor interfaces Chris@16: Chris@16: template Chris@16: BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type) Chris@16: operator()(Value2& value2) Chris@16: { Chris@16: return visitor_(value1_, value2); Chris@16: } Chris@16: Chris@16: private: Chris@16: apply_visitor_binary_invoke& operator=(const apply_visitor_binary_invoke&); Chris@16: }; Chris@16: Chris@16: template Chris@16: class apply_visitor_binary_unwrap Chris@16: { Chris@16: public: // visitor typedefs Chris@16: Chris@16: typedef typename Visitor::result_type Chris@16: result_type; Chris@16: Chris@16: private: // representation Chris@16: Chris@16: Visitor& visitor_; Chris@16: Visitable2& visitable2_; Chris@16: Chris@16: public: // structors Chris@16: Chris@101: apply_visitor_binary_unwrap(Visitor& visitor, Visitable2& visitable2) BOOST_NOEXCEPT Chris@16: : visitor_(visitor) Chris@16: , visitable2_(visitable2) Chris@16: { Chris@16: } Chris@16: Chris@16: public: // visitor interfaces Chris@16: Chris@16: template Chris@16: BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type) Chris@16: operator()(Value1& value1) Chris@16: { Chris@16: apply_visitor_binary_invoke< Chris@16: Visitor Chris@16: , Value1 Chris@16: > invoker(visitor_, value1); Chris@16: Chris@16: return boost::apply_visitor(invoker, visitable2_); Chris@16: } Chris@16: Chris@16: private: Chris@16: apply_visitor_binary_unwrap& operator=(const apply_visitor_binary_unwrap&); Chris@16: Chris@16: }; Chris@16: Chris@16: }} // namespace detail::variant Chris@16: Chris@16: // Chris@16: // nonconst-visitor version: Chris@16: // Chris@16: Chris@16: #if !BOOST_WORKAROUND(__EDG__, BOOST_TESTED_AT(302)) Chris@16: Chris@16: # define BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(V) \ Chris@16: BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename V::result_type) \ Chris@16: /**/ Chris@16: Chris@16: #else // EDG-based compilers Chris@16: Chris@16: # define BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(V) \ Chris@16: typename enable_if< \ Chris@16: mpl::not_< is_const< V > > \ Chris@16: , BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename V::result_type) \ Chris@16: >::type \ Chris@16: /**/ Chris@16: Chris@16: #endif // EDG-based compilers workaround Chris@16: Chris@16: template Chris@16: inline Chris@16: BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(Visitor) Chris@16: apply_visitor( Chris@16: Visitor& visitor Chris@16: , Visitable1& visitable1, Visitable2& visitable2 Chris@16: ) Chris@16: { Chris@16: ::boost::detail::variant::apply_visitor_binary_unwrap< Chris@16: Visitor, Visitable2 Chris@16: > unwrapper(visitor, visitable2); Chris@16: Chris@16: return boost::apply_visitor(unwrapper, visitable1); Chris@16: } Chris@16: Chris@16: #undef BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE Chris@16: Chris@16: // Chris@16: // const-visitor version: Chris@16: // Chris@16: Chris@16: template Chris@16: inline Chris@16: BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE( Chris@16: typename Visitor::result_type Chris@16: ) Chris@16: apply_visitor( Chris@16: const Visitor& visitor Chris@16: , Visitable1& visitable1, Visitable2& visitable2 Chris@16: ) Chris@16: { Chris@16: ::boost::detail::variant::apply_visitor_binary_unwrap< Chris@16: const Visitor, Visitable2 Chris@16: > unwrapper(visitor, visitable2); Chris@16: Chris@16: return boost::apply_visitor(unwrapper, visitable1); Chris@16: } Chris@16: Chris@101: Chris@101: #if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276) Chris@101: Chris@101: ////////////////////////////////////////////////////////////////////////// Chris@101: // function template apply_visitor(visitor, visitable1, visitable2) Chris@101: // Chris@101: // C++14 part. Chris@101: // Chris@101: Chris@101: namespace detail { namespace variant { Chris@101: Chris@101: template Chris@101: class apply_visitor_binary_invoke_cpp14 Chris@101: { Chris@101: Visitor& visitor_; Chris@101: Value1& value1_; Chris@101: Chris@101: public: // structors Chris@101: Chris@101: apply_visitor_binary_invoke_cpp14(Visitor& visitor, Value1& value1) BOOST_NOEXCEPT Chris@101: : visitor_(visitor) Chris@101: , value1_(value1) Chris@101: { Chris@101: } Chris@101: Chris@101: public: // visitor interfaces Chris@101: Chris@101: template Chris@101: decltype(auto) operator()(Value2& value2) Chris@101: { Chris@101: return visitor_(value1_, value2); Chris@101: } Chris@101: Chris@101: private: Chris@101: apply_visitor_binary_invoke_cpp14& operator=(const apply_visitor_binary_invoke_cpp14&); Chris@101: }; Chris@101: Chris@101: template Chris@101: class apply_visitor_binary_unwrap_cpp14 Chris@101: { Chris@101: Visitor& visitor_; Chris@101: Visitable2& visitable2_; Chris@101: Chris@101: public: // structors Chris@101: Chris@101: apply_visitor_binary_unwrap_cpp14(Visitor& visitor, Visitable2& visitable2) BOOST_NOEXCEPT Chris@101: : visitor_(visitor) Chris@101: , visitable2_(visitable2) Chris@101: { Chris@101: } Chris@101: Chris@101: public: // visitor interfaces Chris@101: Chris@101: template Chris@101: decltype(auto) operator()(Value1& value1) Chris@101: { Chris@101: apply_visitor_binary_invoke_cpp14< Chris@101: Visitor Chris@101: , Value1 Chris@101: > invoker(visitor_, value1); Chris@101: Chris@101: return boost::apply_visitor(invoker, visitable2_); Chris@101: } Chris@101: Chris@101: private: Chris@101: apply_visitor_binary_unwrap_cpp14& operator=(const apply_visitor_binary_unwrap_cpp14&); Chris@101: }; Chris@101: Chris@101: }} // namespace detail::variant Chris@101: Chris@101: template Chris@101: inline decltype(auto) apply_visitor(Visitor& visitor, Visitable1& visitable1, Visitable2& visitable2, Chris@101: typename boost::disable_if< Chris@101: boost::detail::variant::has_result_type Chris@101: >::type* = 0) Chris@101: { Chris@101: ::boost::detail::variant::apply_visitor_binary_unwrap_cpp14< Chris@101: Visitor, Visitable2 Chris@101: > unwrapper(visitor, visitable2); Chris@101: Chris@101: return boost::apply_visitor(unwrapper, visitable1); Chris@101: } Chris@101: Chris@101: template Chris@101: inline decltype(auto) apply_visitor(const Visitor& visitor, Visitable1& visitable1, Visitable2& visitable2, Chris@101: typename boost::disable_if< Chris@101: boost::detail::variant::has_result_type Chris@101: >::type* = 0) Chris@101: { Chris@101: ::boost::detail::variant::apply_visitor_binary_unwrap_cpp14< Chris@101: const Visitor, Visitable2 Chris@101: > unwrapper(visitor, visitable2); Chris@101: Chris@101: return boost::apply_visitor(unwrapper, visitable1); Chris@101: } Chris@101: Chris@101: #endif // !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276) Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: #endif // BOOST_VARIANT_DETAIL_APPLY_VISITOR_BINARY_HPP