2012-05-10 00:45:30 -04:00
// Boost result_of library
// Copyright Douglas Gregor 2004. Use, modification and
// 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>
2013-01-13 17:38:19 -05: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>
2012-05-10 00:45:30 -04:00
# include <boost/detail/workaround.hpp>
# include <boost/mpl/has_xxx.hpp>
# include <boost/mpl/if.hpp>
2013-01-13 17:38:19 -05:00
# include <boost/mpl/eval_if.hpp>
2012-05-10 00:45:30 -04:00
# include <boost/mpl/bool.hpp>
2013-01-13 17:38:19 -05:00
# include <boost/mpl/identity.hpp>
2012-05-10 00:45:30 -04:00
# include <boost/mpl/or.hpp>
2013-01-13 17:38:19 -05:00
# include <boost/type_traits/is_class.hpp>
2012-05-10 00:45:30 -04:00
# include <boost/type_traits/is_pointer.hpp>
# include <boost/type_traits/is_member_function_pointer.hpp>
# include <boost/type_traits/remove_cv.hpp>
2013-01-13 17:38:19 -05:00
# include <boost/type_traits/remove_reference.hpp>
2012-05-10 00:45:30 -04:00
# include <boost/utility/declval.hpp>
2013-01-13 17:38:19 -05:00
# include <boost/utility/enable_if.hpp>
2012-05-10 00:45:30 -04:00
# ifndef BOOST_RESULT_OF_NUM_ARGS
2013-01-13 17:38:19 -05:00
# define BOOST_RESULT_OF_NUM_ARGS 16
# endif
// 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>.
// The user can force the choice by defining either BOOST_RESULT_OF_USE_DECLTYPE or
// BOOST_RESULT_OF_USE_TR1, but not both!
# 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.
# endif
# ifndef BOOST_RESULT_OF_USE_TR1
# ifndef BOOST_RESULT_OF_USE_DECLTYPE
2013-02-13 23:03:52 -05:00
# ifndef BOOST_NO_CXX11_DECLTYPE_N3276 // this implies !defined(BOOST_NO_CXX11_DECLTYPE)
2013-01-13 17:38:19 -05:00
# define BOOST_RESULT_OF_USE_DECLTYPE
# else
# define BOOST_RESULT_OF_USE_TR1
# endif
# endif
2012-05-10 00:45:30 -04:00
# endif
namespace boost {
template < typename F > struct result_of ;
template < typename F > struct tr1_result_of ; // a TR1-style implementation of result_of
# if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
namespace detail {
BOOST_MPL_HAS_XXX_TRAIT_DEF ( result_type )
template < typename F , typename FArgs , bool HasResultType > struct tr1_result_of_impl ;
2013-01-13 17:38:19 -05:00
# ifdef BOOST_NO_SFINAE_EXPR
2013-08-25 17:35:47 -04: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
2013-01-13 17:38:19 -05: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 ) ;
} ;
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
template < typename T >
result_of_no_type result_of_is_private_type ( T const & ) ;
result_of_yes_type result_of_is_private_type ( result_of_private_type ) ;
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 ;
} ;
template < typename C >
struct result_of_wrap_callable_class < C const > {
typedef result_of_callable_class < C > const type ;
} ;
template < typename C >
struct result_of_wrap_callable_class < C volatile > {
typedef result_of_callable_class < C > volatile type ;
} ;
template < typename C >
struct result_of_wrap_callable_class < C const volatile > {
typedef result_of_callable_class < C > const volatile type ;
} ;
template < typename C >
struct result_of_wrap_callable_class < C & > {
typedef typename result_of_wrap_callable_class < C > : : type & type ;
} ;
template < typename F , bool TestCallability = true > struct cpp0x_result_of_impl ;
# else // BOOST_NO_SFINAE_EXPR
template < typename T >
struct result_of_always_void
{
typedef void type ;
} ;
template < typename F , typename Enable = void > struct cpp0x_result_of_impl { } ;
# endif // BOOST_NO_SFINAE_EXPR
2012-05-10 00:45:30 -04: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 ;
} ;
// Determine the return type of a function pointer or pointer to member.
template < typename F , typename FArgs >
struct result_of_pointer
: tr1_result_of_impl < typename remove_cv < F > : : type , FArgs , false > { } ;
template < typename F , typename FArgs >
struct tr1_result_of_impl < F , FArgs , true >
{
typedef typename F : : result_type type ;
} ;
template < typename FArgs >
struct is_function_with_no_args : mpl : : false_ { } ;
template < typename F >
struct is_function_with_no_args < F ( void ) > : mpl : : true_ { } ;
template < typename F , typename FArgs >
struct result_of_nested_result : F : : template result < FArgs >
{ } ;
template < typename F , typename FArgs >
struct tr1_result_of_impl < F , FArgs , false >
: mpl : : if_ < is_function_with_no_args < FArgs > ,
result_of_void_impl < F > ,
result_of_nested_result < F , FArgs > > : : type
{ } ;
} // 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()
# else
# define BOOST_NO_RESULT_OF 1
# endif
}
# endif // BOOST_RESULT_OF_HPP