2004-05-02 19:55:02 +00:00
// Boost result_of library
2004-07-25 02:29:29 +00:00
// Copyright Douglas Gregor 2004. Use, modification and
2004-05-02 19:55:02 +00:00
// distribution is subject to the Boost Software License, Version
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// For more information, see http://www.boost.org/libs/utility
# ifndef BOOST_RESULT_OF_HPP
# define BOOST_RESULT_OF_HPP
# include <boost/config.hpp>
2012-09-22 19:15:37 +00:00
# include <boost/preprocessor/cat.hpp>
# include <boost/preprocessor/iteration/iterate.hpp>
# include <boost/preprocessor/repetition/enum_params.hpp>
# include <boost/preprocessor/repetition/enum_trailing_params.hpp>
# include <boost/preprocessor/repetition/enum_binary_params.hpp>
# include <boost/preprocessor/repetition/enum_shifted_params.hpp>
# include <boost/preprocessor/facilities/intercept.hpp>
2004-05-02 19:55:02 +00:00
# include <boost/detail/workaround.hpp>
2004-09-02 15:41:37 +00:00
# include <boost/mpl/has_xxx.hpp>
2007-03-05 15:25:16 +00:00
# include <boost/mpl/if.hpp>
2012-09-22 19:15:37 +00:00
# include <boost/mpl/eval_if.hpp>
2007-03-05 15:25:16 +00:00
# include <boost/mpl/bool.hpp>
2012-09-22 19:15:37 +00:00
# include <boost/mpl/identity.hpp>
2008-05-09 22:08:46 +00:00
# include <boost/mpl/or.hpp>
2012-09-22 19:15:37 +00:00
# include <boost/type_traits/is_class.hpp>
2008-05-09 22:08:46 +00:00
# include <boost/type_traits/is_pointer.hpp>
# include <boost/type_traits/is_member_function_pointer.hpp>
2008-09-05 19:58:30 +00:00
# include <boost/type_traits/remove_cv.hpp>
2012-09-22 19:15:37 +00:00
# include <boost/type_traits/remove_reference.hpp>
2011-01-22 22:18:48 +00:00
# include <boost/utility/declval.hpp>
2012-09-19 23:10:08 +00:00
# include <boost/utility/enable_if.hpp>
2004-05-02 19:55:02 +00:00
# ifndef BOOST_RESULT_OF_NUM_ARGS
2011-05-06 19:55:35 +00:00
# define BOOST_RESULT_OF_NUM_ARGS 16
2004-05-02 19:55:02 +00:00
# endif
2012-04-11 00:28:33 +00:00
// 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>.
2013-07-03 22:14:27 +00:00
// The user can force the choice by defining BOOST_RESULT_OF_USE_DECLTYPE,
// 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)) || \
( 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.
2012-04-11 00:28:33 +00:00
# endif
# ifndef BOOST_RESULT_OF_USE_TR1
# ifndef BOOST_RESULT_OF_USE_DECLTYPE
2013-07-03 22:14:27 +00:00
# ifndef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK
# ifndef BOOST_NO_CXX11_DECLTYPE_N3276 // this implies !defined(BOOST_NO_CXX11_DECLTYPE)
# define BOOST_RESULT_OF_USE_DECLTYPE
# else
# define BOOST_RESULT_OF_USE_TR1
# endif
2012-04-11 00:28:33 +00:00
# endif
# endif
# endif
2004-05-02 19:55:02 +00:00
namespace boost {
template < typename F > struct result_of ;
2010-04-13 15:01:11 +00:00
template < typename F > struct tr1_result_of ; // a TR1-style implementation of result_of
2004-05-02 19:55:02 +00:00
2013-10-11 23:20:59 +00:00
# if !defined(BOOST_NO_SFINAE)
2004-05-02 19:55:02 +00:00
namespace detail {
BOOST_MPL_HAS_XXX_TRAIT_DEF ( result_type )
2014-04-23 15:54:27 -07:00
// Work around a nvcc bug by only defining has_result when it's needed.
# ifdef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK
2013-07-03 22:14:27 +00:00
BOOST_MPL_HAS_XXX_TEMPLATE_DEF ( result )
2014-04-23 15:54:27 -07:00
# endif
2013-07-03 22:14:27 +00:00
2010-04-13 15:01:11 +00:00
template < typename F , typename FArgs , bool HasResultType > struct tr1_result_of_impl ;
2012-09-19 23:10:08 +00:00
2013-07-03 22:14:27 +00:00
template < typename F > struct cpp0x_result_of ;
2012-09-26 18:47:08 +00:00
# ifdef BOOST_NO_SFINAE_EXPR
2012-09-22 19:15:37 +00:00
2013-02-17 23:56:10 +00:00
// There doesn't seem to be any other way to turn this off such that the presence of
// the user-defined operator,() below doesn't cause spurious warning all over the place,
// so unconditionally turn it off.
# if BOOST_MSVC
# pragma warning(disable: 4913) // user defined binary operator ',' exists but no overload could convert all operands, default built-in binary operator ',' used
# endif
2012-09-23 02:08:32 +00:00
struct result_of_private_type { } ;
struct result_of_weird_type {
friend result_of_private_type operator , ( result_of_private_type , result_of_weird_type ) ;
2012-09-22 19:15:37 +00:00
} ;
typedef char result_of_yes_type ; // sizeof(result_of_yes_type) == 1
typedef char ( & result_of_no_type ) [ 2 ] ; // sizeof(result_of_no_type) == 2
2012-09-28 08:47:35 +00:00
template < typename T >
result_of_no_type result_of_is_private_type ( T const & ) ;
2012-09-23 02:08:32 +00:00
result_of_yes_type result_of_is_private_type ( result_of_private_type ) ;
2012-09-22 19:15:37 +00:00
2012-09-23 01:11:00 +00:00
template < typename C >
struct result_of_callable_class : C {
result_of_callable_class ( ) ;
typedef result_of_private_type const & ( * pfn_t ) ( . . . ) ;
operator pfn_t ( ) const volatile ;
} ;
template < typename C >
struct result_of_wrap_callable_class {
typedef result_of_callable_class < C > type ;
2012-09-22 19:15:37 +00:00
} ;
2012-09-23 01:11:00 +00:00
template < typename C >
struct result_of_wrap_callable_class < C const > {
typedef result_of_callable_class < C > const type ;
2012-09-22 19:15:37 +00:00
} ;
2012-09-23 01:11:00 +00:00
template < typename C >
struct result_of_wrap_callable_class < C volatile > {
typedef result_of_callable_class < C > volatile type ;
2012-09-22 19:15:37 +00:00
} ;
2012-09-23 01:11:00 +00:00
template < typename C >
struct result_of_wrap_callable_class < C const volatile > {
typedef result_of_callable_class < C > const volatile type ;
2012-09-22 19:15:37 +00:00
} ;
2012-09-23 01:11:00 +00:00
template < typename C >
struct result_of_wrap_callable_class < C & > {
typedef typename result_of_wrap_callable_class < C > : : type & type ;
2012-09-22 19:15:37 +00:00
} ;
2012-09-19 23:10:08 +00:00
template < typename F , bool TestCallability = true > struct cpp0x_result_of_impl ;
2012-09-26 18:47:08 +00:00
# else // BOOST_NO_SFINAE_EXPR
2012-09-19 23:10:08 +00:00
template < typename T >
struct result_of_always_void
{
2012-09-22 19:15:37 +00:00
typedef void type ;
2012-09-19 23:10:08 +00:00
} ;
2012-09-22 19:15:37 +00:00
2012-09-19 23:10:08 +00:00
template < typename F , typename Enable = void > struct cpp0x_result_of_impl { } ;
2012-09-26 18:47:08 +00:00
# endif // BOOST_NO_SFINAE_EXPR
2004-05-02 19:55:02 +00:00
2007-01-24 06:44:20 +00:00
template < typename F >
struct result_of_void_impl
{
typedef void type ;
} ;
template < typename R >
struct result_of_void_impl < R ( * ) ( void ) >
{
typedef R type ;
} ;
template < typename R >
struct result_of_void_impl < R ( & ) ( void ) >
{
typedef R type ;
} ;
2008-09-05 19:58:30 +00:00
// Determine the return type of a function pointer or pointer to member.
template < typename F , typename FArgs >
struct result_of_pointer
2010-04-13 15:01:11 +00:00
: tr1_result_of_impl < typename remove_cv < F > : : type , FArgs , false > { } ;
2008-09-05 19:58:30 +00:00
2004-05-02 19:55:02 +00:00
template < typename F , typename FArgs >
2010-04-13 15:01:11 +00:00
struct tr1_result_of_impl < F , FArgs , true >
2004-05-02 19:55:02 +00:00
{
typedef typename F : : result_type type ;
} ;
2007-03-05 15:25:16 +00:00
template < typename FArgs >
struct is_function_with_no_args : mpl : : false_ { } ;
template < typename F >
struct is_function_with_no_args < F ( void ) > : mpl : : true_ { } ;
2004-05-02 19:55:02 +00:00
template < typename F , typename FArgs >
2007-03-05 15:25:16 +00:00
struct result_of_nested_result : F : : template result < FArgs >
2006-05-16 22:55:27 +00:00
{ } ;
2004-05-02 19:55:02 +00:00
2007-03-05 15:25:16 +00:00
template < typename F , typename FArgs >
2010-04-13 15:01:11 +00:00
struct tr1_result_of_impl < F , FArgs , false >
2007-03-05 15:25:16 +00:00
: mpl : : if_ < is_function_with_no_args < FArgs > ,
2009-05-20 19:19:00 +00:00
result_of_void_impl < F > ,
result_of_nested_result < F , FArgs > > : : type
2007-01-24 06:44:20 +00:00
{ } ;
2004-05-02 19:55:02 +00:00
} // end namespace detail
# define BOOST_PP_ITERATION_PARAMS_1 (3,(0,BOOST_RESULT_OF_NUM_ARGS,<boost / utility / detail / result_of_iterate.hpp>))
# include BOOST_PP_ITERATE()
2017-05-30 01:20:02 +03:00
#if 0
// inform dependency trackers, as they can't see through macro includes
# include <boost/utility/detail/result_of_iterate.hpp>
# endif
2004-05-06 17:29:54 +00:00
# else
2005-07-13 12:35:37 +00:00
# define BOOST_NO_RESULT_OF 1
2004-05-06 17:29:54 +00:00
# endif
2004-05-02 19:55:02 +00:00
2005-07-18 18:50:47 +00:00
}
2004-05-02 19:55:02 +00:00
# endif // BOOST_RESULT_OF_HPP