Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r83093 - in sandbox/type_erasure: boost/type_erasure boost/type_erasure/detail libs/type_erasure/test
From: steven_at_[hidden]
Date: 2013-02-22 21:23:59


Author: steven_watanabe
Date: 2013-02-22 21:23:58 EST (Fri, 22 Feb 2013)
New Revision: 83093
URL: http://svn.boost.org/trac/boost/changeset/83093

Log:
Initial RValue reference support for arguments.
Text files modified:
   sandbox/type_erasure/boost/type_erasure/call.hpp | 118 +++++++++++++++++++++++++--------------
   sandbox/type_erasure/boost/type_erasure/callable.hpp | 38 ++++++++----
   sandbox/type_erasure/boost/type_erasure/check_match.hpp | 17 ++++-
   sandbox/type_erasure/boost/type_erasure/detail/adapt_to_vtable.hpp | 14 ++++
   sandbox/type_erasure/boost/type_erasure/detail/check_call.hpp | 48 +++++++++++++--
   sandbox/type_erasure/boost/type_erasure/detail/extract_concept.hpp | 2
   sandbox/type_erasure/boost/type_erasure/detail/storage.hpp | 20 ++++++
   sandbox/type_erasure/boost/type_erasure/require_match.hpp | 56 +++++++++++-------
   sandbox/type_erasure/libs/type_erasure/test/test_callable.cpp | 19 ++++++
   9 files changed, 241 insertions(+), 91 deletions(-)

Modified: sandbox/type_erasure/boost/type_erasure/call.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/call.hpp (original)
+++ sandbox/type_erasure/boost/type_erasure/call.hpp 2013-02-22 21:23:58 EST (Fri, 22 Feb 2013)
@@ -24,6 +24,7 @@
 #include <boost/preprocessor/iteration/iterate.hpp>
 #include <boost/preprocessor/repetition/repeat.hpp>
 #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_binary_params.hpp>
 #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
@@ -125,9 +126,18 @@
     return ::boost::type_erasure::detail::access::data(arg);
 }
 
+#ifndef BOOST_NO_RVALUE_REFERENCES
+
+template<class T>
+T&& convert_arg(T&& arg, boost::mpl::false_) { return std::forward<T>(arg); }
+
+#else
+
 template<class T>
 T& convert_arg(T& arg, boost::mpl::false_) { return arg; }
 
+#endif
+
 }
 
 #ifdef BOOST_TYPE_ERASURE_DOXYGEN
@@ -206,7 +216,7 @@
 
 }
 
-#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+#if !defined(BOOST_NO_VARIADIC_TEMPLATES) && !defined(BOOST_NO_RVALUE_REFERENCES)
 
 namespace detail {
 
@@ -244,7 +254,7 @@
     {
         return table->template find<F>()(
             ::boost::type_erasure::detail::convert_arg(
- arg,
+ ::std::forward<U>(arg),
                 ::boost::type_erasure::detail::is_placeholder_arg<T>())...);
     }
 };
@@ -258,7 +268,7 @@
     {
         return type(table->template find<F>()(
             ::boost::type_erasure::detail::convert_arg(
- arg,
+ ::std::forward<U>(arg),
                 ::boost::type_erasure::detail::is_placeholder_arg<T>())...), *table);
     }
 };
@@ -275,13 +285,13 @@
 };
 
 template<class R, class... T, class... U>
-struct call_impl<R(T...), void(U&...), void, true> :
+struct call_impl<R(T...), void(U...), void, true> :
     ::boost::type_erasure::detail::call_impl_dispatch<
         R(T...),
- void(U&...),
+ void(U...),
         typename ::boost::type_erasure::detail::extract_concept<
             void(T...),
- U...
+ typename ::boost::remove_reference<U>::type...
>::type,
         ::boost::type_erasure::detail::is_placeholder_arg<R>::value
>
@@ -297,68 +307,68 @@
>
 typename ::boost::type_erasure::detail::call_result<
     Op,
- void(U&...),
+ void(U&&...),
     Concept
>::type
 unchecked_call(
     const ::boost::type_erasure::binding<Concept>& table,
     const Op&,
- U&... arg)
+ U&&... arg)
 {
     return ::boost::type_erasure::detail::call_impl<
         typename ::boost::type_erasure::detail::get_signature<Op>::type,
- void(U&...),
+ void(U&&...),
         Concept
>::template apply<
         typename ::boost::type_erasure::detail::adapt_to_vtable<Op>::type
- >(&table, arg...);
+ >(&table, std::forward<U>(arg)...);
 }
 
 template<class Concept, class Op, class... U>
 typename ::boost::type_erasure::detail::call_result<
     Op,
