source: NonGTP/Boost/boost/variant/detail/apply_visitor_binary.hpp @ 857

Revision 857, 4.4 KB checked in by igarcia, 18 years ago (diff)
Line 
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
24namespace 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
34namespace detail { namespace variant {
35
36template <typename Visitor, typename Value1>
37class apply_visitor_binary_invoke
38{
39public: // visitor typedefs
40
41    typedef typename Visitor::result_type
42        result_type;
43
44private: // representation
45
46    Visitor& visitor_;
47    Value1& value1_;
48
49public: // structors
50
51    apply_visitor_binary_invoke(Visitor& visitor, Value1& value1)
52        : visitor_(visitor)
53        , value1_(value1)
54    {
55    }
56
57public: // 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
68template <typename Visitor, typename Visitable2>
69class apply_visitor_binary_unwrap
70{
71public: // visitor typedefs
72
73    typedef typename Visitor::result_type
74        result_type;
75
76private: // representation
77
78    Visitor& visitor_;
79    Visitable2& visitable2_;
80
81public: // structors
82
83    apply_visitor_binary_unwrap(Visitor& visitor, Visitable2& visitable2)
84        : visitor_(visitor)
85        , visitable2_(visitable2)
86    {
87    }
88
89public: // 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
128template <typename Visitor, typename Visitable1, typename Visitable2>
129inline
130    BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(Visitor)
131apply_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
151template <typename Visitor, typename Visitable1, typename Visitable2>
152inline
153    BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
154          typename Visitor::result_type
155        )
156apply_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
Note: See TracBrowser for help on using the repository browser.