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