brintos

brintos / llvm-project-archived public Read only

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