|
|
@ -0,0 +1,131 @@ |
|
|
|
From cbdb354a274c8ab51a15dd43eafd02c2b6a576f0 Mon Sep 17 00:00:00 2001 |
|
|
|
From: Edward Catmur <edward.catmur@mavensecurities.com> |
|
|
|
Date: Wed, 17 Apr 2019 15:05:37 +0100 |
|
|
|
Subject: [PATCH 1/2] Copy variant cvref when determining result type |
|
|
|
|
|
|
|
Ensures that we can e.g. call apply_visitor on a lvalue variant |
|
|
|
---
|
|
|
|
boost/variant/detail/apply_visitor_unary.hpp | 9 +++++---- |
|
|
|
1 file changed, 5 insertions(+), 4 deletions(-) |
|
|
|
|
|
|
|
diff --git a/boost/variant/detail/apply_visitor_unary.hpp b/boost/variant/detail/apply_visitor_unary.hpp
|
|
|
|
index 71610cb6..c3a741ef 100644
|
|
|
|
--- a/boost/variant/detail/apply_visitor_unary.hpp
|
|
|
|
+++ b/boost/variant/detail/apply_visitor_unary.hpp
|
|
|
|
@@ -23,6 +23,7 @@
|
|
|
|
# include <boost/mpl/size.hpp> |
|
|
|
# include <boost/utility/declval.hpp> |
|
|
|
# include <boost/core/enable_if.hpp> |
|
|
|
+# include <boost/type_traits/copy_cv_ref.hpp>
|
|
|
|
# include <boost/type_traits/remove_reference.hpp> |
|
|
|
# include <boost/variant/detail/has_result_type.hpp> |
|
|
|
#endif |
|
|
|
@@ -85,7 +86,7 @@ namespace detail { namespace variant {
|
|
|
|
// This class serves only metaprogramming purposes. none of its methods must be called at runtime! |
|
|
|
template <class Visitor, class Variant> |
|
|
|
struct result_multideduce1 { |
|
|
|
- typedef typename Variant::types types;
|
|
|
|
+ typedef typename remove_reference<Variant>::type::types types;
|
|
|
|
typedef typename boost::mpl::begin<types>::type begin_it; |
|
|
|
typedef typename boost::mpl::advance< |
|
|
|
begin_it, boost::mpl::int_<boost::mpl::size<types>::type::value - 1> |
|
|
|
@@ -95,14 +96,14 @@ struct result_multideduce1 {
|
|
|
|
struct deduce_impl { |
|
|
|
typedef typename boost::mpl::next<It>::type next_t; |
|
|
|
typedef typename boost::mpl::deref<It>::type value_t; |
|
|
|
- typedef decltype(true ? boost::declval< Visitor& >()( boost::declval< value_t >() )
|
|
|
|
+ typedef decltype(true ? boost::declval< Visitor& >()( boost::declval< copy_cv_ref_t< value_t, Variant > >() )
|
|
|
|
: boost::declval< typename deduce_impl<next_t>::type >()) type; |
|
|
|
}; |
|
|
|
|
|
|
|
template <class Dummy> |
|
|
|
struct deduce_impl<last_it, Dummy> { |
|
|
|
typedef typename boost::mpl::deref<last_it>::type value_t; |
|
|
|
- typedef decltype(boost::declval< Visitor& >()( boost::declval< value_t >() )) type;
|
|
|
|
+ typedef decltype(boost::declval< Visitor& >()( boost::declval< copy_cv_ref_t< value_t, Variant > >() )) type;
|
|
|
|
}; |
|
|
|
|
|
|
|
typedef typename deduce_impl<begin_it>::type type; |
|
|
|
@@ -132,7 +133,7 @@ inline decltype(auto) apply_visitor(Visitor&& visitor, Visitable&& visitable,
|
|
|
|
boost::detail::variant::has_result_type<Visitor> |
|
|
|
>::type* = 0) |
|
|
|
{ |
|
|
|
- boost::detail::variant::result_wrapper1<Visitor, typename remove_reference<Visitable>::type> cpp14_vis(::boost::forward<Visitor>(visitor));
|
|
|
|
+ boost::detail::variant::result_wrapper1<Visitor, Visitable> cpp14_vis(::boost::forward<Visitor>(visitor));
|
|
|
|
return ::boost::forward<Visitable>(visitable).apply_visitor(cpp14_vis); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
From 7331d648f46b6008138cbd22087b8c5c61ff7926 Mon Sep 17 00:00:00 2001 |
|
|
|
From: Ed Catmur <ed@catmur.uk> |
|
|
|
Date: Sun, 21 Apr 2019 00:50:00 +0100 |
|
|
|
Subject: [PATCH 2/2] Add test. |
|
|
|
|
|
|
|
---
|
|
|
|
libs/variant/test/const_ref_apply_visitor.cpp | 44 ++++++++++++++++++++++++++++++++ |
|
|
|
1 file changed, 44 insertions(+) |
|
|
|
|
|
|
|
diff --git a/libs/variant/test/const_ref_apply_visitor.cpp b/libs/variant/test/const_ref_apply_visitor.cpp
|
|
|
|
index 0ec77bd4..72afff9e 100644
|
|
|
|
--- a/libs/variant/test/const_ref_apply_visitor.cpp
|
|
|
|
+++ b/libs/variant/test/const_ref_apply_visitor.cpp
|
|
|
|
@@ -224,6 +224,44 @@ void test_cpp14_visitor(const variant_type& test_var, const variant_type& test_v
|
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
+void test_cpp14_visitor(variant_type& test_var)
|
|
|
|
+{
|
|
|
|
+ std::cout << "Testing lvalue visitable for c++14\n";
|
|
|
|
+
|
|
|
|
+ BOOST_TEST(boost::apply_visitor([](auto& v) { return lvalue_rvalue_detector()(v); }, test_var) == "lvalue reference");
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void test_cpp14_mutable_visitor(variant_type& test_var)
|
|
|
|
+{
|
|
|
|
+ std::cout << "Testing lvalue visitable for c++14 with inline mutable lambda\n";
|
|
|
|
+
|
|
|
|
+ BOOST_TEST(boost::apply_visitor([](auto& v) mutable -> auto { return lvalue_rvalue_detector()(v); }, test_var) == "lvalue reference");
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void test_cpp14_visitor(variant_type& test_var, variant_type& test_var2)
|
|
|
|
+{
|
|
|
|
+ std::cout << "Testing lvalue visitable for c++14\n";
|
|
|
|
+
|
|
|
|
+ BOOST_TEST(boost::apply_visitor([](auto& v, auto& vv) { return lvalue_rvalue_detector()(v, vv); }, test_var, test_var2)
|
|
|
|
+ == "lvalue reference, lvalue reference");
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void test_cpp14_visitor(variant_type& test_var, variant_type& test_var2, variant_type& test_var3)
|
|
|
|
+{
|
|
|
|
+#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
|
|
|
|
+ std::cout << "Testing lvalue visitable for c++14\n";
|
|
|
|
+
|
|
|
|
+ auto result = boost::apply_visitor([](auto& v, auto& t, auto& p) { return lvalue_rvalue_detector()(v, t, p); },
|
|
|
|
+ test_var, test_var2, test_var3);
|
|
|
|
+ std::cout << "result: " << result << std::endl;
|
|
|
|
+ BOOST_TEST(result == "lvalue reference, lvalue reference, lvalue reference");
|
|
|
|
+#else
|
|
|
|
+ (void)test_var;
|
|
|
|
+ (void)test_var2;
|
|
|
|
+ (void)test_var3;
|
|
|
|
+#endif
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
void test_cpp14_visitor(variant_type&& test_var) |
|
|
|
{ |
|
|
|
std::cout << "Testing rvalue visitable for c++14\n"; |
|
|
|
@@ -344,8 +382,14 @@ void run_cpp14_mixed_tests()
|
|
|
|
void run_cpp14_tests() |
|
|
|
{ |
|
|
|
#ifndef BOOST_NO_CXX14_DECLTYPE_AUTO |
|
|
|
+ variant_type const c1(10), c2(20), c3(30);
|
|
|
|
variant_type v1(10), v2(20), v3(30); |
|
|
|
|
|
|
|
+ test_cpp14_visitor(c1);
|
|
|
|
+ test_cpp14_mutable_visitor(c1);
|
|
|
|
+ test_cpp14_visitor(c2, c3);
|
|
|
|
+ test_cpp14_visitor(c1, c2, c3);
|
|
|
|
+
|
|
|
|
test_cpp14_visitor(v1); |
|
|
|
test_cpp14_mutable_visitor(v1); |
|
|
|
test_cpp14_visitor(v2, v3); |