- void(U&...),
+ void(U&&...),
     Concept
>::type
 call(
     const ::boost::type_erasure::binding<Concept>& table,
     const Op& f,
- U&... arg)
+ U&&... arg)
 {
- ::boost::type_erasure::require_match(table, f, arg...);
- return ::boost::type_erasure::unchecked_call(table, f, arg...);
+ ::boost::type_erasure::require_match(table, f, std::forward<U>(arg)...);
+ return ::boost::type_erasure::unchecked_call(table, f, std::forward<U>(arg)...);
 }
 
 template<class Op, class... U>
 typename ::boost::type_erasure::detail::call_result<
     Op,
- void(U&...)
+ void(U&&...)
>::type
 unchecked_call(
     const Op&,
- U&... arg)
+ U&&... arg)
 {
     return ::boost::type_erasure::detail::call_impl<
         typename ::boost::type_erasure::detail::get_signature<Op>::type,
- void(U&...)
+ void(U&&...)
>::template apply<
         typename ::boost::type_erasure::detail::adapt_to_vtable<Op>::type
>(::boost::type_erasure::detail::extract_table(
         static_cast<typename ::boost::type_erasure::detail::get_signature<Op>::type*>(0), arg...),
- arg...);
+ std::forward<U>(arg)...);
 }
 
 template<class Op, class... U>
 typename ::boost::type_erasure::detail::call_result<
     Op,
- void(U&...)
+ void(U&&...)
>::type
 call(
     const Op& f,
- U&... arg)
+ U&&... arg)
 {
- ::boost::type_erasure::require_match(f, arg...);
- return ::boost::type_erasure::unchecked_call(f, arg...);
+ ::boost::type_erasure::require_match(f, std::forward<U>(arg)...);
+ return ::boost::type_erasure::unchecked_call(f, std::forward<U>(arg)...);
 }
 
 
@@ -381,11 +391,22 @@
 
 #define N BOOST_PP_ITERATION()
 
+#ifndef BOOST_NO_RVALUE_REFERENCES
+
+#define BOOST_TYPE_ERASURE_CONVERT_ARG(z, n, data) \
+ ::boost::type_erasure::detail::convert_arg( \
+ std::forward<BOOST_PP_CAT(U, n)>(BOOST_PP_CAT(arg, n)), \
+ ::boost::type_erasure::detail::is_placeholder_arg<BOOST_PP_CAT(T, n)>())
+
+#else
+
 #define BOOST_TYPE_ERASURE_CONVERT_ARG(z, n, data) \
     ::boost::type_erasure::detail::convert_arg( \
         BOOST_PP_CAT(arg, n), \
         ::boost::type_erasure::detail::is_placeholder_arg<BOOST_PP_CAT(T, n)>())
 
+#endif
+
 #define BOOST_TYPE_ERASURE_GET_TABLE(z, n, data) \
     ::boost::type_erasure::detail::maybe_get_table( \
         BOOST_PP_CAT(arg, n), \
@@ -449,7 +470,7 @@
     typedef R type;
     template<class F>
     static R apply(const ::boost::type_erasure::binding<Concept>* table
- BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, & arg))
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, arg))
     {
         return table->template find<F>()(
             BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_CONVERT_ARG, ~));
@@ -473,7 +494,7 @@
     typedef ::boost::type_erasure::any<Concept, R> type;
     template<class F>
     static type apply(const ::boost::type_erasure::binding<Concept>* table
- BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, & arg))
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, arg))
     {
         return type(table->template find<F>()(
             BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_CONVERT_ARG, ~)), *table);
@@ -486,7 +507,7 @@
     BOOST_PP_ENUM_TRAILING_PARAMS(N, class U),
     class Concept
>
-struct call_impl<R(BOOST_PP_ENUM_PARAMS(N, T)), void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, &u)), Concept, true>
+struct call_impl<R(BOOST_PP_ENUM_PARAMS(N, T)), void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, u)), Concept, true>
   : BOOST_PP_CAT(call_impl, N)<R BOOST_PP_ENUM_TRAILING_PARAMS(N, T) BOOST_PP_ENUM_TRAILING_PARAMS(N, U), Concept>
 {};
 
@@ -497,7 +518,7 @@
     BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)
     BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
>
-struct call_impl<R(BOOST_PP_ENUM_PARAMS(N, T)), void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, &u)), void, true>
+struct call_impl<R(BOOST_PP_ENUM_PARAMS(N, T)), void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, u)), void, true>
   : BOOST_PP_CAT(call_impl, N)<R BOOST_PP_ENUM_TRAILING_PARAMS(N, T) BOOST_PP_ENUM_TRAILING_PARAMS(N, U)>
 {};
 
