diff --git a/include/boost/compat/function_ref.hpp b/include/boost/compat/function_ref.hpp index cd1f353..a079037 100644 --- a/include/boost/compat/function_ref.hpp +++ b/include/boost/compat/function_ref.hpp @@ -62,7 +62,7 @@ struct function_ref_base { template function_ref_base(obj_tag, F&& fn) noexcept : thunk_{}, invoke_(&invoke_object_holder::invoke_object) { - thunk_.pobj_ = static_cast(std::addressof(fn)); + thunk_.pobj_ = const_cast(static_cast(std::addressof(fn))); } function_ref_base(const function_ref_base&) noexcept = default; diff --git a/test/function_ref_obj_noexcept_test.cpp b/test/function_ref_obj_noexcept_test.cpp index ddab3ec..19b2dba 100644 --- a/test/function_ref_obj_noexcept_test.cpp +++ b/test/function_ref_obj_noexcept_test.cpp @@ -67,25 +67,36 @@ int main() { BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1&>)); + BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1&&>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1 const>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1 const&>)); + BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1 const&&>)); compat::function_ref fv2(f1); + BOOST_TEST_EQ(fv2(1), 1); + BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1 const>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1 const&>)); + BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1 const&&>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1&>)); + BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1&&>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1 const>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1 const&>)); + BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1 const&&>)); compat::function_ref fv4(f1); + BOOST_TEST_EQ(fv4(1, 2, 3), 123); + BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1>)); BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1&>)); + BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1&&>)); BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1 const>)); BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1 const&>)); + BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1 const&&>)); } { using S1 = int() const noexcept; @@ -95,25 +106,57 @@ int main() { BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1&>)); + BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1&&>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1 const>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1 const&>)); + BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1 const&&>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1&>)); + BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1&&>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1 const>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1 const&>)); + BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1 const&&>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1&>)); + BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1&&>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1 const>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1 const&>)); + BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1 const&&>)); compat::function_ref fv4(f1); + BOOST_TEST_EQ(fv4(1, 2, 3), 123); + BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1>)); BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1&>)); + BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1&&>)); BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1 const>)); BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1 const&>)); + BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1 const&&>)); + } + + { + using S2 = int(int) noexcept; + using S4 = int(int, int, int) noexcept; + + auto& fref = f1; + + compat::function_ref fv2(fref); + BOOST_TEST_EQ(fv2(1), 1); + + auto const& cfref = f1; + compat::function_ref fv4(cfref); + BOOST_TEST_EQ(fv4(1, 2, 3), 123); + } + + { + using S4 = int(int, int, int) const noexcept; + + auto const& cfref = f1; + compat::function_ref fv4(cfref); + BOOST_TEST_EQ(fv4(1, 2, 3), 123); } } @@ -123,13 +166,17 @@ int main() { BOOST_TEST_TRAIT_FALSE((std::is_constructible, F2>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F2&>)); + BOOST_TEST_TRAIT_FALSE((std::is_constructible, F2&&>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F2 const>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F2 const&>)); + BOOST_TEST_TRAIT_FALSE((std::is_constructible, F2 const&&>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F2>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F2&>)); + BOOST_TEST_TRAIT_FALSE((std::is_constructible, F2&&>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F2 const>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F2 const&>)); + BOOST_TEST_TRAIT_FALSE((std::is_constructible, F2 const&&>)); } // invoke_r diff --git a/test/function_ref_obj_test.cpp b/test/function_ref_obj_test.cpp index 3136ea8..e9b4e62 100644 --- a/test/function_ref_obj_test.cpp +++ b/test/function_ref_obj_test.cpp @@ -59,30 +59,39 @@ int main() { compat::function_ref fv1(f); BOOST_TEST_EQ(fv1(), -1); + BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1 const>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1 const&>)); + BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1 const&&>)); compat::function_ref fv2(f); BOOST_TEST_EQ(fv2(1), 1); + BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1 const>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1 const&>)); compat::function_ref fv3(f); BOOST_TEST_EQ(fv3(1, 2), 12); + BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1>)); BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1&>)); + BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1&&>)); BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1 const>)); BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1 const&>)); + BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1 const&&>)); compat::function_ref fv4(f); BOOST_TEST_EQ(fv4(1, 2, 3), 123); + BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1>)); BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1&>)); + BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1&&>)); BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1 const>)); BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1 const&>)); + BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1 const&&>)); } { @@ -93,29 +102,89 @@ int main() { BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1&>)); + BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1&&>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1 const>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1 const&>)); + BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1 const&&>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1&>)); + BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1&&>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1 const>)); BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1 const&>)); + BOOST_TEST_TRAIT_FALSE((std::is_constructible, F1 const&&>)); compat::function_ref fv3(f); BOOST_TEST_EQ(fv3(1, 2), 12); + BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1>)); BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1&>)); + BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1&&>)); BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1 const>)); BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1 const&>)); + BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1 const&&>)); compat::function_ref fv4(f); BOOST_TEST_EQ(fv4(1, 2, 3), 123); + BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1>)); BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1&>)); + BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1&&>)); BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1 const>)); BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1 const&>)); + BOOST_TEST_TRAIT_TRUE((std::is_constructible, F1 const&&>)); + } + + { + using S1 = int(); + using S2 = int(int); + + auto& fref = f; + + compat::function_ref fv1(fref); + BOOST_TEST_EQ(fv1(), -1); + + compat::function_ref fv2(fref); + BOOST_TEST_EQ(fv2(1), 1); + } + + { + using S1 = int(); + using S2 = int(int); + + compat::function_ref fv1(std::move(f)); + BOOST_TEST_EQ(fv1(), -1); + + compat::function_ref fv2(std::move(f)); + BOOST_TEST_EQ(fv2(1), 1); + } + + { + using S3 = int(int, int) const; + using S4 = int(int, int, int) const; + + auto const& fref = f; + + compat::function_ref fv3(fref); + BOOST_TEST_EQ(fv3(1, 2), 12); + + compat::function_ref fv4(fref); + BOOST_TEST_EQ(fv4(1, 2, 3), 123); + } + + { + using S3 = int(int, int) const; + using S4 = int(int, int, int) const; + + auto const&& fref = std::move(f); + + compat::function_ref fv3(fref); + BOOST_TEST_EQ(fv3(1, 2), 12); + + compat::function_ref fv4(fref); + BOOST_TEST_EQ(fv4(1, 2, 3), 123); } } @@ -125,12 +194,20 @@ int main() { compat::function_ref fv1(g); BOOST_TEST_EQ(fv1(3, 2), 321); + auto& gref = g; + compat::function_ref rfv1(gref); + BOOST_TEST_EQ(rfv1(3, 2), 321); + compat::function_ref fv2(std::move(g)); BOOST_TEST_EQ(fv2(3, 2), 321); compat::function_ref fv3(g); BOOST_TEST_EQ(fv3(3, 2), 322); + auto const& gcref = g; + compat::function_ref crfv3(gcref); + BOOST_TEST_EQ(fv3(3, 2), 322); + compat::function_ref fv4(std::move(g)); BOOST_TEST_EQ(fv4(3, 2), 322); }