1 // Copyright (C) 2015-2020 Free Software Foundation, Inc.
2 //
3 // This file is part of the GNU ISO C++ Library.  This library is free
4 // software; you can redistribute it and/or modify it under the
5 // terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 3, or (at your option)
7 // any later version.
8 //
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License along
15 // with this library; see the file COPYING3.  If not see
16 // <http://www.gnu.org/licenses/>.
17 
18 #include <type_traits>
19 #include <testsuite_tr1.h>
20 #include <utility>
21 #include <array>
22 #include <tuple>
23 #include <queue>
24 #include <stack>
25 
26 #if defined(test_std_is_swappable)
27 #  ifndef __cpp_lib_is_swappable
28 #   error "Feature-test macro for is_swappable missing"
29 #  elif __cpp_lib_is_swappable != 201603
30 #   error "Feature-test macro for is_swappable has wrong value"
31 #  endif
32 // Test std::is_swappable:
33 template<class T>
34 using is_swappable = std::is_swappable<T>;
35 #elif defined(test_std_is_swappable_ext)
36 // Test our __is_swappable extension:
37 template<class T>
38 using is_swappable = std::__is_swappable<T>;
39 #else
40 # error "Either test_std_is_swappable or test_std_is_swappable_ext" \
41         "need to be defined"
42 #endif
43 
44 namespace funny {
45   struct F {};
46   void swap(F&, F&) = delete;
47   void swap(F(&)[5], F(&)[5]);
48 
49   struct F2
50   {
51     friend void swap(F2&, F2&) = delete;
52   };
53 
54   struct F3
55   {
swapF356     friend void swap(F3&, F3) {}
57   };
58 }
test01()59 void test01()
60 {
61   using namespace __gnu_test;
62   // Positive tests.
63   static_assert(test_property<is_swappable, int>(true), "");
64   static_assert(test_property<is_swappable, bool>(true), "");
65   static_assert(test_property<is_swappable, decltype(nullptr)>(true), "");
66   static_assert(test_property<is_swappable, int&>(true), "");
67   static_assert(test_property<is_swappable, int&&>(true), "");
68   static_assert(test_property<is_swappable, int[1]>(true), "");
69   static_assert(test_property<is_swappable, int[1][2]>(true), "");
70   static_assert(test_property<is_swappable, int[1][2][3]>(true), "");
71   static_assert(test_property<is_swappable, int(&)[1]>(true), "");
72   static_assert(test_property<is_swappable, funny::F[5]>(true), "");
73   static_assert(test_property<is_swappable, funny::F3>(true), "");
74   static_assert(test_property<is_swappable, funny::F3[1]>(true), "");
75   static_assert(test_property<is_swappable, funny::F3[1][2]>(true), "");
76   static_assert(test_property<is_swappable, funny::F3[1][2][3]>(true), "");
77   static_assert(test_property<is_swappable,
78     ThrowCopyConsClass>(true), "");
79   static_assert(test_property<is_swappable, EnumType>(true), "");
80   static_assert(test_property<is_swappable, PODType>(true), "");
81   static_assert(test_property<is_swappable, UnionType>(true), "");
82   static_assert(test_property<is_swappable, construct::SE>(true), "");
83   static_assert(test_property<is_swappable, construct::Empty>(true), "");
84   static_assert(test_property<is_swappable, void*>(true), "");
85   static_assert(test_property<is_swappable, int const*>(true), "");
86   static_assert(test_property<is_swappable, ClassType*>(true), "");
87   static_assert(test_property<is_swappable, int ClassType::*>(true), "");
88   static_assert(test_property<is_swappable,
89     void (ClassType::*)()>(true), "");
90   static_assert(test_property<is_swappable,
91     construct::Nontrivial>(true), "");
92   static_assert(test_property<is_swappable, construct::Any>(true), "");
93   static_assert(test_property<is_swappable, construct::nAny>(true), "");
94   static_assert(test_property<is_swappable,
95 		std::pair<int, int>>(true), "");
96   static_assert(test_property<is_swappable,
97 		std::pair<int, int>[1]>(true), "");
98   static_assert(test_property<is_swappable,
99 		std::pair<int, int>[1][2]>(true), "");
100   static_assert(test_property<is_swappable,
101 		std::pair<int, int>[1][2][3]>(true), "");
102   static_assert(test_property<is_swappable,
103 		std::pair<construct::Nontrivial, construct::Nontrivial>>(true), "");
104   static_assert(test_property<is_swappable,
105 		std::tuple<int>>(true), "");
106   static_assert(test_property<is_swappable,
107 		std::tuple<int>[1]>(true), "");
108   static_assert(test_property<is_swappable,
109 		std::tuple<int>[1][2]>(true), "");
110   static_assert(test_property<is_swappable,
111 		std::tuple<int>[1][2][3]>(true), "");
112   static_assert(test_property<is_swappable,
113 		std::tuple<>>(true), "");
114   static_assert(test_property<is_swappable,
115 		std::tuple<>[1]>(true), "");
116   static_assert(test_property<is_swappable,
117 		std::tuple<>[1][2]>(true), "");
118   static_assert(test_property<is_swappable,
119 		std::tuple<>[1][2][3]>(true), "");
120   static_assert(test_property<is_swappable,
121 		std::tuple<construct::Nontrivial>>(true), "");
122   static_assert(test_property<is_swappable,
123 		std::array<int, 1>>(true), "");
124   static_assert(test_property<is_swappable,
125 		std::array<int, 1>[1]>(true), "");
126   static_assert(test_property<is_swappable,
127 		std::array<int, 1>[1][2]>(true), "");
128   static_assert(test_property<is_swappable,
129 		std::array<int, 1>[1][2][3]>(true), "");
130   static_assert(test_property<is_swappable,
131 		std::array<construct::Nontrivial, 1>>(true), "");
132   static_assert(test_property<is_swappable,
133         std::array<int, 0>>(true), "");
134   static_assert(test_property<is_swappable,
135         std::array<construct::DelCopy, 0>>(true), "");
136   static_assert(test_property<is_swappable,
137 		std::queue<int>>(true), "");
138   static_assert(test_property<is_swappable,
139 		std::queue<int>[1]>(true), "");
140   static_assert(test_property<is_swappable,
141 		std::queue<int>[1][2]>(true), "");
142   static_assert(test_property<is_swappable,
143 		std::queue<int>[1][2][3]>(true), "");
144   static_assert(test_property<is_swappable,
145 		std::queue<construct::Nontrivial>>(true), "");
146   static_assert(test_property<is_swappable,
147 		std::priority_queue<int>>(true), "");
148   static_assert(test_property<is_swappable,
149 		std::priority_queue<int>[1]>(true), "");
150   static_assert(test_property<is_swappable,
151 		std::priority_queue<int>[1][2]>(true), "");
152   static_assert(test_property<is_swappable,
153 		std::priority_queue<int>[1][2][3]>(true), "");
154   static_assert(test_property<is_swappable,
155 		std::priority_queue<construct::Nontrivial>>(true), "");
156   static_assert(test_property<is_swappable,
157 		std::stack<int>>(true), "");
158   static_assert(test_property<is_swappable,
159 		std::stack<int>[1]>(true), "");
160   static_assert(test_property<is_swappable,
161 		std::stack<int>[1][2]>(true), "");
162   static_assert(test_property<is_swappable,
163 		std::stack<int>[1][2][3]>(true), "");
164   static_assert(test_property<is_swappable,
165 		std::stack<construct::Nontrivial>>(true), "");
166   // Negative tests.
167   static_assert(test_property<is_swappable, void>(false), "");
168   static_assert(test_property<is_swappable, const void>(false), "");
169   static_assert(test_property<is_swappable, void()>(false), "");
170   static_assert(test_property<is_swappable, void() const>(false), "");
171   static_assert(test_property<is_swappable, void() volatile>(false), "");
172   static_assert(test_property<is_swappable,
173     void() const volatile>(false), "");
174   static_assert(test_property<is_swappable, const int>(false), "");
175   static_assert(test_property<is_swappable, const bool>(false), "");
176   static_assert(test_property<is_swappable, int[]>(false), "");
177   static_assert(test_property<is_swappable, const int[]>(false), "");
178   static_assert(test_property<is_swappable, int[][1]>(false), "");
179   static_assert(test_property<is_swappable, const int[1]>(false), "");
180   static_assert(test_property<is_swappable, const int[1][2]>(false), "");
181   static_assert(test_property<is_swappable, const int[1][2][3]>(false), "");
182   static_assert(test_property<is_swappable, construct::DelCopy>(false), "");
183   static_assert(test_property<is_swappable,
184     construct::Abstract>(false), "");
185   static_assert(test_property<is_swappable,
186     construct::NontrivialUnion>(false), "");
187   static_assert(test_property<is_swappable, funny::F>(false), "");
188   static_assert(test_property<is_swappable, funny::F[1]>(false), "");
189   static_assert(test_property<is_swappable, funny::F[1][2]>(false), "");
190   static_assert(test_property<is_swappable, funny::F[1][2][3]>(false), "");
191   static_assert(test_property<is_swappable, funny::F[4]>(false), "");
192   static_assert(test_property<is_swappable, construct::DelCopy>(false), "");
193   static_assert(test_property<is_swappable,
194      DeletedCopyAssignClass>(false), "");
195   static_assert(test_property<is_swappable,
196      DeletedMoveAssignClass>(false), "");
197   static_assert(test_property<is_swappable, funny::F2>(false), "");
198   static_assert(test_property<is_swappable, funny::F2[1]>(false), "");
199   static_assert(test_property<is_swappable, funny::F2[1][2]>(false), "");
200   static_assert(test_property<is_swappable, funny::F2[1][2][3]>(false), "");
201   static_assert(test_property<is_swappable, funny::F2[4]>(false), "");
202   static_assert(test_property<is_swappable, funny::F2[5]>(false), "");
203 }
204