This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[libstdc++ patch] Fix ambiguity in calls to bind
- From: Douglas Gregor <doug dot gregor at gmail dot com>
- To: "libstdc++" <libstdc++ at gcc dot gnu dot org>,gcc-patches at gcc dot gnu dot org
- Date: Fri, 1 Apr 2005 10:26:51 -0500
- Subject: [libstdc++ patch] Fix ambiguity in calls to bind
A recent change to mainline GCC exposed an ambiguity in function template
partial ordering for tr1::bind. The compiler is right, so here's the
"obvious" fix.
Tested i686-pc-linux-gnu on mainline; no regressions. Okay for mainline?
This will also be needed on the 4.0 branch. Assuming all tests pass there,
okay for 4.0 branch?
Doug
005-04-01 Douglas Gregor <doug.gregor@gmail.com>
* include/tr1/functional (_Maybe_wrap_member_pointer): Wrap up
member pointers in _Mem_fn but let other function objects pass
through unchanged.
* include/tr1/functional_iterator (bind): Reduce number of bind()
overloads to two to eliminate ambiguities. Use
_Maybe_wrap_member_pointer to handle member pointers gracefully.
Index: include/tr1/functional
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/tr1/functional,v
retrieving revision 1.10
diff -c -3 -p -r1.10 functional
*** include/tr1/functional 1 Apr 2005 03:35:58 -0000 1.10
--- include/tr1/functional 1 Apr 2005 15:14:10 -0000
*************** namespace tr1
*** 661,666 ****
--- 661,694 ----
/**
* @if maint
+ * Maps member pointers into instances of _Mem_fn but leaves all
+ * other function objects untouched. Used by tr1::bind(). The
+ * primary template handles the non--member-pointer case.
+ * @endif
+ */
+ template<typename _Tp>
+ struct _Maybe_wrap_member_pointer
+ {
+ typedef _Tp type;
+ static const _Tp& __do_wrap(const _Tp& __x) { return __x; }
+ };
+
+ /**
+ * @if maint
+ * Maps member pointers into instances of _Mem_fn but leaves all
+ * other function objects untouched. Used by tr1::bind(). This
+ * partial specialization handles the member pointer case.
+ * @endif
+ */
+ template<typename _Tp, typename _Class>
+ struct _Maybe_wrap_member_pointer<_Tp _Class::*>
+ {
+ typedef _Mem_fn<_Tp _Class::*> type;
+ static type __do_wrap(_Tp _Class::* __pm) { return type(__pm); }
+ };
+
+ /**
+ * @if maint
* Type of the function object returned from bind().
* @endif
*/
Index: include/tr1/functional_iterate.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/tr1/functional_iterate.h,v
retrieving revision 1.3
diff -c -3 -p -r1.3 functional_iterate.h
*** include/tr1/functional_iterate.h 1 Apr 2005 03:35:58 -0000 1.3
--- include/tr1/functional_iterate.h 1 Apr 2005 15:14:11 -0000
*************** class _Bind_result<_Result, _Functor(_GL
*** 444,489 ****
#undef _GLIBCXX_BIND_REPEAT_HEADER
};
- // Handle member pointers
- template<typename _Tp, typename _Class _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
- inline _Bind<_Mem_fn<_Tp _Class::*>(_GLIBCXX_TEMPLATE_ARGS)>
- bind(_Tp _Class::* __pm _GLIBCXX_COMMA _GLIBCXX_PARAMS)
- {
- typedef _Bind<_Mem_fn<_Tp _Class::*>(_GLIBCXX_TEMPLATE_ARGS)> __result_type;
- return __result_type(_Mem_fn<_Tp _Class::*>(__pm)
- _GLIBCXX_COMMA _GLIBCXX_ARGS);
- }
-
- template<typename _Result, typename _Tp, typename _Class
- _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
- inline _Bind_result<_Result, _Mem_fn<_Tp _Class::*>(_GLIBCXX_TEMPLATE_ARGS)>
- bind(_Tp _Class::* __pm _GLIBCXX_COMMA _GLIBCXX_PARAMS)
- {
- typedef _Bind_result<_Result, _Mem_fn<_Tp _Class::*>(_GLIBCXX_TEMPLATE_ARGS)>
- __result_type;
- return __result_type(_Mem_fn<_Tp _Class::*>(__pm)
- _GLIBCXX_COMMA _GLIBCXX_ARGS);
- }
-
// Handle arbitrary function objects
template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
! inline _Bind<_Functor(_GLIBCXX_TEMPLATE_ARGS)>
bind(_Functor __f _GLIBCXX_COMMA _GLIBCXX_PARAMS)
{
! typedef _Bind<_Functor(_GLIBCXX_TEMPLATE_ARGS)> __result_type;
! return __result_type(__f _GLIBCXX_COMMA _GLIBCXX_ARGS);
}
template<typename _Result, typename _Functor
_GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
inline
! typename __enable_if<_Bind_result<_Result, _Functor(_GLIBCXX_TEMPLATE_ARGS)>,
! !is_member_pointer<_Functor>::value>::__type
bind(_Functor __f _GLIBCXX_COMMA _GLIBCXX_PARAMS)
{
! typedef _Bind_result<_Result, _Functor(_GLIBCXX_TEMPLATE_ARGS)>
__result_type;
! return __result_type(__f _GLIBCXX_COMMA _GLIBCXX_ARGS);
}
template<typename _Res, typename _Functor _GLIBCXX_COMMA
--- 444,477 ----
#undef _GLIBCXX_BIND_REPEAT_HEADER
};
// Handle arbitrary function objects
template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
! inline
! _Bind<typename _Maybe_wrap_member_pointer<_Functor>::type
! (_GLIBCXX_TEMPLATE_ARGS)>
bind(_Functor __f _GLIBCXX_COMMA _GLIBCXX_PARAMS)
{
! typedef _Maybe_wrap_member_pointer<_Functor> __maybe_type;
! typedef typename __maybe_type::type __functor_type;
! typedef _Bind<__functor_type(_GLIBCXX_TEMPLATE_ARGS)> __result_type;
! return __result_type(__maybe_type::__do_wrap(__f)
! _GLIBCXX_COMMA _GLIBCXX_ARGS);
}
template<typename _Result, typename _Functor
_GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
inline
! _Bind_result<_Result,
! typename _Maybe_wrap_member_pointer<_Functor>::type
! (_GLIBCXX_TEMPLATE_ARGS)>
bind(_Functor __f _GLIBCXX_COMMA _GLIBCXX_PARAMS)
{
! typedef _Maybe_wrap_member_pointer<_Functor> __maybe_type;
! typedef typename __maybe_type::type __functor_type;
! typedef _Bind_result<_Result, __functor_type(_GLIBCXX_TEMPLATE_ARGS)>
__result_type;
! return __result_type(__maybe_type::__do_wrap(__f)
! _GLIBCXX_COMMA _GLIBCXX_ARGS);
}
template<typename _Res, typename _Functor _GLIBCXX_COMMA