variant_move_construct.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. // Copyright 2017 Peter Dimov.
  2. //
  3. // Distributed under the Boost Software License, Version 1.0.
  4. //
  5. // See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt
  7. #include <boost/variant2/variant.hpp>
  8. #include <boost/core/lightweight_test.hpp>
  9. #include <boost/core/lightweight_test_trait.hpp>
  10. #include <type_traits>
  11. #include <utility>
  12. #include <string>
  13. using namespace boost::variant2;
  14. #define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
  15. struct X1
  16. {
  17. X1() {}
  18. X1(X1 const&) {}
  19. X1(X1&&) {}
  20. };
  21. inline bool operator==( X1, X1 ) { return true; }
  22. STATIC_ASSERT( !std::is_nothrow_default_constructible<X1>::value );
  23. STATIC_ASSERT( !std::is_nothrow_copy_constructible<X1>::value );
  24. STATIC_ASSERT( !std::is_nothrow_move_constructible<X1>::value );
  25. struct X2
  26. {
  27. X2() {}
  28. X2(X2 const&) {}
  29. X2(X2&&) {}
  30. };
  31. inline bool operator==( X2, X2 ) { return true; }
  32. STATIC_ASSERT( !std::is_nothrow_default_constructible<X2>::value );
  33. STATIC_ASSERT( !std::is_nothrow_copy_constructible<X2>::value );
  34. STATIC_ASSERT( !std::is_nothrow_move_constructible<X2>::value );
  35. struct Y
  36. {
  37. Y( Y&& ) = delete;
  38. };
  39. template<class V> static void test( V&& v )
  40. {
  41. V v2( v );
  42. V v3( std::move(v) );
  43. BOOST_TEST_EQ( v2.index(), v3.index() );
  44. BOOST_TEST( v2 == v3 );
  45. }
  46. int main()
  47. {
  48. test( variant<int>() );
  49. test( variant<int>(1) );
  50. test( variant<int const>() );
  51. test( variant<int const>(1) );
  52. test( variant<int, float>() );
  53. test( variant<int, float>(1) );
  54. test( variant<int, float>(3.14f) );
  55. test( variant<int const, float const>() );
  56. test( variant<int const, float const>(1) );
  57. test( variant<int const, float const>(3.14f) );
  58. test( variant<std::string>() );
  59. test( variant<std::string>("test") );
  60. test( variant<std::string const>() );
  61. test( variant<std::string const>("test") );
  62. test( variant<int, float, std::string>() );
  63. test( variant<int, float, std::string>(1) );
  64. test( variant<int, float, std::string>(3.14f) );
  65. test( variant<int, float, std::string>("test") );
  66. test( variant<int, int>() );
  67. test( variant<int, int, float>() );
  68. test( variant<int, int, float>(3.14f) );
  69. test( variant<int, int, float, float>() );
  70. test( variant<int, int, float, float, std::string>("test") );
  71. test( variant<std::string, std::string, float>() );
  72. test( variant<X1 const>() );
  73. test( variant<X1, X2>() );
  74. test( variant<X1, X2, int>() );
  75. test( variant<X1, X2, X2>() );
  76. test( variant<X1, X1, X2, X2>() );
  77. {
  78. variant<X1, X2> v;
  79. v.emplace<X2>();
  80. test( std::move(v) );
  81. }
  82. {
  83. variant<X1, X1, X2> v;
  84. v.emplace<X2>();
  85. test( std::move(v) );
  86. }
  87. {
  88. BOOST_TEST_TRAIT_TRUE((std::is_nothrow_move_constructible<variant<int>>));
  89. BOOST_TEST_TRAIT_TRUE((std::is_nothrow_move_constructible<variant<int const>>));
  90. BOOST_TEST_TRAIT_TRUE((std::is_nothrow_move_constructible<variant<int, int>>));
  91. BOOST_TEST_TRAIT_TRUE((std::is_nothrow_move_constructible<variant<int, float>>));
  92. BOOST_TEST_TRAIT_TRUE((std::is_nothrow_move_constructible<variant<int, int, float, float>>));
  93. BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_constructible<variant<X1>>));
  94. BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_constructible<variant<X1, int>>));
  95. BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_constructible<variant<X1, int, float>>));
  96. BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_constructible<variant<int, X1>>));
  97. BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_constructible<variant<int, int, X1>>));
  98. BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_constructible<variant<X1, X2>>));
  99. BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_constructible<variant<X1, X2, int, int>>));
  100. BOOST_TEST_TRAIT_TRUE((std::is_move_constructible<variant<X1, X2>>));
  101. #if !BOOST_WORKAROUND( BOOST_MSVC, <= 1910 )
  102. BOOST_TEST_TRAIT_FALSE((std::is_move_constructible<variant<int, float, Y>>));
  103. #endif
  104. }
  105. return boost::report_errors();
  106. }