@@ -505,6 +526,15 @@
 
 }
 
+#ifdef BOOST_NO_RVALUE_REFERENCES
+#define RREF &
+#define BOOST_TYPE_ERASURE_FORWARD_ARGS(N, X, x) BOOST_PP_ENUM_TRAILING_PARAMS(N, x)
+#else
+#define RREF &&
+#define BOOST_TYPE_ERASURE_FORWARD_ARGS_I(z, n, data) std::forward<BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 0, data), n)>(BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 1, data), n))
+#define BOOST_TYPE_ERASURE_FORWARD_ARGS(N, X, x) BOOST_PP_ENUM_TRAILING(N, BOOST_TYPE_ERASURE_FORWARD_ARGS_I, (X, x))
+#endif
+
 template<
     class Concept,
     class Op
@@ -512,21 +542,21 @@
>
 typename ::boost::type_erasure::detail::call_result<
     Op,
- void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, &u)),
+ void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, RREF u)),
     Concept
>::type
 unchecked_call(
     const ::boost::type_erasure::binding<Concept>& table,
     const Op&
- BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, & arg))
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, RREF arg))
 {
     return ::boost::type_erasure::detail::call_impl<
         typename ::boost::type_erasure::detail::get_signature<Op>::type,
- void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, &u)),
+ void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, RREF u)),
         Concept
>::template apply<
         typename ::boost::type_erasure::detail::adapt_to_vtable<Op>::type
- >(&table BOOST_PP_ENUM_TRAILING_PARAMS(N, arg));
+ >(&table BOOST_TYPE_ERASURE_FORWARD_ARGS(N, U, arg));
 }
 
 template<
@@ -536,16 +566,16 @@
>
 typename ::boost::type_erasure::detail::call_result<
     Op,
- void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, &u)),
+ void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, RREF u)),
     Concept
>::type
 call(
     const ::boost::type_erasure::binding<Concept>& table,
     const Op& f
- BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, & arg))
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, RREF arg))
 {
- ::boost::type_erasure::require_match(table, f BOOST_PP_ENUM_TRAILING_PARAMS(N, arg));
- return ::boost::type_erasure::unchecked_call(table, f BOOST_PP_ENUM_TRAILING_PARAMS(N, arg));
+ ::boost::type_erasure::require_match(table, f BOOST_TYPE_ERASURE_FORWARD_ARGS(N, U, arg));
+ return ::boost::type_erasure::unchecked_call(table, f BOOST_TYPE_ERASURE_FORWARD_ARGS(N, U, arg));
 }
 
 #if N != 0
@@ -556,22 +586,22 @@
>
 typename ::boost::type_erasure::detail::call_result<
     Op,
- void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, &u))
+ void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, RREF u))
>::type
 unchecked_call(
     const Op&
- BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, & arg))
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, RREF arg))
 {
     return ::boost::type_erasure::detail::call_impl<
         typename ::boost::type_erasure::detail::get_signature<Op>::type,
- void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, &u))
+ void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, RREF u))
>::template apply<
         typename ::boost::type_erasure::detail::adapt_to_vtable<Op>::type
>(
         ::boost::type_erasure::detail::BOOST_PP_CAT(extract_table, N)(
             (typename ::boost::type_erasure::detail::get_signature<Op>::type*)0,
             BOOST_PP_ENUM_PARAMS(N, arg))
- BOOST_PP_ENUM_TRAILING_PARAMS(N, arg)
+ BOOST_TYPE_ERASURE_FORWARD_ARGS(N, U, arg)
     );
 }
 
@@ -581,18 +611,22 @@
>
 typename ::boost::type_erasure::detail::call_result<
     Op,
- void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, &u))
+ void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, RREF u))
>::type
 call(
     const Op& f
- BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, & arg))
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, RREF arg))
 {
- ::boost::type_erasure::require_match(f BOOST_PP_ENUM_TRAILING_PARAMS(N, arg));
- return ::boost::type_erasure::unchecked_call(f BOOST_PP_ENUM_TRAILING_PARAMS(N, arg));
+ ::boost::type_erasure::require_match(f BOOST_TYPE_ERASURE_FORWARD_ARGS(N, U, arg));
+ return ::boost::type_erasure::unchecked_call(f BOOST_TYPE_ERASURE_FORWARD_ARGS(N, U, arg));
 }
 
 #endif
 
+#undef RREF
+#undef BOOST_TYPE_ERASURE_FORWARD_ARGS
+#undef BOOST_TYPE_ERASURE_FORWARD_ARGS_I
+
 #undef BOOST_TYPE_ERASURE_GET_TABLE
 #undef BOOST_TYPE_ERASURE_CONVERT_ARG
 #undef N

