This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]