brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.4 KiB · 778b24d Raw
104 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++1410 11// is_invocable_r12 13#include <type_traits>14 15// Non-invocable types16 17static_assert(!std::is_invocable_r<void, void>::value);18static_assert(!std::is_invocable_r<void, int>::value);19static_assert(!std::is_invocable_r<void, int*>::value);20static_assert(!std::is_invocable_r<void, int&>::value);21static_assert(!std::is_invocable_r<void, int&&>::value);22 23// Result type matches24 25template <typename T>26T Return();27 28static_assert(std::is_invocable_r<int, decltype(Return<int>)>::value);29static_assert(std::is_invocable_r<char, decltype(Return<char>)>::value);30static_assert(std::is_invocable_r<int*, decltype(Return<int*>)>::value);31static_assert(std::is_invocable_r<int&, decltype(Return<int&>)>::value);32static_assert(std::is_invocable_r<int&&, decltype(Return<int&&>)>::value);33 34// void result type35 36// Any actual return type should be useable with a result type of void.37static_assert(std::is_invocable_r<void, decltype(Return<void>)>::value);38static_assert(std::is_invocable_r<void, decltype(Return<int>)>::value);39static_assert(std::is_invocable_r<void, decltype(Return<int*>)>::value);40static_assert(std::is_invocable_r<void, decltype(Return<int&>)>::value);41static_assert(std::is_invocable_r<void, decltype(Return<int&&>)>::value);42 43// const- and volatile-qualified void should work too.44static_assert(std::is_invocable_r<const void, decltype(Return<void>)>::value);45static_assert(std::is_invocable_r<const void, decltype(Return<int>)>::value);46static_assert(std::is_invocable_r<volatile void, decltype(Return<void>)>::value);47static_assert(std::is_invocable_r<volatile void, decltype(Return<int>)>::value);48static_assert(std::is_invocable_r<const volatile void, decltype(Return<void>)>::value);49static_assert(std::is_invocable_r<const volatile void, decltype(Return<int>)>::value);50 51// Conversion of result type52 53// It should be possible to use a result type to which the actual return type54// can be converted.55static_assert(std::is_invocable_r<char, decltype(Return<int>)>::value);56static_assert(std::is_invocable_r<const int*, decltype(Return<int*>)>::value);57static_assert(std::is_invocable_r<void*, decltype(Return<int*>)>::value);58static_assert(std::is_invocable_r<const int&, decltype(Return<int>)>::value);59static_assert(std::is_invocable_r<const int&, decltype(Return<int&>)>::value);60static_assert(std::is_invocable_r<const int&, decltype(Return<int&&>)>::value);61static_assert(std::is_invocable_r<const char&, decltype(Return<int>)>::value);62 63// But not a result type where the conversion doesn't work.64static_assert(!std::is_invocable_r<int, decltype(Return<void>)>::value);65static_assert(!std::is_invocable_r<int, decltype(Return<int*>)>::value);66 67// Non-moveable result type68 69// Define a type that can't be move-constructed.70struct CantMove {71  CantMove() = default;72  CantMove(CantMove&&) = delete;73};74 75static_assert(!std::is_move_constructible_v<CantMove>);76static_assert(!std::is_copy_constructible_v<CantMove>);77 78// Define functions that return that type.79CantMove MakeCantMove() { return {}; }80CantMove MakeCantMoveWithArg(int) { return {}; }81 82// Assumption check: it should be possible to call one of those functions and83// use it to initialize a CantMove object.84CantMove cant_move = MakeCantMove();85 86// Therefore std::is_invocable_r should agree that they can be invoked to yield87// a CantMove.88static_assert(std::is_invocable_r<CantMove, decltype(MakeCantMove)>::value);89static_assert(std::is_invocable_r<CantMove, decltype(MakeCantMoveWithArg), int>::value);90 91// Of course it still shouldn't be possible to call one of the functions and get92// back some other type.93static_assert(!std::is_invocable_r<int, decltype(MakeCantMove)>::value);94 95// And the argument types should still be important.96static_assert(!std::is_invocable_r<CantMove, decltype(MakeCantMove), int>::value);97static_assert(!std::is_invocable_r<CantMove, decltype(MakeCantMoveWithArg)>::value);98 99// is_invocable_r100 101// The struct form should be available too, not just the _v variant.102static_assert(std::is_invocable_r<int, decltype(Return<int>)>::value);103static_assert(!std::is_invocable_r<int*, decltype(Return<int>)>::value);104