Modified: sandbox/type_erasure/boost/type_erasure/callable.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/callable.hpp (original)
+++ sandbox/type_erasure/boost/type_erasure/callable.hpp 2013-02-22 21:23:58 EST (Fri, 22 Feb 2013)
@@ -56,14 +56,14 @@
 }
 
 #if defined(BOOST_TYPE_ERASURE_DOXYGEN)
-#elif !defined(BOOST_NO_VARIADIC_TEMPLATES)
+#elif !defined(BOOST_NO_VARIADIC_TEMPLATES) && !defined(BOOST_NO_RVALUE_REFERENCES)
 
 template<class R, class... T, class F>
 struct callable<R(T...), F>
 {
     static R apply(F& f, T... arg)
     {
- return f(arg...);
+ return f(std::forward<T>(arg)...);
     }
 };
 
@@ -72,7 +72,7 @@
 {
     static void apply(F& f, T... arg)
     {
- f(arg...);
+ f(std::forward<T>(arg)...);
     }
 };
 
@@ -93,7 +93,8 @@
     typename ::boost::type_erasure::rebind_any<Base, R>::type
     operator()(typename ::boost::type_erasure::as_param<Base, T>::type... arg)
     {
- return ::boost::type_erasure::call(callable<R(T...), F>(), *this, arg...);
+ return ::boost::type_erasure::call(callable<R(T...), F>(), *this,
+ ::std::forward<typename ::boost::type_erasure::as_param<Base, T>::type>(arg)...);
     }
 };
 
@@ -114,7 +115,8 @@
     typename ::boost::type_erasure::rebind_any<Base, R>::type operator()(
         typename ::boost::type_erasure::as_param<Base, T>::type... arg) const
     {
- return ::boost::type_erasure::call(callable<R(T...), const F>(), *this, arg...);
+ return ::boost::type_erasure::call(callable<R(T...), const F>(), *this,
+ ::std::forward<typename ::boost::type_erasure::as_param<Base, T>::type>(arg)...);
     }
 };
 
@@ -141,7 +143,8 @@
     typename ::boost::type_erasure::rebind_any<Base, R>::type
     operator()(typename ::boost::type_erasure::as_param<Base, T>::type... arg)
     {
- return ::boost::type_erasure::call(callable<R(T...), F>(), *this, arg...);
+ return ::boost::type_erasure::call(callable<R(T...), F>(), *this,
+ ::std::forward<typename ::boost::type_erasure::as_param<Base, T>::type>(arg)...);
     }
 };
 
@@ -168,7 +171,8 @@
     typename ::boost::type_erasure::rebind_any<Base, R>::type
     operator()(typename ::boost::type_erasure::as_param<Base, T>::type... arg) const
     {
- return ::boost::type_erasure::call(callable<R(T...), const F>(), *this, arg...);
+ return ::boost::type_erasure::call(callable<R(T...), const F>(), *this,
+ ::std::forward<typename ::boost::type_erasure::as_param<Base, T>::type>(arg)...);
     }
 };
 
@@ -209,12 +213,20 @@
 #define BOOST_TYPE_ERASURE_REBIND(z, n, data)\
     typename ::boost::type_erasure::as_param<Base, BOOST_PP_CAT(T, n)>::type BOOST_PP_CAT(arg, n)
 
+#ifdef BOOST_NO_RVALUE_REFERENCES
+#define BOOST_TYPE_ERASURE_FORWARD(z, n, data) BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 1, data), n)
+#define BOOST_TYPE_ERASURE_FORWARD_REBIND(z, n, data) BOOST_PP_CAT(arg, n)
+#else
+#define BOOST_TYPE_ERASURE_FORWARD(z, n, data) ::std::forward<BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 0, data), n)>(BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 1, data), n))
+#define BOOST_TYPE_ERASURE_FORWARD_REBIND(z, n, data) ::std::forward<typename ::boost::type_erasure::as_param<Base, BOOST_PP_CAT(T, n)>::type>(BOOST_PP_CAT(arg, n))
+#endif
+
 template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T), class F>
 struct callable<R(BOOST_PP_ENUM_PARAMS(N, T)), F>
 {
     static R apply(F& f BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, T, arg))
     {
- return f(BOOST_PP_ENUM_PARAMS(N, arg));
+ return f(BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_FORWARD, (T, arg)));
     }
 };
 
@@ -223,7 +235,7 @@
 {
     static void apply(F& f BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, T, arg))
     {
- f(BOOST_PP_ENUM_PARAMS(N, arg));
+ f(BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_FORWARD, (T, arg)));
     }
 };
 
