15be45129SEric Fiselier //===----------------------------------------------------------------------===// 25be45129SEric Fiselier // 357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65be45129SEric Fiselier // 75be45129SEric Fiselier //===----------------------------------------------------------------------===// 85be45129SEric Fiselier 9*31cbe0f2SLouis Dionne // UNSUPPORTED: c++03, c++11, c++14 105be45129SEric Fiselier 115be45129SEric Fiselier // <functional> 125be45129SEric Fiselier 135be45129SEric Fiselier // template<class F, class... Args> 146c49e1ceSLouis Dionne // invoke_result_t<F, Args...> invoke(F&& f, Args&&... args) // C++17 156c49e1ceSLouis Dionne // noexcept(is_nothrow_invocable_v<_Fn, _Args...>); 165be45129SEric Fiselier 175be45129SEric Fiselier /// C++14 [func.def] 20.9.0 185be45129SEric Fiselier /// (1) The following definitions apply to this Clause: 195be45129SEric Fiselier /// (2) A call signature is the name of a return type followed by a parenthesized 205be45129SEric Fiselier /// comma-separated list of zero or more argument types. 215be45129SEric Fiselier /// (3) A callable type is a function object type (20.9) or a pointer to member. 225be45129SEric Fiselier /// (4) A callable object is an object of a callable type. 235be45129SEric Fiselier /// (5) A call wrapper type is a type that holds a callable object and supports 245be45129SEric Fiselier /// a call operation that forwards to that object. 255be45129SEric Fiselier /// (6) A call wrapper is an object of a call wrapper type. 265be45129SEric Fiselier /// (7) A target object is the callable object held by a call wrapper. 275be45129SEric Fiselier 285be45129SEric Fiselier /// C++14 [func.require] 20.9.1 295be45129SEric Fiselier /// 305be45129SEric Fiselier /// Define INVOKE (f, t1, t2, ..., tN) as follows: 3116270a0bSEric Fiselier /// (1.1) - (t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is an object of 325be45129SEric Fiselier /// type T or a reference to an object of type T or a reference to an object of a type derived from T; 3316270a0bSEric Fiselier /// (1.2) - ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is not one of 345be45129SEric Fiselier /// the types described in the previous item; 3516270a0bSEric Fiselier /// (1.3) - t1.*f when N == 1 and f is a pointer to member data of a class T and t1 is an object of type T or a 365be45129SEric Fiselier /// reference to an object of type T or a reference to an object of a type derived from T; 3716270a0bSEric Fiselier /// (1.4) - (*t1).*f when N == 1 and f is a pointer to member data of a class T and t1 is not one of the types 385be45129SEric Fiselier /// described in the previous item; 3916270a0bSEric Fiselier /// (1.5) - f(t1, t2, ..., tN) in all other cases. 405be45129SEric Fiselier 415be45129SEric Fiselier #include <functional> 425be45129SEric Fiselier #include <type_traits> 43d1180f4aSMarshall Clow #include <utility> // for std::move 445be45129SEric Fiselier #include <cassert> 455be45129SEric Fiselier 467fc6a556SMarshall Clow #include "test_macros.h" 477fc6a556SMarshall Clow 485be45129SEric Fiselier struct NonCopyable { 495be45129SEric Fiselier NonCopyable() {} 505be45129SEric Fiselier private: 515be45129SEric Fiselier NonCopyable(NonCopyable const&) = delete; 525be45129SEric Fiselier NonCopyable& operator=(NonCopyable const&) = delete; 535be45129SEric Fiselier }; 545be45129SEric Fiselier 555be45129SEric Fiselier struct TestClass { 565be45129SEric Fiselier explicit TestClass(int x) : data(x) {} 575be45129SEric Fiselier 585be45129SEric Fiselier int& operator()(NonCopyable&&) & { return data; } 595be45129SEric Fiselier int const& operator()(NonCopyable&&) const & { return data; } 605be45129SEric Fiselier int volatile& operator()(NonCopyable&&) volatile & { return data; } 615be45129SEric Fiselier int const volatile& operator()(NonCopyable&&) const volatile & { return data; } 625be45129SEric Fiselier 635be45129SEric Fiselier int&& operator()(NonCopyable&&) && { return std::move(data); } 645be45129SEric Fiselier int const&& operator()(NonCopyable&&) const && { return std::move(data); } 655be45129SEric Fiselier int volatile&& operator()(NonCopyable&&) volatile && { return std::move(data); } 665be45129SEric Fiselier int const volatile&& operator()(NonCopyable&&) const volatile && { return std::move(data); } 675be45129SEric Fiselier 685be45129SEric Fiselier int data; 695be45129SEric Fiselier private: 705be45129SEric Fiselier TestClass(TestClass const&) = delete; 715be45129SEric Fiselier TestClass& operator=(TestClass const&) = delete; 725be45129SEric Fiselier }; 735be45129SEric Fiselier 745be45129SEric Fiselier struct DerivedFromTestClass : public TestClass { 755be45129SEric Fiselier explicit DerivedFromTestClass(int x) : TestClass(x) {} 765be45129SEric Fiselier }; 775be45129SEric Fiselier 785be45129SEric Fiselier int& foo(NonCopyable&&) { 795be45129SEric Fiselier static int data = 42; 805be45129SEric Fiselier return data; 815be45129SEric Fiselier } 825be45129SEric Fiselier 835be45129SEric Fiselier template <class Signature, class Expect, class Functor> 845be45129SEric Fiselier void test_b12(Functor&& f) { 855be45129SEric Fiselier // Create the callable object. 865be45129SEric Fiselier typedef Signature TestClass::*ClassFunc; 875be45129SEric Fiselier ClassFunc func_ptr = &TestClass::operator(); 885be45129SEric Fiselier 895be45129SEric Fiselier // Create the dummy arg. 905be45129SEric Fiselier NonCopyable arg; 915be45129SEric Fiselier 925be45129SEric Fiselier // Check that the deduced return type of invoke is what is expected. 935be45129SEric Fiselier typedef decltype( 945be45129SEric Fiselier std::invoke(func_ptr, std::forward<Functor>(f), std::move(arg)) 955be45129SEric Fiselier ) DeducedReturnType; 965be45129SEric Fiselier static_assert((std::is_same<DeducedReturnType, Expect>::value), ""); 975be45129SEric Fiselier 985be45129SEric Fiselier // Check that result_of_t matches Expect. 995be45129SEric Fiselier typedef typename std::result_of<ClassFunc&&(Functor&&, NonCopyable&&)>::type 1005be45129SEric Fiselier ResultOfReturnType; 1015be45129SEric Fiselier static_assert((std::is_same<ResultOfReturnType, Expect>::value), ""); 1025be45129SEric Fiselier 1035be45129SEric Fiselier // Run invoke and check the return value. 1045be45129SEric Fiselier DeducedReturnType ret = 1055be45129SEric Fiselier std::invoke(func_ptr, std::forward<Functor>(f), std::move(arg)); 1065be45129SEric Fiselier assert(ret == 42); 1075be45129SEric Fiselier } 1085be45129SEric Fiselier 1095be45129SEric Fiselier template <class Expect, class Functor> 1105be45129SEric Fiselier void test_b34(Functor&& f) { 1115be45129SEric Fiselier // Create the callable object. 1125be45129SEric Fiselier typedef int TestClass::*ClassFunc; 1135be45129SEric Fiselier ClassFunc func_ptr = &TestClass::data; 1145be45129SEric Fiselier 1155be45129SEric Fiselier // Check that the deduced return type of invoke is what is expected. 1165be45129SEric Fiselier typedef decltype( 1175be45129SEric Fiselier std::invoke(func_ptr, std::forward<Functor>(f)) 1185be45129SEric Fiselier ) DeducedReturnType; 1195be45129SEric Fiselier static_assert((std::is_same<DeducedReturnType, Expect>::value), ""); 1205be45129SEric Fiselier 1215be45129SEric Fiselier // Check that result_of_t matches Expect. 1225be45129SEric Fiselier typedef typename std::result_of<ClassFunc&&(Functor&&)>::type 1235be45129SEric Fiselier ResultOfReturnType; 1245be45129SEric Fiselier static_assert((std::is_same<ResultOfReturnType, Expect>::value), ""); 1255be45129SEric Fiselier 1265be45129SEric Fiselier // Run invoke and check the return value. 1275be45129SEric Fiselier DeducedReturnType ret = 1285be45129SEric Fiselier std::invoke(func_ptr, std::forward<Functor>(f)); 1295be45129SEric Fiselier assert(ret == 42); 1305be45129SEric Fiselier } 1315be45129SEric Fiselier 1325be45129SEric Fiselier template <class Expect, class Functor> 1335be45129SEric Fiselier void test_b5(Functor&& f) { 1345be45129SEric Fiselier NonCopyable arg; 1355be45129SEric Fiselier 1365be45129SEric Fiselier // Check that the deduced return type of invoke is what is expected. 1375be45129SEric Fiselier typedef decltype( 1385be45129SEric Fiselier std::invoke(std::forward<Functor>(f), std::move(arg)) 1395be45129SEric Fiselier ) DeducedReturnType; 1405be45129SEric Fiselier static_assert((std::is_same<DeducedReturnType, Expect>::value), ""); 1415be45129SEric Fiselier 1425be45129SEric Fiselier // Check that result_of_t matches Expect. 1435be45129SEric Fiselier typedef typename std::result_of<Functor&&(NonCopyable&&)>::type 1445be45129SEric Fiselier ResultOfReturnType; 1455be45129SEric Fiselier static_assert((std::is_same<ResultOfReturnType, Expect>::value), ""); 1465be45129SEric Fiselier 1475be45129SEric Fiselier // Run invoke and check the return value. 1485be45129SEric Fiselier DeducedReturnType ret = std::invoke(std::forward<Functor>(f), std::move(arg)); 1495be45129SEric Fiselier assert(ret == 42); 1505be45129SEric Fiselier } 1515be45129SEric Fiselier 1525be45129SEric Fiselier void bullet_one_two_tests() { 1535be45129SEric Fiselier { 1545be45129SEric Fiselier TestClass cl(42); 1555be45129SEric Fiselier test_b12<int&(NonCopyable&&) &, int&>(cl); 1565be45129SEric Fiselier test_b12<int const&(NonCopyable&&) const &, int const&>(cl); 1575be45129SEric Fiselier test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl); 1585be45129SEric Fiselier test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl); 1595be45129SEric Fiselier 1605be45129SEric Fiselier test_b12<int&&(NonCopyable&&) &&, int&&>(std::move(cl)); 1615be45129SEric Fiselier test_b12<int const&&(NonCopyable&&) const &&, int const&&>(std::move(cl)); 1625be45129SEric Fiselier test_b12<int volatile&&(NonCopyable&&) volatile &&, int volatile&&>(std::move(cl)); 1635be45129SEric Fiselier test_b12<int const volatile&&(NonCopyable&&) const volatile &&, int const volatile&&>(std::move(cl)); 1645be45129SEric Fiselier } 1655be45129SEric Fiselier { 1665be45129SEric Fiselier DerivedFromTestClass cl(42); 1675be45129SEric Fiselier test_b12<int&(NonCopyable&&) &, int&>(cl); 1685be45129SEric Fiselier test_b12<int const&(NonCopyable&&) const &, int const&>(cl); 1695be45129SEric Fiselier test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl); 1705be45129SEric Fiselier test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl); 1715be45129SEric Fiselier 1725be45129SEric Fiselier test_b12<int&&(NonCopyable&&) &&, int&&>(std::move(cl)); 1735be45129SEric Fiselier test_b12<int const&&(NonCopyable&&) const &&, int const&&>(std::move(cl)); 1745be45129SEric Fiselier test_b12<int volatile&&(NonCopyable&&) volatile &&, int volatile&&>(std::move(cl)); 1755be45129SEric Fiselier test_b12<int const volatile&&(NonCopyable&&) const volatile &&, int const volatile&&>(std::move(cl)); 1765be45129SEric Fiselier } 1775be45129SEric Fiselier { 1785be45129SEric Fiselier TestClass cl_obj(42); 1792152fd76SEric Fiselier std::reference_wrapper<TestClass> cl(cl_obj); 1802152fd76SEric Fiselier test_b12<int&(NonCopyable&&) &, int&>(cl); 1812152fd76SEric Fiselier test_b12<int const&(NonCopyable&&) const &, int const&>(cl); 1822152fd76SEric Fiselier test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl); 1832152fd76SEric Fiselier test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl); 1842152fd76SEric Fiselier 1852152fd76SEric Fiselier test_b12<int&(NonCopyable&&) &, int&>(std::move(cl)); 1862152fd76SEric Fiselier test_b12<int const&(NonCopyable&&) const &, int const&>(std::move(cl)); 1872152fd76SEric Fiselier test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(std::move(cl)); 1882152fd76SEric Fiselier test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(std::move(cl)); 1892152fd76SEric Fiselier } 1902152fd76SEric Fiselier { 1912152fd76SEric Fiselier DerivedFromTestClass cl_obj(42); 1922152fd76SEric Fiselier std::reference_wrapper<DerivedFromTestClass> cl(cl_obj); 1932152fd76SEric Fiselier test_b12<int&(NonCopyable&&) &, int&>(cl); 1942152fd76SEric Fiselier test_b12<int const&(NonCopyable&&) const &, int const&>(cl); 1952152fd76SEric Fiselier test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl); 1962152fd76SEric Fiselier test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl); 1972152fd76SEric Fiselier 1982152fd76SEric Fiselier test_b12<int&(NonCopyable&&) &, int&>(std::move(cl)); 1992152fd76SEric Fiselier test_b12<int const&(NonCopyable&&) const &, int const&>(std::move(cl)); 2002152fd76SEric Fiselier test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(std::move(cl)); 2012152fd76SEric Fiselier test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(std::move(cl)); 2022152fd76SEric Fiselier } 2032152fd76SEric Fiselier { 2042152fd76SEric Fiselier TestClass cl_obj(42); 2055be45129SEric Fiselier TestClass *cl = &cl_obj; 2065be45129SEric Fiselier test_b12<int&(NonCopyable&&) &, int&>(cl); 2075be45129SEric Fiselier test_b12<int const&(NonCopyable&&) const &, int const&>(cl); 2085be45129SEric Fiselier test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl); 2095be45129SEric Fiselier test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl); 2105be45129SEric Fiselier } 2115be45129SEric Fiselier { 2125be45129SEric Fiselier DerivedFromTestClass cl_obj(42); 2135be45129SEric Fiselier DerivedFromTestClass *cl = &cl_obj; 2145be45129SEric Fiselier test_b12<int&(NonCopyable&&) &, int&>(cl); 2155be45129SEric Fiselier test_b12<int const&(NonCopyable&&) const &, int const&>(cl); 2165be45129SEric Fiselier test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl); 2175be45129SEric Fiselier test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl); 2185be45129SEric Fiselier } 2195be45129SEric Fiselier } 2205be45129SEric Fiselier 2215be45129SEric Fiselier void bullet_three_four_tests() { 2225be45129SEric Fiselier { 2235be45129SEric Fiselier typedef TestClass Fn; 2245be45129SEric Fiselier Fn cl(42); 2255be45129SEric Fiselier test_b34<int&>(cl); 2265be45129SEric Fiselier test_b34<int const&>(static_cast<Fn const&>(cl)); 2275be45129SEric Fiselier test_b34<int volatile&>(static_cast<Fn volatile&>(cl)); 2285be45129SEric Fiselier test_b34<int const volatile&>(static_cast<Fn const volatile &>(cl)); 2295be45129SEric Fiselier 2305be45129SEric Fiselier test_b34<int&&>(static_cast<Fn &&>(cl)); 2315be45129SEric Fiselier test_b34<int const&&>(static_cast<Fn const&&>(cl)); 2325be45129SEric Fiselier test_b34<int volatile&&>(static_cast<Fn volatile&&>(cl)); 2335be45129SEric Fiselier test_b34<int const volatile&&>(static_cast<Fn const volatile&&>(cl)); 2345be45129SEric Fiselier } 2355be45129SEric Fiselier { 2365be45129SEric Fiselier typedef DerivedFromTestClass Fn; 2375be45129SEric Fiselier Fn cl(42); 2385be45129SEric Fiselier test_b34<int&>(cl); 2395be45129SEric Fiselier test_b34<int const&>(static_cast<Fn const&>(cl)); 2405be45129SEric Fiselier test_b34<int volatile&>(static_cast<Fn volatile&>(cl)); 2415be45129SEric Fiselier test_b34<int const volatile&>(static_cast<Fn const volatile &>(cl)); 2425be45129SEric Fiselier 2435be45129SEric Fiselier test_b34<int&&>(static_cast<Fn &&>(cl)); 2445be45129SEric Fiselier test_b34<int const&&>(static_cast<Fn const&&>(cl)); 2455be45129SEric Fiselier test_b34<int volatile&&>(static_cast<Fn volatile&&>(cl)); 2465be45129SEric Fiselier test_b34<int const volatile&&>(static_cast<Fn const volatile&&>(cl)); 2475be45129SEric Fiselier } 2485be45129SEric Fiselier { 2495be45129SEric Fiselier typedef TestClass Fn; 2502152fd76SEric Fiselier Fn cl(42); 2512152fd76SEric Fiselier test_b34<int&>(std::reference_wrapper<Fn>(cl)); 2522152fd76SEric Fiselier test_b34<int const&>(std::reference_wrapper<Fn const>(cl)); 2532152fd76SEric Fiselier test_b34<int volatile&>(std::reference_wrapper<Fn volatile>(cl)); 2542152fd76SEric Fiselier test_b34<int const volatile&>(std::reference_wrapper<Fn const volatile>(cl)); 2552152fd76SEric Fiselier } 2562152fd76SEric Fiselier { 2572152fd76SEric Fiselier typedef DerivedFromTestClass Fn; 2582152fd76SEric Fiselier Fn cl(42); 2592152fd76SEric Fiselier test_b34<int&>(std::reference_wrapper<Fn>(cl)); 2602152fd76SEric Fiselier test_b34<int const&>(std::reference_wrapper<Fn const>(cl)); 2612152fd76SEric Fiselier test_b34<int volatile&>(std::reference_wrapper<Fn volatile>(cl)); 2622152fd76SEric Fiselier test_b34<int const volatile&>(std::reference_wrapper<Fn const volatile>(cl)); 2632152fd76SEric Fiselier } 2642152fd76SEric Fiselier { 2652152fd76SEric Fiselier typedef TestClass Fn; 2665be45129SEric Fiselier Fn cl_obj(42); 2675be45129SEric Fiselier Fn* cl = &cl_obj; 2685be45129SEric Fiselier test_b34<int&>(cl); 2695be45129SEric Fiselier test_b34<int const&>(static_cast<Fn const*>(cl)); 2705be45129SEric Fiselier test_b34<int volatile&>(static_cast<Fn volatile*>(cl)); 2715be45129SEric Fiselier test_b34<int const volatile&>(static_cast<Fn const volatile *>(cl)); 2725be45129SEric Fiselier } 2735be45129SEric Fiselier { 2745be45129SEric Fiselier typedef DerivedFromTestClass Fn; 2755be45129SEric Fiselier Fn cl_obj(42); 2765be45129SEric Fiselier Fn* cl = &cl_obj; 2775be45129SEric Fiselier test_b34<int&>(cl); 2785be45129SEric Fiselier test_b34<int const&>(static_cast<Fn const*>(cl)); 2795be45129SEric Fiselier test_b34<int volatile&>(static_cast<Fn volatile*>(cl)); 2805be45129SEric Fiselier test_b34<int const volatile&>(static_cast<Fn const volatile *>(cl)); 2815be45129SEric Fiselier } 2825be45129SEric Fiselier } 2835be45129SEric Fiselier 2845be45129SEric Fiselier void bullet_five_tests() { 2855be45129SEric Fiselier using FooType = int&(NonCopyable&&); 2865be45129SEric Fiselier { 2875be45129SEric Fiselier FooType& fn = foo; 2885be45129SEric Fiselier test_b5<int &>(fn); 2895be45129SEric Fiselier } 2905be45129SEric Fiselier { 2915be45129SEric Fiselier FooType* fn = foo; 2925be45129SEric Fiselier test_b5<int &>(fn); 2935be45129SEric Fiselier } 2945be45129SEric Fiselier { 2955be45129SEric Fiselier typedef TestClass Fn; 2965be45129SEric Fiselier Fn cl(42); 2975be45129SEric Fiselier test_b5<int&>(cl); 2985be45129SEric Fiselier test_b5<int const&>(static_cast<Fn const&>(cl)); 2995be45129SEric Fiselier test_b5<int volatile&>(static_cast<Fn volatile&>(cl)); 3005be45129SEric Fiselier test_b5<int const volatile&>(static_cast<Fn const volatile &>(cl)); 3015be45129SEric Fiselier 3025be45129SEric Fiselier test_b5<int&&>(static_cast<Fn &&>(cl)); 3035be45129SEric Fiselier test_b5<int const&&>(static_cast<Fn const&&>(cl)); 3045be45129SEric Fiselier test_b5<int volatile&&>(static_cast<Fn volatile&&>(cl)); 3055be45129SEric Fiselier test_b5<int const volatile&&>(static_cast<Fn const volatile&&>(cl)); 3065be45129SEric Fiselier } 3075be45129SEric Fiselier } 3085be45129SEric Fiselier 30957257567SEric Fiselier struct CopyThrows { 31057257567SEric Fiselier CopyThrows() {} 31157257567SEric Fiselier CopyThrows(CopyThrows const&) {} 31257257567SEric Fiselier CopyThrows(CopyThrows&&) noexcept {} 31357257567SEric Fiselier }; 31457257567SEric Fiselier 31557257567SEric Fiselier struct NoThrowCallable { 31657257567SEric Fiselier void operator()() noexcept {} 31757257567SEric Fiselier void operator()(CopyThrows) noexcept {} 31857257567SEric Fiselier }; 31957257567SEric Fiselier 32057257567SEric Fiselier struct ThrowsCallable { 32157257567SEric Fiselier void operator()() {} 32257257567SEric Fiselier }; 32357257567SEric Fiselier 32457257567SEric Fiselier struct MemberObj { 32557257567SEric Fiselier int x; 32657257567SEric Fiselier }; 32757257567SEric Fiselier 32857257567SEric Fiselier void noexcept_test() { 32957257567SEric Fiselier { 330c1d08ff0SEric Fiselier NoThrowCallable obj; ((void)obj); // suppress unused warning 331c1d08ff0SEric Fiselier CopyThrows arg; ((void)arg); // suppress unused warning 3327a580d0aSEric Fiselier static_assert(noexcept(std::invoke(obj)), ""); 3337a580d0aSEric Fiselier static_assert(!noexcept(std::invoke(obj, arg)), ""); 3347a580d0aSEric Fiselier static_assert(noexcept(std::invoke(obj, std::move(arg))), ""); 33557257567SEric Fiselier } 33657257567SEric Fiselier { 337c1d08ff0SEric Fiselier ThrowsCallable obj; ((void)obj); // suppress unused warning 3387a580d0aSEric Fiselier static_assert(!noexcept(std::invoke(obj)), ""); 33957257567SEric Fiselier } 34057257567SEric Fiselier { 341c1d08ff0SEric Fiselier MemberObj obj{42}; ((void)obj); // suppress unused warning. 3427a580d0aSEric Fiselier static_assert(noexcept(std::invoke(&MemberObj::x, obj)), ""); 34357257567SEric Fiselier } 34457257567SEric Fiselier } 34557257567SEric Fiselier 3462df59c50SJF Bastien int main(int, char**) { 3475be45129SEric Fiselier bullet_one_two_tests(); 3485be45129SEric Fiselier bullet_three_four_tests(); 3495be45129SEric Fiselier bullet_five_tests(); 35057257567SEric Fiselier noexcept_test(); 3512df59c50SJF Bastien 3522df59c50SJF Bastien return 0; 3535be45129SEric Fiselier } 354