variant_multivisit_test.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. //-----------------------------------------------------------------------------
  2. // boost-libs variant/test/variant_multivisit_test.cpp source file
  3. // See http://www.boost.org for updates, documentation, and revision history.
  4. //-----------------------------------------------------------------------------
  5. //
  6. // Copyright (c) 2013-2019 Antony Polukhin
  7. //
  8. // Distributed under the Boost Software License, Version 1.0. (See
  9. // accompanying file LICENSE_1_0.txt or copy at
  10. // http://www.boost.org/LICENSE_1_0.txt)
  11. #include "boost/config.hpp"
  12. #include "boost/noncopyable.hpp"
  13. #define BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS 5
  14. #include "boost/variant/multivisitors.hpp"
  15. #include "boost/variant.hpp"
  16. #include "boost/core/lightweight_test.hpp"
  17. struct my_noncopyable : boost::noncopyable {
  18. my_noncopyable(){}
  19. ~my_noncopyable(){}
  20. };
  21. typedef boost::variant<my_noncopyable, int> variant_noncopy_t;
  22. typedef boost::variant<char, unsigned char, signed char, unsigned short, int, unsigned int> variant6_t;
  23. struct test_visitor: boost::static_visitor<> {
  24. // operators that shall not be called
  25. template <class T1, class T2, class T3>
  26. void operator()(T1&, T2&, T3&) const
  27. {
  28. BOOST_TEST(false);
  29. }
  30. template <class T1, class T2, class T3, class T4>
  31. void operator()(T1&, T2&, T3&, T4&) const
  32. {
  33. BOOST_TEST(false);
  34. }
  35. template <class T1, class T2, class T3, class T4, class T5>
  36. void operator()(T1&, T2&, T3&, T4&, T5&) const
  37. {
  38. BOOST_TEST(false);
  39. }
  40. // operators that are OK to call
  41. void operator()(char v0, unsigned char v1, signed char v2) const
  42. {
  43. BOOST_TEST(v0 == 0);
  44. BOOST_TEST(v1 == 1);
  45. BOOST_TEST(v2 == 2);
  46. }
  47. void operator()(char v0, unsigned char v1, signed char v2, unsigned short v3) const
  48. {
  49. BOOST_TEST(v0 == 0);
  50. BOOST_TEST(v1 == 1);
  51. BOOST_TEST(v2 == 2);
  52. BOOST_TEST(v3 == 3);
  53. }
  54. void operator()(char v0, unsigned char v1, signed char v2, unsigned short v3, int v4) const
  55. {
  56. BOOST_TEST(v0 == 0);
  57. BOOST_TEST(v1 == 1);
  58. BOOST_TEST(v2 == 2);
  59. BOOST_TEST(v3 == 3);
  60. BOOST_TEST(v4 == 4);
  61. }
  62. // Noncopyables
  63. void operator()(my_noncopyable&, my_noncopyable&, my_noncopyable&) const {
  64. BOOST_TEST(true);
  65. }
  66. void operator()(my_noncopyable&, my_noncopyable&, my_noncopyable&, my_noncopyable&) const {
  67. BOOST_TEST(true);
  68. }
  69. void operator()(my_noncopyable&, my_noncopyable&, my_noncopyable&, my_noncopyable&, my_noncopyable&) const {
  70. BOOST_TEST(true);
  71. }
  72. void operator()(my_noncopyable&, my_noncopyable&, my_noncopyable&, my_noncopyable&, my_noncopyable&, my_noncopyable&) const {
  73. BOOST_TEST(true);
  74. }
  75. };
  76. typedef boost::variant<int, double, bool> bool_like_t;
  77. typedef boost::variant<int, double> arithmetics_t;
  78. struct if_visitor: public boost::static_visitor<arithmetics_t> {
  79. template <class T0, class T1, class T2>
  80. arithmetics_t operator()(T0 b, T1 v1, T2 v2) const {
  81. if (!!b) {
  82. return v1;
  83. } else {
  84. return v2;
  85. }
  86. }
  87. };
  88. int main()
  89. {
  90. test_visitor v;
  91. variant6_t v_array6[6];
  92. v_array6[0] = char(0);
  93. v_array6[1] = static_cast<unsigned char>(1);
  94. v_array6[2] = static_cast<signed char>(2);
  95. v_array6[3] = static_cast<unsigned short>(3);
  96. v_array6[4] = static_cast<int>(4);
  97. v_array6[5] = static_cast<unsigned int>(5);
  98. boost::apply_visitor(v, v_array6[0], v_array6[1], v_array6[2]);
  99. boost::apply_visitor(test_visitor(), v_array6[0], v_array6[1], v_array6[2]);
  100. // Following test also pass, but requires many Gigabytes of RAM for compilation and compile for about 15 minutes
  101. //#define BOOST_VARIANT_MULTIVISITORS_TEST_VERY_EXTREME
  102. #ifdef BOOST_VARIANT_MULTIVISITORS_TEST_VERY_EXTREME
  103. boost::apply_visitor(v, v_array6[0], v_array6[1], v_array6[2], v_array6[3]);
  104. boost::apply_visitor(test_visitor(), v_array6[0], v_array6[1], v_array6[2], v_array6[3]);
  105. boost::apply_visitor(v, v_array6[0], v_array6[1], v_array6[2], v_array6[3], v_array6[4]);
  106. boost::apply_visitor(test_visitor(), v_array6[0], v_array6[1], v_array6[2], v_array6[3], v_array6[4]);
  107. #endif
  108. bool_like_t v0(1), v1(true), v2(1.0);
  109. BOOST_TEST(
  110. boost::apply_visitor(if_visitor(), v0, v1, v2)
  111. ==
  112. arithmetics_t(true)
  113. );
  114. #if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
  115. if_visitor if_vis;
  116. BOOST_TEST(
  117. boost::apply_visitor(if_vis)(v0, v1, v2)
  118. ==
  119. arithmetics_t(true)
  120. );
  121. #endif
  122. variant_noncopy_t vnonc[6];
  123. boost::apply_visitor(v, vnonc[0], vnonc[1], vnonc[2]);
  124. boost::apply_visitor(test_visitor(), vnonc[0], vnonc[1], vnonc[2], vnonc[3]);
  125. #ifdef BOOST_VARIANT_MULTIVISITORS_TEST_VERY_EXTREME
  126. boost::apply_visitor(v, vnonc[0], vnonc[1], vnonc[2], vnonc[3], vnonc[4]);
  127. boost::apply_visitor(test_visitor(), vnonc[0], vnonc[1], vnonc[2], vnonc[3], vnonc[4], vnonc[5]);
  128. #endif
  129. return boost::report_errors();
  130. }