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