#include <type_traits>
static_assert(!std::is_invocable_r<void, void>::value);
static_assert(!std::is_invocable_r<void, int>::value);
static_assert(!std::is_invocable_r<void, int*>::value);
static_assert(!std::is_invocable_r<void, int&>::value);
static_assert(!std::is_invocable_r<void, int&&>::value);
template <typename T>
T Return();
static_assert(std::is_invocable_r<int, decltype(Return<int>)>::value);
static_assert(std::is_invocable_r<char, decltype(Return<char>)>::value);
static_assert(std::is_invocable_r<int*, decltype(Return<int*>)>::value);
static_assert(std::is_invocable_r<int&, decltype(Return<int&>)>::value);
static_assert(std::is_invocable_r<int&&, decltype(Return<int&&>)>::value);
static_assert(std::is_invocable_r<void, decltype(Return<void>)>::value);
static_assert(std::is_invocable_r<void, decltype(Return<int>)>::value);
static_assert(std::is_invocable_r<void, decltype(Return<int*>)>::value);
static_assert(std::is_invocable_r<void, decltype(Return<int&>)>::value);
static_assert(std::is_invocable_r<void, decltype(Return<int&&>)>::value);
static_assert(std::is_invocable_r<const void, decltype(Return<void>)>::value);
static_assert(std::is_invocable_r<const void, decltype(Return<int>)>::value);
static_assert(std::is_invocable_r<volatile void, decltype(Return<void>)>::value);
static_assert(std::is_invocable_r<volatile void, decltype(Return<int>)>::value);
static_assert(std::is_invocable_r<const volatile void, decltype(Return<void>)>::value);
static_assert(std::is_invocable_r<const volatile void, decltype(Return<int>)>::value);
static_assert(std::is_invocable_r<char, decltype(Return<int>)>::value);
static_assert(std::is_invocable_r<const int*, decltype(Return<int*>)>::value);
static_assert(std::is_invocable_r<void*, decltype(Return<int*>)>::value);
static_assert(std::is_invocable_r<const int&, decltype(Return<int>)>::value);
static_assert(std::is_invocable_r<const int&, decltype(Return<int&>)>::value);
static_assert(std::is_invocable_r<const int&, decltype(Return<int&&>)>::value);
static_assert(std::is_invocable_r<const char&, decltype(Return<int>)>::value);
static_assert(!std::is_invocable_r<int, decltype(Return<void>)>::value);
static_assert(!std::is_invocable_r<int, decltype(Return<int*>)>::value);
struct CantMove {
CantMove() = default;
CantMove(CantMove&&) = delete;
};
static_assert(!std::is_move_constructible_v<CantMove>);
static_assert(!std::is_copy_constructible_v<CantMove>);
CantMove MakeCantMove() { return {}; }
CantMove MakeCantMoveWithArg(int) { return {}; }
CantMove cant_move = MakeCantMove();
static_assert(std::is_invocable_r<CantMove, decltype(MakeCantMove)>::value);
static_assert(std::is_invocable_r<CantMove, decltype(MakeCantMoveWithArg), int>::value);
static_assert(!std::is_invocable_r<int, decltype(MakeCantMove)>::value);
static_assert(!std::is_invocable_r<CantMove, decltype(MakeCantMove), int>::value);
static_assert(!std::is_invocable_r<CantMove, decltype(MakeCantMoveWithArg)>::value);
static_assert(std::is_invocable_r<int, decltype(Return<int>)>::value);
static_assert(!std::is_invocable_r<int*, decltype(Return<int>)>::value);