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