swap.pass.cpp 9.9 KB

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