15be45129SEric Fiselier //===----------------------------------------------------------------------===//
25be45129SEric Fiselier //
35be45129SEric Fiselier //                     The LLVM Compiler Infrastructure
45be45129SEric Fiselier //
55be45129SEric Fiselier // This file is dual licensed under the MIT and the University of Illinois Open
65be45129SEric Fiselier // Source Licenses. See LICENSE.TXT for details.
75be45129SEric Fiselier //
85be45129SEric Fiselier //===----------------------------------------------------------------------===//
95be45129SEric Fiselier 
105be45129SEric Fiselier // UNSUPPORTED: c++98, c++03, c++11, c++14
115be45129SEric Fiselier 
125be45129SEric Fiselier // <functional>
135be45129SEric Fiselier 
145be45129SEric Fiselier // template <class F, class ...Args>
155be45129SEric Fiselier // result_of_t<F&&(Args&&...)> invoke(F&&, 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 
465be45129SEric Fiselier struct NonCopyable {
475be45129SEric Fiselier     NonCopyable() {}
485be45129SEric Fiselier private:
495be45129SEric Fiselier     NonCopyable(NonCopyable const&) = delete;
505be45129SEric Fiselier     NonCopyable& operator=(NonCopyable const&) = delete;
515be45129SEric Fiselier };
525be45129SEric Fiselier 
535be45129SEric Fiselier struct TestClass {
545be45129SEric Fiselier     explicit TestClass(int x) : data(x) {}
555be45129SEric Fiselier 
565be45129SEric Fiselier     int& operator()(NonCopyable&&) & { return data; }
575be45129SEric Fiselier     int const& operator()(NonCopyable&&) const & { return data; }
585be45129SEric Fiselier     int volatile& operator()(NonCopyable&&) volatile & { return data; }
595be45129SEric Fiselier     int const volatile& operator()(NonCopyable&&) const volatile & { return data; }
605be45129SEric Fiselier 
615be45129SEric Fiselier     int&& operator()(NonCopyable&&) && { return std::move(data); }
625be45129SEric Fiselier     int const&& operator()(NonCopyable&&) const && { return std::move(data); }
635be45129SEric Fiselier     int volatile&& operator()(NonCopyable&&) volatile && { return std::move(data); }
645be45129SEric Fiselier     int const volatile&& operator()(NonCopyable&&) const volatile && { return std::move(data); }
655be45129SEric Fiselier 
665be45129SEric Fiselier     int data;
675be45129SEric Fiselier private:
685be45129SEric Fiselier     TestClass(TestClass const&) = delete;
695be45129SEric Fiselier     TestClass& operator=(TestClass const&) = delete;
705be45129SEric Fiselier };
715be45129SEric Fiselier 
725be45129SEric Fiselier struct DerivedFromTestClass : public TestClass {
735be45129SEric Fiselier     explicit DerivedFromTestClass(int x) : TestClass(x) {}
745be45129SEric Fiselier };
755be45129SEric Fiselier 
765be45129SEric Fiselier int& foo(NonCopyable&&) {
775be45129SEric Fiselier     static int data = 42;
785be45129SEric Fiselier     return data;
795be45129SEric Fiselier }
805be45129SEric Fiselier 
815be45129SEric Fiselier template <class Signature,  class Expect, class Functor>
825be45129SEric Fiselier void test_b12(Functor&& f) {
835be45129SEric Fiselier     // Create the callable object.
845be45129SEric Fiselier     typedef Signature TestClass::*ClassFunc;
855be45129SEric Fiselier     ClassFunc func_ptr = &TestClass::operator();
865be45129SEric Fiselier 
875be45129SEric Fiselier     // Create the dummy arg.
885be45129SEric Fiselier     NonCopyable arg;
895be45129SEric Fiselier 
905be45129SEric Fiselier     // Check that the deduced return type of invoke is what is expected.
915be45129SEric Fiselier     typedef decltype(
925be45129SEric Fiselier         std::invoke(func_ptr, std::forward<Functor>(f), std::move(arg))
935be45129SEric Fiselier     ) DeducedReturnType;
945be45129SEric Fiselier     static_assert((std::is_same<DeducedReturnType, Expect>::value), "");
955be45129SEric Fiselier 
965be45129SEric Fiselier     // Check that result_of_t matches Expect.
975be45129SEric Fiselier     typedef typename std::result_of<ClassFunc&&(Functor&&, NonCopyable&&)>::type
985be45129SEric Fiselier       ResultOfReturnType;
995be45129SEric Fiselier     static_assert((std::is_same<ResultOfReturnType, Expect>::value), "");
1005be45129SEric Fiselier 
1015be45129SEric Fiselier     // Run invoke and check the return value.
1025be45129SEric Fiselier     DeducedReturnType ret =
1035be45129SEric Fiselier             std::invoke(func_ptr, std::forward<Functor>(f), std::move(arg));
1045be45129SEric Fiselier     assert(ret == 42);
1055be45129SEric Fiselier }
1065be45129SEric Fiselier 
1075be45129SEric Fiselier template <class Expect, class Functor>
1085be45129SEric Fiselier void test_b34(Functor&& f) {
1095be45129SEric Fiselier     // Create the callable object.
1105be45129SEric Fiselier     typedef int TestClass::*ClassFunc;
1115be45129SEric Fiselier     ClassFunc func_ptr = &TestClass::data;
1125be45129SEric Fiselier 
1135be45129SEric Fiselier     // Check that the deduced return type of invoke is what is expected.
1145be45129SEric Fiselier     typedef decltype(
1155be45129SEric Fiselier         std::invoke(func_ptr, std::forward<Functor>(f))
1165be45129SEric Fiselier     ) DeducedReturnType;
1175be45129SEric Fiselier     static_assert((std::is_same<DeducedReturnType, Expect>::value), "");
1185be45129SEric Fiselier 
1195be45129SEric Fiselier     // Check that result_of_t matches Expect.
1205be45129SEric Fiselier     typedef typename std::result_of<ClassFunc&&(Functor&&)>::type
1215be45129SEric Fiselier             ResultOfReturnType;
1225be45129SEric Fiselier     static_assert((std::is_same<ResultOfReturnType, Expect>::value), "");
1235be45129SEric Fiselier 
1245be45129SEric Fiselier     // Run invoke and check the return value.
1255be45129SEric Fiselier     DeducedReturnType ret =
1265be45129SEric Fiselier             std::invoke(func_ptr, std::forward<Functor>(f));
1275be45129SEric Fiselier     assert(ret == 42);
1285be45129SEric Fiselier }
1295be45129SEric Fiselier 
1305be45129SEric Fiselier template <class Expect, class Functor>
1315be45129SEric Fiselier void test_b5(Functor&& f) {
1325be45129SEric Fiselier     NonCopyable arg;
1335be45129SEric Fiselier 
1345be45129SEric Fiselier     // Check that the deduced return type of invoke is what is expected.
1355be45129SEric Fiselier     typedef decltype(
1365be45129SEric Fiselier         std::invoke(std::forward<Functor>(f), std::move(arg))
1375be45129SEric Fiselier     ) DeducedReturnType;
1385be45129SEric Fiselier     static_assert((std::is_same<DeducedReturnType, Expect>::value), "");
1395be45129SEric Fiselier 
1405be45129SEric Fiselier     // Check that result_of_t matches Expect.
1415be45129SEric Fiselier     typedef typename std::result_of<Functor&&(NonCopyable&&)>::type
1425be45129SEric Fiselier             ResultOfReturnType;
1435be45129SEric Fiselier     static_assert((std::is_same<ResultOfReturnType, Expect>::value), "");
1445be45129SEric Fiselier 
1455be45129SEric Fiselier     // Run invoke and check the return value.
1465be45129SEric Fiselier     DeducedReturnType ret = std::invoke(std::forward<Functor>(f), std::move(arg));
1475be45129SEric Fiselier     assert(ret == 42);
1485be45129SEric Fiselier }
1495be45129SEric Fiselier 
1505be45129SEric Fiselier void bullet_one_two_tests() {
1515be45129SEric Fiselier     {
1525be45129SEric Fiselier         TestClass cl(42);
1535be45129SEric Fiselier         test_b12<int&(NonCopyable&&) &, int&>(cl);
1545be45129SEric Fiselier         test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
1555be45129SEric Fiselier         test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
1565be45129SEric Fiselier         test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
1575be45129SEric Fiselier 
1585be45129SEric Fiselier         test_b12<int&&(NonCopyable&&) &&, int&&>(std::move(cl));
1595be45129SEric Fiselier         test_b12<int const&&(NonCopyable&&) const &&, int const&&>(std::move(cl));
1605be45129SEric Fiselier         test_b12<int volatile&&(NonCopyable&&) volatile &&, int volatile&&>(std::move(cl));
1615be45129SEric Fiselier         test_b12<int const volatile&&(NonCopyable&&) const volatile &&, int const volatile&&>(std::move(cl));
1625be45129SEric Fiselier     }
1635be45129SEric Fiselier     {
1645be45129SEric Fiselier         DerivedFromTestClass cl(42);
1655be45129SEric Fiselier         test_b12<int&(NonCopyable&&) &, int&>(cl);
1665be45129SEric Fiselier         test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
1675be45129SEric Fiselier         test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
1685be45129SEric Fiselier         test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
1695be45129SEric Fiselier 
1705be45129SEric Fiselier         test_b12<int&&(NonCopyable&&) &&, int&&>(std::move(cl));
1715be45129SEric Fiselier         test_b12<int const&&(NonCopyable&&) const &&, int const&&>(std::move(cl));
1725be45129SEric Fiselier         test_b12<int volatile&&(NonCopyable&&) volatile &&, int volatile&&>(std::move(cl));
1735be45129SEric Fiselier         test_b12<int const volatile&&(NonCopyable&&) const volatile &&, int const volatile&&>(std::move(cl));
1745be45129SEric Fiselier     }
1755be45129SEric Fiselier     {
1765be45129SEric Fiselier         TestClass cl_obj(42);
1772152fd76SEric Fiselier         std::reference_wrapper<TestClass> cl(cl_obj);
1782152fd76SEric Fiselier         test_b12<int&(NonCopyable&&) &, int&>(cl);
1792152fd76SEric Fiselier         test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
1802152fd76SEric Fiselier         test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
1812152fd76SEric Fiselier         test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
1822152fd76SEric Fiselier 
1832152fd76SEric Fiselier         test_b12<int&(NonCopyable&&) &, int&>(std::move(cl));
1842152fd76SEric Fiselier         test_b12<int const&(NonCopyable&&) const &, int const&>(std::move(cl));
1852152fd76SEric Fiselier         test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(std::move(cl));
1862152fd76SEric Fiselier         test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(std::move(cl));
1872152fd76SEric Fiselier     }
1882152fd76SEric Fiselier     {
1892152fd76SEric Fiselier         DerivedFromTestClass cl_obj(42);
1902152fd76SEric Fiselier         std::reference_wrapper<DerivedFromTestClass> cl(cl_obj);
1912152fd76SEric Fiselier         test_b12<int&(NonCopyable&&) &, int&>(cl);
1922152fd76SEric Fiselier         test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
1932152fd76SEric Fiselier         test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
1942152fd76SEric Fiselier         test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
1952152fd76SEric Fiselier 
1962152fd76SEric Fiselier         test_b12<int&(NonCopyable&&) &, int&>(std::move(cl));
1972152fd76SEric Fiselier         test_b12<int const&(NonCopyable&&) const &, int const&>(std::move(cl));
1982152fd76SEric Fiselier         test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(std::move(cl));
1992152fd76SEric Fiselier         test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(std::move(cl));
2002152fd76SEric Fiselier     }
2012152fd76SEric Fiselier     {
2022152fd76SEric Fiselier         TestClass cl_obj(42);
2035be45129SEric Fiselier         TestClass *cl = &cl_obj;
2045be45129SEric Fiselier         test_b12<int&(NonCopyable&&) &, int&>(cl);
2055be45129SEric Fiselier         test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
2065be45129SEric Fiselier         test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
2075be45129SEric Fiselier         test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
2085be45129SEric Fiselier     }
2095be45129SEric Fiselier     {
2105be45129SEric Fiselier         DerivedFromTestClass cl_obj(42);
2115be45129SEric Fiselier         DerivedFromTestClass *cl = &cl_obj;
2125be45129SEric Fiselier         test_b12<int&(NonCopyable&&) &, int&>(cl);
2135be45129SEric Fiselier         test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
2145be45129SEric Fiselier         test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
2155be45129SEric Fiselier         test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
2165be45129SEric Fiselier     }
2175be45129SEric Fiselier }
2185be45129SEric Fiselier 
2195be45129SEric Fiselier void bullet_three_four_tests() {
2205be45129SEric Fiselier     {
2215be45129SEric Fiselier         typedef TestClass Fn;
2225be45129SEric Fiselier         Fn cl(42);
2235be45129SEric Fiselier         test_b34<int&>(cl);
2245be45129SEric Fiselier         test_b34<int const&>(static_cast<Fn const&>(cl));
2255be45129SEric Fiselier         test_b34<int volatile&>(static_cast<Fn volatile&>(cl));
2265be45129SEric Fiselier         test_b34<int const volatile&>(static_cast<Fn const volatile &>(cl));
2275be45129SEric Fiselier 
2285be45129SEric Fiselier         test_b34<int&&>(static_cast<Fn &&>(cl));
2295be45129SEric Fiselier         test_b34<int const&&>(static_cast<Fn const&&>(cl));
2305be45129SEric Fiselier         test_b34<int volatile&&>(static_cast<Fn volatile&&>(cl));
2315be45129SEric Fiselier         test_b34<int const volatile&&>(static_cast<Fn const volatile&&>(cl));
2325be45129SEric Fiselier     }
2335be45129SEric Fiselier     {
2345be45129SEric Fiselier         typedef DerivedFromTestClass Fn;
2355be45129SEric Fiselier         Fn cl(42);
2365be45129SEric Fiselier         test_b34<int&>(cl);
2375be45129SEric Fiselier         test_b34<int const&>(static_cast<Fn const&>(cl));
2385be45129SEric Fiselier         test_b34<int volatile&>(static_cast<Fn volatile&>(cl));
2395be45129SEric Fiselier         test_b34<int const volatile&>(static_cast<Fn const volatile &>(cl));
2405be45129SEric Fiselier 
2415be45129SEric Fiselier         test_b34<int&&>(static_cast<Fn &&>(cl));
2425be45129SEric Fiselier         test_b34<int const&&>(static_cast<Fn const&&>(cl));
2435be45129SEric Fiselier         test_b34<int volatile&&>(static_cast<Fn volatile&&>(cl));
2445be45129SEric Fiselier         test_b34<int const volatile&&>(static_cast<Fn const volatile&&>(cl));
2455be45129SEric Fiselier     }
2465be45129SEric Fiselier     {
2475be45129SEric Fiselier         typedef TestClass Fn;
2482152fd76SEric Fiselier         Fn cl(42);
2492152fd76SEric Fiselier         test_b34<int&>(std::reference_wrapper<Fn>(cl));
2502152fd76SEric Fiselier         test_b34<int const&>(std::reference_wrapper<Fn const>(cl));
2512152fd76SEric Fiselier         test_b34<int volatile&>(std::reference_wrapper<Fn volatile>(cl));
2522152fd76SEric Fiselier         test_b34<int const volatile&>(std::reference_wrapper<Fn const volatile>(cl));
2532152fd76SEric Fiselier     }
2542152fd76SEric Fiselier     {
2552152fd76SEric Fiselier         typedef DerivedFromTestClass Fn;
2562152fd76SEric Fiselier         Fn cl(42);
2572152fd76SEric Fiselier         test_b34<int&>(std::reference_wrapper<Fn>(cl));
2582152fd76SEric Fiselier         test_b34<int const&>(std::reference_wrapper<Fn const>(cl));
2592152fd76SEric Fiselier         test_b34<int volatile&>(std::reference_wrapper<Fn volatile>(cl));
2602152fd76SEric Fiselier         test_b34<int const volatile&>(std::reference_wrapper<Fn const volatile>(cl));
2612152fd76SEric Fiselier     }
2622152fd76SEric Fiselier     {
2632152fd76SEric Fiselier         typedef TestClass Fn;
2645be45129SEric Fiselier         Fn cl_obj(42);
2655be45129SEric Fiselier         Fn* cl = &cl_obj;
2665be45129SEric Fiselier         test_b34<int&>(cl);
2675be45129SEric Fiselier         test_b34<int const&>(static_cast<Fn const*>(cl));
2685be45129SEric Fiselier         test_b34<int volatile&>(static_cast<Fn volatile*>(cl));
2695be45129SEric Fiselier         test_b34<int const volatile&>(static_cast<Fn const volatile *>(cl));
2705be45129SEric Fiselier     }
2715be45129SEric Fiselier     {
2725be45129SEric Fiselier         typedef DerivedFromTestClass Fn;
2735be45129SEric Fiselier         Fn cl_obj(42);
2745be45129SEric Fiselier         Fn* cl = &cl_obj;
2755be45129SEric Fiselier         test_b34<int&>(cl);
2765be45129SEric Fiselier         test_b34<int const&>(static_cast<Fn const*>(cl));
2775be45129SEric Fiselier         test_b34<int volatile&>(static_cast<Fn volatile*>(cl));
2785be45129SEric Fiselier         test_b34<int const volatile&>(static_cast<Fn const volatile *>(cl));
2795be45129SEric Fiselier     }
2805be45129SEric Fiselier }
2815be45129SEric Fiselier 
2825be45129SEric Fiselier void bullet_five_tests() {
2835be45129SEric Fiselier     using FooType = int&(NonCopyable&&);
2845be45129SEric Fiselier     {
2855be45129SEric Fiselier         FooType& fn = foo;
2865be45129SEric Fiselier         test_b5<int &>(fn);
2875be45129SEric Fiselier     }
2885be45129SEric Fiselier     {
2895be45129SEric Fiselier         FooType* fn = foo;
2905be45129SEric Fiselier         test_b5<int &>(fn);
2915be45129SEric Fiselier     }
2925be45129SEric Fiselier     {
2935be45129SEric Fiselier         typedef TestClass Fn;
2945be45129SEric Fiselier         Fn cl(42);
2955be45129SEric Fiselier         test_b5<int&>(cl);
2965be45129SEric Fiselier         test_b5<int const&>(static_cast<Fn const&>(cl));
2975be45129SEric Fiselier         test_b5<int volatile&>(static_cast<Fn volatile&>(cl));
2985be45129SEric Fiselier         test_b5<int const volatile&>(static_cast<Fn const volatile &>(cl));
2995be45129SEric Fiselier 
3005be45129SEric Fiselier         test_b5<int&&>(static_cast<Fn &&>(cl));
3015be45129SEric Fiselier         test_b5<int const&&>(static_cast<Fn const&&>(cl));
3025be45129SEric Fiselier         test_b5<int volatile&&>(static_cast<Fn volatile&&>(cl));
3035be45129SEric Fiselier         test_b5<int const volatile&&>(static_cast<Fn const volatile&&>(cl));
3045be45129SEric Fiselier     }
3055be45129SEric Fiselier }
3065be45129SEric Fiselier 
307*57257567SEric Fiselier struct CopyThrows {
308*57257567SEric Fiselier   CopyThrows() {}
309*57257567SEric Fiselier   CopyThrows(CopyThrows const&) {}
310*57257567SEric Fiselier   CopyThrows(CopyThrows&&) noexcept {}
311*57257567SEric Fiselier };
312*57257567SEric Fiselier 
313*57257567SEric Fiselier struct NoThrowCallable {
314*57257567SEric Fiselier   void operator()() noexcept {}
315*57257567SEric Fiselier   void operator()(CopyThrows) noexcept {}
316*57257567SEric Fiselier };
317*57257567SEric Fiselier 
318*57257567SEric Fiselier struct ThrowsCallable {
319*57257567SEric Fiselier   void operator()() {}
320*57257567SEric Fiselier };
321*57257567SEric Fiselier 
322*57257567SEric Fiselier struct MemberObj {
323*57257567SEric Fiselier   int x;
324*57257567SEric Fiselier };
325*57257567SEric Fiselier 
326*57257567SEric Fiselier void noexcept_test() {
327*57257567SEric Fiselier     {
328*57257567SEric Fiselier         NoThrowCallable obj;
329*57257567SEric Fiselier         CopyThrows arg;
330*57257567SEric Fiselier         static_assert(noexcept(std::invoke(obj)));
331*57257567SEric Fiselier         static_assert(!noexcept(std::invoke(obj, arg)));
332*57257567SEric Fiselier         static_assert(noexcept(std::invoke(obj, std::move(arg))));
333*57257567SEric Fiselier     }
334*57257567SEric Fiselier     {
335*57257567SEric Fiselier         ThrowsCallable obj;
336*57257567SEric Fiselier         static_assert(!noexcept(std::invoke(obj)));
337*57257567SEric Fiselier     }
338*57257567SEric Fiselier     {
339*57257567SEric Fiselier         MemberObj obj{42};
340*57257567SEric Fiselier         static_assert(noexcept(std::invoke(&MemberObj::x, obj)));
341*57257567SEric Fiselier     }
342*57257567SEric Fiselier }
343*57257567SEric Fiselier 
3445be45129SEric Fiselier int main() {
3455be45129SEric Fiselier     bullet_one_two_tests();
3465be45129SEric Fiselier     bullet_three_four_tests();
3475be45129SEric Fiselier     bullet_five_tests();
348*57257567SEric Fiselier     noexcept_test();
3495be45129SEric Fiselier }
350