[RISCV] Fix mgather -> riscv.masked.strided.load combine not extending indices (...
[llvm-project.git] / libcxx / test / std / utilities / function.objects / func.invoke / invoke.pass.cpp
blob54499c08ad144bc14f50cd94e9b63bb58e3e613f
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 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14
11 // <functional>
13 // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS
14 // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
16 // template<class F, class... Args>
17 // invoke_result_t<F, Args...> invoke(F&& f, Args&&... args) // C++17
18 // noexcept(is_nothrow_invocable_v<_Fn, _Args...>);
20 /// C++14 [func.def] 20.9.0
21 /// (1) The following definitions apply to this Clause:
22 /// (2) A call signature is the name of a return type followed by a parenthesized
23 /// comma-separated list of zero or more argument types.
24 /// (3) A callable type is a function object type (20.9) or a pointer to member.
25 /// (4) A callable object is an object of a callable type.
26 /// (5) A call wrapper type is a type that holds a callable object and supports
27 /// a call operation that forwards to that object.
28 /// (6) A call wrapper is an object of a call wrapper type.
29 /// (7) A target object is the callable object held by a call wrapper.
31 /// C++14 [func.require] 20.9.1
32 ///
33 /// Define INVOKE (f, t1, t2, ..., tN) as follows:
34 /// (1.1) - (t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is an object of
35 /// type T or a reference to an object of type T or a reference to an object of a type derived from T;
36 /// (1.2) - ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is not one of
37 /// the types described in the previous item;
38 /// (1.3) - t1.*f when N == 1 and f is a pointer to member data of a class T and t1 is an object of type T or a
39 /// reference to an object of type T or a reference to an object of a type derived from T;
40 /// (1.4) - (*t1).*f when N == 1 and f is a pointer to member data of a class T and t1 is not one of the types
41 /// described in the previous item;
42 /// (1.5) - f(t1, t2, ..., tN) in all other cases.
44 #include <functional>
45 #include <type_traits>
46 #include <utility> // for std::move
47 #include <cassert>
49 #include "test_macros.h"
51 struct NonCopyable {
52 NonCopyable() {}
53 private:
54 NonCopyable(NonCopyable const&) = delete;
55 NonCopyable& operator=(NonCopyable const&) = delete;
58 struct TestClass {
59 explicit TestClass(int x) : data(x) {}
61 int& operator()(NonCopyable&&) & { return data; }
62 int const& operator()(NonCopyable&&) const & { return data; }
63 int volatile& operator()(NonCopyable&&) volatile & { return data; }
64 int const volatile& operator()(NonCopyable&&) const volatile & { return data; }
66 int&& operator()(NonCopyable&&) && { return std::move(data); }
67 int const&& operator()(NonCopyable&&) const && { return std::move(data); }
68 int volatile&& operator()(NonCopyable&&) volatile && { return std::move(data); }
69 int const volatile&& operator()(NonCopyable&&) const volatile && { return std::move(data); }
71 int data;
72 private:
73 TestClass(TestClass const&) = delete;
74 TestClass& operator=(TestClass const&) = delete;
77 struct DerivedFromTestClass : public TestClass {
78 explicit DerivedFromTestClass(int x) : TestClass(x) {}
81 int& foo(NonCopyable&&) {
82 static int data = 42;
83 return data;
86 template <class Signature, class Expect, class Functor>
87 void test_b12(Functor&& f) {
88 // Create the callable object.
89 typedef Signature TestClass::*ClassFunc;
90 ClassFunc func_ptr = &TestClass::operator();
92 // Create the dummy arg.
93 NonCopyable arg;
95 // Check that the deduced return type of invoke is what is expected.
96 typedef decltype(
97 std::invoke(func_ptr, std::forward<Functor>(f), std::move(arg))
98 ) DeducedReturnType;
99 static_assert((std::is_same<DeducedReturnType, Expect>::value), "");
101 // Check that result_of_t matches Expect.
102 typedef typename std::result_of<ClassFunc&&(Functor&&, NonCopyable&&)>::type
103 ResultOfReturnType;
104 static_assert((std::is_same<ResultOfReturnType, Expect>::value), "");
106 // Run invoke and check the return value.
107 DeducedReturnType ret =
108 std::invoke(func_ptr, std::forward<Functor>(f), std::move(arg));
109 assert(ret == 42);
112 template <class Expect, class Functor>
113 void test_b34(Functor&& f) {
114 // Create the callable object.
115 typedef int TestClass::*ClassFunc;
116 ClassFunc func_ptr = &TestClass::data;
118 // Check that the deduced return type of invoke is what is expected.
119 typedef decltype(
120 std::invoke(func_ptr, std::forward<Functor>(f))
121 ) DeducedReturnType;
122 static_assert((std::is_same<DeducedReturnType, Expect>::value), "");
124 // Check that result_of_t matches Expect.
125 typedef typename std::result_of<ClassFunc&&(Functor&&)>::type
126 ResultOfReturnType;
127 static_assert((std::is_same<ResultOfReturnType, Expect>::value), "");
129 // Run invoke and check the return value.
130 DeducedReturnType ret =
131 std::invoke(func_ptr, std::forward<Functor>(f));
132 assert(ret == 42);
135 template <class Expect, class Functor>
136 void test_b5(Functor&& f) {
137 NonCopyable arg;
139 // Check that the deduced return type of invoke is what is expected.
140 typedef decltype(
141 std::invoke(std::forward<Functor>(f), std::move(arg))
142 ) DeducedReturnType;
143 static_assert((std::is_same<DeducedReturnType, Expect>::value), "");
145 // Check that result_of_t matches Expect.
146 typedef typename std::result_of<Functor&&(NonCopyable&&)>::type
147 ResultOfReturnType;
148 static_assert((std::is_same<ResultOfReturnType, Expect>::value), "");
150 // Run invoke and check the return value.
151 DeducedReturnType ret = std::invoke(std::forward<Functor>(f), std::move(arg));
152 assert(ret == 42);
155 void bullet_one_two_tests() {
157 TestClass cl(42);
158 test_b12<int&(NonCopyable&&) &, int&>(cl);
159 test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
160 test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
161 test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
163 test_b12<int&&(NonCopyable&&) &&, int&&>(std::move(cl));
164 test_b12<int const&&(NonCopyable&&) const &&, int const&&>(std::move(cl));
165 test_b12<int volatile&&(NonCopyable&&) volatile &&, int volatile&&>(std::move(cl));
166 test_b12<int const volatile&&(NonCopyable&&) const volatile &&, int const volatile&&>(std::move(cl));
169 DerivedFromTestClass cl(42);
170 test_b12<int&(NonCopyable&&) &, int&>(cl);
171 test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
172 test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
173 test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
175 test_b12<int&&(NonCopyable&&) &&, int&&>(std::move(cl));
176 test_b12<int const&&(NonCopyable&&) const &&, int const&&>(std::move(cl));
177 test_b12<int volatile&&(NonCopyable&&) volatile &&, int volatile&&>(std::move(cl));
178 test_b12<int const volatile&&(NonCopyable&&) const volatile &&, int const volatile&&>(std::move(cl));
181 TestClass cl_obj(42);
182 std::reference_wrapper<TestClass> cl(cl_obj);
183 test_b12<int&(NonCopyable&&) &, int&>(cl);
184 test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
185 test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
186 test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
188 test_b12<int&(NonCopyable&&) &, int&>(std::move(cl));
189 test_b12<int const&(NonCopyable&&) const &, int const&>(std::move(cl));
190 test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(std::move(cl));
191 test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(std::move(cl));
194 DerivedFromTestClass cl_obj(42);
195 std::reference_wrapper<DerivedFromTestClass> cl(cl_obj);
196 test_b12<int&(NonCopyable&&) &, int&>(cl);
197 test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
198 test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
199 test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
201 test_b12<int&(NonCopyable&&) &, int&>(std::move(cl));
202 test_b12<int const&(NonCopyable&&) const &, int const&>(std::move(cl));
203 test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(std::move(cl));
204 test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(std::move(cl));
207 TestClass cl_obj(42);
208 TestClass *cl = &cl_obj;
209 test_b12<int&(NonCopyable&&) &, int&>(cl);
210 test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
211 test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
212 test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
215 DerivedFromTestClass cl_obj(42);
216 DerivedFromTestClass *cl = &cl_obj;
217 test_b12<int&(NonCopyable&&) &, int&>(cl);
218 test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
219 test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
220 test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
224 void bullet_three_four_tests() {
226 typedef TestClass Fn;
227 Fn cl(42);
228 test_b34<int&>(cl);
229 test_b34<int const&>(static_cast<Fn const&>(cl));
230 test_b34<int volatile&>(static_cast<Fn volatile&>(cl));
231 test_b34<int const volatile&>(static_cast<Fn const volatile &>(cl));
233 test_b34<int&&>(static_cast<Fn &&>(cl));
234 test_b34<int const&&>(static_cast<Fn const&&>(cl));
235 test_b34<int volatile&&>(static_cast<Fn volatile&&>(cl));
236 test_b34<int const volatile&&>(static_cast<Fn const volatile&&>(cl));
239 typedef DerivedFromTestClass Fn;
240 Fn cl(42);
241 test_b34<int&>(cl);
242 test_b34<int const&>(static_cast<Fn const&>(cl));
243 test_b34<int volatile&>(static_cast<Fn volatile&>(cl));
244 test_b34<int const volatile&>(static_cast<Fn const volatile &>(cl));
246 test_b34<int&&>(static_cast<Fn &&>(cl));
247 test_b34<int const&&>(static_cast<Fn const&&>(cl));
248 test_b34<int volatile&&>(static_cast<Fn volatile&&>(cl));
249 test_b34<int const volatile&&>(static_cast<Fn const volatile&&>(cl));
252 typedef TestClass Fn;
253 Fn cl(42);
254 test_b34<int&>(std::reference_wrapper<Fn>(cl));
255 test_b34<int const&>(std::reference_wrapper<Fn const>(cl));
256 test_b34<int volatile&>(std::reference_wrapper<Fn volatile>(cl));
257 test_b34<int const volatile&>(std::reference_wrapper<Fn const volatile>(cl));
260 typedef DerivedFromTestClass Fn;
261 Fn cl(42);
262 test_b34<int&>(std::reference_wrapper<Fn>(cl));
263 test_b34<int const&>(std::reference_wrapper<Fn const>(cl));
264 test_b34<int volatile&>(std::reference_wrapper<Fn volatile>(cl));
265 test_b34<int const volatile&>(std::reference_wrapper<Fn const volatile>(cl));
268 typedef TestClass Fn;
269 Fn cl_obj(42);
270 Fn* cl = &cl_obj;
271 test_b34<int&>(cl);
272 test_b34<int const&>(static_cast<Fn const*>(cl));
273 test_b34<int volatile&>(static_cast<Fn volatile*>(cl));
274 test_b34<int const volatile&>(static_cast<Fn const volatile *>(cl));
277 typedef DerivedFromTestClass Fn;
278 Fn cl_obj(42);
279 Fn* cl = &cl_obj;
280 test_b34<int&>(cl);
281 test_b34<int const&>(static_cast<Fn const*>(cl));
282 test_b34<int volatile&>(static_cast<Fn volatile*>(cl));
283 test_b34<int const volatile&>(static_cast<Fn const volatile *>(cl));
287 void bullet_five_tests() {
288 using FooType = int&(NonCopyable&&);
290 FooType& fn = foo;
291 test_b5<int &>(fn);
294 FooType* fn = foo;
295 test_b5<int &>(fn);
298 typedef TestClass Fn;
299 Fn cl(42);
300 test_b5<int&>(cl);
301 test_b5<int const&>(static_cast<Fn const&>(cl));
302 test_b5<int volatile&>(static_cast<Fn volatile&>(cl));
303 test_b5<int const volatile&>(static_cast<Fn const volatile &>(cl));
305 test_b5<int&&>(static_cast<Fn &&>(cl));
306 test_b5<int const&&>(static_cast<Fn const&&>(cl));
307 test_b5<int volatile&&>(static_cast<Fn volatile&&>(cl));
308 test_b5<int const volatile&&>(static_cast<Fn const volatile&&>(cl));
312 struct CopyThrows {
313 CopyThrows() {}
314 CopyThrows(CopyThrows const&) {}
315 CopyThrows(CopyThrows&&) noexcept {}
318 struct NoThrowCallable {
319 void operator()() noexcept {}
320 void operator()(CopyThrows) noexcept {}
323 struct ThrowsCallable {
324 void operator()() {}
327 struct MemberObj {
328 int x;
331 void noexcept_test() {
333 NoThrowCallable obj; ((void)obj); // suppress unused warning
334 CopyThrows arg; ((void)arg); // suppress unused warning
335 static_assert(noexcept(std::invoke(obj)), "");
336 static_assert(!noexcept(std::invoke(obj, arg)), "");
337 static_assert(noexcept(std::invoke(obj, std::move(arg))), "");
340 ThrowsCallable obj; ((void)obj); // suppress unused warning
341 static_assert(!noexcept(std::invoke(obj)), "");
344 MemberObj obj{42}; ((void)obj); // suppress unused warning.
345 static_assert(noexcept(std::invoke(&MemberObj::x, obj)), "");
349 // LWG3655: The INVOKE operation and union types
350 void union_tests() {
351 union Union {
352 int x;
353 int f() { return 42; }
354 int g() const { return 52; }
357 // With a data member
359 auto get = []() -> Union { return Union{.x = 3}; };
360 int result = std::invoke(&Union::x, get());
361 assert(result == 3);
364 auto get = []() -> Union const { return Union{.x = 3}; };
365 int result = std::invoke(&Union::x, get());
366 assert(result == 3);
369 Union u{3};
370 int& result = std::invoke(&Union::x, u);
371 assert(&result == &u.x);
374 Union const u{3};
375 int const& result = std::invoke(&Union::x, u);
376 assert(&result == &u.x);
379 // With a pointer to a member function
381 auto get = []() -> Union { return Union{.x = 3}; };
382 int result = std::invoke(&Union::f, get());
383 assert(result == 42);
386 Union u{3};
387 int result = std::invoke(&Union::f, u);
388 assert(result == 42);
391 // constness mismatch
392 static_assert(!std::is_invocable_v<int (Union::*)(), Union const>);
393 static_assert(!std::is_invocable_v<int (Union::*)(), Union const&>);
397 auto get = []() -> Union { return Union{.x = 3}; };
398 int result = std::invoke(&Union::g, get());
399 assert(result == 52);
402 auto get = []() -> Union const { return Union{.x = 3}; };
403 int result = std::invoke(&Union::g, get());
404 assert(result == 52);
407 Union u{3};
408 int result = std::invoke(&Union::g, u);
409 assert(result == 52);
412 Union const u{3};
413 int result = std::invoke(&Union::g, u);
414 assert(result == 52);
418 int main(int, char**) {
419 bullet_one_two_tests();
420 bullet_three_four_tests();
421 bullet_five_tests();
422 noexcept_test();
424 return 0;