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 //===----------------------------------------------------------------------===// 8 9 // UNSUPPORTED: c++03, c++11, c++14, c++17 10 // UNSUPPORTED: libcpp-no-concepts 11 12 // template<class T, class U> 13 // concept invocable; 14 15 #include <chrono> 16 #include <concepts> 17 #include <memory> 18 #include <random> 19 #include <type_traits> 20 21 template <class R, class... Args> 22 [[nodiscard]] constexpr bool check_invocable() { 23 constexpr bool result = std::invocable<R(Args...), Args...>; 24 static_assert(std::invocable<R(Args...) noexcept, Args...> == result); 25 static_assert(std::invocable<R (*)(Args...), Args...> == result); 26 static_assert(std::invocable<R (*)(Args...) noexcept, Args...> == result); 27 static_assert(std::invocable<R (&)(Args...), Args...> == result); 28 static_assert(std::invocable<R (&)(Args...) noexcept, Args...> == result); 29 30 return result; 31 } 32 33 static_assert(check_invocable<void>()); 34 static_assert(check_invocable<void, int>()); 35 static_assert(check_invocable<void, int&>()); 36 static_assert(check_invocable<void, int*, double>()); 37 static_assert(check_invocable<int>()); 38 static_assert(check_invocable<int, int[]>()); 39 40 struct S; 41 static_assert(check_invocable<int, int S::*, std::nullptr_t>()); 42 static_assert(check_invocable<int, int (S::*)(), int (S::*)(int), int>()); 43 static_assert(std::invocable<void (*)(int const&), int&>); 44 static_assert(std::invocable<void (*)(int const&), int&&>); 45 static_assert(std::invocable<void (*)(int volatile&), int&>); 46 static_assert(std::invocable<void (*)(int const volatile&), int&>); 47 48 static_assert(!std::invocable<void(), int>); 49 static_assert(!std::invocable<void(int)>); 50 static_assert(!std::invocable<void(int*), double*>); 51 static_assert(!std::invocable<void (*)(int&), double*>); 52 static_assert(std::invocable<int S::*, std::unique_ptr<S> >); 53 static_assert(std::invocable<int S::*, std::shared_ptr<S> >); 54 static_assert(!std::invocable<void (*)(int&&), int&>); 55 static_assert(!std::invocable<void (*)(int&&), int const&>); 56 57 static_assert(!std::invocable<void>); 58 static_assert(!std::invocable<void*>); 59 static_assert(!std::invocable<int>); 60 static_assert(!std::invocable<int&>); 61 static_assert(!std::invocable<int&&>); 62 63 namespace function_objects { 64 struct function_object { 65 void operator()(); 66 }; 67 static_assert(std::invocable<function_object>); 68 static_assert(!std::invocable<function_object const>); 69 static_assert(!std::invocable<function_object volatile>); 70 static_assert(!std::invocable<function_object const volatile>); 71 static_assert(std::invocable<function_object&>); 72 static_assert(!std::invocable<function_object const&>); 73 static_assert(!std::invocable<function_object volatile&>); 74 static_assert(!std::invocable<function_object const volatile&>); 75 76 struct const_function_object { 77 void operator()(int) const; 78 }; 79 static_assert(std::invocable<const_function_object, int>); 80 static_assert(std::invocable<const_function_object const, int>); 81 static_assert(!std::invocable<const_function_object volatile, int>); 82 static_assert(!std::invocable<const_function_object const volatile, int>); 83 static_assert(std::invocable<const_function_object&, int>); 84 static_assert(std::invocable<const_function_object const&, int>); 85 static_assert(!std::invocable<const_function_object volatile&, int>); 86 static_assert(!std::invocable<const_function_object const volatile&, int>); 87 88 struct volatile_function_object { 89 void operator()(int, int) volatile; 90 }; 91 static_assert(std::invocable<volatile_function_object, int, int>); 92 static_assert(!std::invocable<volatile_function_object const, int, int>); 93 static_assert(std::invocable<volatile_function_object volatile, int, int>); 94 static_assert( 95 !std::invocable<volatile_function_object const volatile, int, int>); 96 static_assert(std::invocable<volatile_function_object&, int, int>); 97 static_assert(!std::invocable<volatile_function_object const&, int, int>); 98 static_assert(std::invocable<volatile_function_object volatile&, int, int>); 99 static_assert( 100 !std::invocable<volatile_function_object const volatile&, int, int>); 101 102 struct cv_function_object { 103 void operator()(int[]) const volatile; 104 }; 105 static_assert(std::invocable<cv_function_object, int*>); 106 static_assert(std::invocable<cv_function_object const, int*>); 107 static_assert(std::invocable<cv_function_object volatile, int*>); 108 static_assert(std::invocable<cv_function_object const volatile, int*>); 109 static_assert(std::invocable<cv_function_object&, int*>); 110 static_assert(std::invocable<cv_function_object const&, int*>); 111 static_assert(std::invocable<cv_function_object volatile&, int*>); 112 static_assert(std::invocable<cv_function_object const volatile&, int*>); 113 114 struct lvalue_function_object { 115 void operator()() &; 116 }; 117 static_assert(!std::invocable<lvalue_function_object>); 118 static_assert(!std::invocable<lvalue_function_object const>); 119 static_assert(!std::invocable<lvalue_function_object volatile>); 120 static_assert(!std::invocable<lvalue_function_object const volatile>); 121 static_assert(std::invocable<lvalue_function_object&>); 122 static_assert(!std::invocable<lvalue_function_object const&>); 123 static_assert(!std::invocable<lvalue_function_object volatile&>); 124 static_assert(!std::invocable<lvalue_function_object const volatile&>); 125 126 struct lvalue_const_function_object { 127 void operator()(int) const&; 128 }; 129 static_assert(std::invocable<lvalue_const_function_object, int>); 130 static_assert(std::invocable<lvalue_const_function_object const, int>); 131 static_assert(!std::invocable<lvalue_const_function_object volatile, int>); 132 static_assert( 133 !std::invocable<lvalue_const_function_object const volatile, int>); 134 static_assert(std::invocable<lvalue_const_function_object&, int>); 135 static_assert(std::invocable<lvalue_const_function_object const&, int>); 136 static_assert(!std::invocable<lvalue_const_function_object volatile&, int>); 137 static_assert( 138 !std::invocable<lvalue_const_function_object const volatile&, int>); 139 140 struct lvalue_volatile_function_object { 141 void operator()(int, int) volatile&; 142 }; 143 static_assert(!std::invocable<lvalue_volatile_function_object, int, int>); 144 static_assert(!std::invocable<lvalue_volatile_function_object const, int, int>); 145 static_assert( 146 !std::invocable<lvalue_volatile_function_object volatile, int, int>); 147 static_assert( 148 !std::invocable<lvalue_volatile_function_object const volatile, int, int>); 149 static_assert(std::invocable<lvalue_volatile_function_object&, int, int>); 150 static_assert( 151 !std::invocable<lvalue_volatile_function_object const&, int, int>); 152 static_assert( 153 std::invocable<lvalue_volatile_function_object volatile&, int, int>); 154 static_assert( 155 !std::invocable<lvalue_volatile_function_object const volatile&, int, int>); 156 157 struct lvalue_cv_function_object { 158 void operator()(int[]) const volatile&; 159 }; 160 static_assert(!std::invocable<lvalue_cv_function_object, int*>); 161 static_assert(!std::invocable<lvalue_cv_function_object const, int*>); 162 static_assert(!std::invocable<lvalue_cv_function_object volatile, int*>); 163 static_assert(!std::invocable<lvalue_cv_function_object const volatile, int*>); 164 static_assert(std::invocable<lvalue_cv_function_object&, int*>); 165 static_assert(std::invocable<lvalue_cv_function_object const&, int*>); 166 static_assert(std::invocable<lvalue_cv_function_object volatile&, int*>); 167 static_assert(std::invocable<lvalue_cv_function_object const volatile&, int*>); 168 // 169 struct rvalue_function_object { 170 void operator()() &&; 171 }; 172 static_assert(std::invocable<rvalue_function_object>); 173 static_assert(!std::invocable<rvalue_function_object const>); 174 static_assert(!std::invocable<rvalue_function_object volatile>); 175 static_assert(!std::invocable<rvalue_function_object const volatile>); 176 static_assert(!std::invocable<rvalue_function_object&>); 177 static_assert(!std::invocable<rvalue_function_object const&>); 178 static_assert(!std::invocable<rvalue_function_object volatile&>); 179 static_assert(!std::invocable<rvalue_function_object const volatile&>); 180 181 struct rvalue_const_function_object { 182 void operator()(int) const&&; 183 }; 184 static_assert(std::invocable<rvalue_const_function_object, int>); 185 static_assert(std::invocable<rvalue_const_function_object const, int>); 186 static_assert(!std::invocable<rvalue_const_function_object volatile, int>); 187 static_assert( 188 !std::invocable<rvalue_const_function_object const volatile, int>); 189 static_assert(!std::invocable<rvalue_const_function_object&, int>); 190 static_assert(!std::invocable<rvalue_const_function_object const&, int>); 191 static_assert(!std::invocable<rvalue_const_function_object volatile&, int>); 192 static_assert( 193 !std::invocable<rvalue_const_function_object const volatile&, int>); 194 195 struct rvalue_volatile_function_object { 196 void operator()(int, int) volatile&&; 197 }; 198 static_assert(std::invocable<rvalue_volatile_function_object, int, int>); 199 static_assert(!std::invocable<rvalue_volatile_function_object const, int, int>); 200 static_assert( 201 std::invocable<rvalue_volatile_function_object volatile, int, int>); 202 static_assert( 203 !std::invocable<rvalue_volatile_function_object const volatile, int, int>); 204 static_assert(!std::invocable<rvalue_volatile_function_object&, int, int>); 205 static_assert( 206 !std::invocable<rvalue_volatile_function_object const&, int, int>); 207 static_assert( 208 !std::invocable<rvalue_volatile_function_object volatile&, int, int>); 209 static_assert( 210 !std::invocable<rvalue_volatile_function_object const volatile&, int, int>); 211 212 struct rvalue_cv_function_object { 213 void operator()(int[]) const volatile&&; 214 }; 215 static_assert(std::invocable<rvalue_cv_function_object, int*>); 216 static_assert(std::invocable<rvalue_cv_function_object const, int*>); 217 static_assert(std::invocable<rvalue_cv_function_object volatile, int*>); 218 static_assert(std::invocable<rvalue_cv_function_object const volatile, int*>); 219 static_assert(!std::invocable<rvalue_cv_function_object&, int*>); 220 static_assert(!std::invocable<rvalue_cv_function_object const&, int*>); 221 static_assert(!std::invocable<rvalue_cv_function_object volatile&, int*>); 222 static_assert(!std::invocable<rvalue_cv_function_object const volatile&, int*>); 223 224 struct multiple_overloads { 225 bool operator()(); 226 void operator()(int); 227 int operator()(double); 228 }; 229 static_assert(std::invocable<multiple_overloads&>); 230 static_assert(std::invocable<multiple_overloads&, short>); 231 static_assert(std::invocable<multiple_overloads&, int>); 232 static_assert(!std::invocable<multiple_overloads&, long>); 233 static_assert(std::invocable<multiple_overloads&, double>); 234 static_assert(std::invocable<multiple_overloads&, float>); 235 static_assert(std::invocable<multiple_overloads&, short&>); 236 static_assert(std::invocable<multiple_overloads&, int&>); 237 static_assert(!std::invocable<multiple_overloads&, long&>); 238 static_assert(std::invocable<multiple_overloads&, float&>); 239 static_assert(std::invocable<multiple_overloads&, double&>); 240 } // namespace function_objects 241 242 namespace pointer_to_member_functions { 243 // clang-format off 244 template<class Member, class T, class... Args> 245 [[nodiscard]] constexpr bool check_member_is_invocable() 246 { 247 constexpr bool result = std::invocable<Member, T, Args...>; 248 using uncv_t = std::remove_cvref_t<T>; 249 static_assert(std::invocable<Member, uncv_t*, Args...> == result); 250 static_assert(std::invocable<Member, std::unique_ptr<uncv_t>, Args...> == result); 251 static_assert(std::invocable<Member, std::reference_wrapper<uncv_t>, Args...> == result); 252 static_assert(!std::invocable<Member, std::nullptr_t, Args...>); 253 static_assert(!std::invocable<Member, int, Args...>); 254 static_assert(!std::invocable<Member, int*, Args...>); 255 static_assert(!std::invocable<Member, double*, Args...>); 256 struct S2 {}; 257 static_assert(!std::invocable<Member, S2*, Args...>); 258 return result; 259 } 260 // clang-format on 261 262 static_assert(check_member_is_invocable<int S::*, S>()); 263 static_assert(std::invocable<int S::*, S&>); 264 static_assert(std::invocable<int S::*, S const&>); 265 static_assert(std::invocable<int S::*, S volatile&>); 266 static_assert(std::invocable<int S::*, S const volatile&>); 267 static_assert(std::invocable<int S::*, S&&>); 268 static_assert(std::invocable<int S::*, S const&&>); 269 static_assert(std::invocable<int S::*, S volatile&&>); 270 static_assert(std::invocable<int S::*, S const volatile&&>); 271 272 static_assert(check_member_is_invocable<int (S::*)(int), S, int>()); 273 static_assert(!check_member_is_invocable<int (S::*)(int), S>()); 274 using unqualified = void (S::*)(); 275 static_assert(std::invocable<unqualified, S&>); 276 static_assert(!std::invocable<unqualified, S const&>); 277 static_assert(!std::invocable<unqualified, S volatile&>); 278 static_assert(!std::invocable<unqualified, S const volatile&>); 279 static_assert(std::invocable<unqualified, S&&>); 280 static_assert(!std::invocable<unqualified, S const&&>); 281 static_assert(!std::invocable<unqualified, S volatile&&>); 282 static_assert(!std::invocable<unqualified, S const volatile&&>); 283 284 static_assert(check_member_is_invocable<int (S::*)(double) const, S, double>()); 285 using const_qualified = void (S::*)() const; 286 static_assert(std::invocable<const_qualified, S&>); 287 static_assert(std::invocable<const_qualified, S const&>); 288 static_assert(!std::invocable<const_qualified, S volatile&>); 289 static_assert(!std::invocable<const_qualified, S const volatile&>); 290 static_assert(std::invocable<const_qualified, S&&>); 291 static_assert(std::invocable<const_qualified, S const&&>); 292 static_assert(!std::invocable<const_qualified, S volatile&&>); 293 static_assert(!std::invocable<const_qualified, S const volatile&&>); 294 295 static_assert( 296 check_member_is_invocable<int (S::*)(double[]) volatile, S, double*>()); 297 using volatile_qualified = void (S::*)() volatile; 298 static_assert(std::invocable<volatile_qualified, S&>); 299 static_assert(!std::invocable<volatile_qualified, S const&>); 300 static_assert(std::invocable<volatile_qualified, S volatile&>); 301 static_assert(!std::invocable<volatile_qualified, S const volatile&>); 302 static_assert(std::invocable<volatile_qualified, S&&>); 303 static_assert(!std::invocable<volatile_qualified, S const&&>); 304 static_assert(std::invocable<volatile_qualified, S volatile&&>); 305 static_assert(!std::invocable<volatile_qualified, S const volatile&&>); 306 307 static_assert(check_member_is_invocable<int (S::*)(int, S&) const volatile, S, 308 int, S&>()); 309 using cv_qualified = void (S::*)() const volatile; 310 static_assert(std::invocable<cv_qualified, S&>); 311 static_assert(std::invocable<cv_qualified, S const&>); 312 static_assert(std::invocable<cv_qualified, S volatile&>); 313 static_assert(std::invocable<cv_qualified, S const volatile&>); 314 static_assert(std::invocable<cv_qualified, S&&>); 315 static_assert(std::invocable<cv_qualified, S const&&>); 316 static_assert(std::invocable<cv_qualified, S volatile&&>); 317 static_assert(std::invocable<cv_qualified, S const volatile&&>); 318 319 static_assert(check_member_is_invocable<int (S::*)() &, S&>()); 320 using lvalue_qualified = void (S::*)() &; 321 static_assert(std::invocable<lvalue_qualified, S&>); 322 static_assert(!std::invocable<lvalue_qualified, S const&>); 323 static_assert(!std::invocable<lvalue_qualified, S volatile&>); 324 static_assert(!std::invocable<lvalue_qualified, S const volatile&>); 325 static_assert(!std::invocable<lvalue_qualified, S&&>); 326 static_assert(!std::invocable<lvalue_qualified, S const&&>); 327 static_assert(!std::invocable<lvalue_qualified, S volatile&&>); 328 static_assert(!std::invocable<lvalue_qualified, S const volatile&&>); 329 330 static_assert(check_member_is_invocable<int (S::*)() const&, S>()); 331 using lvalue_const_qualified = void (S::*)() const&; 332 static_assert(std::invocable<lvalue_const_qualified, S&>); 333 static_assert(std::invocable<lvalue_const_qualified, S const&>); 334 static_assert(!std::invocable<lvalue_const_qualified, S volatile&>); 335 static_assert(!std::invocable<lvalue_const_qualified, S const volatile&>); 336 static_assert(std::invocable<lvalue_const_qualified, S&&>); 337 static_assert(std::invocable<lvalue_const_qualified, S const&&>); 338 static_assert(!std::invocable<lvalue_const_qualified, S volatile&&>); 339 static_assert(!std::invocable<lvalue_const_qualified, S const volatile&&>); 340 341 static_assert(check_member_is_invocable<int (S::*)() volatile&, S&>()); 342 using lvalue_volatile_qualified = void (S::*)() volatile&; 343 static_assert(std::invocable<lvalue_volatile_qualified, S&>); 344 static_assert(!std::invocable<lvalue_volatile_qualified, S const&>); 345 static_assert(std::invocable<lvalue_volatile_qualified, S volatile&>); 346 static_assert(!std::invocable<lvalue_volatile_qualified, S const volatile&>); 347 static_assert(!std::invocable<lvalue_volatile_qualified, S&&>); 348 static_assert(!std::invocable<lvalue_volatile_qualified, S const&&>); 349 static_assert(!std::invocable<lvalue_volatile_qualified, S volatile&&>); 350 static_assert(!std::invocable<lvalue_volatile_qualified, S const volatile&&>); 351 352 static_assert(check_member_is_invocable<int (S::*)() const volatile&, S&>()); 353 using lvalue_cv_qualified = void (S::*)() const volatile&; 354 static_assert(std::invocable<lvalue_cv_qualified, S&>); 355 static_assert(std::invocable<lvalue_cv_qualified, S const&>); 356 static_assert(std::invocable<lvalue_cv_qualified, S volatile&>); 357 static_assert(std::invocable<lvalue_cv_qualified, S const volatile&>); 358 static_assert(!std::invocable<lvalue_cv_qualified, S&&>); 359 static_assert(!std::invocable<lvalue_cv_qualified, S const&&>); 360 static_assert(!std::invocable<lvalue_cv_qualified, S volatile&&>); 361 static_assert(!std::invocable<lvalue_cv_qualified, S const volatile&&>); 362 363 using rvalue_unqualified = void (S::*)() &&; 364 static_assert(!std::invocable<rvalue_unqualified, S&>); 365 static_assert(!std::invocable<rvalue_unqualified, S const&>); 366 static_assert(!std::invocable<rvalue_unqualified, S volatile&>); 367 static_assert(!std::invocable<rvalue_unqualified, S const volatile&>); 368 static_assert(std::invocable<rvalue_unqualified, S&&>); 369 static_assert(!std::invocable<rvalue_unqualified, S const&&>); 370 static_assert(!std::invocable<rvalue_unqualified, S volatile&&>); 371 static_assert(!std::invocable<rvalue_unqualified, S const volatile&&>); 372 373 using rvalue_const_unqualified = void (S::*)() const&&; 374 static_assert(!std::invocable<rvalue_const_unqualified, S&>); 375 static_assert(!std::invocable<rvalue_const_unqualified, S const&>); 376 static_assert(!std::invocable<rvalue_const_unqualified, S volatile&>); 377 static_assert(!std::invocable<rvalue_const_unqualified, S const volatile&>); 378 static_assert(std::invocable<rvalue_const_unqualified, S&&>); 379 static_assert(std::invocable<rvalue_const_unqualified, S const&&>); 380 static_assert(!std::invocable<rvalue_const_unqualified, S volatile&&>); 381 static_assert(!std::invocable<rvalue_const_unqualified, S const volatile&&>); 382 383 using rvalue_volatile_unqualified = void (S::*)() volatile&&; 384 static_assert(!std::invocable<rvalue_volatile_unqualified, S&>); 385 static_assert(!std::invocable<rvalue_volatile_unqualified, S const&>); 386 static_assert(!std::invocable<rvalue_volatile_unqualified, S volatile&>); 387 static_assert(!std::invocable<rvalue_volatile_unqualified, S const volatile&>); 388 static_assert(std::invocable<rvalue_volatile_unqualified, S&&>); 389 static_assert(!std::invocable<rvalue_volatile_unqualified, S const&&>); 390 static_assert(std::invocable<rvalue_volatile_unqualified, S volatile&&>); 391 static_assert(!std::invocable<rvalue_volatile_unqualified, S const volatile&&>); 392 393 using rvalue_cv_unqualified = void (S::*)() const volatile&&; 394 static_assert(!std::invocable<rvalue_cv_unqualified, S&>); 395 static_assert(!std::invocable<rvalue_cv_unqualified, S const&>); 396 static_assert(!std::invocable<rvalue_cv_unqualified, S volatile&>); 397 static_assert(!std::invocable<rvalue_cv_unqualified, S const volatile&>); 398 static_assert(std::invocable<rvalue_cv_unqualified, S&&>); 399 static_assert(std::invocable<rvalue_cv_unqualified, S const&&>); 400 static_assert(std::invocable<rvalue_cv_unqualified, S volatile&&>); 401 static_assert(std::invocable<rvalue_cv_unqualified, S const volatile&&>); 402 } // namespace pointer_to_member_functions 403 404 // std::invocable-specific 405 static_assert( 406 std::invocable<std::uniform_int_distribution<>, std::mt19937_64&>); 407 408 [[nodiscard]] constexpr bool check_lambda(auto, auto...) { return false; } 409 410 // clang-format off 411 template<class F, class... Args> 412 requires std::invocable<F, Args...> 413 [[nodiscard]] constexpr bool check_lambda(F, Args&&...) 414 { 415 return true; 416 } 417 // clang-format on 418 419 [[nodiscard]] constexpr bool check_lambdas() { 420 static_assert(check_lambda([] {})); 421 static_assert(check_lambda([](int) {}, 0)); 422 static_assert(check_lambda([](int) {}, 0L)); 423 static_assert(!check_lambda([](int) {}, nullptr)); 424 425 int i = 0; 426 return check_lambda([](int&) {}, i); 427 } 428 429 static_assert(check_lambdas()); 430 431 int main(int, char**) { return 0; } 432