Improve vacpp support.
[boost.git] / boost / boost / variant / detail / apply_visitor_binary.hpp
blob92cdb42328e2cfebd4ab0661836ce08908b56295
1 //-----------------------------------------------------------------------------
2 // boost variant/detail/apply_visitor_binary.hpp header file
3 // See http://www.boost.org for updates, documentation, and revision history.
4 //-----------------------------------------------------------------------------
5 //
6 // Copyright (c) 2002-2003
7 // Eric Friedman
8 //
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"
24 namespace boost {
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
42 result_type;
44 private: // representation
46 Visitor& visitor_;
47 Value1& value1_;
49 public: // structors
51 apply_visitor_binary_invoke(Visitor& visitor, Value1& value1)
52 : visitor_(visitor)
53 , 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
74 result_type;
76 private: // representation
78 Visitor& visitor_;
79 Visitable2& visitable2_;
81 public: // structors
83 apply_visitor_binary_unwrap(Visitor& visitor, Visitable2& visitable2)
84 : visitor_(visitor)
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<
96 Visitor
97 , Value1
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) \
115 /**/
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) \
123 >::type \
124 /**/
126 #endif // EDG-based compilers workaround
128 template <typename Visitor, typename Visitable1, typename Visitable2>
129 inline
130 BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(Visitor)
131 apply_visitor(
132 Visitor& visitor
133 , Visitable1& visitable1, Visitable2& visitable2
136 ::boost::detail::variant::apply_visitor_binary_unwrap<
137 Visitor, Visitable2
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>
152 inline
153 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
154 typename Visitor::result_type
156 apply_visitor(
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
170 } // namespace boost
172 #endif // BOOST_VARIANT_DETAIL_APPLY_VISITOR_BINARY_HPP