variant_visit_test.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. //-----------------------------------------------------------------------------
  2. // boost-libs variant/test/variant_visit_test.cpp source file
  3. // See http://www.boost.org for updates, documentation, and revision history.
  4. //-----------------------------------------------------------------------------
  5. //
  6. // Copyright (c) 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. #include "boost/variant/variant.hpp"
  13. #include "boost/variant/apply_visitor.hpp"
  14. #include "boost/variant/static_visitor.hpp"
  15. #include "boost/core/lightweight_test.hpp"
  16. #include "boost/mpl/bool.hpp"
  17. #include "boost/mpl/and.hpp"
  18. #include "boost/type_traits/is_same.hpp"
  19. struct udt1
  20. {
  21. };
  22. struct udt2
  23. {
  24. };
  25. template <typename T>
  26. class unary_check_content_type
  27. : public boost::static_visitor<bool>
  28. {
  29. public:
  30. // not recommended design, but simplifies workarounds:
  31. template <typename U>
  32. bool operator()(U&) const
  33. {
  34. return ::boost::is_same<T,U>::value;
  35. }
  36. };
  37. template <typename T1, typename T2>
  38. class binary_check_content_type
  39. : public boost::static_visitor<bool>
  40. {
  41. public:
  42. // not recommended design, but simplifies workarounds:
  43. template <typename U1, typename U2>
  44. bool operator()(U1&, U2&) const
  45. {
  46. return ::boost::mpl::and_<
  47. boost::is_same<T1,U1>
  48. , boost::is_same<T2,U2>
  49. >::value;
  50. }
  51. };
  52. #ifndef BOOST_NO_CXX11_REF_QUALIFIERS // BOOST_NO_CXX11_RVALUE_REFERENCES is not enough for disabling buggy GCCs < 4.8
  53. struct rvalue_ref_visitor
  54. {
  55. typedef int result_type;
  56. int operator()(udt1&&) const { return 0; }
  57. int operator()(udt2&&) const { return 1; }
  58. };
  59. #endif
  60. #ifdef BOOST_VARIANT_HAS_DECLTYPE_APPLY_VISITOR_RETURN_TYPE
  61. struct rvalue_ref_decltype_visitor
  62. {
  63. int operator()(udt1&&) const { return 0; }
  64. int operator()(udt2&&) const { return 1; }
  65. };
  66. #endif
  67. template <typename Checker, typename Variant>
  68. inline void unary_test(Variant& var, Checker* = 0)
  69. {
  70. Checker checker;
  71. const Checker& const_checker = checker;
  72. // standard tests
  73. BOOST_TEST( boost::apply_visitor(checker, var) );
  74. BOOST_TEST( boost::apply_visitor(const_checker, var) );
  75. BOOST_TEST( boost::apply_visitor(Checker(), var) );
  76. // delayed tests
  77. BOOST_TEST( boost::apply_visitor(checker)(var) );
  78. BOOST_TEST( boost::apply_visitor(const_checker)(var) );
  79. }
  80. template <typename Checker, typename Variant1, typename Variant2>
  81. inline void binary_test(Variant1& var1, Variant2& var2, Checker* = 0)
  82. {
  83. Checker checker;
  84. const Checker& const_checker = checker;
  85. // standard tests
  86. BOOST_TEST( boost::apply_visitor(checker, var1, var2) );
  87. BOOST_TEST( boost::apply_visitor(const_checker, var1, var2) );
  88. BOOST_TEST( boost::apply_visitor(Checker(), var1, var2) );
  89. // delayed tests
  90. BOOST_TEST( boost::apply_visitor(checker)(var1, var2) );
  91. BOOST_TEST( boost::apply_visitor(const_checker)(var1, var2) );
  92. }
  93. int main()
  94. {
  95. typedef boost::variant<udt1,udt2> var_t;
  96. udt1 u1;
  97. var_t var1(u1);
  98. udt2 u2;
  99. var_t var2(u2);
  100. const var_t& cvar1 = var1;
  101. const var_t& cvar2 = var2;
  102. //
  103. // unary tests
  104. //
  105. typedef unary_check_content_type<udt1> check1_t;
  106. typedef unary_check_content_type<const udt1> check1_const_t;
  107. typedef unary_check_content_type<udt2> check2_t;
  108. typedef unary_check_content_type<const udt2> check2_const_t;
  109. unary_test< check1_t >(var1);
  110. unary_test< check1_const_t >(cvar1);
  111. unary_test< check2_t >(var2);
  112. unary_test< check2_const_t >(cvar2);
  113. #ifndef BOOST_NO_CXX11_REF_QUALIFIERS // BOOST_NO_CXX11_RVALUE_REFERENCES is not enough for disabling buggy GCCs < 4.8
  114. BOOST_TEST_EQ( (boost::apply_visitor(
  115. rvalue_ref_visitor(),
  116. boost::variant<udt1, udt2>(udt2()))), 1 );
  117. #endif
  118. #ifdef BOOST_VARIANT_HAS_DECLTYPE_APPLY_VISITOR_RETURN_TYPE
  119. BOOST_TEST_EQ( (boost::apply_visitor(
  120. rvalue_ref_decltype_visitor(),
  121. boost::variant<udt1, udt2>(udt2()))), 1 );
  122. #endif
  123. //
  124. // binary tests
  125. //
  126. typedef binary_check_content_type<udt1,udt2> check12_t;
  127. typedef binary_check_content_type<const udt1, const udt2> check12_const_t;
  128. typedef binary_check_content_type<udt2,udt1> check21_t;
  129. typedef binary_check_content_type<const udt2, const udt1> check21_const_t;
  130. binary_test< check12_t >(var1,var2);
  131. binary_test< check12_const_t >(cvar1,cvar2);
  132. binary_test< check21_t >(var2,var1);
  133. binary_test< check21_const_t >(cvar2,cvar1);
  134. return boost::report_errors();
  135. }