mirror of
https://github.com/boostorg/utility.git
synced 2025-05-09 15:04:00 +00:00
added new result_of mode that uses TR1 with a decltype fallback as suggested by Nathan Crookston; fixes #7753
[SVN r84949]
This commit is contained in:
parent
9baf33dd16
commit
15021632dc
@ -38,10 +38,25 @@ struct tr1_result_of<F(BOOST_RESULT_OF_ARGS)>
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef BOOST_RESULT_OF_USE_DECLTYPE
|
#ifdef BOOST_RESULT_OF_USE_DECLTYPE
|
||||||
|
|
||||||
// Uses declval following N3225 20.7.7.6 when F is not a pointer.
|
|
||||||
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||||
struct result_of<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
|
struct result_of<F(BOOST_RESULT_OF_ARGS)>
|
||||||
|
: detail::cpp0x_result_of<F(BOOST_RESULT_OF_ARGS)> { };
|
||||||
|
#endif // BOOST_RESULT_OF_USE_DECLTYPE
|
||||||
|
|
||||||
|
#ifdef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK
|
||||||
|
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||||
|
struct result_of<F(BOOST_RESULT_OF_ARGS)>
|
||||||
|
: mpl::if_<mpl::or_<detail::has_result_type<F>, detail::has_result<F> >,
|
||||||
|
tr1_result_of<F(BOOST_RESULT_OF_ARGS)>,
|
||||||
|
detail::cpp0x_result_of<F(BOOST_RESULT_OF_ARGS)> >::type { };
|
||||||
|
#endif // BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK
|
||||||
|
|
||||||
|
#if defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||||
|
struct cpp0x_result_of<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
|
||||||
: mpl::if_<
|
: mpl::if_<
|
||||||
is_member_function_pointer<F>
|
is_member_function_pointer<F>
|
||||||
, detail::tr1_result_of_impl<
|
, detail::tr1_result_of_impl<
|
||||||
@ -54,8 +69,6 @@ struct result_of<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
|
|||||||
>::type
|
>::type
|
||||||
{};
|
{};
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
#ifdef BOOST_NO_SFINAE_EXPR
|
#ifdef BOOST_NO_SFINAE_EXPR
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
@ -139,7 +152,7 @@ struct cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)),
|
|||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
#else // defined(BOOST_RESULT_OF_USE_DECLTYPE)
|
#else // defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)
|
||||||
|
|
||||||
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||||
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||||
|
@ -38,18 +38,27 @@
|
|||||||
|
|
||||||
// Use the decltype-based version of result_of by default if the compiler
|
// Use the decltype-based version of result_of by default if the compiler
|
||||||
// supports N3276 <http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2011/n3276.pdf>.
|
// supports N3276 <http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2011/n3276.pdf>.
|
||||||
// The user can force the choice by defining either BOOST_RESULT_OF_USE_DECLTYPE or
|
// The user can force the choice by defining BOOST_RESULT_OF_USE_DECLTYPE,
|
||||||
// BOOST_RESULT_OF_USE_TR1, but not both!
|
// BOOST_RESULT_OF_USE_TR1, or BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK but not more than one!
|
||||||
#if defined(BOOST_RESULT_OF_USE_DECLTYPE) && defined(BOOST_RESULT_OF_USE_TR1)
|
#if (defined(BOOST_RESULT_OF_USE_DECLTYPE) && defined(BOOST_RESULT_OF_USE_TR1)) || \
|
||||||
# error Both BOOST_RESULT_OF_USE_DECLTYPE and BOOST_RESULT_OF_USE_TR1 cannot be defined at the same time.
|
(defined(BOOST_RESULT_OF_USE_DECLTYPE) && defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)) || \
|
||||||
|
(defined(BOOST_RESULT_OF_USE_TR1) && defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK))
|
||||||
|
# error More than one of BOOST_RESULT_OF_USE_DECLTYPE, BOOST_RESULT_OF_USE_TR1 and \
|
||||||
|
BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK cannot be defined at the same time.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK) && defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE)
|
||||||
|
# error Cannot fallback to decltype if BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE is not defined.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef BOOST_RESULT_OF_USE_TR1
|
#ifndef BOOST_RESULT_OF_USE_TR1
|
||||||
# ifndef BOOST_RESULT_OF_USE_DECLTYPE
|
# ifndef BOOST_RESULT_OF_USE_DECLTYPE
|
||||||
# ifndef BOOST_NO_CXX11_DECLTYPE_N3276 // this implies !defined(BOOST_NO_CXX11_DECLTYPE)
|
# ifndef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK
|
||||||
# define BOOST_RESULT_OF_USE_DECLTYPE
|
# ifndef BOOST_NO_CXX11_DECLTYPE_N3276 // this implies !defined(BOOST_NO_CXX11_DECLTYPE)
|
||||||
# else
|
# define BOOST_RESULT_OF_USE_DECLTYPE
|
||||||
# define BOOST_RESULT_OF_USE_TR1
|
# else
|
||||||
|
# define BOOST_RESULT_OF_USE_TR1
|
||||||
|
# endif
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
@ -64,8 +73,12 @@ namespace detail {
|
|||||||
|
|
||||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type)
|
BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type)
|
||||||
|
|
||||||
|
BOOST_MPL_HAS_XXX_TEMPLATE_DEF(result)
|
||||||
|
|
||||||
template<typename F, typename FArgs, bool HasResultType> struct tr1_result_of_impl;
|
template<typename F, typename FArgs, bool HasResultType> struct tr1_result_of_impl;
|
||||||
|
|
||||||
|
template<typename F> struct cpp0x_result_of;
|
||||||
|
|
||||||
#ifdef BOOST_NO_SFINAE_EXPR
|
#ifdef BOOST_NO_SFINAE_EXPR
|
||||||
|
|
||||||
// There doesn't seem to be any other way to turn this off such that the presence of
|
// There doesn't seem to be any other way to turn this off such that the presence of
|
||||||
|
@ -5,6 +5,12 @@
|
|||||||
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
// Examples:
|
||||||
|
// To run the default test:
|
||||||
|
// $ cd libs/utility/test && bjam
|
||||||
|
// To test decltype on g++ 2.7:
|
||||||
|
// $ cd libs/utility/test && bjam cxxflags="-std=c++11 -D BOOST_RESULT_OF_USE_DECLTYPE"
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
|
|
||||||
// For more information, see http://www.boost.org/libs/utility
|
// For more information, see http://www.boost.org/libs/utility
|
||||||
@ -190,7 +196,7 @@ int main()
|
|||||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<volatile int_result_of_template<void>(void)>::type, void>::value));
|
BOOST_STATIC_ASSERT((is_same<tr1_result_of<volatile int_result_of_template<void>(void)>::type, void>::value));
|
||||||
|
|
||||||
// Prior to decltype, result_of could not deduce the return type
|
// Prior to decltype, result_of could not deduce the return type
|
||||||
// nullary function objects unless they exposed a result_type.
|
// of nullary function objects unless they exposed a result_type.
|
||||||
#if defined(BOOST_RESULT_OF_USE_DECLTYPE)
|
#if defined(BOOST_RESULT_OF_USE_DECLTYPE)
|
||||||
BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(void)>::type, int>::value));
|
BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(void)>::type, int>::value));
|
||||||
BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of(void)>::type, int>::value));
|
BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of(void)>::type, int>::value));
|
||||||
@ -273,7 +279,7 @@ int main()
|
|||||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<pf_t(int)>::type, int>::value));
|
BOOST_STATIC_ASSERT((is_same<tr1_result_of<pf_t(int)>::type, int>::value));
|
||||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<pf_t const(int)>::type,int>::value));
|
BOOST_STATIC_ASSERT((is_same<tr1_result_of<pf_t const(int)>::type,int>::value));
|
||||||
|
|
||||||
#if defined(BOOST_RESULT_OF_USE_DECLTYPE)
|
#if defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)
|
||||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(double)>::type, short>::value));
|
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(double)>::type, short>::value));
|
||||||
BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result(double)>::type, cv_overload_check<const short> >::value));
|
BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result(double)>::type, cv_overload_check<const short> >::value));
|
||||||
BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result(double)>::type, cv_overload_check<volatile short> >::value));
|
BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result(double)>::type, cv_overload_check<volatile short> >::value));
|
||||||
@ -301,7 +307,7 @@ int main()
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(BOOST_RESULT_OF_USE_DECLTYPE)
|
#if defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)
|
||||||
int i = 123;
|
int i = 123;
|
||||||
sfinae_test(sfinae_test_f, i);
|
sfinae_test(sfinae_test_f, i);
|
||||||
#endif // defined(BOOST_RESULT_OF_USE_DECLTYPE)
|
#endif // defined(BOOST_RESULT_OF_USE_DECLTYPE)
|
||||||
|
40
utility.htm
40
utility.htm
@ -259,6 +259,46 @@ typedef boost::result_of<
|
|||||||
represent the return type of
|
represent the return type of
|
||||||
<code>operator()</code> given a call expression.</p>
|
<code>operator()</code> given a call expression.</p>
|
||||||
|
|
||||||
|
<p>Additionally, <code>boost::result_of</code>
|
||||||
|
provides a third mode of operation, which some users
|
||||||
|
may find convenient. When
|
||||||
|
<code>BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK</code>
|
||||||
|
is defined, <code>boost::result_of</code> behaves as
|
||||||
|
follows. If the function object has a member
|
||||||
|
type <code>result_type</code> or member
|
||||||
|
template <code>result<></code>, then
|
||||||
|
<code>boost::result_of</code> will use the TR1
|
||||||
|
protocol. Otherwise,
|
||||||
|
<code>boost::result_of</code> will
|
||||||
|
use <code>decltype</code>. Using TR1 with
|
||||||
|
a <code>declytpe</code> fallback may workaround
|
||||||
|
certain problems at the cost of portability. For
|
||||||
|
example:
|
||||||
|
<ul>
|
||||||
|
<li>Deficient compiler: If your code
|
||||||
|
requires <code>boost::result_of</code> to work
|
||||||
|
with incomplete return types but your
|
||||||
|
compiler's <code>decltype</code> implementation
|
||||||
|
does not support incomplete return types, then you
|
||||||
|
can use the TR1 protocol as a workaround. Support
|
||||||
|
for incomplete return types was added late in the
|
||||||
|
C++11 standardization process
|
||||||
|
(see <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3276.pdf">N3276</a>)
|
||||||
|
and is not implemented by some compilers.</li>
|
||||||
|
|
||||||
|
<li>Deficient legacy code: If your existing TR1
|
||||||
|
function object advertises a different type than
|
||||||
|
the actual result type deduced
|
||||||
|
by <code>decltype</code>, then using TR1 with a
|
||||||
|
<code>decltype</code> fallback will allow you to
|
||||||
|
work with both your existing TR1 function objects
|
||||||
|
and new C++11 function object. This situation
|
||||||
|
could occur if your legacy function objects
|
||||||
|
misused the TR1 protocol. See the documentation on
|
||||||
|
known <a href="#result_of_tr1_diff">differences</a>
|
||||||
|
between <code>boost::result_of</code> and TR1.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<a name="BOOST_NO_RESULT_OF"></a>
|
<a name="BOOST_NO_RESULT_OF"></a>
|
||||||
<p>This implementation of <code>result_of</code>
|
<p>This implementation of <code>result_of</code>
|
||||||
requires class template partial specialization, the
|
requires class template partial specialization, the
|
||||||
|
Loading…
x
Reference in New Issue
Block a user