@@ -251,7 +263,7 @@
     {
         return ::boost::type_erasure::call(
             callable<R(BOOST_PP_ENUM_PARAMS(N, T)), F>(),
- *this BOOST_PP_ENUM_TRAILING_PARAMS(N, arg));
+ *this BOOST_PP_ENUM_TRAILING(N, BOOST_TYPE_ERASURE_FORWARD_REBIND, ~));
     }
 };
 
@@ -279,7 +291,7 @@
     {
         return ::boost::type_erasure::call(
             callable<R(BOOST_PP_ENUM_PARAMS(N, T)), const F>(),
- *this BOOST_PP_ENUM_TRAILING_PARAMS(N, arg));
+ *this BOOST_PP_ENUM_TRAILING(N, BOOST_TYPE_ERASURE_FORWARD_REBIND, ~));
     }
 };
 
@@ -308,7 +320,7 @@
     {
         return ::boost::type_erasure::call(
             callable<R(BOOST_PP_ENUM_PARAMS(N, T)), F>(),
- *this BOOST_PP_ENUM_TRAILING_PARAMS(N, arg));
+ *this BOOST_PP_ENUM_TRAILING(N, BOOST_TYPE_ERASURE_FORWARD_REBIND, ~));
     }
 };
 
@@ -337,7 +349,7 @@
     {
         return ::boost::type_erasure::call(
             callable<R(BOOST_PP_ENUM_PARAMS(N, T)), const F>(),
- *this BOOST_PP_ENUM_TRAILING_PARAMS(N, arg));
+ *this BOOST_PP_ENUM_TRAILING(N, BOOST_TYPE_ERASURE_FORWARD_REBIND, ~));
     }
 };
 

Modified: sandbox/type_erasure/boost/type_erasure/check_match.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/check_match.hpp (original)
+++ sandbox/type_erasure/boost/type_erasure/check_match.hpp 2013-02-22 21:23:58 EST (Fri, 22 Feb 2013)
@@ -90,7 +90,7 @@
 
 #else
 
-#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+#if !defined(BOOST_NO_VARIADIC_TEMPLATES) && !defined(BOOST_NO_RVALUE_REFERENCES)
 
 namespace detail {
 
@@ -125,7 +125,7 @@
 bool check_match(
     const ::boost::type_erasure::binding<Concept>& table,
     const Op&,
- U&... arg)
+ U&&... arg)
 {
 
     return ::boost::type_erasure::detail::check_table(
@@ -140,7 +140,7 @@
>
 bool check_match(
     const Op&,
- U&... arg)
+ U&&... arg)
 {
     const ::boost::type_erasure::binding<
         typename ::boost::type_erasure::detail::extract_concept<
@@ -219,6 +219,12 @@
 
 }
 
+#ifdef BOOST_NO_RVALUE_REFERENCES
+#define RREF &
+#else
+#define RREF &&
+#endif
+
 template<
     class Concept,
     class Op
@@ -227,7 +233,7 @@
 bool check_match(
     const ::boost::type_erasure::binding<Concept>& table,
     const Op&
- BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, & arg))
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, RREF arg))
 {
 
     return ::boost::type_erasure::detail::BOOST_PP_CAT(check_table, N)(
@@ -244,7 +250,7 @@
>
 bool check_match(
     const Op&
- BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, & arg))
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, RREF arg))
 {
     const ::boost::type_erasure::binding<
         typename ::boost::type_erasure::detail::BOOST_PP_CAT(do_extract_concept, N)<
@@ -257,6 +263,7 @@
         BOOST_PP_ENUM_TRAILING_PARAMS(N, arg));
 }
 
+#undef RREF
 #undef BOOST_TYPE_ERASURE_CHECK_TABLE
 #undef N
 

Modified: sandbox/type_erasure/boost/type_erasure/detail/adapt_to_vtable.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/detail/adapt_to_vtable.hpp (original)
+++ sandbox/type_erasure/boost/type_erasure/detail/adapt_to_vtable.hpp 2013-02-22 21:23:58 EST (Fri, 22 Feb 2013)
@@ -213,11 +213,25 @@
 #else
 
 #define N BOOST_PP_ITERATION()
+
+#ifndef BOOST_NO_RVALUE_REFERENCES
+
+#define BOOST_TYPE_ERASURE_EXTRACT(z, n, data) \
+ ::boost::type_erasure::detail::extract< \
+ typename traits:: \
+ BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(n)), _type) \
+ >(std::forward<BOOST_PP_CAT(T, n)>(BOOST_PP_CAT(arg, n)))
+
+#else
+
 #define BOOST_TYPE_ERASURE_EXTRACT(z, n, data) \
     ::boost::type_erasure::detail::extract< \
         typename traits:: \
         BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(n)), _type) \
