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