]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/20_util/is_nothrow_invocable/value.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / 20_util / is_nothrow_invocable / value.cc
1 // Copyright (C) 2016-2022 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 // { dg-do compile { target c++17 } }
19
20 #include <type_traits>
21
22 #ifndef IS_NT_INVOCABLE_DEFINED
23 template<typename... T>
24 constexpr bool is_nt_invocable()
25 {
26 constexpr bool result = std::is_nothrow_invocable_v<T...>;
27 static_assert(std::is_nothrow_invocable<T...>::value == result);
28 return result;
29 }
30
31 template<typename R, typename... T>
32 constexpr bool is_nt_invocable_r()
33 {
34 constexpr bool result = std::is_nothrow_invocable_r_v<R, T...>;
35 static_assert(std::is_nothrow_invocable_r<R, T...>::value == result);
36 return result;
37 }
38 #endif
39
40 void test01()
41 {
42 struct T { T(int) { } };
43 struct NT { NT(int) noexcept { } };
44 struct Ex { explicit Ex(int) noexcept { } };
45
46 using func_type = void(*)();
47 static_assert( ! is_nt_invocable< func_type>(), "");
48
49 #if __cpp_noexcept_function_type
50 using func_type_nt = void(*)() noexcept;
51 static_assert( is_nt_invocable< func_type_nt >(), "");
52 #endif
53
54 struct X { };
55 using mem_type = int X::*;
56
57 static_assert( ! is_nt_invocable< mem_type >(), "");
58 static_assert( ! is_nt_invocable< mem_type, int >(), "");
59 static_assert( ! is_nt_invocable< mem_type, int& >(), "");
60
61 static_assert( is_nt_invocable< mem_type, X& >(), "");
62 static_assert( is_nt_invocable_r< int, mem_type, X& >(), "");
63 static_assert( is_nt_invocable_r< int&, mem_type, X& >(), "");
64 static_assert( is_nt_invocable_r< long, mem_type, X& >(), "");
65 static_assert( ! is_nt_invocable_r< long&, mem_type, X& >(),
66 "conversion fails, cannot bind long& to int");
67 static_assert( is_nt_invocable_r< int&, mem_type, X* >(), "");
68
69 static_assert( ! is_nt_invocable_r< T, mem_type, X& >(),
70 "conversion throws");
71 static_assert( is_nt_invocable_r< NT, mem_type, X& >(), "");
72 static_assert( ! is_nt_invocable_r< Ex, mem_type, X& >(),
73 "conversion fails, would use explicit constructor");
74
75 using memfun_type = int (X::*)();
76
77 static_assert( ! is_nt_invocable< memfun_type >(), "no object");
78 static_assert( ! is_nt_invocable< memfun_type, int >(), "no object");
79 static_assert( ! is_nt_invocable< memfun_type, int& >(), "no object");
80 static_assert( ! is_nt_invocable< memfun_type, X& >(), "call throws");
81 static_assert( ! is_nt_invocable< memfun_type, X* >(), "call throws");
82
83 static_assert( ! is_nt_invocable_r< T, memfun_type, X& >(), "call throws");
84 static_assert( ! is_nt_invocable_r< NT, memfun_type, X& >(), "call throws");
85 static_assert( ! is_nt_invocable_r< Ex, memfun_type, X& >(), "call throws");
86
87 #if __cpp_noexcept_function_type
88 using memfun_type_nt = int (X::*)() noexcept;
89
90 static_assert( ! is_nt_invocable< memfun_type_nt >(), "no object");
91 static_assert( ! is_nt_invocable< memfun_type_nt, int >(), "no object");
92 static_assert( ! is_nt_invocable< memfun_type_nt, int& >(), "no object");
93 static_assert( is_nt_invocable< memfun_type_nt, X& >(), "");
94 static_assert( is_nt_invocable< memfun_type_nt, X* >(), "");
95
96 static_assert( ! is_nt_invocable_r< T, memfun_type_nt, X& >(),
97 "conversion throws");
98 static_assert( is_nt_invocable_r< NT, memfun_type_nt, X& >(), "");
99 static_assert( ! is_nt_invocable_r< Ex, memfun_type_nt, X& >(),
100 "conversion fails, would use explicit constructor");
101 #endif
102
103 struct F {
104 int& operator()();
105 long& operator()() const noexcept;
106 short& operator()(int) &&;
107 char& operator()(int) const& noexcept;
108 private:
109 void operator()(int, int) noexcept;
110 };
111 using CF = const F;
112
113 static_assert( ! is_nt_invocable< F >(), "call throws");
114 static_assert( is_nt_invocable< CF >(), "");
115
116 static_assert( ! is_nt_invocable_r< int&, F >(), "call throws");
117 static_assert( is_nt_invocable_r< long&, CF >(), "");
118 static_assert( ! is_nt_invocable_r< T, F >(), "call throws");
119 static_assert( ! is_nt_invocable_r< NT, F >(), "call throws");
120 static_assert( ! is_nt_invocable_r< Ex, F >(), "call throws");
121 static_assert( ! is_nt_invocable_r< void, F >(), "call throws");
122 static_assert( ! is_nt_invocable_r< T, CF >(), "conversion throws");
123 static_assert( is_nt_invocable_r< NT, CF >(), "" );
124 static_assert( ! is_nt_invocable_r< Ex, CF >(), "conversion fails");
125 static_assert( is_nt_invocable_r< void, CF >(), "");
126
127 static_assert( ! is_nt_invocable< F, int >(), "call throws");
128 static_assert( is_nt_invocable< F&, int >(), "");
129
130 static_assert( ! is_nt_invocable_r< short&, F, int >(),
131 "call throws" );
132 static_assert( is_nt_invocable_r< char&, F&, int >(), "");
133 static_assert( ! is_nt_invocable_r< T, F&, int >(),
134 "conversion throws");
135 static_assert( is_nt_invocable_r< NT, F&, int >(), "");
136 static_assert( ! is_nt_invocable_r< Ex, F&, int >(),
137 "conversion fails, would use explicit constructor");
138
139 static_assert( is_nt_invocable< CF, int >(), "");
140 static_assert( is_nt_invocable< CF&, int >(), "");
141
142 static_assert( is_nt_invocable_r< char&, CF, int >(), "");
143 static_assert( is_nt_invocable_r< char&, CF&, int >(), "");
144 static_assert( is_nt_invocable_r< void, CF&, int >(), "");
145
146 static_assert( ! is_nt_invocable_r< T, CF&, int >(),
147 "conversion throws");
148 static_assert( is_nt_invocable_r< NT, CF&, int >(), "");
149 static_assert( ! is_nt_invocable_r< Ex, CF&, int >(),
150 "conversion fails, would use explicit constructor");
151 static_assert( is_nt_invocable_r< void, CF&, int >(), "");
152
153 static_assert( ! is_nt_invocable< F, int, int >(),
154 "would call private member");
155 static_assert( ! is_nt_invocable_r<void, F, int, int >(),
156 "would call private member");
157
158 struct FX {
159 X operator()() const noexcept { return {}; }
160 };
161 static_assert( is_nt_invocable< FX >(), "FX::operator() is nothrow" );
162 static_assert( is_nt_invocable_r<X, FX >(), "no conversion needed" );
163 static_assert( is_nt_invocable_r<void, FX >(), "" );
164
165 struct Y {
166 explicit Y(X) noexcept; // not viable for implicit conversions
167 Y(...);
168 };
169
170 static_assert( ! is_nt_invocable_r<Y, FX >(), "conversion to Y can throw" );
171 }