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)
|
---|
12 |
|
---|
13 | #ifndef BOOST_VARIANT_DETAIL_APPLY_VISITOR_BINARY_HPP
|
---|
14 | #define BOOST_VARIANT_DETAIL_APPLY_VISITOR_BINARY_HPP
|
---|
15 |
|
---|
16 | #include "boost/config.hpp"
|
---|
17 | #include "boost/detail/workaround.hpp"
|
---|
18 | #include "boost/variant/detail/generic_result_type.hpp"
|
---|
19 |
|
---|
20 | #include "boost/variant/detail/apply_visitor_unary.hpp"
|
---|
21 |
|
---|
22 | #include "boost/utility/enable_if.hpp"
|
---|
23 |
|
---|
24 | namespace boost {
|
---|
25 |
|
---|
26 | //////////////////////////////////////////////////////////////////////////
|
---|
27 | // function template apply_visitor(visitor, visitable1, visitable2)
|
---|
28 | //
|
---|
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).
|
---|
32 | //
|
---|
33 |
|
---|
34 | namespace detail { namespace variant {
|
---|
35 |
|
---|
36 | template <typename Visitor, typename Value1>
|
---|
37 | class apply_visitor_binary_invoke
|
---|
38 | {
|
---|
39 | public: // visitor typedefs
|
---|
40 |
|
---|
41 | typedef typename Visitor::result_type
|
---|
42 | result_type;
|
---|
43 |
|
---|
44 | private: // representation
|
---|
45 |
|
---|
46 | Visitor& visitor_;
|
---|
47 | Value1& value1_;
|
---|
48 |
|
---|
49 | public: // structors
|
---|
50 |
|
---|
51 | apply_visitor_binary_invoke(Visitor& visitor, Value1& value1)
|
---|
52 | : visitor_(visitor)
|
---|
53 | , value1_(value1)
|
---|
54 | {
|
---|
55 | }
|
---|
56 |
|
---|
57 | public: // visitor interfaces
|
---|
58 |
|
---|
59 | template <typename Value2>
|
---|
60 | BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
|
---|
61 | operator()(Value2& value2)
|
---|
62 | {
|
---|
63 | return visitor_(value1_, value2);
|
---|
64 | }
|
---|
65 |
|
---|
66 | };
|
---|
67 |
|
---|
68 | template <typename Visitor, typename Visitable2>
|
---|
69 | class apply_visitor_binary_unwrap
|
---|
70 | {
|
---|
71 | public: // visitor typedefs
|
---|
72 |
|
---|
73 | typedef typename Visitor::result_type
|
---|
74 | result_type;
|
---|
75 |
|
---|
76 | private: // representation
|
---|
77 |
|
---|
78 | Visitor& visitor_;
|
---|
79 | Visitable2& visitable2_;
|
---|
80 |
|
---|
81 | public: // structors
|
---|
82 |
|
---|
83 | apply_visitor_binary_unwrap(Visitor& visitor, Visitable2& visitable2)
|
---|
84 | : visitor_(visitor)
|
---|
85 | , visitable2_(visitable2)
|
---|
86 | {
|
---|
87 | }
|
---|
88 |
|
---|
89 | public: // visitor interfaces
|
---|
90 |
|
---|
91 | template <typename Value1>
|
---|
92 | BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
|
---|
93 | operator()(Value1& value1)
|
---|
94 | {
|
---|
95 | apply_visitor_binary_invoke<
|
---|
96 | Visitor
|
---|
97 | , Value1
|
---|
98 | > invoker(visitor_, value1);
|
---|
99 |
|
---|
100 | return boost::apply_visitor(invoker, visitable2_);
|
---|
101 | }
|
---|
102 |
|
---|
103 | };
|
---|
104 |
|
---|
105 | }} // namespace detail::variant
|
---|
106 |
|
---|
107 | //
|
---|
108 | // nonconst-visitor version:
|
---|
109 | //
|
---|
110 |
|
---|
111 | #if !BOOST_WORKAROUND(__EDG__, BOOST_TESTED_AT(302))
|
---|
112 |
|
---|
113 | # define BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(V) \
|
---|
114 | BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename V::result_type) \
|
---|
115 | /**/
|
---|
116 |
|
---|
117 | #else // EDG-based compilers
|
---|
118 |
|
---|
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 | /**/
|
---|
125 |
|
---|
126 | #endif // EDG-based compilers workaround
|
---|
127 |
|
---|
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
|
---|
134 | )
|
---|
135 | {
|
---|
136 | ::boost::detail::variant::apply_visitor_binary_unwrap<
|
---|
137 | Visitor, Visitable2
|
---|
138 | > unwrapper(visitor, visitable2);
|
---|
139 |
|
---|
140 | return boost::apply_visitor(unwrapper, visitable1);
|
---|
141 | }
|
---|
142 |
|
---|
143 | #undef BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE
|
---|
144 |
|
---|
145 | //
|
---|
146 | // const-visitor version:
|
---|
147 | //
|
---|
148 |
|
---|
149 | #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
---|
150 |
|
---|
151 | template <typename Visitor, typename Visitable1, typename Visitable2>
|
---|
152 | inline
|
---|
153 | BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
|
---|
154 | typename Visitor::result_type
|
---|
155 | )
|
---|
156 | apply_visitor(
|
---|
157 | const Visitor& visitor
|
---|
158 | , Visitable1& visitable1, Visitable2& visitable2
|
---|
159 | )
|
---|
160 | {
|
---|
161 | ::boost::detail::variant::apply_visitor_binary_unwrap<
|
---|
162 | const Visitor, Visitable2
|
---|
163 | > unwrapper(visitor, visitable2);
|
---|
164 |
|
---|
165 | return boost::apply_visitor(unwrapper, visitable1);
|
---|
166 | }
|
---|
167 |
|
---|
168 | #endif // MSVC7 and below exclusion
|
---|
169 |
|
---|
170 | } // namespace boost
|
---|
171 |
|
---|
172 | #endif // BOOST_VARIANT_DETAIL_APPLY_VISITOR_BINARY_HPP
|
---|