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