libcxx

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

is_nothrow_invocable.pass.cpp (4315B)


      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_nothrow_invocable
     15 
     16 #include <type_traits>
     17 #include <functional>
     18 
     19 #include "test_macros.h"
     20 
     21 struct Tag {};
     22 
     23 struct Implicit {
     24   Implicit(int) noexcept {}
     25 };
     26 
     27 struct ThrowsImplicit {
     28   ThrowsImplicit(int) {}
     29 };
     30 
     31 struct Explicit {
     32   explicit Explicit(int) noexcept {}
     33 };
     34 
     35 template <bool IsNoexcept, class Ret, class ...Args>
     36 struct CallObject {
     37   Ret operator()(Args&&...) const noexcept(IsNoexcept);
     38 };
     39 
     40 template <class Fn, class ...Args>
     41 constexpr bool throws_invocable() {
     42     return std::is_invocable<Fn, Args...>::value &&
     43         !std::is_nothrow_invocable<Fn, Args...>::value;
     44 }
     45 
     46 template <class Ret, class Fn, class ...Args>
     47 constexpr bool throws_invocable_r() {
     48     return std::is_invocable_r<Ret, Fn, Args...>::value &&
     49         !std::is_nothrow_invocable_r<Ret, Fn, Args...>::value;
     50 }
     51 
     52 // FIXME(EricWF) Don't test the where noexcept is *not* part of the type system
     53 // once implementations have caught up.
     54 void test_noexcept_function_pointers()
     55 {
     56     struct Dummy { void foo() noexcept {} static void bar() noexcept {} };
     57 #if !defined(__cpp_noexcept_function_type)
     58     {
     59         // Check that PMF's and function pointers *work*. is_nothrow_invocable will always
     60         // return false because 'noexcept' is not part of the function type.
     61         static_assert(throws_invocable<decltype(&Dummy::foo), Dummy&>(), "");
     62         static_assert(throws_invocable<decltype(&Dummy::bar)>(), "");
     63     }
     64 #else
     65     {
     66         // Check that PMF's and function pointers actually work and that
     67         // is_nothrow_invocable returns true for noexcept PMF's and function
     68         // pointers.
     69         static_assert(std::is_nothrow_invocable<decltype(&Dummy::foo), Dummy&>::value, "");
     70         static_assert(std::is_nothrow_invocable<decltype(&Dummy::bar)>::value, "");
     71     }
     72 #endif
     73 }
     74 
     75 int main()
     76 {
     77     {
     78         // Check that the conversion to the return type is properly checked
     79         using Fn = CallObject<true, int>;
     80         static_assert(std::is_nothrow_invocable_r<Implicit, Fn>::value, "");
     81         static_assert(std::is_nothrow_invocable_r<double, Fn>::value, "");
     82         static_assert(std::is_nothrow_invocable_r<const volatile void, Fn>::value, "");
     83         static_assert(throws_invocable_r<ThrowsImplicit, Fn>(), "");
     84         static_assert(!std::is_nothrow_invocable<Fn(), Explicit>(), "");
     85     }
     86     {
     87         // Check that the conversion to the parameters is properly checked
     88         using Fn = CallObject<true, void, const Implicit&, const ThrowsImplicit&>;
     89         static_assert(std::is_nothrow_invocable<Fn, Implicit&, ThrowsImplicit&>::value, "");
     90         static_assert(std::is_nothrow_invocable<Fn, int, ThrowsImplicit&>::value, "");
     91         static_assert(throws_invocable<Fn, int, int>(), "");
     92         static_assert(!std::is_nothrow_invocable<Fn>::value, "");
     93     }
     94     {
     95         // Check that the noexcept-ness of function objects is checked.
     96         using Fn = CallObject<true, void>;
     97         using Fn2 = CallObject<false, void>;
     98         static_assert(std::is_nothrow_invocable<Fn>::value, "");
     99         static_assert(throws_invocable<Fn2>(), "");
    100     }
    101     {
    102         // Check that PMD derefs are noexcept
    103         using Fn = int (Tag::*);
    104         static_assert(std::is_nothrow_invocable<Fn, Tag&>::value, "");
    105         static_assert(std::is_nothrow_invocable_r<Implicit, Fn, Tag&>::value, "");
    106         static_assert(throws_invocable_r<ThrowsImplicit, Fn, Tag&>(), "");
    107     }
    108     {
    109         // Check for is_nothrow_invocable_v
    110         using Fn = CallObject<true, int>;
    111         static_assert(std::is_nothrow_invocable_v<Fn>, "");
    112         static_assert(!std::is_nothrow_invocable_v<Fn, int>, "");
    113     }
    114     {
    115         // Check for is_nothrow_invocable_r_v
    116         using Fn = CallObject<true, int>;
    117         static_assert(std::is_nothrow_invocable_r_v<void, Fn>, "");
    118         static_assert(!std::is_nothrow_invocable_r_v<int, Fn, int>, "");
    119     }
    120     test_noexcept_function_pointers();
    121 }