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