[RISCV] Fix mgather -> riscv.masked.strided.load combine not extending indices (...
[llvm-project.git] / libcxx / test / std / utilities / meta / meta.rel / is_invocable_r_v.compile.pass.cpp
blob32530f2c20865207d79bd13910048151ca443ea4
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_v<void, void>);
18 static_assert(!std::is_invocable_r_v<void, int>);
19 static_assert(!std::is_invocable_r_v<void, int*>);
20 static_assert(!std::is_invocable_r_v<void, int&>);
21 static_assert(!std::is_invocable_r_v<void, int&&>);
23 // Result type matches
25 template <typename T>
26 T Return();
28 static_assert(std::is_invocable_r_v<int, decltype(Return<int>)>);
29 static_assert(std::is_invocable_r_v<char, decltype(Return<char>)>);
30 static_assert(std::is_invocable_r_v<int*, decltype(Return<int*>)>);
31 static_assert(std::is_invocable_r_v<int&, decltype(Return<int&>)>);
32 static_assert(std::is_invocable_r_v<int&&, decltype(Return<int&&>)>);
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_v<void, decltype(Return<void>)>);
38 static_assert(std::is_invocable_r_v<void, decltype(Return<int>)>);
39 static_assert(std::is_invocable_r_v<void, decltype(Return<int*>)>);
40 static_assert(std::is_invocable_r_v<void, decltype(Return<int&>)>);
41 static_assert(std::is_invocable_r_v<void, decltype(Return<int&&>)>);
43 // const- and volatile-qualified void should work too.
44 static_assert(std::is_invocable_r_v<const void, decltype(Return<void>)>);
45 static_assert(std::is_invocable_r_v<const void, decltype(Return<int>)>);
46 static_assert(std::is_invocable_r_v<volatile void, decltype(Return<void>)>);
47 static_assert(std::is_invocable_r_v<volatile void, decltype(Return<int>)>);
48 static_assert(std::is_invocable_r_v<const volatile void, decltype(Return<void>)>);
49 static_assert(std::is_invocable_r_v<const volatile void, decltype(Return<int>)>);
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_v<char, decltype(Return<int>)>);
56 static_assert(std::is_invocable_r_v<const int*, decltype(Return<int*>)>);
57 static_assert(std::is_invocable_r_v<void*, decltype(Return<int*>)>);
58 static_assert(std::is_invocable_r_v<const int&, decltype(Return<int>)>);
59 static_assert(std::is_invocable_r_v<const int&, decltype(Return<int&>)>);
60 static_assert(std::is_invocable_r_v<const int&, decltype(Return<int&&>)>);
61 static_assert(std::is_invocable_r_v<const char&, decltype(Return<int>)>);
63 // But not a result type where the conversion doesn't work.
64 static_assert(!std::is_invocable_r_v<int, decltype(Return<void>)>);
65 static_assert(!std::is_invocable_r_v<int, decltype(Return<int*>)>);
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_v<CantMove, decltype(MakeCantMove)>);
89 static_assert(std::is_invocable_r_v<CantMove, decltype(MakeCantMoveWithArg), int>);
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_v<int, decltype(MakeCantMove)>);
95 // And the argument types should still be important.
96 static_assert(!std::is_invocable_r_v<CantMove, decltype(MakeCantMove), int>);
97 static_assert(!std::is_invocable_r_v<CantMove, decltype(MakeCantMoveWithArg)>);
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);