1 //-----------------------------------------------------------------------------
2 // boost variant/detail/apply_visitor_delayed.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_DELAYED_HPP
14 #define BOOST_VARIANT_DETAIL_APPLY_VISITOR_DELAYED_HPP
15 
16 #include <boost/variant/detail/generic_result_type.hpp>
17 
18 #include <boost/variant/detail/apply_visitor_unary.hpp>
19 #include <boost/variant/detail/apply_visitor_binary.hpp>
20 #include <boost/variant/variant_fwd.hpp> // for BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
21 
22 
23 #include <boost/variant/detail/has_result_type.hpp>
24 #include <boost/core/enable_if.hpp>
25 
26 namespace boost {
27 
28 //////////////////////////////////////////////////////////////////////////
29 // function template apply_visitor(visitor)
30 //
31 // Returns a function object, overloaded for unary and binary usage, that
32 // visits its arguments using visitor (or a copy of visitor) via
33 //  * apply_visitor( visitor, [argument] )
34 // under unary invocation, or
35 //  * apply_visitor( visitor, [argument1], [argument2] )
36 // under binary invocation.
37 //
38 // NOTE: Unlike other apply_visitor forms, the visitor object must be
39 //   non-const; this prevents user from giving temporary, to disastrous
40 //   effect (i.e., returned function object would have dead reference).
41 //
42 
43 template <typename Visitor>
44 class apply_visitor_delayed_t
45 {
46 public: // visitor typedefs
47 
48     typedef typename Visitor::result_type
49         result_type;
50 
51 private: // representation
52 
53     Visitor& visitor_;
54 
55 public: // structors
56 
apply_visitor_delayed_t(Visitor & visitor)57     explicit apply_visitor_delayed_t(Visitor& visitor) BOOST_NOEXCEPT
58       : visitor_(visitor)
59     {
60     }
61 
62 #if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
63 
64 public: // N-ary visitor interface
65     template <typename... Visitables>
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)66         BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
67     operator()(Visitables&... visitables) const
68     {
69         return apply_visitor(visitor_, visitables...);
70     }
71 
72 #else // !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
73 
74 public: // unary visitor interface
75 
76     template <typename Visitable>
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)77         BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
78     operator()(Visitable& visitable) const
79     {
80         return apply_visitor(visitor_, visitable);
81     }
82 
83 public: // binary visitor interface
84 
85     template <typename Visitable1, typename Visitable2>
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)86         BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
87     operator()(Visitable1& visitable1, Visitable2& visitable2) const
88     {
89         return apply_visitor(visitor_, visitable1, visitable2);
90     }
91 
92 #endif // !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
93 
94 private:
95     apply_visitor_delayed_t& operator=(const apply_visitor_delayed_t&);
96 
97 };
98 
99 template <typename Visitor>
100 inline typename boost::enable_if<
101         boost::detail::variant::has_result_type<Visitor>,
102         apply_visitor_delayed_t<Visitor>
apply_visitor(Visitor & visitor)103     >::type apply_visitor(Visitor& visitor)
104 {
105     return apply_visitor_delayed_t<Visitor>(visitor);
106 }
107 
108 #if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276) \
109     && !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
110 
111 template <typename Visitor>
112 class apply_visitor_delayed_cpp14_t
113 {
114 private: // representation
115     Visitor& visitor_;
116 
117 public: // structors
118 
apply_visitor_delayed_cpp14_t(Visitor & visitor)119     explicit apply_visitor_delayed_cpp14_t(Visitor& visitor) BOOST_NOEXCEPT
120       : visitor_(visitor)
121     {
122     }
123 
124 public: // N-ary visitor interface
125     template <typename... Visitables>
operator ()(Visitables &...visitables) const126     decltype(auto) operator()(Visitables&... visitables) const
127     {
128         return apply_visitor(visitor_, visitables...);
129     }
130 
131 private:
132     apply_visitor_delayed_cpp14_t& operator=(const apply_visitor_delayed_cpp14_t&);
133 
134 };
135 
136 template <typename Visitor>
137 inline  typename boost::disable_if<
138         boost::detail::variant::has_result_type<Visitor>,
139         apply_visitor_delayed_cpp14_t<Visitor>
apply_visitor(Visitor & visitor)140     >::type apply_visitor(Visitor& visitor)
141 {
142     return apply_visitor_delayed_cpp14_t<Visitor>(visitor);
143 }
144 
145 #endif // !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
146             // && !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
147 
148 
149 } // namespace boost
150 
151 #endif // BOOST_VARIANT_DETAIL_APPLY_VISITOR_DELAYED_HPP
152