>(BOOST_PP_CAT(arg, n))
+
+#endif
+
 #define BOOST_TYPE_ERASURE_REPLACE_PARAM(z, n, data) \
     typename ::boost::type_erasure::detail::replace_param_for_vtable< \
         BOOST_PP_CAT(T, n)>::type

Modified: sandbox/type_erasure/boost/type_erasure/detail/check_call.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/detail/check_call.hpp (original)
+++ sandbox/type_erasure/boost/type_erasure/detail/check_call.hpp 2013-02-22 21:23:58 EST (Fri, 22 Feb 2013)
@@ -43,7 +43,7 @@
 };
 
 template<class T>
-struct qualified_placeholder<T, typename T::_boost_type_erasure_is_any>
+struct qualified_placeholder<T&, typename T::_boost_type_erasure_is_any>
 {
     typedef typename ::boost::type_erasure::placeholder_of<T>::type placeholder;
     typedef typename ::boost::remove_reference<placeholder>::type unref;
@@ -54,26 +54,58 @@
     typedef typename ::boost::mpl::if_< ::boost::is_reference<placeholder>,
         unref,
         add_const
+ >::type& type;
+};
+
+#ifndef BOOST_NO_RVALUE_REFERENCES
+
+template<class T>
+struct qualified_placeholder<T&&, typename T::_boost_type_erasure_is_any>
+{
+ typedef typename ::boost::type_erasure::placeholder_of<T>::type placeholder;
+ typedef typename ::boost::remove_reference<placeholder>::type unref;
+ typedef typename ::boost::mpl::if_< ::boost::is_reference<placeholder>,
+ unref&,
+ unref&&
>::type type;
 };
 
+#endif
+
 template<class P, class A>
 struct check_placeholder_arg_impl : ::boost::mpl::false_ {};
 
 template<class P>
-struct check_placeholder_arg_impl<P, P> : ::boost::mpl::true_ {};
+struct check_placeholder_arg_impl<P, P&> : ::boost::mpl::true_ {};
+
+template<class P>
+struct check_placeholder_arg_impl<P, const P&> : ::boost::mpl::true_ {};
+
+#ifndef BOOST_NO_RVALUE_REFERENCES
 
 template<class P>
-struct check_placeholder_arg_impl<P, const P> : ::boost::mpl::true_ {};
+struct check_placeholder_arg_impl<P, P&&> : ::boost::mpl::true_ {};
+
+#endif
 
 template<class P>
-struct check_placeholder_arg_impl<P&, P> : ::boost::mpl::true_ {};
+struct check_placeholder_arg_impl<P&, P&> : ::boost::mpl::true_ {};
 
 template<class P>
-struct check_placeholder_arg_impl<const P&, P> : ::boost::mpl::true_ {};
+struct check_placeholder_arg_impl<const P&, P&> : ::boost::mpl::true_ {};
 
 template<class P>
-struct check_placeholder_arg_impl<const P&, const P> : ::boost::mpl::true_ {};
+struct check_placeholder_arg_impl<const P&, const P&> : ::boost::mpl::true_ {};
+
+#ifndef BOOST_NO_RVALUE_REFERENCES
+
+template<class P>
+struct check_placeholder_arg_impl<const P&, P&&> : ::boost::mpl::true_ {};
+
+template<class P>
+struct check_placeholder_arg_impl<P&&, P&&> : ::boost::mpl::true_ {};
+
+#endif
 
 template<class P, class Arg>
 struct check_placeholder_arg :
@@ -93,7 +125,7 @@
>::type
>,
         ::boost::type_erasure::detail::check_placeholder_arg<FormalArg, ActualArg>,
- ::boost::is_convertible<ActualArg&, FormalArg>
+ ::boost::is_convertible<ActualArg, FormalArg>
>::type type;
 };
 
@@ -126,7 +158,7 @@
     BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)
     BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
>
-struct check_call<R(BOOST_PP_ENUM_PARAMS(N, T)), void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, &u))> {
+struct check_call<R(BOOST_PP_ENUM_PARAMS(N, T)), void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, u))> {
     typedef ::boost::mpl::true_ type0;
     BOOST_PP_REPEAT(N, BOOST_TYPE_ERASURE_CHECK_ARG, ~)
     typedef BOOST_PP_CAT(type, N) type;

Modified: sandbox/type_erasure/boost/type_erasure/detail/extract_concept.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/detail/extract_concept.hpp (original)
+++ sandbox/type_erasure/boost/type_erasure/detail/extract_concept.hpp 2013-02-22 21:23:58 EST (Fri, 22 Feb 2013)
@@ -51,7 +51,7 @@
                 typename ::boost::remove_reference<T>::type
>::type
>,
- ::boost::type_erasure::concept_of<U>,
+ ::boost::type_erasure::concept_of<typename ::boost::remove_reference<U>::type>,
         ::boost::mpl::identity<void>
>::type type;
 };

