1 // { dg-options "-std=gnu++17" }
2 // { dg-do compile }
3 
4 // Copyright (C) 2016-2020 Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library.  This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 3, or (at your option)
10 // any later version.
11 //
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING3.  If not see
19 // <http://www.gnu.org/licenses/>.
20 
21 #include <type_traits>
22 #include <testsuite_tr1.h>
23 
24 #ifndef __cpp_lib_is_swappable
25 # error "Feature-test macro for is_swappable_with missing"
26 #elif __cpp_lib_is_swappable != 201603
27 # error "Feature-test macro for is_swappable_with has wrong value"
28 #endif
29 
30 namespace funny {
31   struct T0 {};
32 
33   void swap(T0, T0);
34 
35   struct T1 {};
36   struct T2 {};
37 
38   void swap(T1, T2);
39   void swap(T2, T1);
40 
41   struct BoolLike {};
42 
43   void swap(BoolLike, bool&);
44   void swap(bool&, BoolLike);
45 
46   struct F0 {};
47 
48   void swap(F0, F0) = delete;
49 
50   struct F1 {};
51 
52   void swap(F0, F1) = delete;
53   void swap(F1, F0) = delete;
54 
55   struct F2 {};
56   struct F3 {};
57 
58   void swap(F2, F3);
59   void swap(F3, F2) = delete;
60 
61   struct F4
62   {
63     friend void swap(F4, F4) = delete;
64   };
65 }
66 
test01()67 void test01()
68 {
69   using std::is_swappable_with;
70   using namespace __gnu_test;
71   // Positive tests.
72   static_assert(test_property<is_swappable_with, int&, int&>(true), "");
73   static_assert(test_property<is_swappable_with, funny::T0,
74     funny::T0>(true), "");
75   static_assert(test_property<is_swappable_with, funny::T0,
76     const funny::T0>(true), "");
77   static_assert(test_property<is_swappable_with, funny::T1,
78     funny::T2>(true), "");
79   static_assert(test_property<is_swappable_with, funny::T2,
80     funny::T1>(true), "");
81   static_assert(test_property<is_swappable_with, funny::BoolLike,
82     bool&>(true), "");
83   static_assert(test_property<is_swappable_with, const funny::BoolLike,
84     bool&>(true), "");
85 
86   // Negative tests.
87   static_assert(test_property<is_swappable_with, int, int>(false), "");
88   static_assert(test_property<is_swappable_with, int&, unsigned&>(false), "");
89   static_assert(test_property<is_swappable_with, const int&,
90     const int&>(false), "");
91   static_assert(test_property<is_swappable_with, funny::F0,
92     funny::F0>(false), "");
93   static_assert(test_property<is_swappable_with, funny::F0,
94     const funny::F0>(false), "");
95   static_assert(test_property<is_swappable_with, funny::T0,
96     funny::T1>(false), "");
97   static_assert(test_property<is_swappable_with, funny::F0,
98     funny::F1>(false), "");
99   static_assert(test_property<is_swappable_with, funny::F0,
100     const funny::F1>(false), "");
101   static_assert(test_property<is_swappable_with, const funny::F0,
102     funny::F1>(false), "");
103   static_assert(test_property<is_swappable_with, funny::F2,
104     funny::F3>(false), "");
105   static_assert(test_property<is_swappable_with, funny::F2,
106     const funny::F3>(false), "");
107   static_assert(test_property<is_swappable_with, const funny::F2,
108     funny::F3>(false), "");
109   static_assert(test_property<is_swappable_with, funny::F4,
110     funny::F4>(false), "");
111   static_assert(test_property<is_swappable_with, funny::BoolLike,
112     funny::BoolLike>(false), "");
113 }
114