move.pass.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  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(optional<T>&& rhs);
  12. #include <optional>
  13. #include <type_traits>
  14. #include <cassert>
  15. #include "test_macros.h"
  16. #include "archetypes.hpp"
  17. using std::optional;
  18. template <class T, class ...InitArgs>
  19. void test(InitArgs&&... args)
  20. {
  21. const optional<T> orig(std::forward<InitArgs>(args)...);
  22. optional<T> rhs(orig);
  23. bool rhs_engaged = static_cast<bool>(rhs);
  24. optional<T> lhs = std::move(rhs);
  25. assert(static_cast<bool>(lhs) == rhs_engaged);
  26. if (rhs_engaged)
  27. assert(*lhs == *orig);
  28. }
  29. void test_throwing_ctor() {
  30. #ifndef TEST_HAS_NO_EXCEPTIONS
  31. struct Z {
  32. Z() : count(0) {}
  33. Z(Z&& o) : count(o.count + 1)
  34. { if (count == 2) throw 6; }
  35. int count;
  36. };
  37. Z z;
  38. optional<Z> rhs(std::move(z));
  39. try
  40. {
  41. optional<Z> lhs(std::move(rhs));
  42. assert(false);
  43. }
  44. catch (int i)
  45. {
  46. assert(i == 6);
  47. }
  48. #endif
  49. }
  50. template <class T, class ...InitArgs>
  51. void test_ref(InitArgs&&... args)
  52. {
  53. optional<T> rhs(std::forward<InitArgs>(args)...);
  54. bool rhs_engaged = static_cast<bool>(rhs);
  55. optional<T> lhs = std::move(rhs);
  56. assert(static_cast<bool>(lhs) == rhs_engaged);
  57. if (rhs_engaged)
  58. assert(&(*lhs) == &(*rhs));
  59. }
  60. void test_reference_extension()
  61. {
  62. #if defined(_LIBCPP_VERSION) && 0 // FIXME these extensions are currently disabled.
  63. using T = TestTypes::TestType;
  64. T::reset();
  65. {
  66. T t;
  67. T::reset_constructors();
  68. test_ref<T&>();
  69. test_ref<T&>(t);
  70. assert(T::alive == 1);
  71. assert(T::constructed == 0);
  72. assert(T::assigned == 0);
  73. assert(T::destroyed == 0);
  74. }
  75. assert(T::destroyed == 1);
  76. assert(T::alive == 0);
  77. {
  78. T t;
  79. const T& ct = t;
  80. T::reset_constructors();
  81. test_ref<T const&>();
  82. test_ref<T const&>(t);
  83. test_ref<T const&>(ct);
  84. assert(T::alive == 1);
  85. assert(T::constructed == 0);
  86. assert(T::assigned == 0);
  87. assert(T::destroyed == 0);
  88. }
  89. assert(T::alive == 0);
  90. assert(T::destroyed == 1);
  91. {
  92. T t;
  93. T::reset_constructors();
  94. test_ref<T&&>();
  95. test_ref<T&&>(std::move(t));
  96. assert(T::alive == 1);
  97. assert(T::constructed == 0);
  98. assert(T::assigned == 0);
  99. assert(T::destroyed == 0);
  100. }
  101. assert(T::alive == 0);
  102. assert(T::destroyed == 1);
  103. {
  104. T t;
  105. const T& ct = t;
  106. T::reset_constructors();
  107. test_ref<T const&&>();
  108. test_ref<T const&&>(std::move(t));
  109. test_ref<T const&&>(std::move(ct));
  110. assert(T::alive == 1);
  111. assert(T::constructed == 0);
  112. assert(T::assigned == 0);
  113. assert(T::destroyed == 0);
  114. }
  115. assert(T::alive == 0);
  116. assert(T::destroyed == 1);
  117. {
  118. static_assert(!std::is_copy_constructible<std::optional<T&&>>::value, "");
  119. static_assert(!std::is_copy_constructible<std::optional<T const&&>>::value, "");
  120. }
  121. #endif
  122. }
  123. int main()
  124. {
  125. test<int>();
  126. test<int>(3);
  127. {
  128. using T = TestTypes::TestType;
  129. T::reset();
  130. optional<T> rhs;
  131. assert(T::alive == 0);
  132. const optional<T> lhs(std::move(rhs));
  133. assert(lhs.has_value() == false);
  134. assert(rhs.has_value() == false);
  135. assert(T::alive == 0);
  136. }
  137. TestTypes::TestType::reset();
  138. {
  139. using T = TestTypes::TestType;
  140. T::reset();
  141. optional<T> rhs(42);
  142. assert(T::alive == 1);
  143. assert(T::value_constructed == 1);
  144. assert(T::move_constructed == 0);
  145. const optional<T> lhs(std::move(rhs));
  146. assert(lhs.has_value());
  147. assert(rhs.has_value());
  148. assert(lhs.value().value == 42);
  149. assert(rhs.value().value == -1);
  150. assert(T::move_constructed == 1);
  151. assert(T::alive == 2);
  152. }
  153. TestTypes::TestType::reset();
  154. {
  155. using namespace ConstexprTestTypes;
  156. test<TestType>();
  157. test<TestType>(42);
  158. }
  159. {
  160. using namespace TrivialTestTypes;
  161. test<TestType>();
  162. test<TestType>(42);
  163. }
  164. {
  165. test_throwing_ctor();
  166. }
  167. {
  168. struct ThrowsMove {
  169. ThrowsMove() noexcept(false) {}
  170. ThrowsMove(ThrowsMove const&) noexcept(false) {}
  171. ThrowsMove(ThrowsMove &&) noexcept(false) {}
  172. };
  173. static_assert(!std::is_nothrow_move_constructible<optional<ThrowsMove>>::value, "");
  174. struct NoThrowMove {
  175. NoThrowMove() noexcept(false) {}
  176. NoThrowMove(NoThrowMove const&) noexcept(false) {}
  177. NoThrowMove(NoThrowMove &&) noexcept(true) {}
  178. };
  179. static_assert(std::is_nothrow_move_constructible<optional<NoThrowMove>>::value, "");
  180. }
  181. {
  182. test_reference_extension();
  183. }
  184. }