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