Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r83332 - in sandbox/type_erasure: boost/type_erasure boost/type_erasure/detail libs/type_erasure/test
From: steven_at_[hidden]
Date: 2013-03-06 13:46:58


Author: steven_watanabe
Date: 2013-03-06 13:46:56 EST (Wed, 06 Mar 2013)
New Revision: 83332
URL: http://svn.boost.org/trac/boost/changeset/83332

Log:
handle rvalue references in BOOST_TYPE_ERASURE_FREE
Text files modified:
   sandbox/type_erasure/boost/type_erasure/detail/const.hpp | 19 +++++++++++++++++++
   sandbox/type_erasure/boost/type_erasure/free.hpp | 38 +++++++++++++++++++++++++++++++-------
   sandbox/type_erasure/libs/type_erasure/test/test_free.cpp | 13 +++++++++++++
   3 files changed, 63 insertions(+), 7 deletions(-)

Modified: sandbox/type_erasure/boost/type_erasure/detail/const.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/detail/const.hpp (original)
+++ sandbox/type_erasure/boost/type_erasure/detail/const.hpp 2013-03-06 13:46:56 EST (Wed, 06 Mar 2013)
@@ -96,6 +96,25 @@
>::type type;
 };
 
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+template<class Placeholder, class Base>
+struct maybe_const_this_param<Placeholder&&, Base>
+{
+ typedef typename ::boost::type_erasure::derived<Base>::type plain_type;
+ typedef typename ::boost::remove_reference<Placeholder>::type plain_placeholder;
+ typedef typename ::boost::type_erasure::placeholder_of<plain_type>::type self_placeholder;
+ typedef typename ::boost::mpl::if_< ::boost::is_lvalue_reference<self_placeholder>,
+ ::boost::type_erasure::detail::uncallable<plain_type>,
+ typename ::boost::mpl::if_< ::boost::is_rvalue_reference<self_placeholder>,
+ const plain_type&,
+ plain_type&&
+ >::type
+ >::type type;
+};
+
+#endif
+
 }
 }
 }

Modified: sandbox/type_erasure/boost/type_erasure/free.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/free.hpp (original)
+++ sandbox/type_erasure/boost/type_erasure/free.hpp 2013-03-06 13:46:56 EST (Wed, 06 Mar 2013)
@@ -12,6 +12,7 @@
 #define BOOST_TYPE_ERASURE_FREE_HPP_INCLUDED
 
 #include <boost/preprocessor/repetition/enum.hpp>
+#include <boost/preprocessor/repetition/enum_trailing.hpp>
 #include <boost/preprocessor/repetition/enum_params.hpp>
 #include <boost/preprocessor/repetition/enum_shifted_params.hpp>
 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
@@ -33,7 +34,7 @@
 #include <boost/type_erasure/call.hpp>
 #include <boost/type_erasure/concept_interface.hpp>
 
