swap.pass.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  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. // template <class T> void swap(optional<T>& x, optional<T>& y)
  12. // noexcept(noexcept(x.swap(y)));
  13. #include <optional>
  14. #include <type_traits>
  15. #include <cassert>
  16. #include "test_macros.h"
  17. #include "archetypes.hpp"
  18. using std::optional;
  19. class X
  20. {
  21. int i_;
  22. public:
  23. static unsigned dtor_called;
  24. X(int i) : i_(i) {}
  25. X(X&& x) = default;
  26. X& operator=(X&&) = default;
  27. ~X() {++dtor_called;}
  28. friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
  29. };
  30. unsigned X::dtor_called = 0;
  31. class Y
  32. {
  33. int i_;
  34. public:
  35. static unsigned dtor_called;
  36. Y(int i) : i_(i) {}
  37. Y(Y&&) = default;
  38. ~Y() {++dtor_called;}
  39. friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;}
  40. friend void swap(Y& x, Y& y) {std::swap(x.i_, y.i_);}
  41. };
  42. unsigned Y::dtor_called = 0;
  43. class Z
  44. {
  45. int i_;
  46. public:
  47. Z(int i) : i_(i) {}
  48. Z(Z&&) { TEST_THROW(7);}
  49. friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;}
  50. friend void swap(Z& x, Z& y) { TEST_THROW(6);}
  51. };
  52. struct NonSwappable {
  53. NonSwappable(NonSwappable const&) = delete;
  54. };
  55. void swap(NonSwappable&, NonSwappable&) = delete;
  56. void test_swap_sfinae() {
  57. using std::optional;
  58. {
  59. using T = TestTypes::TestType;
  60. static_assert(std::is_swappable_v<optional<T>>, "");
  61. }
  62. {
  63. using T = TestTypes::MoveOnly;
  64. static_assert(std::is_swappable_v<optional<T>>, "");
  65. }
  66. {
  67. using T = TestTypes::Copyable;
  68. static_assert(std::is_swappable_v<optional<T>>, "");
  69. }
  70. {
  71. using T = TestTypes::NoCtors;
  72. static_assert(!std::is_swappable_v<optional<T>>, "");
  73. }
  74. {
  75. using T = NonSwappable;
  76. static_assert(!std::is_swappable_v<optional<T>>, "");
  77. }
  78. {
  79. // Even thought CopyOnly has deleted move operations, those operations
  80. // cause optional<CopyOnly> to have implicitly deleted move operations
  81. // that decay into copies.
  82. using T = TestTypes::CopyOnly;
  83. using Opt = optional<T>;
  84. T::reset();
  85. Opt L(101), R(42);
  86. T::reset_constructors();
  87. std::swap(L, R);
  88. assert(L->value == 42);
  89. assert(R->value == 101);
  90. assert(T::copy_constructed == 1);
  91. assert(T::constructed == T::copy_constructed);
  92. assert(T::assigned == 2);
  93. assert(T::assigned == T::copy_assigned);
  94. }
  95. }
  96. int main()
  97. {
  98. test_swap_sfinae();
  99. {
  100. optional<int> opt1;
  101. optional<int> opt2;
  102. static_assert(noexcept(swap(opt1, opt2)) == true, "");
  103. assert(static_cast<bool>(opt1) == false);
  104. assert(static_cast<bool>(opt2) == false);
  105. swap(opt1, opt2);
  106. assert(static_cast<bool>(opt1) == false);
  107. assert(static_cast<bool>(opt2) == false);
  108. }
  109. {
  110. optional<int> opt1(1);
  111. optional<int> opt2;
  112. static_assert(noexcept(swap(opt1, opt2)) == true, "");
  113. assert(static_cast<bool>(opt1) == true);
  114. assert(*opt1 == 1);
  115. assert(static_cast<bool>(opt2) == false);
  116. swap(opt1, opt2);
  117. assert(static_cast<bool>(opt1) == false);
  118. assert(static_cast<bool>(opt2) == true);
  119. assert(*opt2 == 1);
  120. }
  121. {
  122. optional<int> opt1;
  123. optional<int> opt2(2);
  124. static_assert(noexcept(swap(opt1, opt2)) == true, "");
  125. assert(static_cast<bool>(opt1) == false);
  126. assert(static_cast<bool>(opt2) == true);
  127. assert(*opt2 == 2);
  128. swap(opt1, opt2);
  129. assert(static_cast<bool>(opt1) == true);
  130. assert(*opt1 == 2);
  131. assert(static_cast<bool>(opt2) == false);
  132. }
  133. {
  134. optional<int> opt1(1);
  135. optional<int> opt2(2);
  136. static_assert(noexcept(swap(opt1, opt2)) == true, "");
  137. assert(static_cast<bool>(opt1) == true);
  138. assert(*opt1 == 1);
  139. assert(static_cast<bool>(opt2) == true);
  140. assert(*opt2 == 2);
  141. swap(opt1, opt2);
  142. assert(static_cast<bool>(opt1) == true);
  143. assert(*opt1 == 2);
  144. assert(static_cast<bool>(opt2) == true);
  145. assert(*opt2 == 1);
  146. }
  147. {
  148. optional<X> opt1;
  149. optional<X> opt2;
  150. static_assert(noexcept(swap(opt1, opt2)) == true, "");
  151. assert(static_cast<bool>(opt1) == false);
  152. assert(static_cast<bool>(opt2) == false);
  153. swap(opt1, opt2);
  154. assert(static_cast<bool>(opt1) == false);
  155. assert(static_cast<bool>(opt2) == false);
  156. assert(X::dtor_called == 0);
  157. }
  158. {
  159. optional<X> opt1(1);
  160. optional<X> opt2;
  161. static_assert(noexcept(swap(opt1, opt2)) == true, "");
  162. assert(static_cast<bool>(opt1) == true);
  163. assert(*opt1 == 1);
  164. assert(static_cast<bool>(opt2) == false);
  165. X::dtor_called = 0;
  166. swap(opt1, opt2);
  167. assert(X::dtor_called == 1);
  168. assert(static_cast<bool>(opt1) == false);
  169. assert(static_cast<bool>(opt2) == true);
  170. assert(*opt2 == 1);
  171. }
  172. {
  173. optional<X> opt1;
  174. optional<X> opt2(2);
  175. static_assert(noexcept(swap(opt1, opt2)) == true, "");
  176. assert(static_cast<bool>(opt1) == false);
  177. assert(static_cast<bool>(opt2) == true);
  178. assert(*opt2 == 2);
  179. X::dtor_called = 0;
  180. swap(opt1, opt2);
  181. assert(X::dtor_called == 1);
  182. assert(static_cast<bool>(opt1) == true);
  183. assert(*opt1 == 2);
  184. assert(static_cast<bool>(opt2) == false);
  185. }
  186. {
  187. optional<X> opt1(1);
  188. optional<X> opt2(2);
  189. static_assert(noexcept(swap(opt1, opt2)) == true, "");
  190. assert(static_cast<bool>(opt1) == true);
  191. assert(*opt1 == 1);
  192. assert(static_cast<bool>(opt2) == true);
  193. assert(*opt2 == 2);
  194. X::dtor_called = 0;
  195. swap(opt1, opt2);
  196. assert(X::dtor_called == 1); // from inside std::swap
  197. assert(static_cast<bool>(opt1) == true);
  198. assert(*opt1 == 2);
  199. assert(static_cast<bool>(opt2) == true);
  200. assert(*opt2 == 1);
  201. }
  202. {
  203. optional<Y> opt1;
  204. optional<Y> opt2;
  205. static_assert(noexcept(swap(opt1, opt2)) == false, "");
  206. assert(static_cast<bool>(opt1) == false);
  207. assert(static_cast<bool>(opt2) == false);
  208. swap(opt1, opt2);
  209. assert(static_cast<bool>(opt1) == false);
  210. assert(static_cast<bool>(opt2) == false);
  211. assert(Y::dtor_called == 0);
  212. }
  213. {
  214. optional<Y> opt1(1);
  215. optional<Y> opt2;
  216. static_assert(noexcept(swap(opt1, opt2)) == false, "");
  217. assert(static_cast<bool>(opt1) == true);
  218. assert(*opt1 == 1);
  219. assert(static_cast<bool>(opt2) == false);
  220. Y::dtor_called = 0;
  221. swap(opt1, opt2);
  222. assert(Y::dtor_called == 1);
  223. assert(static_cast<bool>(opt1) == false);
  224. assert(static_cast<bool>(opt2) == true);
  225. assert(*opt2 == 1);
  226. }
  227. {
  228. optional<Y> opt1;
  229. optional<Y> opt2(2);
  230. static_assert(noexcept(swap(opt1, opt2)) == false, "");
  231. assert(static_cast<bool>(opt1) == false);
  232. assert(static_cast<bool>(opt2) == true);
  233. assert(*opt2 == 2);
  234. Y::dtor_called = 0;
  235. swap(opt1, opt2);
  236. assert(Y::dtor_called == 1);
  237. assert(static_cast<bool>(opt1) == true);
  238. assert(*opt1 == 2);
  239. assert(static_cast<bool>(opt2) == false);
  240. }
  241. {
  242. optional<Y> opt1(1);
  243. optional<Y> opt2(2);
  244. static_assert(noexcept(swap(opt1, opt2)) == false, "");
  245. assert(static_cast<bool>(opt1) == true);
  246. assert(*opt1 == 1);
  247. assert(static_cast<bool>(opt2) == true);
  248. assert(*opt2 == 2);
  249. Y::dtor_called = 0;
  250. swap(opt1, opt2);
  251. assert(Y::dtor_called == 0);
  252. assert(static_cast<bool>(opt1) == true);
  253. assert(*opt1 == 2);
  254. assert(static_cast<bool>(opt2) == true);
  255. assert(*opt2 == 1);
  256. }
  257. {
  258. optional<Z> opt1;
  259. optional<Z> opt2;
  260. static_assert(noexcept(swap(opt1, opt2)) == false, "");
  261. assert(static_cast<bool>(opt1) == false);
  262. assert(static_cast<bool>(opt2) == false);
  263. swap(opt1, opt2);
  264. assert(static_cast<bool>(opt1) == false);
  265. assert(static_cast<bool>(opt2) == false);
  266. }
  267. #ifndef TEST_HAS_NO_EXCEPTIONS
  268. {
  269. optional<Z> opt1;
  270. opt1.emplace(1);
  271. optional<Z> opt2;
  272. static_assert(noexcept(swap(opt1, opt2)) == false, "");
  273. assert(static_cast<bool>(opt1) == true);
  274. assert(*opt1 == 1);
  275. assert(static_cast<bool>(opt2) == false);
  276. try
  277. {
  278. swap(opt1, opt2);
  279. assert(false);
  280. }
  281. catch (int i)
  282. {
  283. assert(i == 7);
  284. }
  285. assert(static_cast<bool>(opt1) == true);
  286. assert(*opt1 == 1);
  287. assert(static_cast<bool>(opt2) == false);
  288. }
  289. {
  290. optional<Z> opt1;
  291. optional<Z> opt2;
  292. opt2.emplace(2);
  293. static_assert(noexcept(swap(opt1, opt2)) == false, "");
  294. assert(static_cast<bool>(opt1) == false);
  295. assert(static_cast<bool>(opt2) == true);
  296. assert(*opt2 == 2);
  297. try
  298. {
  299. swap(opt1, opt2);
  300. assert(false);
  301. }
  302. catch (int i)
  303. {
  304. assert(i == 7);
  305. }
  306. assert(static_cast<bool>(opt1) == false);
  307. assert(static_cast<bool>(opt2) == true);
  308. assert(*opt2 == 2);
  309. }
  310. {
  311. optional<Z> opt1;
  312. opt1.emplace(1);
  313. optional<Z> opt2;
  314. opt2.emplace(2);
  315. static_assert(noexcept(swap(opt1, opt2)) == false, "");
  316. assert(static_cast<bool>(opt1) == true);
  317. assert(*opt1 == 1);
  318. assert(static_cast<bool>(opt2) == true);
  319. assert(*opt2 == 2);
  320. try
  321. {
  322. swap(opt1, opt2);
  323. assert(false);
  324. }
  325. catch (int i)
  326. {
  327. assert(i == 6);
  328. }
  329. assert(static_cast<bool>(opt1) == true);
  330. assert(*opt1 == 1);
  331. assert(static_cast<bool>(opt2) == true);
  332. assert(*opt2 == 2);
  333. }
  334. #endif // TEST_HAS_NO_EXCEPTIONS
  335. }