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
931cbe0f2SLouis Dionne // UNSUPPORTED: c++03, c++11, c++14
105be45129SEric Fiselier
115be45129SEric Fiselier // <functional>
125be45129SEric Fiselier
13*2ff5a56eSwmbat // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS
14*2ff5a56eSwmbat // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
15*2ff5a56eSwmbat
165be45129SEric Fiselier // template<class F, class... Args>
176c49e1ceSLouis Dionne // invoke_result_t<F, Args...> invoke(F&& f, Args&&... args) // C++17
186c49e1ceSLouis Dionne // noexcept(is_nothrow_invocable_v<_Fn, _Args...>);
195be45129SEric Fiselier
205be45129SEric Fiselier /// C++14 [func.def] 20.9.0
215be45129SEric Fiselier /// (1) The following definitions apply to this Clause:
225be45129SEric Fiselier /// (2) A call signature is the name of a return type followed by a parenthesized
235be45129SEric Fiselier /// comma-separated list of zero or more argument types.
245be45129SEric Fiselier /// (3) A callable type is a function object type (20.9) or a pointer to member.
255be45129SEric Fiselier /// (4) A callable object is an object of a callable type.
265be45129SEric Fiselier /// (5) A call wrapper type is a type that holds a callable object and supports
275be45129SEric Fiselier /// a call operation that forwards to that object.
285be45129SEric Fiselier /// (6) A call wrapper is an object of a call wrapper type.
295be45129SEric Fiselier /// (7) A target object is the callable object held by a call wrapper.
305be45129SEric Fiselier
315be45129SEric Fiselier /// C++14 [func.require] 20.9.1
325be45129SEric Fiselier ///
335be45129SEric Fiselier /// Define INVOKE (f, t1, t2, ..., tN) as follows:
3416270a0bSEric 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
355be45129SEric Fiselier /// type T or a reference to an object of type T or a reference to an object of a type derived from T;
3616270a0bSEric 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
375be45129SEric Fiselier /// the types described in the previous item;
3816270a0bSEric 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
395be45129SEric Fiselier /// reference to an object of type T or a reference to an object of a type derived from T;
4016270a0bSEric 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
415be45129SEric Fiselier /// described in the previous item;
4216270a0bSEric Fiselier /// (1.5) - f(t1, t2, ..., tN) in all other cases.
435be45129SEric Fiselier
445be45129SEric Fiselier #include <functional>
455be45129SEric Fiselier #include <type_traits>
46d1180f4aSMarshall Clow #include <utility> // for std::move
475be45129SEric Fiselier #include <cassert>
485be45129SEric Fiselier
497fc6a556SMarshall Clow #include "test_macros.h"
507fc6a556SMarshall Clow
515be45129SEric Fiselier struct NonCopyable {
NonCopyableNonCopyable525be45129SEric Fiselier NonCopyable() {}
535be45129SEric Fiselier private:
545be45129SEric Fiselier NonCopyable(NonCopyable const&) = delete;
555be45129SEric Fiselier NonCopyable& operator=(NonCopyable const&) = delete;
565be45129SEric Fiselier };
575be45129SEric Fiselier
585be45129SEric Fiselier struct TestClass {
TestClassTestClass595be45129SEric Fiselier explicit TestClass(int x) : data(x) {}
605be45129SEric Fiselier
operator ()TestClass615be45129SEric Fiselier int& operator()(NonCopyable&&) & { return data; }
operator ()TestClass625be45129SEric Fiselier int const& operator()(NonCopyable&&) const & { return data; }
operator ()TestClass635be45129SEric Fiselier int volatile& operator()(NonCopyable&&) volatile & { return data; }
operator ()TestClass645be45129SEric Fiselier int const volatile& operator()(NonCopyable&&) const volatile & { return data; }
655be45129SEric Fiselier
operator ()TestClass665be45129SEric Fiselier int&& operator()(NonCopyable&&) && { return std::move(data); }
operator ()TestClass675be45129SEric Fiselier int const&& operator()(NonCopyable&&) const && { return std::move(data); }
operator ()TestClass685be45129SEric Fiselier int volatile&& operator()(NonCopyable&&) volatile && { return std::move(data); }
operator ()TestClass695be45129SEric Fiselier int const volatile&& operator()(NonCopyable&&) const volatile && { return std::move(data); }
705be45129SEric Fiselier
715be45129SEric Fiselier int data;
725be45129SEric Fiselier private:
735be45129SEric Fiselier TestClass(TestClass const&) = delete;
745be45129SEric Fiselier TestClass& operator=(TestClass const&) = delete;
755be45129SEric Fiselier };
765be45129SEric Fiselier
775be45129SEric Fiselier struct DerivedFromTestClass : public TestClass {
DerivedFromTestClassDerivedFromTestClass785be45129SEric Fiselier explicit DerivedFromTestClass(int x) : TestClass(x) {}
795be45129SEric Fiselier };
805be45129SEric Fiselier
foo(NonCopyable &&)815be45129SEric Fiselier int& foo(NonCopyable&&) {
825be45129SEric Fiselier static int data = 42;
835be45129SEric Fiselier return data;
845be45129SEric Fiselier }
855be45129SEric Fiselier
865be45129SEric Fiselier template <class Signature, class Expect, class Functor>
test_b12(Functor && f)875be45129SEric Fiselier void test_b12(Functor&& f) {
885be45129SEric Fiselier // Create the callable object.
895be45129SEric Fiselier typedef Signature TestClass::*ClassFunc;
905be45129SEric Fiselier ClassFunc func_ptr = &TestClass::operator();
915be45129SEric Fiselier
925be45129SEric Fiselier // Create the dummy arg.
935be45129SEric Fiselier NonCopyable arg;
945be45129SEric Fiselier
955be45129SEric Fiselier // Check that the deduced return type of invoke is what is expected.
965be45129SEric Fiselier typedef decltype(
975be45129SEric Fiselier std::invoke(func_ptr, std::forward<Functor>(f), std::move(arg))
985be45129SEric Fiselier ) DeducedReturnType;
995be45129SEric Fiselier static_assert((std::is_same<DeducedReturnType, Expect>::value), "");
1005be45129SEric Fiselier
1015be45129SEric Fiselier // Check that result_of_t matches Expect.
1025be45129SEric Fiselier typedef typename std::result_of<ClassFunc&&(Functor&&, NonCopyable&&)>::type
1035be45129SEric Fiselier ResultOfReturnType;
1045be45129SEric Fiselier static_assert((std::is_same<ResultOfReturnType, Expect>::value), "");
1055be45129SEric Fiselier
1065be45129SEric Fiselier // Run invoke and check the return value.
1075be45129SEric Fiselier DeducedReturnType ret =
1085be45129SEric Fiselier std::invoke(func_ptr, std::forward<Functor>(f), std::move(arg));
1095be45129SEric Fiselier assert(ret == 42);
1105be45129SEric Fiselier }
1115be45129SEric Fiselier
1125be45129SEric Fiselier template <class Expect, class Functor>
test_b34(Functor && f)1135be45129SEric Fiselier void test_b34(Functor&& f) {
1145be45129SEric Fiselier // Create the callable object.
1155be45129SEric Fiselier typedef int TestClass::*ClassFunc;
1165be45129SEric Fiselier ClassFunc func_ptr = &TestClass::data;
1175be45129SEric Fiselier
1185be45129SEric Fiselier // Check that the deduced return type of invoke is what is expected.
1195be45129SEric Fiselier typedef decltype(
1205be45129SEric Fiselier std::invoke(func_ptr, std::forward<Functor>(f))
1215be45129SEric Fiselier ) DeducedReturnType;
1225be45129SEric Fiselier static_assert((std::is_same<DeducedReturnType, Expect>::value), "");
1235be45129SEric Fiselier
1245be45129SEric Fiselier // Check that result_of_t matches Expect.
1255be45129SEric Fiselier typedef typename std::result_of<ClassFunc&&(Functor&&)>::type
1265be45129SEric Fiselier ResultOfReturnType;
1275be45129SEric Fiselier static_assert((std::is_same<ResultOfReturnType, Expect>::value), "");
1285be45129SEric Fiselier
1295be45129SEric Fiselier // Run invoke and check the return value.
1305be45129SEric Fiselier DeducedReturnType ret =
1315be45129SEric Fiselier std::invoke(func_ptr, std::forward<Functor>(f));
1325be45129SEric Fiselier assert(ret == 42);
1335be45129SEric Fiselier }
1345be45129SEric Fiselier
1355be45129SEric Fiselier template <class Expect, class Functor>
test_b5(Functor && f)1365be45129SEric Fiselier void test_b5(Functor&& f) {
1375be45129SEric Fiselier NonCopyable arg;
1385be45129SEric Fiselier
1395be45129SEric Fiselier // Check that the deduced return type of invoke is what is expected.
1405be45129SEric Fiselier typedef decltype(
1415be45129SEric Fiselier std::invoke(std::forward<Functor>(f), std::move(arg))
1425be45129SEric Fiselier ) DeducedReturnType;
1435be45129SEric Fiselier static_assert((std::is_same<DeducedReturnType, Expect>::value), "");
1445be45129SEric Fiselier
1455be45129SEric Fiselier // Check that result_of_t matches Expect.
1465be45129SEric Fiselier typedef typename std::result_of<Functor&&(NonCopyable&&)>::type
1475be45129SEric Fiselier ResultOfReturnType;
1485be45129SEric Fiselier static_assert((std::is_same<ResultOfReturnType, Expect>::value), "");
1495be45129SEric Fiselier
1505be45129SEric Fiselier // Run invoke and check the return value.
1515be45129SEric Fiselier DeducedReturnType ret = std::invoke(std::forward<Functor>(f), std::move(arg));
1525be45129SEric Fiselier assert(ret == 42);
1535be45129SEric Fiselier }
1545be45129SEric Fiselier
bullet_one_two_tests()1555be45129SEric Fiselier void bullet_one_two_tests() {
1565be45129SEric Fiselier {
1575be45129SEric Fiselier TestClass cl(42);
1585be45129SEric Fiselier test_b12<int&(NonCopyable&&) &, int&>(cl);
1595be45129SEric Fiselier test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
1605be45129SEric Fiselier test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
1615be45129SEric Fiselier test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
1625be45129SEric Fiselier
1635be45129SEric Fiselier test_b12<int&&(NonCopyable&&) &&, int&&>(std::move(cl));
1645be45129SEric Fiselier test_b12<int const&&(NonCopyable&&) const &&, int const&&>(std::move(cl));
1655be45129SEric Fiselier test_b12<int volatile&&(NonCopyable&&) volatile &&, int volatile&&>(std::move(cl));
1665be45129SEric Fiselier test_b12<int const volatile&&(NonCopyable&&) const volatile &&, int const volatile&&>(std::move(cl));
1675be45129SEric Fiselier }
1685be45129SEric Fiselier {
1695be45129SEric Fiselier DerivedFromTestClass cl(42);
1705be45129SEric Fiselier test_b12<int&(NonCopyable&&) &, int&>(cl);
1715be45129SEric Fiselier test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
1725be45129SEric Fiselier test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
1735be45129SEric Fiselier test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
1745be45129SEric Fiselier
1755be45129SEric Fiselier test_b12<int&&(NonCopyable&&) &&, int&&>(std::move(cl));
1765be45129SEric Fiselier test_b12<int const&&(NonCopyable&&) const &&, int const&&>(std::move(cl));
1775be45129SEric Fiselier test_b12<int volatile&&(NonCopyable&&) volatile &&, int volatile&&>(std::move(cl));
1785be45129SEric Fiselier test_b12<int const volatile&&(NonCopyable&&) const volatile &&, int const volatile&&>(std::move(cl));
1795be45129SEric Fiselier }
1805be45129SEric Fiselier {
1815be45129SEric Fiselier TestClass cl_obj(42);
1822152fd76SEric Fiselier std::reference_wrapper<TestClass> cl(cl_obj);
1832152fd76SEric Fiselier test_b12<int&(NonCopyable&&) &, int&>(cl);
1842152fd76SEric Fiselier test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
1852152fd76SEric Fiselier test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
1862152fd76SEric Fiselier test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
1872152fd76SEric Fiselier
1882152fd76SEric Fiselier test_b12<int&(NonCopyable&&) &, int&>(std::move(cl));
1892152fd76SEric Fiselier test_b12<int const&(NonCopyable&&) const &, int const&>(std::move(cl));
1902152fd76SEric Fiselier test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(std::move(cl));
1912152fd76SEric Fiselier test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(std::move(cl));
1922152fd76SEric Fiselier }
1932152fd76SEric Fiselier {
1942152fd76SEric Fiselier DerivedFromTestClass cl_obj(42);
1952152fd76SEric Fiselier std::reference_wrapper<DerivedFromTestClass> cl(cl_obj);
1962152fd76SEric Fiselier test_b12<int&(NonCopyable&&) &, int&>(cl);
1972152fd76SEric Fiselier test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
1982152fd76SEric Fiselier test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
1992152fd76SEric Fiselier test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
2002152fd76SEric Fiselier
2012152fd76SEric Fiselier test_b12<int&(NonCopyable&&) &, int&>(std::move(cl));
2022152fd76SEric Fiselier test_b12<int const&(NonCopyable&&) const &, int const&>(std::move(cl));
2032152fd76SEric Fiselier test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(std::move(cl));
2042152fd76SEric Fiselier test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(std::move(cl));
2052152fd76SEric Fiselier }
2062152fd76SEric Fiselier {
2072152fd76SEric Fiselier TestClass cl_obj(42);
2085be45129SEric Fiselier TestClass *cl = &cl_obj;
2095be45129SEric Fiselier test_b12<int&(NonCopyable&&) &, int&>(cl);
2105be45129SEric Fiselier test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
2115be45129SEric Fiselier test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
2125be45129SEric Fiselier test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
2135be45129SEric Fiselier }
2145be45129SEric Fiselier {
2155be45129SEric Fiselier DerivedFromTestClass cl_obj(42);
2165be45129SEric Fiselier DerivedFromTestClass *cl = &cl_obj;
2175be45129SEric Fiselier test_b12<int&(NonCopyable&&) &, int&>(cl);
2185be45129SEric Fiselier test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
2195be45129SEric Fiselier test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
2205be45129SEric Fiselier test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
2215be45129SEric Fiselier }
2225be45129SEric Fiselier }
2235be45129SEric Fiselier
bullet_three_four_tests()2245be45129SEric Fiselier void bullet_three_four_tests() {
2255be45129SEric Fiselier {
2265be45129SEric Fiselier typedef TestClass Fn;
2275be45129SEric Fiselier Fn cl(42);
2285be45129SEric Fiselier test_b34<int&>(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 test_b34<int&&>(static_cast<Fn &&>(cl));
2345be45129SEric Fiselier test_b34<int const&&>(static_cast<Fn const&&>(cl));
2355be45129SEric Fiselier test_b34<int volatile&&>(static_cast<Fn volatile&&>(cl));
2365be45129SEric Fiselier test_b34<int const volatile&&>(static_cast<Fn const volatile&&>(cl));
2375be45129SEric Fiselier }
2385be45129SEric Fiselier {
2395be45129SEric Fiselier typedef DerivedFromTestClass Fn;
2405be45129SEric Fiselier Fn cl(42);
2415be45129SEric Fiselier test_b34<int&>(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 test_b34<int&&>(static_cast<Fn &&>(cl));
2475be45129SEric Fiselier test_b34<int const&&>(static_cast<Fn const&&>(cl));
2485be45129SEric Fiselier test_b34<int volatile&&>(static_cast<Fn volatile&&>(cl));
2495be45129SEric Fiselier test_b34<int const volatile&&>(static_cast<Fn const volatile&&>(cl));
2505be45129SEric Fiselier }
2515be45129SEric Fiselier {
2525be45129SEric Fiselier typedef TestClass Fn;
2532152fd76SEric Fiselier Fn cl(42);
2542152fd76SEric Fiselier test_b34<int&>(std::reference_wrapper<Fn>(cl));
2552152fd76SEric Fiselier test_b34<int const&>(std::reference_wrapper<Fn const>(cl));
2562152fd76SEric Fiselier test_b34<int volatile&>(std::reference_wrapper<Fn volatile>(cl));
2572152fd76SEric Fiselier test_b34<int const volatile&>(std::reference_wrapper<Fn const volatile>(cl));
2582152fd76SEric Fiselier }
2592152fd76SEric Fiselier {
2602152fd76SEric Fiselier typedef DerivedFromTestClass Fn;
2612152fd76SEric Fiselier Fn cl(42);
2622152fd76SEric Fiselier test_b34<int&>(std::reference_wrapper<Fn>(cl));
2632152fd76SEric Fiselier test_b34<int const&>(std::reference_wrapper<Fn const>(cl));
2642152fd76SEric Fiselier test_b34<int volatile&>(std::reference_wrapper<Fn volatile>(cl));
2652152fd76SEric Fiselier test_b34<int const volatile&>(std::reference_wrapper<Fn const volatile>(cl));
2662152fd76SEric Fiselier }
2672152fd76SEric Fiselier {
2682152fd76SEric Fiselier typedef TestClass Fn;
2695be45129SEric Fiselier Fn cl_obj(42);
2705be45129SEric Fiselier Fn* cl = &cl_obj;
2715be45129SEric Fiselier test_b34<int&>(cl);
2725be45129SEric Fiselier test_b34<int const&>(static_cast<Fn const*>(cl));
2735be45129SEric Fiselier test_b34<int volatile&>(static_cast<Fn volatile*>(cl));
2745be45129SEric Fiselier test_b34<int const volatile&>(static_cast<Fn const volatile *>(cl));
2755be45129SEric Fiselier }
2765be45129SEric Fiselier {
2775be45129SEric Fiselier typedef DerivedFromTestClass Fn;
2785be45129SEric Fiselier Fn cl_obj(42);
2795be45129SEric Fiselier Fn* cl = &cl_obj;
2805be45129SEric Fiselier test_b34<int&>(cl);
2815be45129SEric Fiselier test_b34<int const&>(static_cast<Fn const*>(cl));
2825be45129SEric Fiselier test_b34<int volatile&>(static_cast<Fn volatile*>(cl));
2835be45129SEric Fiselier test_b34<int const volatile&>(static_cast<Fn const volatile *>(cl));
2845be45129SEric Fiselier }
2855be45129SEric Fiselier }
2865be45129SEric Fiselier
bullet_five_tests()2875be45129SEric Fiselier void bullet_five_tests() {
2885be45129SEric Fiselier using FooType = int&(NonCopyable&&);
2895be45129SEric Fiselier {
2905be45129SEric Fiselier FooType& fn = foo;
2915be45129SEric Fiselier test_b5<int &>(fn);
2925be45129SEric Fiselier }
2935be45129SEric Fiselier {
2945be45129SEric Fiselier FooType* fn = foo;
2955be45129SEric Fiselier test_b5<int &>(fn);
2965be45129SEric Fiselier }
2975be45129SEric Fiselier {
2985be45129SEric Fiselier typedef TestClass Fn;
2995be45129SEric Fiselier Fn cl(42);
3005be45129SEric Fiselier test_b5<int&>(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 test_b5<int&&>(static_cast<Fn &&>(cl));
3065be45129SEric Fiselier test_b5<int const&&>(static_cast<Fn const&&>(cl));
3075be45129SEric Fiselier test_b5<int volatile&&>(static_cast<Fn volatile&&>(cl));
3085be45129SEric Fiselier test_b5<int const volatile&&>(static_cast<Fn const volatile&&>(cl));
3095be45129SEric Fiselier }
3105be45129SEric Fiselier }
3115be45129SEric Fiselier
31257257567SEric Fiselier struct CopyThrows {
CopyThrowsCopyThrows31357257567SEric Fiselier CopyThrows() {}
CopyThrowsCopyThrows31457257567SEric Fiselier CopyThrows(CopyThrows const&) {}
CopyThrowsCopyThrows31557257567SEric Fiselier CopyThrows(CopyThrows&&) noexcept {}
31657257567SEric Fiselier };
31757257567SEric Fiselier
31857257567SEric Fiselier struct NoThrowCallable {
operator ()NoThrowCallable31957257567SEric Fiselier void operator()() noexcept {}
operator ()NoThrowCallable32057257567SEric Fiselier void operator()(CopyThrows) noexcept {}
32157257567SEric Fiselier };
32257257567SEric Fiselier
32357257567SEric Fiselier struct ThrowsCallable {
operator ()ThrowsCallable32457257567SEric Fiselier void operator()() {}
32557257567SEric Fiselier };
32657257567SEric Fiselier
32757257567SEric Fiselier struct MemberObj {
32857257567SEric Fiselier int x;
32957257567SEric Fiselier };
33057257567SEric Fiselier
noexcept_test()33157257567SEric Fiselier void noexcept_test() {
33257257567SEric Fiselier {
333c1d08ff0SEric Fiselier NoThrowCallable obj; ((void)obj); // suppress unused warning
334c1d08ff0SEric Fiselier CopyThrows arg; ((void)arg); // suppress unused warning
3357a580d0aSEric Fiselier static_assert(noexcept(std::invoke(obj)), "");
3367a580d0aSEric Fiselier static_assert(!noexcept(std::invoke(obj, arg)), "");
3377a580d0aSEric Fiselier static_assert(noexcept(std::invoke(obj, std::move(arg))), "");
33857257567SEric Fiselier }
33957257567SEric Fiselier {
340c1d08ff0SEric Fiselier ThrowsCallable obj; ((void)obj); // suppress unused warning
3417a580d0aSEric Fiselier static_assert(!noexcept(std::invoke(obj)), "");
34257257567SEric Fiselier }
34357257567SEric Fiselier {
344c1d08ff0SEric Fiselier MemberObj obj{42}; ((void)obj); // suppress unused warning.
3457a580d0aSEric Fiselier static_assert(noexcept(std::invoke(&MemberObj::x, obj)), "");
34657257567SEric Fiselier }
34757257567SEric Fiselier }
34857257567SEric Fiselier
main(int,char **)3492df59c50SJF Bastien int main(int, char**) {
3505be45129SEric Fiselier bullet_one_two_tests();
3515be45129SEric Fiselier bullet_three_four_tests();
3525be45129SEric Fiselier bullet_five_tests();
35357257567SEric Fiselier noexcept_test();
3542df59c50SJF Bastien
3552df59c50SJF Bastien return 0;
3565be45129SEric Fiselier }
357