// Copyright 2024 Christian Mazakas // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt #if defined(__GNUC__) && __GNUC__ == 7 #pragma GCC diagnostic ignored "-Wnoexcept-type" #endif #include #include #include #include #include #include int f0() { return -1; } int g0() { return 7331; } int f1(int x1) noexcept { return x1; } int f2(int x1, int x2) { return 10 * x1 + x2; } int f3(int x1, int x2, int x3) noexcept { return 100 * x1 + 10 * x2 + x3; } int g(std::unique_ptr p, std::unique_ptr q) { return 10 * *p + *q; } struct X { int v = 0; X() = default; X(int v_) noexcept : v{v_} {} }; struct Y { int v = 0; Y() = default; explicit Y(int v_) : v{v_} {} }; struct Z { int v = 0; Z() = default; Z(int v_) : v{v_} {} }; namespace compat = boost::compat; int main() { #if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable>)); BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable>)); BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable>)); BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable>)); BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable>)); BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable>)); BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable>)); BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable>)); BOOST_TEST_TRAIT_TRUE( (std::is_trivially_copyable, std::unique_ptr)>>)); BOOST_TEST_TRAIT_TRUE( (std::is_trivially_copyable, std::unique_ptr) const>>)); BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable>)); BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable>)); BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable>)); BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable>)); #if !BOOST_WORKAROUND(BOOST_MSVC, < 1910) struct W { int w_; }; BOOST_TEST_TRAIT_FALSE((std::is_assignable, W>)); BOOST_TEST_TRAIT_FALSE((std::is_assignable, W>)); BOOST_TEST_TRAIT_FALSE((std::is_assignable, compat::function_ref>)); BOOST_TEST_TRAIT_FALSE((std::is_assignable, compat::function_ref>)); BOOST_TEST_TRAIT_FALSE((std::is_assignable, compat::function_ref>)); BOOST_TEST_TRAIT_FALSE((std::is_assignable, compat::function_ref>)); #endif #else BOOST_PRAGMA_MESSAGE(" is incomplete, skipping is_trivially_copyable checks") #endif // f0 { compat::function_ref fv1(f0); BOOST_TEST_EQ(fv1(), -1); compat::function_ref fv2(f0); BOOST_TEST_EQ(fv2(), -1); } // f1 { int x = 1; compat::function_ref fv1(f1); BOOST_TEST_EQ(fv1(x), 1); compat::function_ref fv2(f1); BOOST_TEST_EQ(fv2(1), 1); } // f2 { compat::function_ref fv1(f2); BOOST_TEST_EQ(fv1(1, 2), 12); compat::function_ref fv2(f2); BOOST_TEST_EQ(fv2(1, 2), 12); } // f3 { compat::function_ref fv1(f3); BOOST_TEST_EQ(fv1(1, 2, 3), 123); compat::function_ref fv2(f3); BOOST_TEST_EQ(fv2(1, 2, 3), 123); } // g { using S1 = int(std::unique_ptr, std::unique_ptr); using S2 = int(std::unique_ptr, std::unique_ptr) const; compat::function_ref fv1(g); { auto p = std::unique_ptr(new int{1}); auto q = std::unique_ptr(new int{2}); BOOST_TEST_EQ(fv1(std::move(p), std::move(q)), 12); } compat::function_ref fv2(g); { auto p = std::unique_ptr(new int{130}); auto q = std::unique_ptr(new int{37}); BOOST_TEST_EQ(fv1(std::move(p), std::move(q)), 1337); } } // invoke_r { compat::function_ref fv1(f3); BOOST_TEST_EQ(fv1(1, 2, 3).v, 123); BOOST_TEST_TRAIT_FALSE((std::is_constructible, decltype(f3)>)); BOOST_TEST_TRAIT_TRUE((std::is_constructible, decltype(f3)>)); compat::function_ref fv2(f3); BOOST_TEST_EQ(fv2(1, 2, 3).v, 123); BOOST_TEST_TRAIT_FALSE((std::is_constructible, decltype(f3)>)); BOOST_TEST_TRAIT_TRUE((std::is_constructible, decltype(f3)>)); compat::function_ref fv3(f3); fv3(1, 2, 3); compat::function_ref fv4(f3); fv4(1, 2, 3); } // copy construct, copy assign { compat::function_ref fv(f0); compat::function_ref fv2(fv); BOOST_TEST_EQ(fv(), fv2()); fv2 = g0; BOOST_TEST_EQ(fv2(), 7331); compat::function_ref cfv(f0); compat::function_ref cfv2(cfv); BOOST_TEST_EQ(cfv(), cfv2()); cfv2 = g0; BOOST_TEST_EQ(cfv2(), 7331); } return boost::report_errors(); }