slightly modified implementation works around msvc 7.1/8.0 compiler bugs

[SVN r36668]
This commit is contained in:
Eric Niebler 2007-01-08 20:38:51 +00:00
parent 1950f292df
commit 63cde4d3fd
3 changed files with 35 additions and 14 deletions

View File

@ -21,21 +21,21 @@
template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
struct result_of<F(BOOST_RESULT_OF_ARGS)> struct result_of<F(BOOST_RESULT_OF_ARGS)>
: detail::result_of_impl<F, F(BOOST_RESULT_OF_ARGS)> {}; : detail::result_of_impl<F, F(BOOST_RESULT_OF_ARGS), (detail::has_result_type<F>::value)> {};
#endif #endif
namespace detail { namespace detail {
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
struct result_of_impl<R (*)(BOOST_RESULT_OF_ARGS), FArgs> struct result_of_impl<R (*)(BOOST_RESULT_OF_ARGS), FArgs, false>
{ {
typedef R type; typedef R type;
}; };
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
struct result_of_impl<R (&)(BOOST_RESULT_OF_ARGS), FArgs> struct result_of_impl<R (&)(BOOST_RESULT_OF_ARGS), FArgs, false>
{ {
typedef R type; typedef R type;
}; };
@ -47,7 +47,7 @@ template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
struct result_of_impl<R (T0::*) struct result_of_impl<R (T0::*)
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)), (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)),
FArgs> FArgs, false>
{ {
typedef R type; typedef R type;
}; };
@ -57,7 +57,7 @@ template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
struct result_of_impl<R (T0::*) struct result_of_impl<R (T0::*)
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)) (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T))
const, const,
FArgs> FArgs, false>
{ {
typedef R type; typedef R type;
}; };
@ -67,7 +67,7 @@ template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
struct result_of_impl<R (T0::*) struct result_of_impl<R (T0::*)
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)) (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T))
volatile, volatile,
FArgs> FArgs, false>
{ {
typedef R type; typedef R type;
}; };
@ -77,7 +77,7 @@ template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
struct result_of_impl<R (T0::*) struct result_of_impl<R (T0::*)
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)) (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T))
const volatile, const volatile,
FArgs> FArgs, false>
{ {
typedef R type; typedef R type;
}; };

View File

@ -29,28 +29,25 @@ namespace detail {
BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type) BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type)
template<typename F, typename FArgs, bool HasResultType> struct get_result_of; template<typename F, typename FArgs, bool HasResultType> struct result_of_impl;
template<typename F, typename FArgs> template<typename F, typename FArgs>
struct get_result_of<F, FArgs, true> struct result_of_impl<F, FArgs, true>
{ {
typedef typename F::result_type type; typedef typename F::result_type type;
}; };
template<typename F, typename FArgs> template<typename F, typename FArgs>
struct get_result_of<F, FArgs, false> struct result_of_impl<F, FArgs, false>
: F::template result<FArgs> : F::template result<FArgs>
{}; {};
template<typename F> template<typename F>
struct get_result_of<F, F(void), false> struct result_of_impl<F, F(void), false>
{ {
typedef void type; typedef void type;
}; };
template<typename F, typename FArgs>
struct result_of_impl : get_result_of<F, FArgs, (has_result_type<F>::value)> {};
} // end namespace detail } // end namespace detail
#define BOOST_PP_ITERATION_PARAMS_1 (3,(0,BOOST_RESULT_OF_NUM_ARGS,<boost/utility/detail/result_of_iterate.hpp>)) #define BOOST_PP_ITERATION_PARAMS_1 (3,(0,BOOST_RESULT_OF_NUM_ARGS,<boost/utility/detail/result_of_iterate.hpp>))

View File

@ -24,6 +24,24 @@ struct int_result_type_and_float_result_of
template<typename F> struct result { typedef float type; }; template<typename F> struct result { typedef float type; };
}; };
template<typename T>
struct int_result_type_template { typedef int result_type; };
template<typename T>
struct int_result_of_template
{
template<typename F> struct result;
template<typename This, typename That> struct result<This(That)> { typedef int type; };
};
template<typename T>
struct int_result_type_and_float_result_of_template
{
typedef int result_type;
template<typename F> struct result;
template<typename This, typename That> struct result<This(That)> { typedef float type; };
};
struct X {}; struct X {};
int main() int main()
@ -43,6 +61,12 @@ int main()
BOOST_STATIC_ASSERT((is_same<result_of<const int_result_of(double)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<const int_result_of(double)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of(void)>::type, void>::value)); BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of(void)>::type, void>::value));
BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of(char)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of(char)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_template<void>(float)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<int_result_of_template<void>(double)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<int_result_of_template<void>(void)>::type, void>::value));
BOOST_STATIC_ASSERT((is_same<result_of<const int_result_of_template<void>(double)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of_template<void>(void)>::type, void>::value));
BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_template<void>(char)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<func_ptr(char, float)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<func_ptr(char, float)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<func_ref(char, float)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<func_ref(char, float)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr(X,char)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr(X,char)>::type, int>::value));