functional (_Maybe_wrap_member_pointer): Wrap up member pointers in _Mem_fn but let...
authorDouglas Gregor <doug.gregor@gmail.com>
Sat, 2 Apr 2005 02:02:29 +0000 (02:02 +0000)
committerDoug Gregor <dgregor@gcc.gnu.org>
Sat, 2 Apr 2005 02:02:29 +0000 (02:02 +0000)
2005-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.

From-SVN: r97428

libstdc++-v3/ChangeLog
libstdc++-v3/include/tr1/functional
libstdc++-v3/include/tr1/functional_iterate.h

index 9873fb170d92db570be82a4c62c5bbdc305ab938..8c4f0821f561654285fd162d0056d8978ddf6627 100644 (file)
@@ -1,3 +1,12 @@
+2005-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.
+       
 2005-04-01  Mark Mitchell  <mark@codesourcery.com>
 
        * testsuite/Makefile.am (noinst_PROGRAMS): Remove.
index ab811d1c8a6ee186a8cc27a6086af0da582b2407..abe92e3bf237f70b7fb87598eced8171607114c9 100644 (file)
@@ -659,6 +659,34 @@ namespace tr1
       { return __arg; }
     };
 
+  /**
+   *  @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().
index 0a1ccee94e87becca9a92673bbdfb77ec093d3f9..524f2d2be192418f0cdf6b652080a28e425477da 100644 (file)
@@ -444,46 +444,34 @@ class _Bind_result<_Result, _Functor(_GLIBCXX_TEMPLATE_ARGS)>
 #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)>
+inline
+_Bind<typename _Maybe_wrap_member_pointer<_Functor>::type
+        (_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);
+  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
-typename __enable_if<_Bind_result<_Result, _Functor(_GLIBCXX_TEMPLATE_ARGS)>,
-                     !is_member_pointer<_Functor>::value>::__type
+_Bind_result<_Result,
+             typename _Maybe_wrap_member_pointer<_Functor>::type
+               (_GLIBCXX_TEMPLATE_ARGS)>
 bind(_Functor __f _GLIBCXX_COMMA _GLIBCXX_PARAMS)
 {
-  typedef _Bind_result<_Result, _Functor(_GLIBCXX_TEMPLATE_ARGS)>
+  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(__f _GLIBCXX_COMMA _GLIBCXX_ARGS);
+  return __result_type(__maybe_type::__do_wrap(__f)
+                       _GLIBCXX_COMMA _GLIBCXX_ARGS);
 }
 
 template<typename _Res, typename _Functor _GLIBCXX_COMMA