move.pass.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. //===----------------------------------------------------------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is dual licensed under the MIT and the University of Illinois Open
  6. // Source Licenses. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. // UNSUPPORTED: c++98, c++03, c++11, c++14
  10. // <optional>
  11. // optional<T>& operator=(optional<T>&& rhs)
  12. // noexcept(is_nothrow_move_assignable<T>::value &&
  13. // is_nothrow_move_constructible<T>::value);
  14. #include <optional>
  15. #include <type_traits>
  16. #include <cassert>
  17. #include "test_macros.h"
  18. #include "archetypes.hpp"
  19. using std::optional;
  20. struct X
  21. {
  22. static bool throw_now;
  23. static int alive;
  24. X() { ++alive; }
  25. X(X&&)
  26. {
  27. if (throw_now)
  28. TEST_THROW(6);
  29. ++alive;
  30. }
  31. X& operator=(X&&)
  32. {
  33. if (throw_now)
  34. TEST_THROW(42);
  35. return *this;
  36. }
  37. ~X() { assert(alive > 0); --alive; }
  38. };
  39. struct Y {};
  40. bool X::throw_now = false;
  41. int X::alive = 0;
  42. int main()
  43. {
  44. {
  45. static_assert(std::is_nothrow_move_assignable<optional<int>>::value, "");
  46. optional<int> opt;
  47. constexpr optional<int> opt2;
  48. opt = std::move(opt2);
  49. static_assert(static_cast<bool>(opt2) == false, "");
  50. assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
  51. }
  52. {
  53. optional<int> opt;
  54. constexpr optional<int> opt2(2);
  55. opt = std::move(opt2);
  56. static_assert(static_cast<bool>(opt2) == true, "");
  57. static_assert(*opt2 == 2, "");
  58. assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
  59. assert(*opt == *opt2);
  60. }
  61. {
  62. optional<int> opt(3);
  63. constexpr optional<int> opt2;
  64. opt = std::move(opt2);
  65. static_assert(static_cast<bool>(opt2) == false, "");
  66. assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
  67. }
  68. {
  69. using T = TestTypes::TestType;
  70. T::reset();
  71. optional<T> opt(3);
  72. optional<T> opt2;
  73. assert(T::alive == 1);
  74. opt = std::move(opt2);
  75. assert(T::alive == 0);
  76. assert(static_cast<bool>(opt2) == false);
  77. assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
  78. }
  79. {
  80. optional<int> opt(3);
  81. constexpr optional<int> opt2(2);
  82. opt = std::move(opt2);
  83. static_assert(static_cast<bool>(opt2) == true, "");
  84. static_assert(*opt2 == 2, "");
  85. assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
  86. assert(*opt == *opt2);
  87. }
  88. #ifndef TEST_HAS_NO_EXCEPTIONS
  89. {
  90. static_assert(!std::is_nothrow_move_assignable<optional<X>>::value, "");
  91. X::alive = 0;
  92. X::throw_now = false;
  93. optional<X> opt;
  94. optional<X> opt2(X{});
  95. assert(X::alive == 1);
  96. assert(static_cast<bool>(opt2) == true);
  97. try
  98. {
  99. X::throw_now = true;
  100. opt = std::move(opt2);
  101. assert(false);
  102. }
  103. catch (int i)
  104. {
  105. assert(i == 6);
  106. assert(static_cast<bool>(opt) == false);
  107. }
  108. assert(X::alive == 1);
  109. }
  110. assert(X::alive == 0);
  111. {
  112. static_assert(!std::is_nothrow_move_assignable<optional<X>>::value, "");
  113. X::throw_now = false;
  114. optional<X> opt(X{});
  115. optional<X> opt2(X{});
  116. assert(X::alive == 2);
  117. assert(static_cast<bool>(opt2) == true);
  118. try
  119. {
  120. X::throw_now = true;
  121. opt = std::move(opt2);
  122. assert(false);
  123. }
  124. catch (int i)
  125. {
  126. assert(i == 42);
  127. assert(static_cast<bool>(opt) == true);
  128. }
  129. assert(X::alive == 2);
  130. }
  131. assert(X::alive == 0);
  132. #endif // TEST_HAS_NO_EXCEPTIONS
  133. {
  134. static_assert(std::is_nothrow_move_assignable<optional<Y>>::value, "");
  135. }
  136. {
  137. struct ThrowsMove {
  138. ThrowsMove() noexcept {}
  139. ThrowsMove(ThrowsMove const&) noexcept {}
  140. ThrowsMove(ThrowsMove &&) noexcept(false) {}
  141. ThrowsMove& operator=(ThrowsMove const&) noexcept { return *this; }
  142. ThrowsMove& operator=(ThrowsMove &&) noexcept { return *this; }
  143. };
  144. static_assert(!std::is_nothrow_move_assignable<optional<ThrowsMove>>::value, "");
  145. struct ThrowsMoveAssign {
  146. ThrowsMoveAssign() noexcept {}
  147. ThrowsMoveAssign(ThrowsMoveAssign const&) noexcept {}
  148. ThrowsMoveAssign(ThrowsMoveAssign &&) noexcept {}
  149. ThrowsMoveAssign& operator=(ThrowsMoveAssign const&) noexcept { return *this; }
  150. ThrowsMoveAssign& operator=(ThrowsMoveAssign &&) noexcept(false) { return *this; }
  151. };
  152. static_assert(!std::is_nothrow_move_assignable<optional<ThrowsMoveAssign>>::value, "");
  153. struct NoThrowMove {
  154. NoThrowMove() noexcept(false) {}
  155. NoThrowMove(NoThrowMove const&) noexcept(false) {}
  156. NoThrowMove(NoThrowMove &&) noexcept {}
  157. NoThrowMove& operator=(NoThrowMove const&) noexcept { return *this; }
  158. NoThrowMove& operator=(NoThrowMove&&) noexcept { return *this; }
  159. };
  160. static_assert(std::is_nothrow_move_assignable<optional<NoThrowMove>>::value, "");
  161. }
  162. }