libcxx

libcxx mirror with random patches
git clone https://git.neptards.moe/neptards/libcxx.git
Log | Files | Refs

is_invocable.pass.cpp (6375B)


      1 //===----------------------------------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is dual licensed under the MIT and the University of Illinois Open
      6 // Source Licenses. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 // UNSUPPORTED: c++98, c++03, c++11, c++14
     11 
     12 // type_traits
     13 
     14 // is_invocable
     15 
     16 // Most testing of is_invocable is done within the [meta.trans.other] result_of
     17 // tests.
     18 
     19 #include <type_traits>
     20 #include <functional>
     21 #include <memory>
     22 
     23 #include "test_macros.h"
     24 
     25 struct Tag {};
     26 struct DerFromTag : Tag {};
     27 
     28 struct Implicit {
     29   Implicit(int) {}
     30 };
     31 
     32 struct Explicit {
     33   explicit Explicit(int) {}
     34 };
     35 
     36 struct NotCallableWithInt {
     37   int operator()(int) = delete;
     38   int operator()(Tag) { return 42; }
     39 };
     40 
     41 int main()
     42 {
     43     {
     44         using Fn = int(Tag::*)(int);
     45         using RFn = int(Tag::*)(int) &&;
     46         // INVOKE bullet 1, 2 and 3
     47         {
     48             // Bullet 1
     49             static_assert(std::is_invocable<Fn, Tag&, int>::value, "");
     50             static_assert(std::is_invocable<Fn, DerFromTag&, int>::value, "");
     51             static_assert(std::is_invocable<RFn, Tag&&, int>::value, "");
     52             static_assert(!std::is_invocable<RFn, Tag&, int>::value, "");
     53             static_assert(!std::is_invocable<Fn, Tag&>::value, "");
     54             static_assert(!std::is_invocable<Fn, Tag const&, int>::value, "");
     55         }
     56         {
     57             // Bullet 2
     58             using T = std::reference_wrapper<Tag>;
     59             using DT = std::reference_wrapper<DerFromTag>;
     60             using CT = std::reference_wrapper<const Tag>;
     61             static_assert(std::is_invocable<Fn, T&, int>::value, "");
     62             static_assert(std::is_invocable<Fn, DT&, int>::value, "");
     63             static_assert(std::is_invocable<Fn, const T&, int>::value, "");
     64             static_assert(std::is_invocable<Fn, T&&, int>::value, "");
     65             static_assert(!std::is_invocable<Fn, CT&, int>::value, "");
     66             static_assert(!std::is_invocable<RFn, T, int>::value, "");
     67         }
     68         {
     69             // Bullet 3
     70             using T = Tag*;
     71             using DT = DerFromTag*;
     72             using CT = const Tag*;
     73             using ST = std::unique_ptr<Tag>;
     74             static_assert(std::is_invocable<Fn, T&, int>::value, "");
     75             static_assert(std::is_invocable<Fn, DT&, int>::value, "");
     76             static_assert(std::is_invocable<Fn, const T&, int>::value, "");
     77             static_assert(std::is_invocable<Fn, T&&, int>::value, "");
     78             static_assert(std::is_invocable<Fn, ST, int>::value, "");
     79             static_assert(!std::is_invocable<Fn, CT&, int>::value, "");
     80             static_assert(!std::is_invocable<RFn, T, int>::value, "");
     81         }
     82     }
     83     {
     84         // Bullets 4, 5 and 6
     85         using Fn = int (Tag::*);
     86         static_assert(!std::is_invocable<Fn>::value, "");
     87         {
     88             // Bullet 4
     89             static_assert(std::is_invocable<Fn, Tag&>::value, "");
     90             static_assert(std::is_invocable<Fn, DerFromTag&>::value, "");
     91             static_assert(std::is_invocable<Fn, Tag&&>::value, "");
     92             static_assert(std::is_invocable<Fn, Tag const&>::value, "");
     93         }
     94         {
     95             // Bullet 5
     96             using T = std::reference_wrapper<Tag>;
     97             using DT = std::reference_wrapper<DerFromTag>;
     98             using CT = std::reference_wrapper<const Tag>;
     99             static_assert(std::is_invocable<Fn, T&>::value, "");
    100             static_assert(std::is_invocable<Fn, DT&>::value, "");
    101             static_assert(std::is_invocable<Fn, const T&>::value, "");
    102             static_assert(std::is_invocable<Fn, T&&>::value, "");
    103             static_assert(std::is_invocable<Fn, CT&>::value, "");
    104         }
    105         {
    106             // Bullet 6
    107             using T = Tag*;
    108             using DT = DerFromTag*;
    109             using CT = const Tag*;
    110             using ST = std::unique_ptr<Tag>;
    111             static_assert(std::is_invocable<Fn, T&>::value, "");
    112             static_assert(std::is_invocable<Fn, DT&>::value, "");
    113             static_assert(std::is_invocable<Fn, const T&>::value, "");
    114             static_assert(std::is_invocable<Fn, T&&>::value, "");
    115             static_assert(std::is_invocable<Fn, ST>::value, "");
    116             static_assert(std::is_invocable<Fn, CT&>::value, "");
    117         }
    118     }
    119     {
    120         // INVOKE bullet 7
    121         {
    122             // Function pointer
    123             using Fp = void(*)(Tag&, int);
    124             static_assert(std::is_invocable<Fp, Tag&, int>::value, "");
    125             static_assert(std::is_invocable<Fp, DerFromTag&, int>::value, "");
    126             static_assert(!std::is_invocable<Fp, const Tag&, int>::value, "");
    127             static_assert(!std::is_invocable<Fp>::value, "");
    128             static_assert(!std::is_invocable<Fp, Tag&>::value, "");
    129         }
    130         {
    131             // Function reference
    132             using Fp = void(&)(Tag&, int);
    133             static_assert(std::is_invocable<Fp, Tag&, int>::value, "");
    134             static_assert(std::is_invocable<Fp, DerFromTag&, int>::value, "");
    135             static_assert(!std::is_invocable<Fp, const Tag&, int>::value, "");
    136             static_assert(!std::is_invocable<Fp>::value, "");
    137             static_assert(!std::is_invocable<Fp, Tag&>::value, "");
    138         }
    139         {
    140             // Function object
    141             using Fn = NotCallableWithInt;
    142             static_assert(std::is_invocable<Fn, Tag>::value, "");
    143             static_assert(!std::is_invocable<Fn, int>::value, "");
    144         }
    145     }
    146     {
    147         // Check that the conversion to the return type is properly checked
    148         using Fn = int(*)();
    149         static_assert(std::is_invocable_r<Implicit, Fn>::value, "");
    150         static_assert(std::is_invocable_r<double, Fn>::value, "");
    151         static_assert(std::is_invocable_r<const volatile void, Fn>::value, "");
    152         static_assert(!std::is_invocable_r<Explicit, Fn>::value, "");
    153     }
    154     {
    155         // Check for is_invocable_v
    156         using Fn = void(*)();
    157         static_assert(std::is_invocable_v<Fn>, "");
    158         static_assert(!std::is_invocable_v<Fn, int>, "");
    159     }
    160     {
    161         // Check for is_invocable_r_v
    162         using Fn = void(*)();
    163         static_assert(std::is_invocable_r_v<void, Fn>, "");
    164         static_assert(!std::is_invocable_r_v<int, Fn>, "");
    165     }
    166 }