[result_of] msvc work-around -- TESTERS NEEDED

The following trivial use of boost::result_of fails on msvc-7.1 and msvc-8.0: #include <boost/utility/result_of.hpp> template<typename T> struct function { template<typename Sig> struct result; template<typename This, typename U> struct result<This(U)> { typedef U type; }; }; int main() { boost::result_of<function<void>(int)>::type i = 0; return 0; } The attached patch works around the problem. (Yes, I've reported this to Microsoft.) I've also added some additional test cases to catch this problem (see result_of_test.cpp attached). I've confirmed the tests pass on msvc-7.1, msvc-8.0, gcc-3.4, gcc-4.0 and gcc-4.1. The following compilers should also be tested, but I don't have access to them. Can anybody help out? gcc-3.3 cw-9.4 intel-* sun-5.8 qcc-* hp_cxx_* acc Any help is much appreciated. -- Eric Niebler Boost Consulting www.boost-consulting.com // Boost result_of library // Copyright Douglas Gregor 2003-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 #include <boost/utility/result_of.hpp> #include <utility> #include <boost/static_assert.hpp> #include <boost/type_traits/is_same.hpp> struct int_result_type { typedef int result_type; }; struct int_result_of { template<typename F> struct result { typedef int type; }; }; struct int_result_type_and_float_result_of { typedef int result_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 {}; int main() { using namespace boost; typedef int (*func_ptr)(float, double); typedef int (&func_ref)(float, double); typedef int (X::*mem_func_ptr)(float); typedef int (X::*mem_func_ptr_c)(float) const; typedef int (X::*mem_func_ptr_v)(float) volatile; typedef int (X::*mem_func_ptr_cv)(float) const volatile; BOOST_STATIC_ASSERT((is_same<result_of<int_result_type(float)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(double)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(void)>::type, void>::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<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_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_c(X,char)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_v(X,char)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_cv(X,char)>::type, int>::value)); return 0; } ? result_of_patch.txt Index: result_of.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/utility/result_of.hpp,v retrieving revision 1.7 diff -b -d -u -r1.7 result_of.hpp --- result_of.hpp 16 May 2006 22:55:27 -0000 1.7 +++ result_of.hpp 7 Jan 2007 05:16:46 -0000 @@ -29,28 +29,25 @@ 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> -struct get_result_of<F, FArgs, true> +struct result_of_impl<F, FArgs, true> { typedef typename F::result_type type; }; template<typename F, typename FArgs> -struct get_result_of<F, FArgs, false> +struct result_of_impl<F, FArgs, false> : F::template result<FArgs> {}; template<typename F> -struct get_result_of<F, F(void), false> +struct result_of_impl<F, F(void), false> { 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 #define BOOST_PP_ITERATION_PARAMS_1 (3,(0,BOOST_RESULT_OF_NUM_ARGS,<boost/utility/detail/result_of_iterate.hpp>)) Index: detail/result_of_iterate.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/utility/detail/result_of_iterate.hpp,v retrieving revision 1.3 diff -b -d -u -r1.3 result_of_iterate.hpp --- detail/result_of_iterate.hpp 16 May 2006 22:55:26 -0000 1.3 +++ detail/result_of_iterate.hpp 7 Jan 2007 05:16:46 -0000 @@ -21,21 +21,21 @@ template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> 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 namespace detail { template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) 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; }; template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) 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; }; @@ -47,7 +47,7 @@ BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> struct result_of_impl<R (T0::*) (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)), - FArgs> + FArgs, false> { typedef R type; }; @@ -57,7 +57,7 @@ struct result_of_impl<R (T0::*) (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)) const, - FArgs> + FArgs, false> { typedef R type; }; @@ -67,7 +67,7 @@ struct result_of_impl<R (T0::*) (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)) volatile, - FArgs> + FArgs, false> { typedef R type; }; @@ -77,7 +77,7 @@ struct result_of_impl<R (T0::*) (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)) const volatile, - FArgs> + FArgs, false> { typedef R type; };

