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
10 // UNSUPPORTED: c++98, c++03, c++11, c++14
11
12 // type_traits
13
14 // is_swappable
15
16 #include <type_traits>
17 #include <utility>
18 #include <vector>
19 #include "test_macros.h"
20
21 namespace MyNS {
22
23 // Make the test types non-copyable so that generic std::swap is not valid.
24 struct A {
25 A(A const&) = delete;
26 A& operator=(A const&) = delete;
27 };
28
29 struct B {
30 B(B const&) = delete;
31 B& operator=(B const&) = delete;
32 };
33
34 struct C {};
35 struct D {};
36
swap(A &,A &)37 void swap(A&, A&) {}
38
swap(A &,B &)39 void swap(A&, B&) {}
swap(B &,A &)40 void swap(B&, A&) {}
41
swap(A &,C &)42 void swap(A&, C&) {} // missing swap(C, A)
swap(D &,C &)43 void swap(D&, C&) {}
44
45 struct M {
46 M(M const&) = delete;
47 M& operator=(M const&) = delete;
48 };
49
swap(M &&,M &&)50 void swap(M&&, M&&) {}
51
52 struct DeletedSwap {
53 friend void swap(DeletedSwap&, DeletedSwap&) = delete;
54 };
55
56 } // namespace MyNS
57
58 namespace MyNS2 {
59
60 struct AmbiguousSwap {};
61
62 template <class T>
swap(T &,T &)63 void swap(T&, T&) {}
64
65 } // end namespace MyNS2
66
main()67 int main()
68 {
69 using namespace MyNS;
70 {
71 // Test that is_swappable applies an lvalue reference to the type.
72 static_assert(std::is_swappable<A>::value, "");
73 static_assert(std::is_swappable<A&>::value, "");
74 static_assert(!std::is_swappable<M>::value, "");
75 static_assert(!std::is_swappable<M&&>::value, "");
76 }
77 static_assert(!std::is_swappable<B>::value, "");
78 static_assert(std::is_swappable<C>::value, "");
79 {
80 // test non-referencable types
81 static_assert(!std::is_swappable<void>::value, "");
82 static_assert(!std::is_swappable<int() const>::value, "");
83 static_assert(!std::is_swappable<int() &>::value, "");
84 }
85 {
86 // test that a deleted swap is correctly handled.
87 static_assert(!std::is_swappable<DeletedSwap>::value, "");
88 }
89 {
90 // test that a swap with ambiguous overloads is handled correctly.
91 static_assert(!std::is_swappable<MyNS2::AmbiguousSwap>::value, "");
92 }
93 {
94 // test for presence of is_swappable_v
95 static_assert(std::is_swappable_v<int>, "");
96 static_assert(!std::is_swappable_v<M>, "");
97 }
98 }
99