blob: f52af4cb896e9850e76ed474d3ff19804bddbbde [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
JF Bastien2df59c52019-02-04 20:31:13 +000065int main(int, char**)
Howard Hinnant3e519522010-05-11 19:42:16 +000066{
Eric Fiselierf07dd8d2016-04-21 23:38:59 +000067
68 {
69 int i = 1;
70 int j = 2;
71 std::swap(i, j);
72 assert(i == 2);
73 assert(j == 1);
74 }
75#if TEST_STD_VER >= 11
76 {
77
78 std::unique_ptr<int> i(new int(1));
79 std::unique_ptr<int> j(new int(2));
80 std::swap(i, j);
81 assert(*i == 2);
82 assert(*j == 1);
83
84 }
85 {
86 // test that the swap
87 static_assert(can_swap<CopyOnly&>(), "");
88 static_assert(can_swap<MoveOnly&>(), "");
89 static_assert(can_swap<NoexceptMoveOnly&>(), "");
90
91 static_assert(!can_swap<NotMoveConstructible&>(), "");
92 static_assert(!can_swap<NotMoveAssignable&>(), "");
93
94 CopyOnly c;
95 MoveOnly m;
96 NoexceptMoveOnly nm;
97 static_assert(!noexcept(std::swap(c, c)), "");
98 static_assert(!noexcept(std::swap(m, m)), "");
99 static_assert(noexcept(std::swap(nm, nm)), "");
100 }
Howard Hinnant3e519522010-05-11 19:42:16 +0000101#endif
JF Bastien2df59c52019-02-04 20:31:13 +0000102
103 return 0;
Howard Hinnant3e519522010-05-11 19:42:16 +0000104}