124dd2d2fSChristopher Di Bella //===----------------------------------------------------------------------===// 224dd2d2fSChristopher Di Bella // 324dd2d2fSChristopher Di Bella // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 424dd2d2fSChristopher Di Bella // See https://llvm.org/LICENSE.txt for license information. 524dd2d2fSChristopher Di Bella // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 624dd2d2fSChristopher Di Bella // 724dd2d2fSChristopher Di Bella //===----------------------------------------------------------------------===// 824dd2d2fSChristopher Di Bella 924dd2d2fSChristopher Di Bella // UNSUPPORTED: c++03, c++11, c++14, c++17 1024dd2d2fSChristopher Di Bella 1124dd2d2fSChristopher Di Bella // template<class T, class U> 1224dd2d2fSChristopher Di Bella // concept invocable; 1324dd2d2fSChristopher Di Bella 1424dd2d2fSChristopher Di Bella #include <concepts> 15*e99c4906SNikolas Klauser #include <cstddef> 1634f73804SNikolas Klauser #include <functional> 1724dd2d2fSChristopher Di Bella #include <memory> 1824dd2d2fSChristopher Di Bella #include <random> 1924dd2d2fSChristopher Di Bella #include <type_traits> 2024dd2d2fSChristopher Di Bella 21e06f1a8eSChristopher Di Bella template <class R, class... Args> 2288b73a98SLouis Dionne constexpr bool check_invocable() { 23e06f1a8eSChristopher Di Bella constexpr bool result = std::invocable<R(Args...), Args...>; 24e06f1a8eSChristopher Di Bella static_assert(std::invocable<R(Args...) noexcept, Args...> == result); 25e06f1a8eSChristopher Di Bella static_assert(std::invocable<R (*)(Args...), Args...> == result); 26e06f1a8eSChristopher Di Bella static_assert(std::invocable<R (*)(Args...) noexcept, Args...> == result); 27e06f1a8eSChristopher Di Bella static_assert(std::invocable<R (&)(Args...), Args...> == result); 28e06f1a8eSChristopher Di Bella static_assert(std::invocable<R (&)(Args...) noexcept, Args...> == result); 2924dd2d2fSChristopher Di Bella 30e06f1a8eSChristopher Di Bella return result; 31e06f1a8eSChristopher Di Bella } 3224dd2d2fSChristopher Di Bella 33e06f1a8eSChristopher Di Bella static_assert(check_invocable<void>()); 34e06f1a8eSChristopher Di Bella static_assert(check_invocable<void, int>()); 35e06f1a8eSChristopher Di Bella static_assert(check_invocable<void, int&>()); 36e06f1a8eSChristopher Di Bella static_assert(check_invocable<void, int*, double>()); 37e06f1a8eSChristopher Di Bella static_assert(check_invocable<int>()); 38e06f1a8eSChristopher Di Bella static_assert(check_invocable<int, int[]>()); 39e06f1a8eSChristopher Di Bella 40e06f1a8eSChristopher Di Bella struct S; 41e06f1a8eSChristopher Di Bella static_assert(check_invocable<int, int S::*, std::nullptr_t>()); 42e06f1a8eSChristopher Di Bella static_assert(check_invocable<int, int (S::*)(), int (S::*)(int), int>()); 43e06f1a8eSChristopher Di Bella static_assert(std::invocable<void (*)(int const&), int&>); 44e06f1a8eSChristopher Di Bella static_assert(std::invocable<void (*)(int const&), int&&>); 45e06f1a8eSChristopher Di Bella static_assert(std::invocable<void (*)(int volatile&), int&>); 46e06f1a8eSChristopher Di Bella static_assert(std::invocable<void (*)(int const volatile&), int&>); 47e06f1a8eSChristopher Di Bella 48e06f1a8eSChristopher Di Bella static_assert(!std::invocable<void(), int>); 49e06f1a8eSChristopher Di Bella static_assert(!std::invocable<void(int)>); 50e06f1a8eSChristopher Di Bella static_assert(!std::invocable<void(int*), double*>); 51e06f1a8eSChristopher Di Bella static_assert(!std::invocable<void (*)(int&), double*>); 52e06f1a8eSChristopher Di Bella static_assert(std::invocable<int S::*, std::unique_ptr<S> >); 53e06f1a8eSChristopher Di Bella static_assert(std::invocable<int S::*, std::shared_ptr<S> >); 54e06f1a8eSChristopher Di Bella static_assert(!std::invocable<void (*)(int&&), int&>); 55e06f1a8eSChristopher Di Bella static_assert(!std::invocable<void (*)(int&&), int const&>); 5624dd2d2fSChristopher Di Bella 5724dd2d2fSChristopher Di Bella static_assert(!std::invocable<void>); 5824dd2d2fSChristopher Di Bella static_assert(!std::invocable<void*>); 5924dd2d2fSChristopher Di Bella static_assert(!std::invocable<int>); 6024dd2d2fSChristopher Di Bella static_assert(!std::invocable<int&>); 6124dd2d2fSChristopher Di Bella static_assert(!std::invocable<int&&>); 6224dd2d2fSChristopher Di Bella 63e06f1a8eSChristopher Di Bella namespace function_objects { 64e06f1a8eSChristopher Di Bella struct function_object { 65e06f1a8eSChristopher Di Bella void operator()(); 66e06f1a8eSChristopher Di Bella }; 67e06f1a8eSChristopher Di Bella static_assert(std::invocable<function_object>); 68e06f1a8eSChristopher Di Bella static_assert(!std::invocable<function_object const>); 69e06f1a8eSChristopher Di Bella static_assert(!std::invocable<function_object volatile>); 70e06f1a8eSChristopher Di Bella static_assert(!std::invocable<function_object const volatile>); 71e06f1a8eSChristopher Di Bella static_assert(std::invocable<function_object&>); 72e06f1a8eSChristopher Di Bella static_assert(!std::invocable<function_object const&>); 73e06f1a8eSChristopher Di Bella static_assert(!std::invocable<function_object volatile&>); 74e06f1a8eSChristopher Di Bella static_assert(!std::invocable<function_object const volatile&>); 75e06f1a8eSChristopher Di Bella 76e06f1a8eSChristopher Di Bella struct const_function_object { 77e06f1a8eSChristopher Di Bella void operator()(int) const; 78e06f1a8eSChristopher Di Bella }; 79e06f1a8eSChristopher Di Bella static_assert(std::invocable<const_function_object, int>); 80e06f1a8eSChristopher Di Bella static_assert(std::invocable<const_function_object const, int>); 81e06f1a8eSChristopher Di Bella static_assert(!std::invocable<const_function_object volatile, int>); 82e06f1a8eSChristopher Di Bella static_assert(!std::invocable<const_function_object const volatile, int>); 83e06f1a8eSChristopher Di Bella static_assert(std::invocable<const_function_object&, int>); 84e06f1a8eSChristopher Di Bella static_assert(std::invocable<const_function_object const&, int>); 85e06f1a8eSChristopher Di Bella static_assert(!std::invocable<const_function_object volatile&, int>); 86e06f1a8eSChristopher Di Bella static_assert(!std::invocable<const_function_object const volatile&, int>); 87e06f1a8eSChristopher Di Bella 88e06f1a8eSChristopher Di Bella struct volatile_function_object { 89e06f1a8eSChristopher Di Bella void operator()(int, int) volatile; 90e06f1a8eSChristopher Di Bella }; 91e06f1a8eSChristopher Di Bella static_assert(std::invocable<volatile_function_object, int, int>); 92e06f1a8eSChristopher Di Bella static_assert(!std::invocable<volatile_function_object const, int, int>); 93e06f1a8eSChristopher Di Bella static_assert(std::invocable<volatile_function_object volatile, int, int>); 94e06f1a8eSChristopher Di Bella static_assert( 95e06f1a8eSChristopher Di Bella !std::invocable<volatile_function_object const volatile, int, int>); 96e06f1a8eSChristopher Di Bella static_assert(std::invocable<volatile_function_object&, int, int>); 97e06f1a8eSChristopher Di Bella static_assert(!std::invocable<volatile_function_object const&, int, int>); 98e06f1a8eSChristopher Di Bella static_assert(std::invocable<volatile_function_object volatile&, int, int>); 99e06f1a8eSChristopher Di Bella static_assert( 100e06f1a8eSChristopher Di Bella !std::invocable<volatile_function_object const volatile&, int, int>); 101e06f1a8eSChristopher Di Bella 102e06f1a8eSChristopher Di Bella struct cv_function_object { 103e06f1a8eSChristopher Di Bella void operator()(int[]) const volatile; 104e06f1a8eSChristopher Di Bella }; 105e06f1a8eSChristopher Di Bella static_assert(std::invocable<cv_function_object, int*>); 106e06f1a8eSChristopher Di Bella static_assert(std::invocable<cv_function_object const, int*>); 107e06f1a8eSChristopher Di Bella static_assert(std::invocable<cv_function_object volatile, int*>); 108e06f1a8eSChristopher Di Bella static_assert(std::invocable<cv_function_object const volatile, int*>); 109e06f1a8eSChristopher Di Bella static_assert(std::invocable<cv_function_object&, int*>); 110e06f1a8eSChristopher Di Bella static_assert(std::invocable<cv_function_object const&, int*>); 111e06f1a8eSChristopher Di Bella static_assert(std::invocable<cv_function_object volatile&, int*>); 112e06f1a8eSChristopher Di Bella static_assert(std::invocable<cv_function_object const volatile&, int*>); 113e06f1a8eSChristopher Di Bella 114e06f1a8eSChristopher Di Bella struct lvalue_function_object { 115e06f1a8eSChristopher Di Bella void operator()() &; 116e06f1a8eSChristopher Di Bella }; 117e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_function_object>); 118e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_function_object const>); 119e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_function_object volatile>); 120e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_function_object const volatile>); 121e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_function_object&>); 122e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_function_object const&>); 123e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_function_object volatile&>); 124e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_function_object const volatile&>); 125e06f1a8eSChristopher Di Bella 126e06f1a8eSChristopher Di Bella struct lvalue_const_function_object { 127e06f1a8eSChristopher Di Bella void operator()(int) const&; 128e06f1a8eSChristopher Di Bella }; 129e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_const_function_object, int>); 130e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_const_function_object const, int>); 131e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_const_function_object volatile, int>); 132e06f1a8eSChristopher Di Bella static_assert( 133e06f1a8eSChristopher Di Bella !std::invocable<lvalue_const_function_object const volatile, int>); 134e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_const_function_object&, int>); 135e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_const_function_object const&, int>); 136e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_const_function_object volatile&, int>); 137e06f1a8eSChristopher Di Bella static_assert( 138e06f1a8eSChristopher Di Bella !std::invocable<lvalue_const_function_object const volatile&, int>); 139e06f1a8eSChristopher Di Bella 140e06f1a8eSChristopher Di Bella struct lvalue_volatile_function_object { 141e06f1a8eSChristopher Di Bella void operator()(int, int) volatile&; 142e06f1a8eSChristopher Di Bella }; 143e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_volatile_function_object, int, int>); 144e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_volatile_function_object const, int, int>); 145e06f1a8eSChristopher Di Bella static_assert( 146e06f1a8eSChristopher Di Bella !std::invocable<lvalue_volatile_function_object volatile, int, int>); 147e06f1a8eSChristopher Di Bella static_assert( 148e06f1a8eSChristopher Di Bella !std::invocable<lvalue_volatile_function_object const volatile, int, int>); 149e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_volatile_function_object&, int, int>); 150e06f1a8eSChristopher Di Bella static_assert( 151e06f1a8eSChristopher Di Bella !std::invocable<lvalue_volatile_function_object const&, int, int>); 152e06f1a8eSChristopher Di Bella static_assert( 153e06f1a8eSChristopher Di Bella std::invocable<lvalue_volatile_function_object volatile&, int, int>); 154e06f1a8eSChristopher Di Bella static_assert( 155e06f1a8eSChristopher Di Bella !std::invocable<lvalue_volatile_function_object const volatile&, int, int>); 156e06f1a8eSChristopher Di Bella 157e06f1a8eSChristopher Di Bella struct lvalue_cv_function_object { 158e06f1a8eSChristopher Di Bella void operator()(int[]) const volatile&; 159e06f1a8eSChristopher Di Bella }; 160e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_cv_function_object, int*>); 161e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_cv_function_object const, int*>); 162e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_cv_function_object volatile, int*>); 163e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_cv_function_object const volatile, int*>); 164e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_cv_function_object&, int*>); 165e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_cv_function_object const&, int*>); 166e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_cv_function_object volatile&, int*>); 167e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_cv_function_object const volatile&, int*>); 168e06f1a8eSChristopher Di Bella // 169e06f1a8eSChristopher Di Bella struct rvalue_function_object { 170e06f1a8eSChristopher Di Bella void operator()() &&; 171e06f1a8eSChristopher Di Bella }; 172e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_function_object>); 173e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_function_object const>); 174e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_function_object volatile>); 175e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_function_object const volatile>); 176e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_function_object&>); 177e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_function_object const&>); 178e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_function_object volatile&>); 179e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_function_object const volatile&>); 180e06f1a8eSChristopher Di Bella 181e06f1a8eSChristopher Di Bella struct rvalue_const_function_object { 182e06f1a8eSChristopher Di Bella void operator()(int) const&&; 183e06f1a8eSChristopher Di Bella }; 184e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_const_function_object, int>); 185e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_const_function_object const, int>); 186e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_const_function_object volatile, int>); 187e06f1a8eSChristopher Di Bella static_assert( 188e06f1a8eSChristopher Di Bella !std::invocable<rvalue_const_function_object const volatile, int>); 189e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_const_function_object&, int>); 190e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_const_function_object const&, int>); 191e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_const_function_object volatile&, int>); 192e06f1a8eSChristopher Di Bella static_assert( 193e06f1a8eSChristopher Di Bella !std::invocable<rvalue_const_function_object const volatile&, int>); 194e06f1a8eSChristopher Di Bella 195e06f1a8eSChristopher Di Bella struct rvalue_volatile_function_object { 196e06f1a8eSChristopher Di Bella void operator()(int, int) volatile&&; 197e06f1a8eSChristopher Di Bella }; 198e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_volatile_function_object, int, int>); 199e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_volatile_function_object const, int, int>); 200e06f1a8eSChristopher Di Bella static_assert( 201e06f1a8eSChristopher Di Bella std::invocable<rvalue_volatile_function_object volatile, int, int>); 202e06f1a8eSChristopher Di Bella static_assert( 203e06f1a8eSChristopher Di Bella !std::invocable<rvalue_volatile_function_object const volatile, int, int>); 204e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_volatile_function_object&, int, int>); 205e06f1a8eSChristopher Di Bella static_assert( 206e06f1a8eSChristopher Di Bella !std::invocable<rvalue_volatile_function_object const&, int, int>); 207e06f1a8eSChristopher Di Bella static_assert( 208e06f1a8eSChristopher Di Bella !std::invocable<rvalue_volatile_function_object volatile&, int, int>); 209e06f1a8eSChristopher Di Bella static_assert( 210e06f1a8eSChristopher Di Bella !std::invocable<rvalue_volatile_function_object const volatile&, int, int>); 211e06f1a8eSChristopher Di Bella 212e06f1a8eSChristopher Di Bella struct rvalue_cv_function_object { 213e06f1a8eSChristopher Di Bella void operator()(int[]) const volatile&&; 214e06f1a8eSChristopher Di Bella }; 215e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_cv_function_object, int*>); 216e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_cv_function_object const, int*>); 217e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_cv_function_object volatile, int*>); 218e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_cv_function_object const volatile, int*>); 219e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_cv_function_object&, int*>); 220e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_cv_function_object const&, int*>); 221e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_cv_function_object volatile&, int*>); 222e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_cv_function_object const volatile&, int*>); 223e06f1a8eSChristopher Di Bella 224e06f1a8eSChristopher Di Bella struct multiple_overloads { 22591d6debbSMartin Storsjö struct A {}; 22691d6debbSMartin Storsjö struct B { B(int); }; 22791d6debbSMartin Storsjö struct AB : A, B {}; 22891d6debbSMartin Storsjö struct O {}; 229ae318bebSArthur O'Dwyer void operator()(A) const; 230ae318bebSArthur O'Dwyer void operator()(B) const; 231e06f1a8eSChristopher Di Bella }; 232ae318bebSArthur O'Dwyer static_assert(std::invocable<multiple_overloads, multiple_overloads::A>); 233ae318bebSArthur O'Dwyer static_assert(std::invocable<multiple_overloads, multiple_overloads::B>); 234ae318bebSArthur O'Dwyer static_assert(std::invocable<multiple_overloads, int>); 235ae318bebSArthur O'Dwyer static_assert(!std::invocable<multiple_overloads, multiple_overloads::AB>); 236ae318bebSArthur O'Dwyer static_assert(!std::invocable<multiple_overloads, multiple_overloads::O>); 237e06f1a8eSChristopher Di Bella } // namespace function_objects 238e06f1a8eSChristopher Di Bella 239e06f1a8eSChristopher Di Bella namespace pointer_to_member_functions { 240e06f1a8eSChristopher Di Bella template<class Member, class T, class... Args> 24188b73a98SLouis Dionne constexpr bool check_member_is_invocable() 24224dd2d2fSChristopher Di Bella { 2435a3c2763SArthur O'Dwyer constexpr bool result = std::invocable<Member, T&&, Args...>; 244e06f1a8eSChristopher Di Bella using uncv_t = std::remove_cvref_t<T>; 245e06f1a8eSChristopher Di Bella static_assert(std::invocable<Member, uncv_t*, Args...> == result); 246e06f1a8eSChristopher Di Bella static_assert(std::invocable<Member, std::unique_ptr<uncv_t>, Args...> == result); 247e06f1a8eSChristopher Di Bella static_assert(std::invocable<Member, std::reference_wrapper<uncv_t>, Args...> == result); 248e06f1a8eSChristopher Di Bella static_assert(!std::invocable<Member, std::nullptr_t, Args...>); 249e06f1a8eSChristopher Di Bella static_assert(!std::invocable<Member, int, Args...>); 250e06f1a8eSChristopher Di Bella static_assert(!std::invocable<Member, int*, Args...>); 251e06f1a8eSChristopher Di Bella static_assert(!std::invocable<Member, double*, Args...>); 252e06f1a8eSChristopher Di Bella struct S2 {}; 253e06f1a8eSChristopher Di Bella static_assert(!std::invocable<Member, S2*, Args...>); 254e06f1a8eSChristopher Di Bella return result; 255e06f1a8eSChristopher Di Bella } 25624dd2d2fSChristopher Di Bella 257e06f1a8eSChristopher Di Bella static_assert(check_member_is_invocable<int S::*, S>()); 258e06f1a8eSChristopher Di Bella static_assert(std::invocable<int S::*, S&>); 259e06f1a8eSChristopher Di Bella static_assert(std::invocable<int S::*, S const&>); 260e06f1a8eSChristopher Di Bella static_assert(std::invocable<int S::*, S volatile&>); 261e06f1a8eSChristopher Di Bella static_assert(std::invocable<int S::*, S const volatile&>); 262e06f1a8eSChristopher Di Bella static_assert(std::invocable<int S::*, S&&>); 263e06f1a8eSChristopher Di Bella static_assert(std::invocable<int S::*, S const&&>); 264e06f1a8eSChristopher Di Bella static_assert(std::invocable<int S::*, S volatile&&>); 265e06f1a8eSChristopher Di Bella static_assert(std::invocable<int S::*, S const volatile&&>); 26624dd2d2fSChristopher Di Bella 267e06f1a8eSChristopher Di Bella static_assert(check_member_is_invocable<int (S::*)(int), S, int>()); 268e06f1a8eSChristopher Di Bella static_assert(!check_member_is_invocable<int (S::*)(int), S>()); 269e06f1a8eSChristopher Di Bella using unqualified = void (S::*)(); 270e06f1a8eSChristopher Di Bella static_assert(std::invocable<unqualified, S&>); 271e06f1a8eSChristopher Di Bella static_assert(!std::invocable<unqualified, S const&>); 272e06f1a8eSChristopher Di Bella static_assert(!std::invocable<unqualified, S volatile&>); 273e06f1a8eSChristopher Di Bella static_assert(!std::invocable<unqualified, S const volatile&>); 274e06f1a8eSChristopher Di Bella static_assert(std::invocable<unqualified, S&&>); 275e06f1a8eSChristopher Di Bella static_assert(!std::invocable<unqualified, S const&&>); 276e06f1a8eSChristopher Di Bella static_assert(!std::invocable<unqualified, S volatile&&>); 277e06f1a8eSChristopher Di Bella static_assert(!std::invocable<unqualified, S const volatile&&>); 27824dd2d2fSChristopher Di Bella 279e06f1a8eSChristopher Di Bella static_assert(check_member_is_invocable<int (S::*)(double) const, S, double>()); 280e06f1a8eSChristopher Di Bella using const_qualified = void (S::*)() const; 281e06f1a8eSChristopher Di Bella static_assert(std::invocable<const_qualified, S&>); 282e06f1a8eSChristopher Di Bella static_assert(std::invocable<const_qualified, S const&>); 283e06f1a8eSChristopher Di Bella static_assert(!std::invocable<const_qualified, S volatile&>); 284e06f1a8eSChristopher Di Bella static_assert(!std::invocable<const_qualified, S const volatile&>); 285e06f1a8eSChristopher Di Bella static_assert(std::invocable<const_qualified, S&&>); 286e06f1a8eSChristopher Di Bella static_assert(std::invocable<const_qualified, S const&&>); 287e06f1a8eSChristopher Di Bella static_assert(!std::invocable<const_qualified, S volatile&&>); 288e06f1a8eSChristopher Di Bella static_assert(!std::invocable<const_qualified, S const volatile&&>); 28924dd2d2fSChristopher Di Bella 290e06f1a8eSChristopher Di Bella static_assert( 291e06f1a8eSChristopher Di Bella check_member_is_invocable<int (S::*)(double[]) volatile, S, double*>()); 292e06f1a8eSChristopher Di Bella using volatile_qualified = void (S::*)() volatile; 293e06f1a8eSChristopher Di Bella static_assert(std::invocable<volatile_qualified, S&>); 294e06f1a8eSChristopher Di Bella static_assert(!std::invocable<volatile_qualified, S const&>); 295e06f1a8eSChristopher Di Bella static_assert(std::invocable<volatile_qualified, S volatile&>); 296e06f1a8eSChristopher Di Bella static_assert(!std::invocable<volatile_qualified, S const volatile&>); 297e06f1a8eSChristopher Di Bella static_assert(std::invocable<volatile_qualified, S&&>); 298e06f1a8eSChristopher Di Bella static_assert(!std::invocable<volatile_qualified, S const&&>); 299e06f1a8eSChristopher Di Bella static_assert(std::invocable<volatile_qualified, S volatile&&>); 300e06f1a8eSChristopher Di Bella static_assert(!std::invocable<volatile_qualified, S const volatile&&>); 301e06f1a8eSChristopher Di Bella 302e06f1a8eSChristopher Di Bella static_assert(check_member_is_invocable<int (S::*)(int, S&) const volatile, S, 303e06f1a8eSChristopher Di Bella int, S&>()); 304e06f1a8eSChristopher Di Bella using cv_qualified = void (S::*)() const volatile; 305e06f1a8eSChristopher Di Bella static_assert(std::invocable<cv_qualified, S&>); 306e06f1a8eSChristopher Di Bella static_assert(std::invocable<cv_qualified, S const&>); 307e06f1a8eSChristopher Di Bella static_assert(std::invocable<cv_qualified, S volatile&>); 308e06f1a8eSChristopher Di Bella static_assert(std::invocable<cv_qualified, S const volatile&>); 309e06f1a8eSChristopher Di Bella static_assert(std::invocable<cv_qualified, S&&>); 310e06f1a8eSChristopher Di Bella static_assert(std::invocable<cv_qualified, S const&&>); 311e06f1a8eSChristopher Di Bella static_assert(std::invocable<cv_qualified, S volatile&&>); 312e06f1a8eSChristopher Di Bella static_assert(std::invocable<cv_qualified, S const volatile&&>); 313e06f1a8eSChristopher Di Bella 314e06f1a8eSChristopher Di Bella static_assert(check_member_is_invocable<int (S::*)() &, S&>()); 315e06f1a8eSChristopher Di Bella using lvalue_qualified = void (S::*)() &; 316e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_qualified, S&>); 317e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_qualified, S const&>); 318e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_qualified, S volatile&>); 319e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_qualified, S const volatile&>); 320e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_qualified, S&&>); 321e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_qualified, S const&&>); 322e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_qualified, S volatile&&>); 323e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_qualified, S const volatile&&>); 324e06f1a8eSChristopher Di Bella 325e06f1a8eSChristopher Di Bella static_assert(check_member_is_invocable<int (S::*)() const&, S>()); 326e06f1a8eSChristopher Di Bella using lvalue_const_qualified = void (S::*)() const&; 327e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_const_qualified, S&>); 328e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_const_qualified, S const&>); 329e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_const_qualified, S volatile&>); 330e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_const_qualified, S const volatile&>); 331e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_const_qualified, S&&>); 332e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_const_qualified, S const&&>); 333e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_const_qualified, S volatile&&>); 334e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_const_qualified, S const volatile&&>); 335e06f1a8eSChristopher Di Bella 336e06f1a8eSChristopher Di Bella static_assert(check_member_is_invocable<int (S::*)() volatile&, S&>()); 337e06f1a8eSChristopher Di Bella using lvalue_volatile_qualified = void (S::*)() volatile&; 338e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_volatile_qualified, S&>); 339e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_volatile_qualified, S const&>); 340e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_volatile_qualified, S volatile&>); 341e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_volatile_qualified, S const volatile&>); 342e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_volatile_qualified, S&&>); 343e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_volatile_qualified, S const&&>); 344e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_volatile_qualified, S volatile&&>); 345e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_volatile_qualified, S const volatile&&>); 346e06f1a8eSChristopher Di Bella 347e06f1a8eSChristopher Di Bella static_assert(check_member_is_invocable<int (S::*)() const volatile&, S&>()); 348e06f1a8eSChristopher Di Bella using lvalue_cv_qualified = void (S::*)() const volatile&; 349e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_cv_qualified, S&>); 350e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_cv_qualified, S const&>); 351e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_cv_qualified, S volatile&>); 352e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_cv_qualified, S const volatile&>); 353e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_cv_qualified, S&&>); 354e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_cv_qualified, S const&&>); 355e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_cv_qualified, S volatile&&>); 356e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_cv_qualified, S const volatile&&>); 357e06f1a8eSChristopher Di Bella 358e06f1a8eSChristopher Di Bella using rvalue_unqualified = void (S::*)() &&; 359e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_unqualified, S&>); 360e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_unqualified, S const&>); 361e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_unqualified, S volatile&>); 362e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_unqualified, S const volatile&>); 363e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_unqualified, S&&>); 364e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_unqualified, S const&&>); 365e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_unqualified, S volatile&&>); 366e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_unqualified, S const volatile&&>); 367e06f1a8eSChristopher Di Bella 368e06f1a8eSChristopher Di Bella using rvalue_const_unqualified = void (S::*)() const&&; 369e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_const_unqualified, S&>); 370e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_const_unqualified, S const&>); 371e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_const_unqualified, S volatile&>); 372e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_const_unqualified, S const volatile&>); 373e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_const_unqualified, S&&>); 374e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_const_unqualified, S const&&>); 375e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_const_unqualified, S volatile&&>); 376e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_const_unqualified, S const volatile&&>); 377e06f1a8eSChristopher Di Bella 378e06f1a8eSChristopher Di Bella using rvalue_volatile_unqualified = void (S::*)() volatile&&; 379e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_volatile_unqualified, S&>); 380e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_volatile_unqualified, S const&>); 381e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_volatile_unqualified, S volatile&>); 382e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_volatile_unqualified, S const volatile&>); 383e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_volatile_unqualified, S&&>); 384e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_volatile_unqualified, S const&&>); 385e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_volatile_unqualified, S volatile&&>); 386e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_volatile_unqualified, S const volatile&&>); 387e06f1a8eSChristopher Di Bella 388e06f1a8eSChristopher Di Bella using rvalue_cv_unqualified = void (S::*)() const volatile&&; 389e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_cv_unqualified, S&>); 390e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_cv_unqualified, S const&>); 391e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_cv_unqualified, S volatile&>); 392e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_cv_unqualified, S const volatile&>); 393e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_cv_unqualified, S&&>); 394e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_cv_unqualified, S const&&>); 395e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_cv_unqualified, S volatile&&>); 396e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_cv_unqualified, S const volatile&&>); 397e06f1a8eSChristopher Di Bella } // namespace pointer_to_member_functions 398e06f1a8eSChristopher Di Bella 399e06f1a8eSChristopher Di Bella // std::invocable-specific 40031191e15SLouis Dionne static_assert(std::invocable<std::uniform_int_distribution<>, std::mt19937_64&>); 401e06f1a8eSChristopher Di Bella 40231191e15SLouis Dionne // Check the concept with closure types 403e06f1a8eSChristopher Di Bella template<class F, class... Args> 40431191e15SLouis Dionne constexpr bool is_invocable(F, Args&&...) { 40531191e15SLouis Dionne return std::invocable<F, Args...>; 406e06f1a8eSChristopher Di Bella } 40724dd2d2fSChristopher Di Bella 40831191e15SLouis Dionne static_assert(is_invocable([] {})); 40931191e15SLouis Dionne static_assert(is_invocable([](int) {}, 0)); 41031191e15SLouis Dionne static_assert(is_invocable([](int) {}, 0L)); 41131191e15SLouis Dionne static_assert(!is_invocable([](int) {}, nullptr)); 412e06f1a8eSChristopher Di Bella int i = 0; 41331191e15SLouis Dionne static_assert(is_invocable([](int&) {}, i)); 414