File variant.patch of Package boost.22385
commit 33784034b70a6607c9413633375e84912213a123
Author: Pawel Dac <pawel.dac@gmail.com>
Date: Tue Nov 7 17:49:15 2017 +0100
Perfect forwarding for passing visitor in apply_visitor.
Allows to catch Visitor&&, Visitor& and const Visitor&.
Removed apply_visitor with const Visitor& since it was catching inlined Visitors&&.
Passing const Visitor to result_wrapper resulted in compilation error when Visitor was mutable.
commit 03035b2f6b5d48d82270725f6eb52968180a2c64
Author: Antony Polukhin <antoshkka@gmail.com>
Date: Thu Jul 23 15:28:07 2020 +0300
Fix wrong usage of boost::move (fixes #53, #82)
Index: boost_1_66_0/boost/variant/detail/apply_visitor_unary.hpp
===================================================================
--- boost_1_66_0.orig/boost/variant/detail/apply_visitor_unary.hpp
+++ boost_1_66_0/boost/variant/detail/apply_visitor_unary.hpp
@@ -155,9 +155,9 @@ struct result_wrapper1
{
typedef decltype(result_multideduce1<Visitor, Variant>::deduce()) result_type;
- Visitor& visitor_;
- explicit result_wrapper1(Visitor& visitor) BOOST_NOEXCEPT
- : visitor_(visitor)
+ Visitor&& visitor_;
+ explicit result_wrapper1(Visitor&& visitor) BOOST_NOEXCEPT
+ : visitor_(::boost::forward<Visitor>(visitor))
{}
template <class T>
@@ -169,26 +169,15 @@ struct result_wrapper1
}} // namespace detail::variant
template <typename Visitor, typename Visitable>
-inline decltype(auto) apply_visitor(Visitor& visitor, Visitable&& visitable,
+inline decltype(auto) apply_visitor(Visitor&& visitor, Visitable&& visitable,
typename boost::disable_if<
boost::detail::variant::has_result_type<Visitor>
>::type* = 0)
{
- boost::detail::variant::result_wrapper1<Visitor, typename remove_reference<Visitable>::type> cpp14_vis(visitor);
+ boost::detail::variant::result_wrapper1<Visitor, typename remove_reference<Visitable>::type> cpp14_vis(::boost::forward<Visitor>(visitor));
return ::boost::forward<Visitable>(visitable).apply_visitor(cpp14_vis);
}
-template <typename Visitor, typename Visitable>
-inline decltype(auto) apply_visitor(const Visitor& visitor, Visitable&& visitable,
- typename boost::disable_if<
- boost::detail::variant::has_result_type<Visitor>
- >::type* = 0)
-{
- boost::detail::variant::result_wrapper1<const Visitor, typename remove_reference<Visitable>::type> cpp14_vis(visitor);
- return ::boost::forward<Visitable>(visitable).apply_visitor(cpp14_vis);
-}
-
-
#endif // !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
} // namespace boost
Index: boost_1_66_0/libs/variant/test/const_ref_apply_visitor.cpp
===================================================================
--- boost_1_66_0.orig/libs/variant/test/const_ref_apply_visitor.cpp
+++ boost_1_66_0/libs/variant/test/const_ref_apply_visitor.cpp
@@ -190,6 +190,13 @@ void test_cpp14_visitor(const variant_ty
BOOST_CHECK(boost::apply_visitor([](auto&& v) { return lvalue_rvalue_detector()(FORWARD(v)); }, test_var) == "lvalue reference");
}
+void test_cpp14_mutable_visitor(const variant_type& test_var)
+{
+ std::cout << "Testing const lvalue visitable for c++14 with inline mutable lambda\n";
+
+ BOOST_CHECK(boost::apply_visitor([](auto&& v) mutable -> auto { return lvalue_rvalue_detector()(FORWARD(v)); }, test_var) == "lvalue reference");
+}
+
void test_cpp14_visitor(const variant_type& test_var, const variant_type& test_var2)
{
std::cout << "Testing const lvalue visitable for c++14\n";
@@ -329,6 +336,7 @@ void run_cpp14_tests()
variant_type v1(10), v2(20), v3(30);
test_cpp14_visitor(v1);
+ test_cpp14_mutable_visitor(v1);
test_cpp14_visitor(v2, v3);
test_cpp14_visitor(v1, v2, v3);
Index: boost_1_66_0/boost/variant/variant.hpp
===================================================================
--- boost_1_66_0.orig/boost/variant/variant.hpp
+++ boost_1_66_0/boost/variant/variant.hpp
@@ -1048,7 +1048,7 @@ public: // internal visitor interfaces
template <typename T>
typename enable_if_c<MoveSemantics && is_same<T, T>::value, result_type>::type internal_visit(T&& operand, int)
{
- return visitor_(::boost::move<T>(operand));
+ return visitor_(::boost::move(operand));
}
//using workaround with is_same<T, T> to prenvent compilation error, because we need to use T in enable_if to make SFINAE work