Modified: sandbox/type_erasure/boost/type_erasure/detail/storage.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/detail/storage.hpp (original)
+++ sandbox/type_erasure/boost/type_erasure/detail/storage.hpp 2013-02-22 21:23:58 EST (Fri, 22 Feb 2013)
@@ -25,9 +25,19 @@
     void* data;
 };
 
+
+#ifndef BOOST_NO_RVALUE_REFERENCES
+
+template<class T>
+T extract(T arg) { return std::forward<T>(arg); }
+
+#else
+
 template<class T>
 T extract(T arg) { return arg; }
 
+#endif
+
 template<class T>
 T extract(storage& arg)
 {
@@ -40,6 +50,16 @@
     return *static_cast<const typename ::boost::remove_reference<T>::type*>(arg.data);
 }
 
+#ifndef BOOST_NO_RVALUE_REFERENCES
+
+template<class T>
+T extract(storage&& arg)
+{
+ return static_cast<T>(*static_cast<typename ::boost::remove_reference<T>::type*>(arg.data));
+}
+
+#endif
+
 }
 }
 }

Modified: sandbox/type_erasure/boost/type_erasure/require_match.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/require_match.hpp (original)
+++ sandbox/type_erasure/boost/type_erasure/require_match.hpp 2013-02-22 21:23:58 EST (Fri, 22 Feb 2013)
@@ -60,7 +60,7 @@
 
 #else
 
-#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+#if !defined(BOOST_NO_VARIADIC_TEMPLATES) && !defined(BOOST_NO_RVALUE_REFERENCES)
 
 namespace detail {
 
@@ -69,9 +69,9 @@
     ::boost::mpl::true_,
     const ::boost::type_erasure::binding<Concept>& table,
     const Op& op,
- U&... arg)
+ U&&... arg)
 {
- if(!::boost::type_erasure::check_match(table, op, arg...)) {
+ if(!::boost::type_erasure::check_match(table, op, std::forward<U>(arg)...)) {
         BOOST_THROW_EXCEPTION(::boost::type_erasure::bad_function_call());
     }
 }
@@ -81,16 +81,16 @@
     ::boost::mpl::false_,
     const ::boost::type_erasure::binding<Concept>&,
     const Op&,
- U&...)
+ U&&...)
 {}
 
 template<class Op, class... U>
 void require_match_impl(
     ::boost::mpl::true_,
     const Op& op,
- U&... arg)
+ U&&... arg)
 {
- if(!::boost::type_erasure::check_match(op, arg...)) {
+ if(!::boost::type_erasure::check_match(op, ::std::forward<U>(arg)...)) {
         BOOST_THROW_EXCEPTION(::boost::type_erasure::bad_function_call());
     }
 }
@@ -99,7 +99,7 @@
 void require_match_impl(
     ::boost::mpl::false_,
     const Op&,
- U&...)
+ U&&...)
 {}
 
 }
@@ -108,23 +108,23 @@
 void require_match(
     const ::boost::type_erasure::binding<Concept>& table,
     const Op& op,
- U&... arg)
+ U&&... arg)
 {
     ::boost::type_erasure::is_relaxed<Concept> cond;
- ::boost::type_erasure::detail::require_match_impl(cond, table, op, arg...);
+ ::boost::type_erasure::detail::require_match_impl(cond, table, op, ::std::forward<U>(arg)...);
 }
 
 template<class Op, class... U>
 void require_match(
     const Op& op,
- U&... arg)
+ U&&... arg)
 {
     ::boost::type_erasure::is_relaxed<
         typename ::boost::type_erasure::detail::extract_concept<
             typename ::boost::type_erasure::detail::get_signature<Op>::type,
             U...>::type
> cond;
- ::boost::type_erasure::detail::require_match_impl(cond, op, arg...);
+ ::boost::type_erasure::detail::require_match_impl(cond, op, ::std::forward<U>(arg)...);
 }
 
 #else
@@ -146,6 +146,15 @@
 
 #define N BOOST_PP_ITERATION()
 