Hello Eric, Sunday, January 7, 2007, 8:31:10 AM, you wrote:
The following trivial use of boost::result_of fails on msvc-7.1 and msvc-8.0:
#include <boost/utility/result_of.hpp>
template<typename T> struct function { template<typename Sig> struct result;
template<typename This, typename U> struct result<This(U)> { typedef U type; }; };
int main() { boost::result_of<function<void>(int)>::type i = 0; return 0; }
The attached patch works around the problem. (Yes, I've reported this to Microsoft.) I've also added some additional test cases to catch this problem (see result_of_test.cpp attached).
I've confirmed the tests pass on msvc-7.1, msvc-8.0, gcc-3.4, gcc-4.0 and gcc-4.1. The following compilers should also be tested, but I don't have access to them. Can anybody help out?
gcc-3.3 cw-9.4 intel-* sun-5.8 qcc-* hp_cxx_* acc
Any help is much appreciated.
I've tried Intel C++ Compiler 9.1 for Windows (9.1.033) on Boost head repository. The test above compiles and passes both with and without the patch. -- Best regards, Andrey mailto:andysem@mail.ru

On Jan 7, 2007, at 12:31 AM, Eric Niebler wrote:
The attached patch works around the problem. (Yes, I've reported this to Microsoft.) I've also added some additional test cases to catch this problem (see result_of_test.cpp attached).
The patch looks good... go ahead and commit. Cheers, Doug

Doug Gregor wrote:
On Jan 7, 2007, at 12:31 AM, Eric Niebler wrote:
The attached patch works around the problem. (Yes, I've reported this to Microsoft.) I've also added some additional test cases to catch this problem (see result_of_test.cpp attached).
The patch looks good... go ahead and commit.
Done. -- Eric Niebler Boost Consulting www.boost-consulting.com

Thomas Witt wrote:
Eric Niebler wrote:
The following trivial use of boost::result_of fails on msvc-7.1 and msvc-8.0:
Is this for 1.34.0?
The fix went into HEAD. The problem exists on the RC branch as well, but IMO it's too risky a fix to make there. -- Eric Niebler Boost Consulting www.boost-consulting.com

Eric Niebler wrote:
Thomas Witt wrote:
Eric Niebler wrote:
The following trivial use of boost::result_of fails on msvc-7.1 and msvc-8.0: Is this for 1.34.0?
The fix went into HEAD. The problem exists on the RC branch as well, but IMO it's too risky a fix to make there.
AFAIK, non-patched 'result_of' requires a FunctionObject template to have a "base class" or "user-defined constructor". VC++ dislikes something like Aggregates? I'm not sure. Well, if a FunctionObject template doesn't have a base, I recommand to write an empty default-constructor; until patched version comes. (Note iterator adaptors need DefaultConstructible FunctionObject.) Regards, -- Shunsuke Sogame

Eric Niebler wrote:
Thomas Witt wrote:
Eric Niebler wrote:
The following trivial use of boost::result_of fails on msvc-7.1 and msvc-8.0: Is this for 1.34.0?
The fix went into HEAD. The problem exists on the RC branch as well, but IMO it's too risky a fix to make there.
OK, thanks! Thomas
-- Thomas Witt witt@acm.org

Hi, here is how it breaks. Let's start with the new bug: 1. typedef int (*func_ptr_0)(); BOOST_STATIC_ASSERT((is_same< result_of<func_ptr_0()>::type, int>::value)); ==> Ambiguous template specialization, this one got introduced by Eric's workaround 2. Although it seems to be the same problem, it's actually a different one (just a typo - see result_of_iterate.patch). This test fails with the RC 1.34 version, too: typedef int (X::*mem_func_ptr_0)(); BOOST_STATIC_ASSERT((is_same< result_of<mem_func_ptr_0(X)>::type, int>::value)); Regards, Tobias Index: boost/utility/detail/result_of_iterate.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/utility/detail/result_of_iterate.hpp,v retrieving revision 1.4 diff -u -r1.4 result_of_iterate.hpp --- boost/utility/detail/result_of_iterate.hpp 8 Jan 2007 20:38:51 -0000 1.4 +++ boost/utility/detail/result_of_iterate.hpp 13 Jan 2007 23:55:08 -0000 @@ -42,7 +42,7 @@ #undef BOOST_RESULT_OF_ARGS -#if BOOST_PP_ITERATION() > 1 && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) +#if BOOST_PP_ITERATION() >= 1 && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> struct result_of_impl<R (T0::*) // Boost result_of library // Copyright Douglas Gregor 2003-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 #include <boost/utility/result_of.hpp> #include <utility> #include <boost/static_assert.hpp> #include <boost/type_traits/is_same.hpp> struct int_result_type { typedef int result_type; }; struct int_result_of { template<typename F> struct result { typedef int type; }; }; struct int_result_type_and_float_result_of { typedef int result_type; template<typename F> struct result { typedef float type; }; }; struct X {}; int main() { using namespace boost; typedef int (*func_ptr)(float, double); typedef int (*func_ptr_0)(); typedef int (&func_ref)(float, double); typedef int (*func_ref_0)(); typedef int (X::*mem_func_ptr)(float); typedef int (X::*mem_func_ptr_0)(); typedef int (X::*mem_func_ptr_c)(float) const; typedef int (X::*mem_func_ptr_v)(float) volatile; typedef int (X::*mem_func_ptr_cv)(float) const volatile; BOOST_STATIC_ASSERT((is_same<result_of<int_result_type(float)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(double)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(void)>::type, void>::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<int_result_type_and_float_result_of(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_0()>::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_0()>::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_0(X)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_c(X,char)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_v(X,char)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_cv(X,char)>::type, int>::value)); return 0; }

Tobias Schwinger wrote:
Hi,
here is how it breaks.
Let's start with the new bug:
1.
typedef int (*func_ptr_0)();
BOOST_STATIC_ASSERT((is_same< result_of<func_ptr_0()>::type, int>::value));
==> Ambiguous template specialization, this one got introduced by Eric's workaround
Yep, you're right. I hope find a fix before I leave for vacation on Monday. If I can't and this is a serious issue for you, feel free to revert the change until I can patch this up.
2.
Although it seems to be the same problem, it's actually a different one (just a typo - see result_of_iterate.patch). This test fails with the RC 1.34 version, too:
typedef int (X::*mem_func_ptr_0)();
BOOST_STATIC_ASSERT((is_same< result_of<mem_func_ptr_0(X)>::type, int>::value));
I'll let Doug comment on this one. -- Eric Niebler Boost Consulting www.boost-consulting.com

Eric Niebler wrote:
Tobias Schwinger wrote:
Hi,
here is how it breaks.
Let's start with the new bug:
1.
typedef int (*func_ptr_0)();
BOOST_STATIC_ASSERT((is_same< result_of<func_ptr_0()>::type, int>::value));
==> Ambiguous template specialization, this one got introduced by Eric's workaround
Yep, you're right. I hope find a fix before I leave for vacation on Monday. If I can't and this is a serious issue for you, feel free to revert the change until I can patch this up.
2.
Although it seems to be the same problem, it's actually a different one (just a typo - see result_of_iterate.patch). This test fails with the RC 1.34 version, too:
typedef int (X::*mem_func_ptr_0)();
BOOST_STATIC_ASSERT((is_same< result_of<mem_func_ptr_0(X)>::type, int>::value));
I'll let Doug comment on this one.
The attached patch fixes both problems. Doug, should I commit (to HEAD)? Also see the new test (attached). -- Eric Niebler Boost Consulting www.boost-consulting.com ? boost/utility/result_of_patch.txt Index: boost/utility/result_of.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/utility/result_of.hpp,v retrieving revision 1.8 diff -b -d -u -r1.8 result_of.hpp --- boost/utility/result_of.hpp 8 Jan 2007 20:38:51 -0000 1.8 +++ boost/utility/result_of.hpp 14 Jan 2007 06:13:50 -0000 @@ -31,6 +31,24 @@ template<typename F, typename FArgs, bool HasResultType> struct result_of_impl; +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; +}; + template<typename F, typename FArgs> struct result_of_impl<F, FArgs, true> { @@ -44,9 +62,8 @@ template<typename F> struct result_of_impl<F, F(void), false> -{ - typedef void type; -}; + : result_of_void_impl<F> +{}; } // end namespace detail Index: boost/utility/detail/result_of_iterate.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/utility/detail/result_of_iterate.hpp,v retrieving revision 1.4 diff -b -d -u -r1.4 result_of_iterate.hpp --- boost/utility/detail/result_of_iterate.hpp 8 Jan 2007 20:38:51 -0000 1.4 +++ boost/utility/detail/result_of_iterate.hpp 14 Jan 2007 06:13:50 -0000 @@ -24,25 +24,27 @@ : detail::result_of_impl<F, F(BOOST_RESULT_OF_ARGS), (detail::has_result_type<F>::value)> {}; #endif +#undef BOOST_RESULT_OF_ARGS + +#if BOOST_PP_ITERATION() >= 1 + namespace detail { template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> -struct result_of_impl<R (*)(BOOST_RESULT_OF_ARGS), FArgs, false> +struct result_of_impl<R (*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), FArgs, false> { typedef R type; }; template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> -struct result_of_impl<R (&)(BOOST_RESULT_OF_ARGS), FArgs, false> +struct result_of_impl<R (&)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), FArgs, false> { typedef R type; }; -#undef BOOST_RESULT_OF_ARGS - -#if BOOST_PP_ITERATION() > 1 && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) +#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> struct result_of_impl<R (T0::*) @@ -84,3 +86,4 @@ #endif } +#endif // Boost result_of library // Copyright Douglas Gregor 2003-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 #include <boost/utility/result_of.hpp> #include <utility> #include <boost/static_assert.hpp> #include <boost/type_traits/is_same.hpp> struct int_result_type { typedef int result_type; }; struct int_result_of { template<typename F> struct result { typedef int type; }; }; struct int_result_type_and_float_result_of { typedef int result_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 {}; int main() { using namespace boost; typedef int (*func_ptr)(float, double); typedef int (&func_ref)(float, double); typedef int (*func_ptr_0)(); typedef int (&func_ref_0)(); typedef int (X::*mem_func_ptr)(float); typedef int (X::*mem_func_ptr_c)(float) const; typedef int (X::*mem_func_ptr_v)(float) volatile; typedef int (X::*mem_func_ptr_cv)(float) const volatile; typedef int (X::*mem_func_ptr_0)(); BOOST_STATIC_ASSERT((is_same<result_of<int_result_type(float)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(double)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(void)>::type, void>::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<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_ref(char, float)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<func_ptr_0()>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<func_ref_0()>::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_c(X,char)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_v(X,char)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_cv(X,char)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_0(X)>::type, int>::value)); return 0; }

Eric Niebler wrote:
Eric Niebler wrote:
Tobias Schwinger wrote:
<snip>
2.
Although it seems to be the same problem, it's actually a different one (just a typo - see result_of_iterate.patch). This test fails with the RC 1.34 version, too:
typedef int (X::*mem_func_ptr_0)();
BOOST_STATIC_ASSERT((is_same< result_of<mem_func_ptr_0(X)>::type, int>::value));
I'll let Doug comment on this one.
The attached patch fixes both problems. Doug, should I commit (to HEAD)? Also see the new test (attached).
...and No.2 is corrected in my copy of the RC branch - ready to fire. Just confirm. Regards, Tobias

On 1/14/07, Tobias Schwinger <tschwinger@isonews2.com> wrote:
Eric Niebler wrote:
Eric Niebler wrote: [snip] The attached patch fixes both problems. Doug, should I commit (to HEAD)? Also see the new test (attached).
...and No.2 is corrected in my copy of the RC branch - ready to fire. Just confirm.
Both fixes are okay for HEAD. If we're talking about a showstopper for the RC, then we need to get Thomas's permission before putting this fix in. Are we talking about a showstopper? Cheers, Doug

Doug Gregor wrote:
The attached patch fixes both problems. Doug, should I commit (to HEAD)? Also see the new test (attached).
...and No.2 is corrected in my copy of the RC branch - ready to fire. Just confirm.
Both fixes are okay for HEAD.
Only Eric's patch is required for the HEAD (it fixes both problems).
If we're talking about a showstopper for the RC, then we need to get Thomas's permission before putting this fix in.
That's why I put Thomas on the list of recipients.
Are we talking about a showstopper?
No (not for me, at least). It might not be too good of an idea to release with a bug in that basic of a component (and even a standardized one), still. Regards, Tobias

Hi, On Jan 16, 2007, at 2:03 PM, Tobias Schwinger wrote:
Doug Gregor wrote:
Are we talking about a showstopper?
No (not for me, at least).
It might not be too good of an idea to release with a bug in that basic of a component (and even a standardized one), still.
I've to admit that I am still in the dark as to how serious the problem is and what the patch for 1.34 would be. Any clarification would be appreciated. Thanks Thomas Thomas Witt witt@acm.org

Thomas Witt wrote:
Hi,
On Jan 16, 2007, at 2:03 PM, Tobias Schwinger wrote:
Doug Gregor wrote:
Are we talking about a showstopper? No (not for me, at least).
It might not be too good of an idea to release with a bug in that basic of a component (and even a standardized one), still.
I've to admit that I am still in the dark as to how serious the problem is
Using a pointer to a member function without parameters (except "this") with result_of causes a compile error. The problem obviously doesn't break any of our existing tests, but possibly non-existing ones. Four Boost libraries currently #include result_of.hpp: Parameter, PtrContainer, XPressive (HEAD only), and TR1 ('using boost::result_of').
and what the patch for 1.34 would be.
See attached files. Note that it might be overly careful (I don't have the Metrowerks compiler to verify whether repeating that Workaround is really needed). If it isn't needed, the first line changed by that patch (>= 1 instead of > 1) will be sufficient.
Any clarification would be appreciated.
HTH Regards, Tobias Index: libs/utility/test/result_of_test.cpp =================================================================== RCS file: /cvsroot/boost/boost/libs/utility/test/result_of_test.cpp,v retrieving revision 1.2 diff -u -r1.2 result_of_test.cpp --- libs/utility/test/result_of_test.cpp 25 Jul 2004 03:57:20 -0000 1.2 +++ libs/utility/test/result_of_test.cpp 14 Jan 2007 00:07:34 -0000 @@ -33,6 +33,7 @@ typedef int (*func_ptr)(float, double); typedef int (&func_ref)(float, double); typedef int (X::*mem_func_ptr)(float); + typedef int (X::*mem_func_ptr_0)(); typedef int (X::*mem_func_ptr_c)(float) const; typedef int (X::*mem_func_ptr_v)(float) volatile; typedef int (X::*mem_func_ptr_cv)(float) const volatile; @@ -46,6 +47,7 @@ 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<mem_func_ptr(X,char)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_0(X)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_c(X,char)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_v(X,char)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_cv(X,char)>::type, int>::value)); Index: boost/utility/detail/result_of_iterate.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/utility/detail/result_of_iterate.hpp,v retrieving revision 1.2 diff -u -r1.2 result_of_iterate.hpp --- boost/utility/detail/result_of_iterate.hpp 10 Aug 2004 13:57:30 -0000 1.2 +++ boost/utility/detail/result_of_iterate.hpp 17 Jan 2007 09:28:47 -0000 @@ -42,45 +42,46 @@ #undef BOOST_RESULT_OF_ARGS -#if BOOST_PP_ITERATION() > 1 && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) +#if BOOST_PP_ITERATION() >= 1 && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) + +// CWPro8 requires an argument in a function type specialization +#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3002)) && BOOST_PP_ITERATION() == 1 +# define BOOST_RESULT_OF_ARGS void +#else +# define BOOST_RESULT_OF_ARGS \ + BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T) +#endif + template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> -struct result_of<R (T0::*) - (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)), - FArgs> +struct result_of<R (T0::*)(BOOST_RESULT_OF_ARGS),FArgs> { typedef R type; }; template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> -struct result_of<R (T0::*) - (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)) - const, - FArgs> +struct result_of<R (T0::*)(BOOST_RESULT_OF_ARGS) const, FArgs> { typedef R type; }; template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> -struct result_of<R (T0::*) - (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)) - volatile, - FArgs> +struct result_of<R (T0::*)(BOOST_RESULT_OF_ARGS) volatile, FArgs> { typedef R type; }; template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> -struct result_of<R (T0::*) - (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)) - const volatile, - FArgs> +struct result_of<R (T0::*)(BOOST_RESULT_OF_ARGS) const volatile, FArgs> { typedef R type; }; + +#undef BOOST_RESULT_OF_ARGS + #endif }

Tobias Schwinger wrote:
Thomas Witt wrote:
Hi,
On Jan 16, 2007, at 2:03 PM, Tobias Schwinger wrote:
Doug Gregor wrote:
Are we talking about a showstopper? No (not for me, at least).
It might not be too good of an idea to release with a bug in that basic of a component (and even a standardized one), still.
I've to admit that I am still in the dark as to how serious the problem is
Using a pointer to a member function without parameters (except "this") with result_of causes a compile error.
The problem obviously doesn't break any of our existing tests, but possibly non-existing ones.
Four Boost libraries currently #include result_of.hpp: Parameter, PtrContainer, XPressive (HEAD only), and TR1 ('using boost::result_of').
and what the patch for 1.34 would be.
See attached files.
Note that it might be overly careful (I don't have the Metrowerks compiler to verify whether repeating that Workaround is really needed). If it isn't needed, the first line changed by that patch (>= 1 instead of > 1) will be sufficient.
Any clarification would be appreciated.
My 0.02 euros: it's too late to take this fix this for 1.34. No users have complained about it, it's a core library that other boost libraries depend on, there are subtle work-arounds in the code for broken compilers that could be disrupted by the change. It has the potential to further delay 1.34. -- Eric Niebler Boost Consulting www.boost-consulting.com

Eric Eric Niebler wrote:
My 0.02 euros: it's too late to take this fix this for 1.34. No users have complained about it, it's a core library that other boost libraries depend on, there are subtle work-arounds in the code for broken compilers that could be disrupted by the change. It has the potential to further delay 1.34.
Thanks for using a currency I am familiar with ;-). I do agree that no user complaints is a strong argument for keeping it out of 1.34. If complaints come up we know what to do. Lets try to play this one safe. Thomas -- Thomas Witt witt@acm.org

Tobias Schwinger wrote:
Thomas Witt wrote:
I've to admit that I am still in the dark as to how serious the problem is
Using a pointer to a member function without parameters (except "this") with result_of causes a compile error.
The problem obviously doesn't break any of our existing tests, but possibly non-existing ones.
Four Boost libraries currently #include result_of.hpp: Parameter, PtrContainer, XPressive (HEAD only), and TR1 ('using boost::result_of').
and what the patch for 1.34 would be.
Thanks a lot for the great summary Tobias, it makes my life so much easier. Thomas -- Thomas Witt witt@acm.org
participants (7)
-
Andrey Semashev
-
Doug Gregor
-
Doug Gregor
-
Eric Niebler
-
shunsuke
-
Thomas Witt
-
Tobias Schwinger