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 template<class Member, class T, class... Args> 267 constexpr bool check_member_is_invocable() 268 { 269 constexpr bool result = std::regular_invocable<Member, T&&, Args...>; 270 using uncv_t = std::remove_cvref_t<T>; 271 static_assert(std::regular_invocable<Member, uncv_t*, Args...> == result); 272 static_assert(std::regular_invocable<Member, std::unique_ptr<uncv_t>, Args...> == result); 273 static_assert(std::regular_invocable<Member, std::reference_wrapper<uncv_t>, Args...> == result); 274 static_assert(!std::regular_invocable<Member, std::nullptr_t, Args...>); 275 static_assert(!std::regular_invocable<Member, int, Args...>); 276 static_assert(!std::regular_invocable<Member, int*, Args...>); 277 static_assert(!std::regular_invocable<Member, double*, Args...>); 278 struct S2 {}; 279 static_assert(!std::regular_invocable<Member, S2*, Args...>); 280 return result; 281 } 282 283 static_assert(check_member_is_invocable<int S::*, S>()); 284 static_assert(std::regular_invocable<int S::*, S&>); 285 static_assert(std::regular_invocable<int S::*, S const&>); 286 static_assert(std::regular_invocable<int S::*, S volatile&>); 287 static_assert(std::regular_invocable<int S::*, S const volatile&>); 288 static_assert(std::regular_invocable<int S::*, S&&>); 289 static_assert(std::regular_invocable<int S::*, S const&&>); 290 static_assert(std::regular_invocable<int S::*, S volatile&&>); 291 static_assert(std::regular_invocable<int S::*, S const volatile&&>); 292 293 static_assert(check_member_is_invocable<int (S::*)(int), S, int>()); 294 static_assert(!check_member_is_invocable<int (S::*)(int), S>()); 295 using unqualified = void (S::*)(); 296 static_assert(std::regular_invocable<unqualified, S&>); 297 static_assert(!std::regular_invocable<unqualified, S const&>); 298 static_assert(!std::regular_invocable<unqualified, S volatile&>); 299 static_assert(!std::regular_invocable<unqualified, S const volatile&>); 300 static_assert(std::regular_invocable<unqualified, S&&>); 301 static_assert(!std::regular_invocable<unqualified, S const&&>); 302 static_assert(!std::regular_invocable<unqualified, S volatile&&>); 303 static_assert(!std::regular_invocable<unqualified, S const volatile&&>); 304 305 static_assert(check_member_is_invocable<int (S::*)(double) const, S, double>()); 306 using const_qualified = void (S::*)() const; 307 static_assert(std::regular_invocable<const_qualified, S&>); 308 static_assert(std::regular_invocable<const_qualified, S const&>); 309 static_assert(!std::regular_invocable<const_qualified, S volatile&>); 310 static_assert(!std::regular_invocable<const_qualified, S const volatile&>); 311 static_assert(std::regular_invocable<const_qualified, S&&>); 312 static_assert(std::regular_invocable<const_qualified, S const&&>); 313 static_assert(!std::regular_invocable<const_qualified, S volatile&&>); 314 static_assert(!std::regular_invocable<const_qualified, S const volatile&&>); 315 316 static_assert( 317 check_member_is_invocable<int (S::*)(double[]) volatile, S, double*>()); 318 using volatile_qualified = void (S::*)() volatile; 319 static_assert(std::regular_invocable<volatile_qualified, S&>); 320 static_assert(!std::regular_invocable<volatile_qualified, S const&>); 321 static_assert(std::regular_invocable<volatile_qualified, S volatile&>); 322 static_assert(!std::regular_invocable<volatile_qualified, S const volatile&>); 323 static_assert(std::regular_invocable<volatile_qualified, S&&>); 324 static_assert(!std::regular_invocable<volatile_qualified, S const&&>); 325 static_assert(std::regular_invocable<volatile_qualified, S volatile&&>); 326 static_assert(!std::regular_invocable<volatile_qualified, S const volatile&&>); 327 328 static_assert(check_member_is_invocable<int (S::*)(int, S&) const volatile, S, 329 int, S&>()); 330 using cv_qualified = void (S::*)() const volatile; 331 static_assert(std::regular_invocable<cv_qualified, S&>); 332 static_assert(std::regular_invocable<cv_qualified, S const&>); 333 static_assert(std::regular_invocable<cv_qualified, S volatile&>); 334 static_assert(std::regular_invocable<cv_qualified, S const volatile&>); 335 static_assert(std::regular_invocable<cv_qualified, S&&>); 336 static_assert(std::regular_invocable<cv_qualified, S const&&>); 337 static_assert(std::regular_invocable<cv_qualified, S volatile&&>); 338 static_assert(std::regular_invocable<cv_qualified, S const volatile&&>); 339 340 static_assert(check_member_is_invocable<int (S::*)() &, S&>()); 341 using lvalue_qualified = void (S::*)() &; 342 static_assert(std::regular_invocable<lvalue_qualified, S&>); 343 static_assert(!std::regular_invocable<lvalue_qualified, S const&>); 344 static_assert(!std::regular_invocable<lvalue_qualified, S volatile&>); 345 static_assert(!std::regular_invocable<lvalue_qualified, S const volatile&>); 346 static_assert(!std::regular_invocable<lvalue_qualified, S&&>); 347 static_assert(!std::regular_invocable<lvalue_qualified, S const&&>); 348 static_assert(!std::regular_invocable<lvalue_qualified, S volatile&&>); 349 static_assert(!std::regular_invocable<lvalue_qualified, S const volatile&&>); 350 351 static_assert(check_member_is_invocable<int (S::*)() const&, S>()); 352 using lvalue_const_qualified = void (S::*)() const&; 353 static_assert(std::regular_invocable<lvalue_const_qualified, S&>); 354 static_assert(std::regular_invocable<lvalue_const_qualified, S const&>); 355 static_assert(!std::regular_invocable<lvalue_const_qualified, S volatile&>); 356 static_assert( 357 !std::regular_invocable<lvalue_const_qualified, S const volatile&>); 358 static_assert(std::regular_invocable<lvalue_const_qualified, S&&>); 359 static_assert(std::regular_invocable<lvalue_const_qualified, S const&&>); 360 static_assert(!std::regular_invocable<lvalue_const_qualified, S volatile&&>); 361 static_assert( 362 !std::regular_invocable<lvalue_const_qualified, S const volatile&&>); 363 364 static_assert(check_member_is_invocable<int (S::*)() volatile&, S&>()); 365 using lvalue_volatile_qualified = void (S::*)() volatile&; 366 static_assert(std::regular_invocable<lvalue_volatile_qualified, S&>); 367 static_assert(!std::regular_invocable<lvalue_volatile_qualified, S const&>); 368 static_assert(std::regular_invocable<lvalue_volatile_qualified, S volatile&>); 369 static_assert( 370 !std::regular_invocable<lvalue_volatile_qualified, S const volatile&>); 371 static_assert(!std::regular_invocable<lvalue_volatile_qualified, S&&>); 372 static_assert(!std::regular_invocable<lvalue_volatile_qualified, S const&&>); 373 static_assert(!std::regular_invocable<lvalue_volatile_qualified, S volatile&&>); 374 static_assert( 375 !std::regular_invocable<lvalue_volatile_qualified, S const volatile&&>); 376 377 static_assert(check_member_is_invocable<int (S::*)() const volatile&, S&>()); 378 using lvalue_cv_qualified = void (S::*)() const volatile&; 379 static_assert(std::regular_invocable<lvalue_cv_qualified, S&>); 380 static_assert(std::regular_invocable<lvalue_cv_qualified, S const&>); 381 static_assert(std::regular_invocable<lvalue_cv_qualified, S volatile&>); 382 static_assert(std::regular_invocable<lvalue_cv_qualified, S const volatile&>); 383 static_assert(!std::regular_invocable<lvalue_cv_qualified, S&&>); 384 static_assert(!std::regular_invocable<lvalue_cv_qualified, S const&&>); 385 static_assert(!std::regular_invocable<lvalue_cv_qualified, S volatile&&>); 386 static_assert(!std::regular_invocable<lvalue_cv_qualified, S const volatile&&>); 387 388 using rvalue_unqualified = void (S::*)() &&; 389 static_assert(!std::regular_invocable<rvalue_unqualified, S&>); 390 static_assert(!std::regular_invocable<rvalue_unqualified, S const&>); 391 static_assert(!std::regular_invocable<rvalue_unqualified, S volatile&>); 392 static_assert(!std::regular_invocable<rvalue_unqualified, S const volatile&>); 393 static_assert(std::regular_invocable<rvalue_unqualified, S&&>); 394 static_assert(!std::regular_invocable<rvalue_unqualified, S const&&>); 395 static_assert(!std::regular_invocable<rvalue_unqualified, S volatile&&>); 396 static_assert(!std::regular_invocable<rvalue_unqualified, S const volatile&&>); 397 398 using rvalue_const_unqualified = void (S::*)() const&&; 399 static_assert(!std::regular_invocable<rvalue_const_unqualified, S&>); 400 static_assert(!std::regular_invocable<rvalue_const_unqualified, S const&>); 401 static_assert(!std::regular_invocable<rvalue_const_unqualified, S volatile&>); 402 static_assert( 403 !std::regular_invocable<rvalue_const_unqualified, S const volatile&>); 404 static_assert(std::regular_invocable<rvalue_const_unqualified, S&&>); 405 static_assert(std::regular_invocable<rvalue_const_unqualified, S const&&>); 406 static_assert(!std::regular_invocable<rvalue_const_unqualified, S volatile&&>); 407 static_assert( 408 !std::regular_invocable<rvalue_const_unqualified, S const volatile&&>); 409 410 using rvalue_volatile_unqualified = void (S::*)() volatile&&; 411 static_assert(!std::regular_invocable<rvalue_volatile_unqualified, S&>); 412 static_assert(!std::regular_invocable<rvalue_volatile_unqualified, S const&>); 413 static_assert( 414 !std::regular_invocable<rvalue_volatile_unqualified, S volatile&>); 415 static_assert( 416 !std::regular_invocable<rvalue_volatile_unqualified, S const volatile&>); 417 static_assert(std::regular_invocable<rvalue_volatile_unqualified, S&&>); 418 static_assert(!std::regular_invocable<rvalue_volatile_unqualified, S const&&>); 419 static_assert( 420 std::regular_invocable<rvalue_volatile_unqualified, S volatile&&>); 421 static_assert( 422 !std::regular_invocable<rvalue_volatile_unqualified, S const volatile&&>); 423 424 using rvalue_cv_unqualified = void (S::*)() const volatile&&; 425 static_assert(!std::regular_invocable<rvalue_cv_unqualified, S&>); 426 static_assert(!std::regular_invocable<rvalue_cv_unqualified, S const&>); 427 static_assert(!std::regular_invocable<rvalue_cv_unqualified, S volatile&>); 428 static_assert( 429 !std::regular_invocable<rvalue_cv_unqualified, S const volatile&>); 430 static_assert(std::regular_invocable<rvalue_cv_unqualified, S&&>); 431 static_assert(std::regular_invocable<rvalue_cv_unqualified, S const&&>); 432 static_assert(std::regular_invocable<rvalue_cv_unqualified, S volatile&&>); 433 static_assert( 434 std::regular_invocable<rvalue_cv_unqualified, S const volatile&&>); 435 } // namespace pointer_to_member_functions 436 437 // Check the concept with closure types (and also check for subsumption) 438 template<class F, class... Args> 439 constexpr bool is_regular_invocable(F, Args&&...) { 440 return false; 441 } 442 443 template<class F, class... Args> 444 requires std::invocable<F, Args...> 445 constexpr bool is_regular_invocable(F, Args&&...) { 446 return false; 447 } 448 449 template<class F, class... Args> 450 requires std::regular_invocable<F, Args...> && true 451 constexpr bool is_regular_invocable(F, Args&&...) { 452 return true; 453 } 454 455 static_assert(is_regular_invocable([] {})); 456 static_assert(is_regular_invocable([](int) {}, 0)); 457 static_assert(is_regular_invocable([](int) {}, 0L)); 458 static_assert(!is_regular_invocable([](int) {}, nullptr)); 459 460 int i = 0; 461 static_assert(is_regular_invocable([](int&) {}, i)); 462