apply_visitor_delayed.hpp 4.4 KB

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