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