brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.2 KiB · 2eecf79 Raw
245 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++1410 11// type_traits12 13// is_invocable14 15// Most testing of is_invocable is done within the [meta.trans.other] result_of16// tests.17 18// Fn and all types in the template parameter pack ArgTypes shall be19//  complete types, cv void, or arrays of unknown bound.20 21#include <cstddef>22#include <functional>23#include <memory>24#include <type_traits>25#include <vector>26 27struct Tag {};28struct DerFromTag : Tag {};29 30struct Implicit {31  Implicit(int) {}32};33 34struct Explicit {35  explicit Explicit(int) {}36};37 38struct NotCallableWithInt {39  int operator()(int) = delete;40  int operator()(Tag) { return 42; }41};42 43struct Sink {44  template <class ...Args>45  void operator()(Args&&...) const {}46};47 48int main(int, char**) {49  using AbominableFunc = void(...) const;50 51  //  Non-callable things52  {53    static_assert(!std::is_invocable<void>::value, "");54    static_assert(!std::is_invocable<const void>::value, "");55    static_assert(!std::is_invocable<volatile void>::value, "");56    static_assert(!std::is_invocable<const volatile void>::value, "");57    static_assert(!std::is_invocable<std::nullptr_t>::value, "");58    static_assert(!std::is_invocable<int>::value, "");59    static_assert(!std::is_invocable<double>::value, "");60 61    static_assert(!std::is_invocable<int[]>::value, "");62    static_assert(!std::is_invocable<int[3]>::value, "");63 64    static_assert(!std::is_invocable<int*>::value, "");65    static_assert(!std::is_invocable<const int*>::value, "");66    static_assert(!std::is_invocable<int const*>::value, "");67 68    static_assert(!std::is_invocable<int&>::value, "");69    static_assert(!std::is_invocable<const int&>::value, "");70    static_assert(!std::is_invocable<int&&>::value, "");71 72    static_assert(!std::is_invocable<std::vector<int> >::value, "");73    static_assert(!std::is_invocable<std::vector<int*> >::value, "");74    static_assert(!std::is_invocable<std::vector<int**> >::value, "");75 76    static_assert(!std::is_invocable<AbominableFunc>::value, "");77 78    //  with parameters79    static_assert(!std::is_invocable<int, int>::value, "");80    static_assert(!std::is_invocable<int, double, float>::value, "");81    static_assert(!std::is_invocable<int, char, float, double>::value, "");82    static_assert(!std::is_invocable<Sink, AbominableFunc>::value, "");83    static_assert(!std::is_invocable<Sink, void>::value, "");84    static_assert(!std::is_invocable<Sink, const volatile void>::value,85                  "");86 87 88    static_assert(!std::is_invocable_r<int, void>::value, "");89    static_assert(!std::is_invocable_r<int, const void>::value, "");90    static_assert(!std::is_invocable_r<int, volatile void>::value, "");91    static_assert(!std::is_invocable_r<int, const volatile void>::value, "");92    static_assert(!std::is_invocable_r<int, std::nullptr_t>::value, "");93    static_assert(!std::is_invocable_r<int, int>::value, "");94    static_assert(!std::is_invocable_r<int, double>::value, "");95 96    static_assert(!std::is_invocable_r<int, int[]>::value, "");97    static_assert(!std::is_invocable_r<int, int[3]>::value, "");98 99    static_assert(!std::is_invocable_r<int, int*>::value, "");100    static_assert(!std::is_invocable_r<int, const int*>::value, "");101    static_assert(!std::is_invocable_r<int, int const*>::value, "");102 103    static_assert(!std::is_invocable_r<int, int&>::value, "");104    static_assert(!std::is_invocable_r<int, const int&>::value, "");105    static_assert(!std::is_invocable_r<int, int&&>::value, "");106 107    static_assert(!std::is_invocable_r<int, std::vector<int> >::value, "");108    static_assert(!std::is_invocable_r<int, std::vector<int*> >::value, "");109    static_assert(!std::is_invocable_r<int, std::vector<int**> >::value, "");110    static_assert(!std::is_invocable_r<void, AbominableFunc>::value, "");111 112    //  with parameters113    static_assert(!std::is_invocable_r<int, int, int>::value, "");114    static_assert(!std::is_invocable_r<int, int, double, float>::value, "");115    static_assert(!std::is_invocable_r<int, int, char, float, double>::value,116                  "");117    static_assert(!std::is_invocable_r<void, Sink, AbominableFunc>::value, "");118    static_assert(!std::is_invocable_r<void, Sink, void>::value, "");119    static_assert(!std::is_invocable_r<void, Sink, const volatile void>::value,120                  "");121  }122  {123    using Fn = int (Tag::*)(int);124    using RFn = int (Tag::*)(int)&&;125    // INVOKE bullet 1, 2 and 3126    {127      // Bullet 1128      static_assert(std::is_invocable<Fn, Tag&, int>::value, "");129      static_assert(std::is_invocable<Fn, DerFromTag&, int>::value, "");130      static_assert(std::is_invocable<RFn, Tag&&, int>::value, "");131      static_assert(!std::is_invocable<RFn, Tag&, int>::value, "");132      static_assert(!std::is_invocable<Fn, Tag&>::value, "");133      static_assert(!std::is_invocable<Fn, Tag const&, int>::value, "");134    }135    {136      // Bullet 2137      using T = std::reference_wrapper<Tag>;138      using DT = std::reference_wrapper<DerFromTag>;139      using CT = std::reference_wrapper<const Tag>;140      static_assert(std::is_invocable<Fn, T&, int>::value, "");141      static_assert(std::is_invocable<Fn, DT&, int>::value, "");142      static_assert(std::is_invocable<Fn, const T&, int>::value, "");143      static_assert(std::is_invocable<Fn, T&&, int>::value, "");144      static_assert(!std::is_invocable<Fn, CT&, int>::value, "");145      static_assert(!std::is_invocable<RFn, T, int>::value, "");146    }147    {148      // Bullet 3149      using T = Tag*;150      using DT = DerFromTag*;151      using CT = const Tag*;152      using ST = std::unique_ptr<Tag>;153      static_assert(std::is_invocable<Fn, T&, int>::value, "");154      static_assert(std::is_invocable<Fn, DT&, int>::value, "");155      static_assert(std::is_invocable<Fn, const T&, int>::value, "");156      static_assert(std::is_invocable<Fn, T&&, int>::value, "");157      static_assert(std::is_invocable<Fn, ST, int>::value, "");158      static_assert(!std::is_invocable<Fn, CT&, int>::value, "");159      static_assert(!std::is_invocable<RFn, T, int>::value, "");160    }161  }162  {163    // Bullets 4, 5 and 6164    using Fn = int(Tag::*);165    static_assert(!std::is_invocable<Fn>::value, "");166    {167      // Bullet 4168      static_assert(std::is_invocable<Fn, Tag&>::value, "");169      static_assert(std::is_invocable<Fn, DerFromTag&>::value, "");170      static_assert(std::is_invocable<Fn, Tag&&>::value, "");171      static_assert(std::is_invocable<Fn, Tag const&>::value, "");172    }173    {174      // Bullet 5175      using T = std::reference_wrapper<Tag>;176      using DT = std::reference_wrapper<DerFromTag>;177      using CT = std::reference_wrapper<const Tag>;178      static_assert(std::is_invocable<Fn, T&>::value, "");179      static_assert(std::is_invocable<Fn, DT&>::value, "");180      static_assert(std::is_invocable<Fn, const T&>::value, "");181      static_assert(std::is_invocable<Fn, T&&>::value, "");182      static_assert(std::is_invocable<Fn, CT&>::value, "");183    }184    {185      // Bullet 6186      using T = Tag*;187      using DT = DerFromTag*;188      using CT = const Tag*;189      using ST = std::unique_ptr<Tag>;190      static_assert(std::is_invocable<Fn, T&>::value, "");191      static_assert(std::is_invocable<Fn, DT&>::value, "");192      static_assert(std::is_invocable<Fn, const T&>::value, "");193      static_assert(std::is_invocable<Fn, T&&>::value, "");194      static_assert(std::is_invocable<Fn, ST>::value, "");195      static_assert(std::is_invocable<Fn, CT&>::value, "");196    }197  }198  { // INVOKE bullet 7199   {// Function pointer200    using Fp = void(*)(Tag&, int);201  static_assert(std::is_invocable<Fp, Tag&, int>::value, "");202  static_assert(std::is_invocable<Fp, DerFromTag&, int>::value, "");203  static_assert(!std::is_invocable<Fp, const Tag&, int>::value, "");204  static_assert(!std::is_invocable<Fp>::value, "");205  static_assert(!std::is_invocable<Fp, Tag&>::value, "");206}207{208  // Function reference209  using Fp = void (&)(Tag&, int);210  static_assert(std::is_invocable<Fp, Tag&, int>::value, "");211  static_assert(std::is_invocable<Fp, DerFromTag&, int>::value, "");212  static_assert(!std::is_invocable<Fp, const Tag&, int>::value, "");213  static_assert(!std::is_invocable<Fp>::value, "");214  static_assert(!std::is_invocable<Fp, Tag&>::value, "");215}216{217  // Function object218  using Fn = NotCallableWithInt;219  static_assert(std::is_invocable<Fn, Tag>::value, "");220  static_assert(!std::is_invocable<Fn, int>::value, "");221}222}223{224  // Check that the conversion to the return type is properly checked225  using Fn = int (*)();226  static_assert(std::is_invocable_r<Implicit, Fn>::value, "");227  static_assert(std::is_invocable_r<double, Fn>::value, "");228  static_assert(std::is_invocable_r<const volatile void, Fn>::value, "");229  static_assert(!std::is_invocable_r<Explicit, Fn>::value, "");230}231{232  // Check for is_invocable_v233  using Fn = void (*)();234  static_assert(std::is_invocable_v<Fn>, "");235  static_assert(!std::is_invocable_v<Fn, int>, "");236}237{238  // Check for is_invocable_r_v239  using Fn = void (*)();240  static_assert(std::is_invocable_r_v<void, Fn>, "");241  static_assert(!std::is_invocable_r_v<int, Fn>, "");242}243  return 0;244}245