-#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_TYPE_ERASURE_DOXYGEN)
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || defined(BOOST_TYPE_ERASURE_DOXYGEN)
 
 namespace boost {
 namespace type_erasure {
@@ -77,6 +78,26 @@
         ::boost::type_erasure::as_param<Base, BOOST_PP_CAT(T, n)> \
>::type BOOST_PP_CAT(t, n)
 
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+/** INTERNAL ONLY */
+#define BOOST_TYPE_ERASURE_FREE_FORWARD_I(z, n, data) ::std::forward<BOOST_PP_CAT(T, n)>(BOOST_PP_CAT(t, n))
+/** INTERNAL ONLY */
+#define BOOST_TYPE_ERASURE_FREE_FORWARD(n) BOOST_PP_ENUM(n, BOOST_TYPE_ERASURE_FREE_FORWARD_I, ~)
+/** INTERNAL ONLY */
+#define BOOST_TYPE_ERASURE_FREE_FORWARD_PARAM_I(z, n, data) \
+ ::std::forward<typename ::boost::mpl::eval_if_c<(_boost_type_erasure_free_p_idx::value == n), \
+ ::boost::type_erasure::detail::maybe_const_this_param<BOOST_PP_CAT(T, n), Base>, \
+ ::boost::type_erasure::as_param<Base, BOOST_PP_CAT(T, n)> \
+ >::type>(BOOST_PP_CAT(t, n))
+
+#else
+
+#define BOOST_TYPE_ERASURE_FREE_FORWARD(n) BOOST_PP_ENUM_PARAMS(n, t)
+#define BOOST_TYPE_ERASURE_FREE_FORWARD_PARAM_I(z, n, data) BOOST_PP_CAT(t, n)
+
+#endif
+
 /** INTERNAL ONLY */
 #define BOOST_TYPE_ERASURE_FREE_II(qual_name, concept_name, function_name, N) \
     BOOST_TYPE_ERASURE_OPEN_NAMESPACE(qual_name) \
@@ -87,13 +108,13 @@
     template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)> \
     struct concept_name<R(BOOST_PP_ENUM_PARAMS(N, T))> { \
         static R apply(BOOST_PP_ENUM_BINARY_PARAMS(N, T, t)) \
- { return function_name(BOOST_PP_ENUM_PARAMS(N, t)); } \
+ { return function_name(BOOST_TYPE_ERASURE_FREE_FORWARD(N)); } \
     }; \
                                                                         \
     template<BOOST_PP_ENUM_PARAMS(N, class T)> \
     struct concept_name<void(BOOST_PP_ENUM_PARAMS(N, T))> { \
         static void apply(BOOST_PP_ENUM_BINARY_PARAMS(N, T, t)) \
- { function_name(BOOST_PP_ENUM_PARAMS(N, t)); } \
+ { function_name(BOOST_TYPE_ERASURE_FREE_FORWARD(N)); } \
     }; \
                                                                         \
     BOOST_TYPE_ERASURE_CLOSE_NAMESPACE(qual_name) \
@@ -116,7 +137,7 @@
         { \
             return ::boost::type_erasure::call( \
                 BOOST_TYPE_ERASURE_FREE_QUALIFIED_ID(qual_name, N)() \
- BOOST_PP_ENUM_TRAILING_PARAMS(N, t)); \
+ BOOST_PP_ENUM_TRAILING(N, BOOST_TYPE_ERASURE_FREE_FORWARD_PARAM_I, ~)); \
         } \
     }; \
                                                                         \
@@ -197,13 +218,13 @@
     template<class R, class... T> \
     struct concept_name<R(T...)> { \
         static R apply(T... t) \
- { return function_name(t...); } \
+ { return function_name(std::forward<T>(t)...); } \
     }; \
                                                                         \
     template<class... T> \
     struct concept_name<void(T...)> { \
         static void apply(T... t) \
- { function_name(t...); } \
+ { function_name(std::forward<T>(t)...); } \
     }; \
                                                                         \
     BOOST_TYPE_ERASURE_CLOSE_NAMESPACE(qual_name) \
@@ -229,7 +250,10 @@
        { \
             return ::boost::type_erasure::call( \
                 BOOST_TYPE_ERASURE_QUALIFIED_NAME(qual_name)<R(T...)>(),\
- t...); \
+ std::forward<typename ::boost::mpl::eval_if_c<(_boost_type_erasure_free_p_idx::value == I), \
+ ::boost::type_erasure::detail::maybe_const_this_param<T, Base>, \
+ ::boost::type_erasure::as_param<Base, T> \
+ >::type>(t)...); \
         } \
     }; \
                                                                         \

Modified: sandbox/type_erasure/libs/type_erasure/test/test_free.cpp
==============================================================================
--- sandbox/type_erasure/libs/type_erasure/test/test_free.cpp (original)
+++ sandbox/type_erasure/libs/type_erasure/test/test_free.cpp 2013-03-06 13:46:56 EST (Wed, 06 Mar 2013)
@@ -97,3 +97,16 @@
     BOOST_CHECK_EQUAL(f1(x), 10);
     BOOST_CHECK_EQUAL(f1(x, 5), 15);
 }
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+BOOST_AUTO_TEST_CASE(test_global_has_f1_rv) {
+ typedef ::boost::mpl::vector<
+ global_has_f1_2<int(_self&&, int&&)>,
+ copy_constructible<> > concept_type;
+ model_const m(10);
+ any<concept_type> x(m);
+ BOOST_CHECK_EQUAL(f1(std::move(x), 5), 15);
+}
+
+#endif


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk