apply_visitor_binary.hpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. //-----------------------------------------------------------------------------
  2. // boost variant/detail/apply_visitor_binary.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_BINARY_HPP
  13. #define BOOST_VARIANT_DETAIL_APPLY_VISITOR_BINARY_HPP
  14. #include "boost/config.hpp"
  15. #include "boost/detail/workaround.hpp"
  16. #include "boost/variant/detail/generic_result_type.hpp"
  17. #include "boost/variant/detail/apply_visitor_unary.hpp"
  18. #if BOOST_WORKAROUND(__EDG__, BOOST_TESTED_AT(302))
  19. #include "boost/utility/enable_if.hpp"
  20. #include "boost/mpl/not.hpp"
  21. #include "boost/type_traits/is_const.hpp"
  22. #endif
  23. namespace boost {
  24. //////////////////////////////////////////////////////////////////////////
  25. // function template apply_visitor(visitor, visitable1, visitable2)
  26. //
  27. // Visits visitable1 and visitable2 such that their values (which we
  28. // shall call x and y, respectively) are used as arguments in the
  29. // expression visitor(x, y).
  30. //
  31. namespace detail { namespace variant {
  32. template <typename Visitor, typename Value1>
  33. class apply_visitor_binary_invoke
  34. {
  35. public: // visitor typedefs
  36. typedef typename Visitor::result_type
  37. result_type;
  38. private: // representation
  39. Visitor& visitor_;
  40. Value1& value1_;
  41. public: // structors
  42. apply_visitor_binary_invoke(Visitor& visitor, Value1& value1)
  43. : visitor_(visitor)
  44. , value1_(value1)
  45. {
  46. }
  47. public: // visitor interfaces
  48. template <typename Value2>
  49. BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
  50. operator()(Value2& value2)
  51. {
  52. return visitor_(value1_, value2);
  53. }
  54. private:
  55. apply_visitor_binary_invoke& operator=(const apply_visitor_binary_invoke&);
  56. };
  57. template <typename Visitor, typename Visitable2>
  58. class apply_visitor_binary_unwrap
  59. {
  60. public: // visitor typedefs
  61. typedef typename Visitor::result_type
  62. result_type;
  63. private: // representation
  64. Visitor& visitor_;
  65. Visitable2& visitable2_;
  66. public: // structors
  67. apply_visitor_binary_unwrap(Visitor& visitor, Visitable2& visitable2)
  68. : visitor_(visitor)
  69. , visitable2_(visitable2)
  70. {
  71. }
  72. public: // visitor interfaces
  73. template <typename Value1>
  74. BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
  75. operator()(Value1& value1)
  76. {
  77. apply_visitor_binary_invoke<
  78. Visitor
  79. , Value1
  80. > invoker(visitor_, value1);
  81. return boost::apply_visitor(invoker, visitable2_);
  82. }
  83. private:
  84. apply_visitor_binary_unwrap& operator=(const apply_visitor_binary_unwrap&);
  85. };
  86. }} // namespace detail::variant
  87. //
  88. // nonconst-visitor version:
  89. //
  90. #if !BOOST_WORKAROUND(__EDG__, BOOST_TESTED_AT(302))
  91. # define BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(V) \
  92. BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename V::result_type) \
  93. /**/
  94. #else // EDG-based compilers
  95. # define BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(V) \
  96. typename enable_if< \
  97. mpl::not_< is_const< V > > \
  98. , BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename V::result_type) \
  99. >::type \
  100. /**/
  101. #endif // EDG-based compilers workaround
  102. template <typename Visitor, typename Visitable1, typename Visitable2>
  103. inline
  104. BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(Visitor)
  105. apply_visitor(
  106. Visitor& visitor
  107. , Visitable1& visitable1, Visitable2& visitable2
  108. )
  109. {
  110. ::boost::detail::variant::apply_visitor_binary_unwrap<
  111. Visitor, Visitable2
  112. > unwrapper(visitor, visitable2);
  113. return boost::apply_visitor(unwrapper, visitable1);
  114. }
  115. #undef BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE
  116. //
  117. // const-visitor version:
  118. //
  119. #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
  120. template <typename Visitor, typename Visitable1, typename Visitable2>
  121. inline
  122. BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
  123. typename Visitor::result_type
  124. )
  125. apply_visitor(
  126. const Visitor& visitor
  127. , Visitable1& visitable1, Visitable2& visitable2
  128. )
  129. {
  130. ::boost::detail::variant::apply_visitor_binary_unwrap<
  131. const Visitor, Visitable2
  132. > unwrapper(visitor, visitable2);
  133. return boost::apply_visitor(unwrapper, visitable1);
  134. }
  135. #endif // MSVC7 and below exclusion
  136. } // namespace boost
  137. #endif // BOOST_VARIANT_DETAIL_APPLY_VISITOR_BINARY_HPP