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