+#ifdef BOOST_NO_RVALUE_REFERENCES
+#define RREF &
+#define BOOST_TYPE_ERASURE_FORWARD_ARGS(N, X, x) BOOST_PP_ENUM_TRAILING_PARAMS(N, x)
+#else
+#define RREF &&
+#define BOOST_TYPE_ERASURE_FORWARD_ARGS_I(z, n, data) std::forward<BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 0, data), n)>(BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 1, data), n))
+#define BOOST_TYPE_ERASURE_FORWARD_ARGS(N, X, x) BOOST_PP_ENUM_TRAILING(N, BOOST_TYPE_ERASURE_FORWARD_ARGS_I, (X, x))
+#endif
+
 namespace detail {
 
 template<
@@ -157,10 +166,10 @@
     ::boost::mpl::true_,
     const ::boost::type_erasure::binding<Concept>& table,
     const Op& op
- BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, & arg))
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, RREF arg))
 {
     if(!::boost::type_erasure::check_match
- (table, op BOOST_PP_ENUM_TRAILING_PARAMS(N, arg))) {
+ (table, op BOOST_TYPE_ERASURE_FORWARD_ARGS(N, U, arg))) {
         BOOST_THROW_EXCEPTION(::boost::type_erasure::bad_function_call());
     }
 }
@@ -174,7 +183,7 @@
     ::boost::mpl::false_,
     const ::boost::type_erasure::binding<Concept>&,
     const Op&
- BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, & BOOST_PP_INTERCEPT))
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, RREF BOOST_PP_INTERCEPT))
 {}
 
 #if N != 0
@@ -186,10 +195,10 @@
 void require_match_impl(
     ::boost::mpl::true_,
     const Op& op
- BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, & arg))
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, RREF arg))
 {
     if(!::boost::type_erasure::check_match
- (op BOOST_PP_ENUM_TRAILING_PARAMS(N, arg))) {
+ (op BOOST_TYPE_ERASURE_FORWARD_ARGS(N, U, arg))) {
         BOOST_THROW_EXCEPTION(::boost::type_erasure::bad_function_call());
     }
 }
@@ -201,7 +210,7 @@
 void require_match_impl(
     ::boost::mpl::false_,
     const Op&
- BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, & BOOST_PP_INTERCEPT))
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, RREF BOOST_PP_INTERCEPT))
 {}
 
 #endif
@@ -216,11 +225,11 @@
 void require_match(
     const ::boost::type_erasure::binding<Concept>& table,
     const Op& op
- BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, & arg))
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, RREF arg))
 {
     ::boost::type_erasure::is_relaxed<Concept> cond;
     ::boost::type_erasure::detail::require_match_impl
- (cond, table, op BOOST_PP_ENUM_TRAILING_PARAMS(N, arg));
+ (cond, table, op BOOST_TYPE_ERASURE_FORWARD_ARGS(N, U, arg));
 }
 
 #if N != 0
@@ -231,7 +240,7 @@
>
 void require_match(
     const Op& op
- BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, & arg))
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, RREF arg))
 {
     ::boost::type_erasure::is_relaxed<
         typename ::boost::type_erasure::detail::BOOST_PP_CAT(do_extract_concept, N)<
@@ -239,11 +248,14 @@
         BOOST_PP_ENUM_PARAMS(N, U)>::type
> cond;
     ::boost::type_erasure::detail::require_match_impl
- (cond, op BOOST_PP_ENUM_TRAILING_PARAMS(N, arg));
+ (cond, op BOOST_TYPE_ERASURE_FORWARD_ARGS(N, U, arg));
 }
 
 #endif
-
+
+#undef RREF
+#undef BOOST_TYPE_ERASURE_FORWARD_ARGS
+#undef BOOST_TYPE_ERASURE_FORWARD_ARGS_I
 #undef N
 
 #endif

Modified: sandbox/type_erasure/libs/type_erasure/test/test_callable.cpp
==============================================================================
--- sandbox/type_erasure/libs/type_erasure/test/test_callable.cpp (original)
+++ sandbox/type_erasure/libs/type_erasure/test/test_callable.cpp 2013-02-22 21:23:58 EST (Fri, 22 Feb 2013)
@@ -375,3 +375,22 @@
     BOOST_MPL_ASSERT((boost::is_same<boost::result_of<const any<test_concept>(int)>::type, int>));
     BOOST_MPL_ASSERT((boost::is_same<boost::result_of<const any<test_concept>(any<test_concept, _a>)>::type, int>));
 }
+
+#ifndef BOOST_NO_RVALUE_REFERENCES
+
+int f_rv_value = 0;
+void f_rv(int&& i) { f_rv_value += i; }
+
+BOOST_AUTO_TEST_CASE(test_rvalue_int)
+{
+ typedef ::boost::mpl::vector<
+ common<>,
+ callable<void(int&&)>
+ > test_concept;
+ any<test_concept> f(&f_rv);
+
+ f(2);
+ BOOST_CHECK_EQUAL(f_rv_value, 2);
+}
+
+#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