1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14
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
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
);
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
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.
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
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
);
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
);