1 //-----------------------------------------------------------------------------
2 // boost variant/detail/apply_visitor_binary.hpp header file
3 // See http://www.boost.org for updates, documentation, and revision history.
4 //-----------------------------------------------------------------------------
6 // Copyright (c) 2002-2003
9 // Distributed under the Boost Software License, Version 1.0. (See
10 // accompanying file LICENSE_1_0.txt or copy at
11 // http://www.boost.org/LICENSE_1_0.txt)
13 #ifndef BOOST_VARIANT_DETAIL_APPLY_VISITOR_BINARY_HPP
14 #define BOOST_VARIANT_DETAIL_APPLY_VISITOR_BINARY_HPP
16 #include "boost/config.hpp"
17 #include "boost/detail/workaround.hpp"
18 #include "boost/variant/detail/generic_result_type.hpp"
20 #include "boost/variant/detail/apply_visitor_unary.hpp"
22 #include "boost/utility/enable_if.hpp"
26 //////////////////////////////////////////////////////////////////////////
27 // function template apply_visitor(visitor, visitable1, visitable2)
29 // Visits visitable1 and visitable2 such that their values (which we
30 // shall call x and y, respectively) are used as arguments in the
31 // expression visitor(x, y).
34 namespace detail
{ namespace variant
{
36 template <typename Visitor
, typename Value1
>
37 class apply_visitor_binary_invoke
39 public: // visitor typedefs
41 typedef typename
Visitor::result_type
44 private: // representation
51 apply_visitor_binary_invoke(Visitor
& visitor
, Value1
& value1
)
57 public: // visitor interfaces
59 template <typename Value2
>
60 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type
)
61 operator()(Value2
& value2
)
63 return visitor_(value1_
, value2
);
68 template <typename Visitor
, typename Visitable2
>
69 class apply_visitor_binary_unwrap
71 public: // visitor typedefs
73 typedef typename
Visitor::result_type
76 private: // representation
79 Visitable2
& visitable2_
;
83 apply_visitor_binary_unwrap(Visitor
& visitor
, Visitable2
& visitable2
)
85 , visitable2_(visitable2
)
89 public: // visitor interfaces
91 template <typename Value1
>
92 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type
)
93 operator()(Value1
& value1
)
95 apply_visitor_binary_invoke
<
98 > invoker(visitor_
, value1
);
100 return boost::apply_visitor(invoker
, visitable2_
);
105 }} // namespace detail::variant
108 // nonconst-visitor version:
111 #if !BOOST_WORKAROUND(__EDG__, BOOST_TESTED_AT(302))
113 # define BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(V) \
114 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename V::result_type) \
117 #else // EDG-based compilers
119 # define BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(V) \
120 typename enable_if< \
121 mpl::not_< is_const< V > > \
122 , BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename V::result_type) \
126 #endif // EDG-based compilers workaround
128 template <typename Visitor
, typename Visitable1
, typename Visitable2
>
130 BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(Visitor
)
133 , Visitable1
& visitable1
, Visitable2
& visitable2
136 ::boost::detail::variant::apply_visitor_binary_unwrap
<
138 > unwrapper(visitor
, visitable2
);
140 return boost::apply_visitor(unwrapper
, visitable1
);
143 #undef BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE
146 // const-visitor version:
149 #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
151 template <typename Visitor
, typename Visitable1
, typename Visitable2
>
153 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
154 typename
Visitor::result_type
157 const Visitor
& visitor
158 , Visitable1
& visitable1
, Visitable2
& visitable2
161 ::boost::detail::variant::apply_visitor_binary_unwrap
<
162 const Visitor
, Visitable2
163 > unwrapper(visitor
, visitable2
);
165 return boost::apply_visitor(unwrapper
, visitable1
);
168 #endif // MSVC7 and below exclusion
172 #endif // BOOST_VARIANT_DETAIL_APPLY_VISITOR_BINARY_HPP