|
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