blob: c9146ee7637d8291bc668f58cd879b2877ddd6f1 [file] [log] [blame]
Howard Hinnant3e519522010-05-11 19:42:16 +00001//===----------------------------------------------------------------------===//
2//
Chandler Carruth57b08b02019-01-19 10:56:40 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Howard Hinnant3e519522010-05-11 19:42:16 +00006//
7//===----------------------------------------------------------------------===//
8
9// <utility>
10
Howard Hinnant94b2dd02010-08-22 00:59:46 +000011// template<class T>
12// requires MoveAssignable<T> && MoveConstructible<T>
Howard Hinnant3e519522010-05-11 19:42:16 +000013// void
14// swap(T& a, T& b);
15
16#include <utility>
17#include <cassert>
Howard Hinnant3e519522010-05-11 19:42:16 +000018#include <memory>
Eric Fiselierf07dd8d2016-04-21 23:38:59 +000019
20#include "test_macros.h"
21
22#if TEST_STD_VER >= 11
23struct CopyOnly {
24 CopyOnly() {}
25 CopyOnly(CopyOnly const&) noexcept {}
26 CopyOnly& operator=(CopyOnly const&) { return *this; }
27};
28
29struct MoveOnly {
30 MoveOnly() {}
31 MoveOnly(MoveOnly&&) {}
32 MoveOnly& operator=(MoveOnly&&) noexcept { return *this; }
33};
34
35struct NoexceptMoveOnly {
36 NoexceptMoveOnly() {}
37 NoexceptMoveOnly(NoexceptMoveOnly&&) noexcept {}
38 NoexceptMoveOnly& operator=(NoexceptMoveOnly&&) noexcept { return *this; }
39};
40
41struct NotMoveConstructible {
42 NotMoveConstructible& operator=(NotMoveConstructible&&) { return *this; }
43private:
44 NotMoveConstructible(NotMoveConstructible&&);
45};
46
47struct NotMoveAssignable {
48 NotMoveAssignable(NotMoveAssignable&&);
49private:
50 NotMoveAssignable& operator=(NotMoveAssignable&&);
51};
52
53template <class Tp>
54auto can_swap_test(int) -> decltype(std::swap(std::declval<Tp>(), std::declval<Tp>()));
55
56template <class Tp>
57auto can_swap_test(...) -> std::false_type;
58
59template <class Tp>
60constexpr bool can_swap() {
61 return std::is_same<decltype(can_swap_test<Tp>(0)), void>::value;
62}
Howard Hinnant3e519522010-05-11 19:42:16 +000063#endif
64
Zoe Carver28e01872019-07-05 20:13:34 +000065#if TEST_STD_VER > 17
66constexpr bool test_swap_constexpr()
67{
68 int i = 1;
69 int j = 2;
70 std::swap(i, j);
71 return i == 2 && j == 1;
72}
73#endif // TEST_STD_VER > 17
74
JF Bastien2df59c52019-02-04 20:31:13 +000075int main(int, char**)
Howard Hinnant3e519522010-05-11 19:42:16 +000076{
Eric Fiselierf07dd8d2016-04-21 23:38:59 +000077
78 {
79 int i = 1;
80 int j = 2;
81 std::swap(i, j);
82 assert(i == 2);
83 assert(j == 1);
84 }
85#if TEST_STD_VER >= 11
86 {
87
88 std::unique_ptr<int> i(new int(1));
89 std::unique_ptr<int> j(new int(2));
90 std::swap(i, j);
91 assert(*i == 2);
92 assert(*j == 1);
93
94 }
95 {
96 // test that the swap
97 static_assert(can_swap<CopyOnly&>(), "");
98 static_assert(can_swap<MoveOnly&>(), "");
99 static_assert(can_swap<NoexceptMoveOnly&>(), "");
100
101 static_assert(!can_swap<NotMoveConstructible&>(), "");
102 static_assert(!can_swap<NotMoveAssignable&>(), "");
103
104 CopyOnly c;
105 MoveOnly m;
106 NoexceptMoveOnly nm;
107 static_assert(!noexcept(std::swap(c, c)), "");
108 static_assert(!noexcept(std::swap(m, m)), "");
109 static_assert(noexcept(std::swap(nm, nm)), "");
110 }
Howard Hinnant3e519522010-05-11 19:42:16 +0000111#endif
JF Bastien2df59c52019-02-04 20:31:13 +0000112
Zoe Carver28e01872019-07-05 20:13:34 +0000113#if TEST_STD_VER > 17
114 static_assert(test_swap_constexpr());
115#endif // TEST_STD_VER > 17
116
JF Bastien2df59c52019-02-04 20:31:13 +0000117 return 0;
Howard Hinnant3e519522010-05-11 19:42:16 +0000118}