[RISCV] Fix mgather -> riscv.masked.strided.load combine not extending indices (...
[llvm-project.git] / libcxx / test / std / utilities / meta / meta.rel / is_invocable_r.compile.pass.cpp
blob778b24d99e91e96ab9362a2c457873555cb02570
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 // is_invocable_r
13 #include <type_traits>
15 // Non-invocable types
17 static_assert(!std::is_invocable_r<void, void>::value);
18 static_assert(!std::is_invocable_r<void, int>::value);
19 static_assert(!std::is_invocable_r<void, int*>::value);
20 static_assert(!std::is_invocable_r<void, int&>::value);
21 static_assert(!std::is_invocable_r<void, int&&>::value);
23 // Result type matches
25 template <typename T>
26 T Return();
28 static_assert(std::is_invocable_r<int, decltype(Return<int>)>::value);
29 static_assert(std::is_invocable_r<char, decltype(Return<char>)>::value);
30 static_assert(std::is_invocable_r<int*, decltype(Return<int*>)>::value);
31 static_assert(std::is_invocable_r<int&, decltype(Return<int&>)>::value);
32 static_assert(std::is_invocable_r<int&&, decltype(Return<int&&>)>::value);
34 // void result type
36 // Any actual return type should be useable with a result type of void.
37 static_assert(std::is_invocable_r<void, decltype(Return<void>)>::value);
38 static_assert(std::is_invocable_r<void, decltype(Return<int>)>::value);
39 static_assert(std::is_invocable_r<void, decltype(Return<int*>)>::value);
40 static_assert(std::is_invocable_r<void, decltype(Return<int&>)>::value);
41 static_assert(std::is_invocable_r<void, decltype(Return<int&&>)>::value);
43 // const- and volatile-qualified void should work too.
44 static_assert(std::is_invocable_r<const void, decltype(Return<void>)>::value);
45 static_assert(std::is_invocable_r<const void, decltype(Return<int>)>::value);
46 static_assert(std::is_invocable_r<volatile void, decltype(Return<void>)>::value);
47 static_assert(std::is_invocable_r<volatile void, decltype(Return<int>)>::value);
48 static_assert(std::is_invocable_r<const volatile void, decltype(Return<void>)>::value);
49 static_assert(std::is_invocable_r<const volatile void, decltype(Return<int>)>::value);
51 // Conversion of result type
53 // It should be possible to use a result type to which the actual return type
54 // can be converted.
55 static_assert(std::is_invocable_r<char, decltype(Return<int>)>::value);
56 static_assert(std::is_invocable_r<const int*, decltype(Return<int*>)>::value);
57 static_assert(std::is_invocable_r<void*, decltype(Return<int*>)>::value);
58 static_assert(std::is_invocable_r<const int&, decltype(Return<int>)>::value);
59 static_assert(std::is_invocable_r<const int&, decltype(Return<int&>)>::value);
60 static_assert(std::is_invocable_r<const int&, decltype(Return<int&&>)>::value);
61 static_assert(std::is_invocable_r<const char&, decltype(Return<int>)>::value);
63 // But not a result type where the conversion doesn't work.
64 static_assert(!std::is_invocable_r<int, decltype(Return<void>)>::value);
65 static_assert(!std::is_invocable_r<int, decltype(Return<int*>)>::value);
67 // Non-moveable result type
69 // Define a type that can't be move-constructed.
70 struct CantMove {
71 CantMove() = default;
72 CantMove(CantMove&&) = delete;
75 static_assert(!std::is_move_constructible_v<CantMove>);
76 static_assert(!std::is_copy_constructible_v<CantMove>);
78 // Define functions that return that type.
79 CantMove MakeCantMove() { return {}; }
80 CantMove MakeCantMoveWithArg(int) { return {}; }
82 // Assumption check: it should be possible to call one of those functions and
83 // use it to initialize a CantMove object.
84 CantMove cant_move = MakeCantMove();
86 // Therefore std::is_invocable_r should agree that they can be invoked to yield
87 // a CantMove.
88 static_assert(std::is_invocable_r<CantMove, decltype(MakeCantMove)>::value);
89 static_assert(std::is_invocable_r<CantMove, decltype(MakeCantMoveWithArg), int>::value);
91 // Of course it still shouldn't be possible to call one of the functions and get
92 // back some other type.
93 static_assert(!std::is_invocable_r<int, decltype(MakeCantMove)>::value);
95 // And the argument types should still be important.
96 static_assert(!std::is_invocable_r<CantMove, decltype(MakeCantMove), int>::value);
97 static_assert(!std::is_invocable_r<CantMove, decltype(MakeCantMoveWithArg)>::value);
99 // is_invocable_r
101 // The struct form should be available too, not just the _v variant.
102 static_assert(std::is_invocable_r<int, decltype(Return<int>)>::value);
103 static_assert(!std::is_invocable_r<int*, decltype(Return<int>)>::value);