visitor_ptr.hpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. //-----------------------------------------------------------------------------
  2. // boost variant/visitor_ptr.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_VISITOR_PTR_HPP
  13. #define BOOST_VARIANT_VISITOR_PTR_HPP
  14. #include "boost/variant/bad_visit.hpp"
  15. #include "boost/variant/static_visitor.hpp"
  16. #include "boost/mpl/eval_if.hpp"
  17. #include "boost/mpl/identity.hpp"
  18. #include "boost/throw_exception.hpp"
  19. #include "boost/type_traits/add_reference.hpp"
  20. #include "boost/type_traits/is_reference.hpp"
  21. #include "boost/type_traits/is_void.hpp"
  22. namespace boost {
  23. //////////////////////////////////////////////////////////////////////////
  24. // function template visitor_ptr
  25. //
  26. // Adapts a function pointer for use as visitor capable of handling
  27. // values of a single type. Throws bad_visit if inappropriately applied.
  28. //
  29. template <typename T, typename R>
  30. class visitor_ptr_t
  31. : public static_visitor<R>
  32. {
  33. private: // representation
  34. typedef R (*visitor_t)(T);
  35. visitor_t visitor_;
  36. public: // typedefs
  37. typedef R result_type;
  38. private: // private typedefs
  39. typedef typename mpl::eval_if<
  40. is_reference<T>
  41. , mpl::identity<T>
  42. , add_reference<const T>
  43. >::type argument_fwd_type;
  44. public: // structors
  45. explicit visitor_ptr_t(visitor_t visitor) BOOST_NOEXCEPT
  46. : visitor_(visitor)
  47. {
  48. }
  49. public: // static visitor interfaces
  50. template <typename U>
  51. result_type operator()(const U&) const
  52. {
  53. boost::throw_exception(bad_visit());
  54. }
  55. #if !defined(BOOST_NO_VOID_RETURNS)
  56. public: // static visitor interfaces, cont.
  57. result_type operator()(argument_fwd_type operand) const
  58. {
  59. return visitor_(operand);
  60. }
  61. #else // defined(BOOST_NO_VOID_RETURNS)
  62. private: // helpers, for static visitor interfaces (below)
  63. result_type execute_impl(argument_fwd_type operand, mpl::false_) const
  64. {
  65. return visitor_(operand);
  66. }
  67. BOOST_VARIANT_AUX_RETURN_VOID_TYPE
  68. execute_impl(argument_fwd_type operand, mpl::true_) const
  69. {
  70. visitor_(operand);
  71. BOOST_VARIANT_AUX_RETURN_VOID;
  72. }
  73. public: // static visitor interfaces, cont.
  74. BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
  75. operator()(argument_fwd_type operand) const
  76. {
  77. typedef typename is_void<result_type>::type has_void_result;
  78. return execute_impl(operand, has_void_result());
  79. }
  80. #endif // BOOST_NO_VOID_RETURNS workaround
  81. };
  82. template <typename R, typename T>
  83. inline visitor_ptr_t<T,R> visitor_ptr(R (*visitor)(T))
  84. {
  85. return visitor_ptr_t<T,R>(visitor);
  86. }
  87. } // namespace boost
  88. #endif// BOOST_VISITOR_VISITOR_PTR_HPP