Index: boost/functional/detail/forward_adaptor_detail.hpp =================================================================== --- boost/functional/detail/forward_adaptor_detail.hpp (revision 0) +++ boost/functional/detail/forward_adaptor_detail.hpp (revision 0) @@ -0,0 +1,56 @@ +/*============================================================================= + Copyright (c) 2012 Eric Niebler + + Use modification and distribution are 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). +==============================================================================*/ + +#ifndef BOOST_FUNCTIONAL_FORWARD_ADAPTER_DETAIL_HPP_INCLUDED +#define BOOST_FUNCTIONAL_FORWARD_ADAPTER_DETAIL_HPP_INCLUDED + +#include +#include + +namespace boost +{ + namespace detail + { + struct not_a_valid_type {}; + typedef not_a_valid_type (*pfn_vararg_t)(...); + + template< class Sig, class Result = BOOST_DEDUCED_TYPENAME boost::result_of< Sig >::type > + struct result_of_wrap + { + typedef Result type; + }; + + template< class Sig > + struct result_of_wrap< Sig, not_a_valid_type > + { }; + + template< class F > + struct vararg_function_wrapper + : F + { + using F::operator(); + operator pfn_vararg_t() const volatile; + vararg_function_wrapper(); + }; + + template< class F > + struct wrap_vararg_function + { + typedef vararg_function_wrapper< F > type; + }; + + template< class F > + struct wrap_vararg_function< F const > + { + typedef vararg_function_wrapper< F > const type; + }; + } +} + +#endif + Index: boost/functional/lightweight_forward_adapter.hpp =================================================================== --- boost/functional/lightweight_forward_adapter.hpp (revision 78260) +++ boost/functional/lightweight_forward_adapter.hpp (working copy) @@ -19,6 +19,7 @@ # include # include +# include # include # include @@ -153,13 +154,15 @@ struct lightweight_forward_adapter_impl : lightweight_forward_adapter_result { - inline typename boost::result_of< FC() >::type + typedef BOOST_DEDUCED_TYPENAME wrap_vararg_function< FC >::type WFC; + inline typename boost::result_of< WFC() >::type operator()() const { return static_cast(this)->target_function()(); } - inline typename boost::result_of< F() >::type + typedef BOOST_DEDUCED_TYPENAME wrap_vararg_function< F >::type WF; + inline typename boost::result_of< WF() >::type operator()() { return static_cast(this)->target_function()(); @@ -213,8 +216,9 @@ struct lightweight_forward_adapter_impl : lightweight_forward_adapter_result { + typedef BOOST_DEDUCED_TYPENAME wrap_vararg_function< F >::type WF; template< BOOST_PP_ENUM_PARAMS(N,typename T) > - inline typename boost::result_of< F(BOOST_PP_ENUM_BINARY_PARAMS(N, + inline typename result_of_wrap< WF(BOOST_PP_ENUM_BINARY_PARAMS(N, T,const& BOOST_PP_INTERCEPT)) >::type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT)); }; Index: boost/functional/forward_adapter.hpp =================================================================== --- boost/functional/forward_adapter.hpp (revision 78260) +++ boost/functional/forward_adapter.hpp (working copy) @@ -19,6 +19,7 @@ # include # include +# include # ifndef BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY # define BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY 6 @@ -147,13 +148,15 @@ template< class MD, class F, class FC > struct forward_adapter_impl { - inline typename boost::result_of< FC() >::type + typedef BOOST_DEDUCED_TYPENAME wrap_vararg_function< FC >::type WFC; + inline typename boost::result_of< WFC() >::type operator()() const { return static_cast(this)->target_function()(); } - inline typename boost::result_of< F() >::type + typedef BOOST_DEDUCED_TYPENAME wrap_vararg_function< F >::type WF; + inline typename boost::result_of< WF() >::type operator()() { return static_cast(this)->target_function()(); @@ -161,15 +164,15 @@ // closing brace gets generated by preprocessing code, below -# define BOOST_TMP_MACRO(tpl_params,arg_types,params,args) \ +# define BOOST_TMP_MACRO(tpl_params,arg_types,params,args) \ template< tpl_params > \ - inline typename boost::result_of< FC(arg_types) >::type \ + inline typename result_of_wrap< WFC(arg_types) >::type \ operator()(params) const \ { \ return static_cast(this)->target_function()(args); \ } \ template< tpl_params > \ - inline typename boost::result_of< F(arg_types)>::type \ + inline typename result_of_wrap< WF(arg_types)>::type \ operator()(params) \ { \ return static_cast(this)->target_function()(args); \ @@ -333,6 +336,8 @@ struct forward_adapter_impl : forward_adapter_impl { + typedef BOOST_DEDUCED_TYPENAME forward_adapter_impl::WF WF; + typedef BOOST_DEDUCED_TYPENAME forward_adapter_impl::WFC WFC; using forward_adapter_impl::operator(); # endif @@ -424,7 +429,7 @@ # if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1400)) template< BOOST_PP_ENUM_PARAMS(N,typename T) > - inline typename boost::result_of< FC(BOOST_PP_ENUM_PARAMS(N,PT)) + inline typename result_of_wrap< WFC(BOOST_PP_ENUM_PARAMS(N,PT)) >::type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,PT,a)) const { @@ -432,7 +437,7 @@ ->target_function()(BOOST_PP_ENUM_PARAMS(N,a)); } template< BOOST_PP_ENUM_PARAMS(N,typename T) > - inline typename boost::result_of< F(BOOST_PP_ENUM_PARAMS(N,PT)) + inline typename result_of_wrap< WF(BOOST_PP_ENUM_PARAMS(N,PT)) >::type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,PT,a)) { Index: libs/functional/forward/test/lightweight_forward_adapter.cpp =================================================================== --- libs/functional/forward/test/lightweight_forward_adapter.cpp (revision 78260) +++ libs/functional/forward/test/lightweight_forward_adapter.cpp (working copy) @@ -60,7 +60,10 @@ struct result< Self(int&,int const&) > { typedef long type; }; template - struct result< Self(int&,int&) > { typedef char type; }; + struct result< Self const(int&,int&) > { typedef int type; }; + + template + struct result< Self(int&,int&) > { typedef long type; }; }; enum { int_, long_, char_ }; @@ -90,9 +93,9 @@ result_of< f const (ref, cref) >::type, int >::value )); // lvalue,lvalue BOOST_TEST(( is_same< - result_of< f(ref, ref) >::type, char >::value )); + result_of< f(ref, ref) >::type, long >::value )); BOOST_TEST(( is_same< - result_of< f const (ref, ref) >::type, char >::value )); + result_of< f const (ref, ref) >::type, int >::value )); } { using boost::noncopyable; @@ -113,7 +116,7 @@ BOOST_TEST( type_of( func_c(x,1) ) == int_ ); BOOST_TEST( type_of( func_c2(x,1) ) == int_ ); BOOST_TEST( type_of( func_c_ref(x,1) ) == int_ ); - BOOST_TEST( type_of( func(x,x) ) == char_ ); + BOOST_TEST( type_of( func(x,x) ) == long_ ); BOOST_TEST( func(x,1) == -8 ); BOOST_TEST( func_ref(x,1) == -8 ); Index: libs/functional/forward/test/forward_adapter.cpp =================================================================== --- libs/functional/forward/test/forward_adapter.cpp (revision 78260) +++ libs/functional/forward/test/forward_adapter.cpp (working copy) @@ -60,7 +60,10 @@ struct result< Self(int&,int const&) > { typedef long type; }; template - struct result< Self(int&,int&) > { typedef char type; }; + struct result< Self const(int&,int&) > { typedef int type; }; + + template + struct result< Self(int&,int&) > { typedef long type; }; }; enum { int_, long_, char_ }; @@ -88,9 +91,9 @@ result_of< f const (int&, int const &) >::type, int >::value )); // lvalue,lvalue BOOST_TEST(( is_same< - result_of< f(int&, int&) >::type, char >::value )); + result_of< f(int&, int&) >::type, long >::value )); BOOST_TEST(( is_same< - result_of< f const (int&, int&) >::type, char >::value )); + result_of< f const (int&, int&) >::type, int >::value )); } { @@ -112,7 +115,7 @@ BOOST_TEST( type_of( func_c(x,1) ) == int_ ); BOOST_TEST( type_of( func_c2(x,1) ) == int_ ); BOOST_TEST( type_of( func_c_ref(x,1) ) == int_ ); - BOOST_TEST( type_of( func(x,x) ) == char_ ); + BOOST_TEST( type_of( func(x,x) ) == long_ ); BOOST_TEST( func(x,1) == -8 ); BOOST_TEST( func_ref(x,1) == -8 );