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 
95be45129SEric Fiselier // UNSUPPORTED: c++98, c++03, c++11, c++14
105be45129SEric Fiselier 
115be45129SEric Fiselier // <functional>
125be45129SEric Fiselier 
135be45129SEric Fiselier // template <class F, class ...Args>
145be45129SEric Fiselier // result_of_t<F&&(Args&&...)> invoke(F&&, Args&&...);
155be45129SEric Fiselier 
165be45129SEric Fiselier /// C++14 [func.def] 20.9.0
175be45129SEric Fiselier /// (1) The following definitions apply to this Clause:
185be45129SEric Fiselier /// (2) A call signature is the name of a return type followed by a parenthesized
195be45129SEric Fiselier ///     comma-separated list of zero or more argument types.
205be45129SEric Fiselier /// (3) A callable type is a function object type (20.9) or a pointer to member.
215be45129SEric Fiselier /// (4) A callable object is an object of a callable type.
225be45129SEric Fiselier /// (5) A call wrapper type is a type that holds a callable object and supports
235be45129SEric Fiselier ///     a call operation that forwards to that object.
245be45129SEric Fiselier /// (6) A call wrapper is an object of a call wrapper type.
255be45129SEric Fiselier /// (7) A target object is the callable object held by a call wrapper.
265be45129SEric Fiselier 
275be45129SEric Fiselier /// C++14 [func.require] 20.9.1
285be45129SEric Fiselier ///
295be45129SEric Fiselier /// Define INVOKE (f, t1, t2, ..., tN) as follows:
3016270a0bSEric 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
315be45129SEric Fiselier ///   type T or a reference to an object of type T or a reference to an object of a type derived from T;
3216270a0bSEric 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
335be45129SEric Fiselier ///   the types described in the previous item;
3416270a0bSEric 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
355be45129SEric Fiselier ///   reference to an object of type T or a reference to an object of a type derived from T;
3616270a0bSEric 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
375be45129SEric Fiselier ///   described in the previous item;
3816270a0bSEric Fiselier ///   (1.5) - f(t1, t2, ..., tN) in all other cases.
395be45129SEric Fiselier 
405be45129SEric Fiselier #include <functional>
415be45129SEric Fiselier #include <type_traits>
42d1180f4aSMarshall Clow #include <utility> // for std::move
435be45129SEric Fiselier #include <cassert>
445be45129SEric Fiselier 
455be45129SEric Fiselier struct NonCopyable {
465be45129SEric Fiselier     NonCopyable() {}
475be45129SEric Fiselier private:
485be45129SEric Fiselier     NonCopyable(NonCopyable const&) = delete;
495be45129SEric Fiselier     NonCopyable& operator=(NonCopyable const&) = delete;
505be45129SEric Fiselier };
515be45129SEric Fiselier 
525be45129SEric Fiselier struct TestClass {
535be45129SEric Fiselier     explicit TestClass(int x) : data(x) {}
545be45129SEric Fiselier 
555be45129SEric Fiselier     int& operator()(NonCopyable&&) & { return data; }
565be45129SEric Fiselier     int const& operator()(NonCopyable&&) const & { return data; }
575be45129SEric Fiselier     int volatile& operator()(NonCopyable&&) volatile & { return data; }
585be45129SEric Fiselier     int const volatile& operator()(NonCopyable&&) const volatile & { return data; }
595be45129SEric Fiselier 
605be45129SEric Fiselier     int&& operator()(NonCopyable&&) && { return std::move(data); }
615be45129SEric Fiselier     int const&& operator()(NonCopyable&&) const && { return std::move(data); }
625be45129SEric Fiselier     int volatile&& operator()(NonCopyable&&) volatile && { return std::move(data); }
635be45129SEric Fiselier     int const volatile&& operator()(NonCopyable&&) const volatile && { return std::move(data); }
645be45129SEric Fiselier 
655be45129SEric Fiselier     int data;
665be45129SEric Fiselier private:
675be45129SEric Fiselier     TestClass(TestClass const&) = delete;
685be45129SEric Fiselier     TestClass& operator=(TestClass const&) = delete;
695be45129SEric Fiselier };
705be45129SEric Fiselier 
715be45129SEric Fiselier struct DerivedFromTestClass : public TestClass {
725be45129SEric Fiselier     explicit DerivedFromTestClass(int x) : TestClass(x) {}
735be45129SEric Fiselier };
745be45129SEric Fiselier 
755be45129SEric Fiselier int& foo(NonCopyable&&) {
765be45129SEric Fiselier     static int data = 42;
775be45129SEric Fiselier     return data;
785be45129SEric Fiselier }
795be45129SEric Fiselier 
805be45129SEric Fiselier template <class Signature,  class Expect, class Functor>
815be45129SEric Fiselier void test_b12(Functor&& f) {
825be45129SEric Fiselier     // Create the callable object.
835be45129SEric Fiselier     typedef Signature TestClass::*ClassFunc;
845be45129SEric Fiselier     ClassFunc func_ptr = &TestClass::operator();
855be45129SEric Fiselier 
865be45129SEric Fiselier     // Create the dummy arg.
875be45129SEric Fiselier     NonCopyable arg;
885be45129SEric Fiselier 
895be45129SEric Fiselier     // Check that the deduced return type of invoke is what is expected.
905be45129SEric Fiselier     typedef decltype(
915be45129SEric Fiselier         std::invoke(func_ptr, std::forward<Functor>(f), std::move(arg))
925be45129SEric Fiselier     ) DeducedReturnType;
935be45129SEric Fiselier     static_assert((std::is_same<DeducedReturnType, Expect>::value), "");
945be45129SEric Fiselier 
955be45129SEric Fiselier     // Check that result_of_t matches Expect.
965be45129SEric Fiselier     typedef typename std::result_of<ClassFunc&&(Functor&&, NonCopyable&&)>::type
975be45129SEric Fiselier       ResultOfReturnType;
985be45129SEric Fiselier     static_assert((std::is_same<ResultOfReturnType, Expect>::value), "");
995be45129SEric Fiselier 
1005be45129SEric Fiselier     // Run invoke and check the return value.
1015be45129SEric Fiselier     DeducedReturnType ret =
1025be45129SEric Fiselier             std::invoke(func_ptr, std::forward<Functor>(f), std::move(arg));
1035be45129SEric Fiselier     assert(ret == 42);
1045be45129SEric Fiselier }
1055be45129SEric Fiselier 
1065be45129SEric Fiselier template <class Expect, class Functor>
1075be45129SEric Fiselier void test_b34(Functor&& f) {
1085be45129SEric Fiselier     // Create the callable object.
1095be45129SEric Fiselier     typedef int TestClass::*ClassFunc;
1105be45129SEric Fiselier     ClassFunc func_ptr = &TestClass::data;
1115be45129SEric Fiselier 
1125be45129SEric Fiselier     // Check that the deduced return type of invoke is what is expected.
1135be45129SEric Fiselier     typedef decltype(
1145be45129SEric Fiselier         std::invoke(func_ptr, std::forward<Functor>(f))
1155be45129SEric Fiselier     ) DeducedReturnType;
1165be45129SEric Fiselier     static_assert((std::is_same<DeducedReturnType, Expect>::value), "");
1175be45129SEric Fiselier 
1185be45129SEric Fiselier     // Check that result_of_t matches Expect.
1195be45129SEric Fiselier     typedef typename std::result_of<ClassFunc&&(Functor&&)>::type
1205be45129SEric Fiselier             ResultOfReturnType;
1215be45129SEric Fiselier     static_assert((std::is_same<ResultOfReturnType, Expect>::value), "");
1225be45129SEric Fiselier 
1235be45129SEric Fiselier     // Run invoke and check the return value.
1245be45129SEric Fiselier     DeducedReturnType ret =
1255be45129SEric Fiselier             std::invoke(func_ptr, std::forward<Functor>(f));
1265be45129SEric Fiselier     assert(ret == 42);
1275be45129SEric Fiselier }
1285be45129SEric Fiselier 
1295be45129SEric Fiselier template <class Expect, class Functor>
1305be45129SEric Fiselier void test_b5(Functor&& f) {
1315be45129SEric Fiselier     NonCopyable arg;
1325be45129SEric Fiselier 
1335be45129SEric Fiselier     // Check that the deduced return type of invoke is what is expected.
1345be45129SEric Fiselier     typedef decltype(
1355be45129SEric Fiselier         std::invoke(std::forward<Functor>(f), std::move(arg))
1365be45129SEric Fiselier     ) DeducedReturnType;
1375be45129SEric Fiselier     static_assert((std::is_same<DeducedReturnType, Expect>::value), "");
1385be45129SEric Fiselier 
1395be45129SEric Fiselier     // Check that result_of_t matches Expect.
1405be45129SEric Fiselier     typedef typename std::result_of<Functor&&(NonCopyable&&)>::type
1415be45129SEric Fiselier             ResultOfReturnType;
1425be45129SEric Fiselier     static_assert((std::is_same<ResultOfReturnType, Expect>::value), "");
1435be45129SEric Fiselier 
1445be45129SEric Fiselier     // Run invoke and check the return value.
1455be45129SEric Fiselier     DeducedReturnType ret = std::invoke(std::forward<Functor>(f), std::move(arg));
1465be45129SEric Fiselier     assert(ret == 42);
1475be45129SEric Fiselier }
1485be45129SEric Fiselier 
1495be45129SEric Fiselier void bullet_one_two_tests() {
1505be45129SEric Fiselier     {
1515be45129SEric Fiselier         TestClass cl(42);
1525be45129SEric Fiselier         test_b12<int&(NonCopyable&&) &, int&>(cl);
1535be45129SEric Fiselier         test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
1545be45129SEric Fiselier         test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
1555be45129SEric Fiselier         test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
1565be45129SEric Fiselier 
1575be45129SEric Fiselier         test_b12<int&&(NonCopyable&&) &&, int&&>(std::move(cl));
1585be45129SEric Fiselier         test_b12<int const&&(NonCopyable&&) const &&, int const&&>(std::move(cl));
1595be45129SEric Fiselier         test_b12<int volatile&&(NonCopyable&&) volatile &&, int volatile&&>(std::move(cl));
1605be45129SEric Fiselier         test_b12<int const volatile&&(NonCopyable&&) const volatile &&, int const volatile&&>(std::move(cl));
1615be45129SEric Fiselier     }
1625be45129SEric Fiselier     {
1635be45129SEric Fiselier         DerivedFromTestClass cl(42);
1645be45129SEric Fiselier         test_b12<int&(NonCopyable&&) &, int&>(cl);
1655be45129SEric Fiselier         test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
1665be45129SEric Fiselier         test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
1675be45129SEric Fiselier         test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
1685be45129SEric Fiselier 
1695be45129SEric Fiselier         test_b12<int&&(NonCopyable&&) &&, int&&>(std::move(cl));
1705be45129SEric Fiselier         test_b12<int const&&(NonCopyable&&) const &&, int const&&>(std::move(cl));
1715be45129SEric Fiselier         test_b12<int volatile&&(NonCopyable&&) volatile &&, int volatile&&>(std::move(cl));
1725be45129SEric Fiselier         test_b12<int const volatile&&(NonCopyable&&) const volatile &&, int const volatile&&>(std::move(cl));
1735be45129SEric Fiselier     }
1745be45129SEric Fiselier     {
1755be45129SEric Fiselier         TestClass cl_obj(42);
1762152fd76SEric Fiselier         std::reference_wrapper<TestClass> cl(cl_obj);
1772152fd76SEric Fiselier         test_b12<int&(NonCopyable&&) &, int&>(cl);
1782152fd76SEric Fiselier         test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
1792152fd76SEric Fiselier         test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
1802152fd76SEric Fiselier         test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
1812152fd76SEric Fiselier 
1822152fd76SEric Fiselier         test_b12<int&(NonCopyable&&) &, int&>(std::move(cl));
1832152fd76SEric Fiselier         test_b12<int const&(NonCopyable&&) const &, int const&>(std::move(cl));
1842152fd76SEric Fiselier         test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(std::move(cl));
1852152fd76SEric Fiselier         test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(std::move(cl));
1862152fd76SEric Fiselier     }
1872152fd76SEric Fiselier     {
1882152fd76SEric Fiselier         DerivedFromTestClass cl_obj(42);
1892152fd76SEric Fiselier         std::reference_wrapper<DerivedFromTestClass> cl(cl_obj);
1902152fd76SEric Fiselier         test_b12<int&(NonCopyable&&) &, int&>(cl);
1912152fd76SEric Fiselier         test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
1922152fd76SEric Fiselier         test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
1932152fd76SEric Fiselier         test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
1942152fd76SEric Fiselier 
1952152fd76SEric Fiselier         test_b12<int&(NonCopyable&&) &, int&>(std::move(cl));
1962152fd76SEric Fiselier         test_b12<int const&(NonCopyable&&) const &, int const&>(std::move(cl));
1972152fd76SEric Fiselier         test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(std::move(cl));
1982152fd76SEric Fiselier         test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(std::move(cl));
1992152fd76SEric Fiselier     }
2002152fd76SEric Fiselier     {
2012152fd76SEric Fiselier         TestClass cl_obj(42);
2025be45129SEric Fiselier         TestClass *cl = &cl_obj;
2035be45129SEric Fiselier         test_b12<int&(NonCopyable&&) &, int&>(cl);
2045be45129SEric Fiselier         test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
2055be45129SEric Fiselier         test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
2065be45129SEric Fiselier         test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
2075be45129SEric Fiselier     }
2085be45129SEric Fiselier     {
2095be45129SEric Fiselier         DerivedFromTestClass cl_obj(42);
2105be45129SEric Fiselier         DerivedFromTestClass *cl = &cl_obj;
2115be45129SEric Fiselier         test_b12<int&(NonCopyable&&) &, int&>(cl);
2125be45129SEric Fiselier         test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
2135be45129SEric Fiselier         test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
2145be45129SEric Fiselier         test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
2155be45129SEric Fiselier     }
2165be45129SEric Fiselier }
2175be45129SEric Fiselier 
2185be45129SEric Fiselier void bullet_three_four_tests() {
2195be45129SEric Fiselier     {
2205be45129SEric Fiselier         typedef TestClass Fn;
2215be45129SEric Fiselier         Fn cl(42);
2225be45129SEric Fiselier         test_b34<int&>(cl);
2235be45129SEric Fiselier         test_b34<int const&>(static_cast<Fn const&>(cl));
2245be45129SEric Fiselier         test_b34<int volatile&>(static_cast<Fn volatile&>(cl));
2255be45129SEric Fiselier         test_b34<int const volatile&>(static_cast<Fn const volatile &>(cl));
2265be45129SEric Fiselier 
2275be45129SEric Fiselier         test_b34<int&&>(static_cast<Fn &&>(cl));
2285be45129SEric Fiselier         test_b34<int const&&>(static_cast<Fn const&&>(cl));
2295be45129SEric Fiselier         test_b34<int volatile&&>(static_cast<Fn volatile&&>(cl));
2305be45129SEric Fiselier         test_b34<int const volatile&&>(static_cast<Fn const volatile&&>(cl));
2315be45129SEric Fiselier     }
2325be45129SEric Fiselier     {
2335be45129SEric Fiselier         typedef DerivedFromTestClass Fn;
2345be45129SEric Fiselier         Fn cl(42);
2355be45129SEric Fiselier         test_b34<int&>(cl);
2365be45129SEric Fiselier         test_b34<int const&>(static_cast<Fn const&>(cl));
2375be45129SEric Fiselier         test_b34<int volatile&>(static_cast<Fn volatile&>(cl));
2385be45129SEric Fiselier         test_b34<int const volatile&>(static_cast<Fn const volatile &>(cl));
2395be45129SEric Fiselier 
2405be45129SEric Fiselier         test_b34<int&&>(static_cast<Fn &&>(cl));
2415be45129SEric Fiselier         test_b34<int const&&>(static_cast<Fn const&&>(cl));
2425be45129SEric Fiselier         test_b34<int volatile&&>(static_cast<Fn volatile&&>(cl));
2435be45129SEric Fiselier         test_b34<int const volatile&&>(static_cast<Fn const volatile&&>(cl));
2445be45129SEric Fiselier     }
2455be45129SEric Fiselier     {
2465be45129SEric Fiselier         typedef TestClass Fn;
2472152fd76SEric Fiselier         Fn cl(42);
2482152fd76SEric Fiselier         test_b34<int&>(std::reference_wrapper<Fn>(cl));
2492152fd76SEric Fiselier         test_b34<int const&>(std::reference_wrapper<Fn const>(cl));
2502152fd76SEric Fiselier         test_b34<int volatile&>(std::reference_wrapper<Fn volatile>(cl));
2512152fd76SEric Fiselier         test_b34<int const volatile&>(std::reference_wrapper<Fn const volatile>(cl));
2522152fd76SEric Fiselier     }
2532152fd76SEric Fiselier     {
2542152fd76SEric Fiselier         typedef DerivedFromTestClass Fn;
2552152fd76SEric Fiselier         Fn cl(42);
2562152fd76SEric Fiselier         test_b34<int&>(std::reference_wrapper<Fn>(cl));
2572152fd76SEric Fiselier         test_b34<int const&>(std::reference_wrapper<Fn const>(cl));
2582152fd76SEric Fiselier         test_b34<int volatile&>(std::reference_wrapper<Fn volatile>(cl));
2592152fd76SEric Fiselier         test_b34<int const volatile&>(std::reference_wrapper<Fn const volatile>(cl));
2602152fd76SEric Fiselier     }
2612152fd76SEric Fiselier     {
2622152fd76SEric Fiselier         typedef TestClass Fn;
2635be45129SEric Fiselier         Fn cl_obj(42);
2645be45129SEric Fiselier         Fn* cl = &cl_obj;
2655be45129SEric Fiselier         test_b34<int&>(cl);
2665be45129SEric Fiselier         test_b34<int const&>(static_cast<Fn const*>(cl));
2675be45129SEric Fiselier         test_b34<int volatile&>(static_cast<Fn volatile*>(cl));
2685be45129SEric Fiselier         test_b34<int const volatile&>(static_cast<Fn const volatile *>(cl));
2695be45129SEric Fiselier     }
2705be45129SEric Fiselier     {
2715be45129SEric Fiselier         typedef DerivedFromTestClass Fn;
2725be45129SEric Fiselier         Fn cl_obj(42);
2735be45129SEric Fiselier         Fn* cl = &cl_obj;
2745be45129SEric Fiselier         test_b34<int&>(cl);
2755be45129SEric Fiselier         test_b34<int const&>(static_cast<Fn const*>(cl));
2765be45129SEric Fiselier         test_b34<int volatile&>(static_cast<Fn volatile*>(cl));
2775be45129SEric Fiselier         test_b34<int const volatile&>(static_cast<Fn const volatile *>(cl));
2785be45129SEric Fiselier     }
2795be45129SEric Fiselier }
2805be45129SEric Fiselier 
2815be45129SEric Fiselier void bullet_five_tests() {
2825be45129SEric Fiselier     using FooType = int&(NonCopyable&&);
2835be45129SEric Fiselier     {
2845be45129SEric Fiselier         FooType& fn = foo;
2855be45129SEric Fiselier         test_b5<int &>(fn);
2865be45129SEric Fiselier     }
2875be45129SEric Fiselier     {
2885be45129SEric Fiselier         FooType* fn = foo;
2895be45129SEric Fiselier         test_b5<int &>(fn);
2905be45129SEric Fiselier     }
2915be45129SEric Fiselier     {
2925be45129SEric Fiselier         typedef TestClass Fn;
2935be45129SEric Fiselier         Fn cl(42);
2945be45129SEric Fiselier         test_b5<int&>(cl);
2955be45129SEric Fiselier         test_b5<int const&>(static_cast<Fn const&>(cl));
2965be45129SEric Fiselier         test_b5<int volatile&>(static_cast<Fn volatile&>(cl));
2975be45129SEric Fiselier         test_b5<int const volatile&>(static_cast<Fn const volatile &>(cl));
2985be45129SEric Fiselier 
2995be45129SEric Fiselier         test_b5<int&&>(static_cast<Fn &&>(cl));
3005be45129SEric Fiselier         test_b5<int const&&>(static_cast<Fn const&&>(cl));
3015be45129SEric Fiselier         test_b5<int volatile&&>(static_cast<Fn volatile&&>(cl));
3025be45129SEric Fiselier         test_b5<int const volatile&&>(static_cast<Fn const volatile&&>(cl));
3035be45129SEric Fiselier     }
3045be45129SEric Fiselier }
3055be45129SEric Fiselier 
30657257567SEric Fiselier struct CopyThrows {
30757257567SEric Fiselier   CopyThrows() {}
30857257567SEric Fiselier   CopyThrows(CopyThrows const&) {}
30957257567SEric Fiselier   CopyThrows(CopyThrows&&) noexcept {}
31057257567SEric Fiselier };
31157257567SEric Fiselier 
31257257567SEric Fiselier struct NoThrowCallable {
31357257567SEric Fiselier   void operator()() noexcept {}
31457257567SEric Fiselier   void operator()(CopyThrows) noexcept {}
31557257567SEric Fiselier };
31657257567SEric Fiselier 
31757257567SEric Fiselier struct ThrowsCallable {
31857257567SEric Fiselier   void operator()() {}
31957257567SEric Fiselier };
32057257567SEric Fiselier 
32157257567SEric Fiselier struct MemberObj {
32257257567SEric Fiselier   int x;
32357257567SEric Fiselier };
32457257567SEric Fiselier 
32557257567SEric Fiselier void noexcept_test() {
32657257567SEric Fiselier     {
327c1d08ff0SEric Fiselier         NoThrowCallable obj; ((void)obj); // suppress unused warning
328c1d08ff0SEric Fiselier         CopyThrows arg; ((void)arg); // suppress unused warning
3297a580d0aSEric Fiselier         static_assert(noexcept(std::invoke(obj)), "");
3307a580d0aSEric Fiselier         static_assert(!noexcept(std::invoke(obj, arg)), "");
3317a580d0aSEric Fiselier         static_assert(noexcept(std::invoke(obj, std::move(arg))), "");
33257257567SEric Fiselier     }
33357257567SEric Fiselier     {
334c1d08ff0SEric Fiselier         ThrowsCallable obj; ((void)obj); // suppress unused warning
3357a580d0aSEric Fiselier         static_assert(!noexcept(std::invoke(obj)), "");
33657257567SEric Fiselier     }
33757257567SEric Fiselier     {
338c1d08ff0SEric Fiselier         MemberObj obj{42}; ((void)obj); // suppress unused warning.
3397a580d0aSEric Fiselier         static_assert(noexcept(std::invoke(&MemberObj::x, obj)), "");
34057257567SEric Fiselier     }
34157257567SEric Fiselier }
34257257567SEric Fiselier 
343*2df59c50SJF Bastien int main(int, char**) {
3445be45129SEric Fiselier     bullet_one_two_tests();
3455be45129SEric Fiselier     bullet_three_four_tests();
3465be45129SEric Fiselier     bullet_five_tests();
34757257567SEric Fiselier     noexcept_test();
348*2df59c50SJF Bastien 
349*2df59c50SJF Bastien   return 0;
3505be45129SEric Fiselier }
351