Add support for ref-qualified functions to std::mem_fn
authorJonathan Wakely <jwakely@redhat.com>
Mon, 3 Nov 2014 02:55:32 +0000 (02:55 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Mon, 3 Nov 2014 02:55:32 +0000 (02:55 +0000)
PR libstdc++/57898
* include/std/functional (_Mem_fn_traits_base): New class template.
(_Mem_fn_traits): New class template with specializations for every
combination of cv-qualified and ref-qualified member function.
(_Mem_fn_base): New class template for all pointer to member function
types and partial specialization for pointer to member object types.
(_Mem_fn): Inherit from _Mem_fn_base.
* testsuite/20_util/function_objects/mem_fn/refqual.cc: New.

From-SVN: r217024

libstdc++-v3/ChangeLog
libstdc++-v3/include/std/functional
libstdc++-v3/testsuite/20_util/function_objects/mem_fn/refqual.cc [new file with mode: 0644]

index d24f3a3e9a589465e0e7a5994fe306f234ccf2b1..86bc08fe3cce9122a63b8853170442afa00832ec 100644 (file)
@@ -1,3 +1,14 @@
+2014-11-02  Jonathan Wakely  <jwakely@redhat.com>
+
+       PR libstdc++/57898
+       * include/std/functional (_Mem_fn_traits_base): New class template.
+       (_Mem_fn_traits): New class template with specializations for every
+       combination of cv-qualified and ref-qualified member function.
+       (_Mem_fn_base): New class template for all pointer to member function
+       types and partial specialization for pointer to member object types.
+       (_Mem_fn): Inherit from _Mem_fn_base.
+       * testsuite/20_util/function_objects/mem_fn/refqual.cc: New.
+
 2014-10-31  Jonathan Wakely  <jwakely@redhat.com>
 
        * include/bits/stl_bvector.h (_Bvector_base): Use allocator_traits.
index 5bc2730c2f5f685f8a0c02c4f17f31bac5724d7a..ecc5bc98f05ce1e47ac4a43c416f2440fcc0b0dc 100644 (file)
@@ -504,344 +504,231 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
     struct _Maybe_unary_or_binary_function<_Res, _T1, _T2>
     : std::binary_function<_T1, _T2, _Res> { };
 
-  /// Implementation of @c mem_fn for member function pointers.
+  template<typename _Signature>
+    struct _Mem_fn_traits;
+
   template<typename _Res, typename _Class, typename... _ArgTypes>
-    class _Mem_fn<_Res (_Class::*)(_ArgTypes...)>
-    : public _Maybe_unary_or_binary_function<_Res, _Class*, _ArgTypes...>
+    struct _Mem_fn_traits_base
     {
-      typedef _Res (_Class::*_Functor)(_ArgTypes...);
-
-      template<typename _Tp, typename... _Args>
-       _Res
-       _M_call(_Tp&& __object, const volatile _Class *,
-               _Args&&... __args) const
-       {
-         return (std::forward<_Tp>(__object).*__pmf)
-           (std::forward<_Args>(__args)...);
-       }
-
-      template<typename _Tp, typename... _Args>
-       _Res
-       _M_call(_Tp&& __ptr, const volatile void *, _Args&&... __args) const
-       { return ((*__ptr).*__pmf)(std::forward<_Args>(__args)...); }
-
-      // Require each _Args to be convertible to corresponding _ArgTypes
-      template<typename... _Args>
-       using _RequireValidArgs
-         = _Require<_AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
-
-      // Require each _Args to be convertible to corresponding _ArgTypes
-      // and require _Tp is not _Class, _Class& or _Class*
-      template<typename _Tp, typename... _Args>
-       using _RequireValidArgs2
-         = _Require<_NotSame<_Class, _Tp>, _NotSame<_Class*, _Tp>,
-                    _AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
-
-      // Require each _Args to be convertible to corresponding _ArgTypes
-      // and require _Tp is _Class or derived from _Class
-      template<typename _Tp, typename... _Args>
-       using _RequireValidArgs3
-         = _Require<is_base_of<_Class, _Tp>,
-                    _AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
-
-    public:
-      typedef _Res result_type;
-
-      explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
-
-      // Handle objects
-      template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
-       _Res
-       operator()(_Class& __object, _Args&&... __args) const
-       { return (__object.*__pmf)(std::forward<_Args>(__args)...); }
-
-      template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
-       _Res
-       operator()(_Class&& __object, _Args&&... __args) const
-       {
-         return (std::move(__object).*__pmf)(std::forward<_Args>(__args)...);
-       }
-
-      // Handle pointers
-      template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
-       _Res
-       operator()(_Class* __object, _Args&&... __args) const
-       { return (__object->*__pmf)(std::forward<_Args>(__args)...); }
-
-      // Handle smart pointers, references and pointers to derived
-      template<typename _Tp, typename... _Args,
-              typename _Req = _RequireValidArgs2<_Tp, _Args...>>
-       _Res
-       operator()(_Tp&& __object, _Args&&... __args) const
-       {
-         return _M_call(std::forward<_Tp>(__object), &__object,
-             std::forward<_Args>(__args)...);
-       }
-
-      template<typename _Tp, typename... _Args,
-              typename _Req = _RequireValidArgs3<_Tp, _Args...>>
-       _Res
-       operator()(reference_wrapper<_Tp> __ref, _Args&&... __args) const
-       { return operator()(__ref.get(), std::forward<_Args>(__args)...); }
-
-    private:
-      _Functor __pmf;
+      using __result_type = _Res;
+      using __class_type =  _Class;
+      using __arg_types = _Pack<_ArgTypes...>;
+      using __maybe_type
+       = _Maybe_unary_or_binary_function<_Res, _Class*, _ArgTypes...>;
     };
 
-  /// Implementation of @c mem_fn for const member function pointers.
   template<typename _Res, typename _Class, typename... _ArgTypes>
-    class _Mem_fn<_Res (_Class::*)(_ArgTypes...) const>
-    : public _Maybe_unary_or_binary_function<_Res, const _Class*,
-                                            _ArgTypes...>
+    struct _Mem_fn_traits<_Res (_Class::*)(_ArgTypes...)>
+    : _Mem_fn_traits_base<_Res, _Class, _ArgTypes...>
     {
-      typedef _Res (_Class::*_Functor)(_ArgTypes...) const;
-
-      template<typename _Tp, typename... _Args>
-       _Res
-       _M_call(_Tp&& __object, const volatile _Class *,
-               _Args&&... __args) const
-       {
-         return (std::forward<_Tp>(__object).*__pmf)
-           (std::forward<_Args>(__args)...);
-       }
-
-      template<typename _Tp, typename... _Args>
-       _Res
-       _M_call(_Tp&& __ptr, const volatile void *, _Args&&... __args) const
-       { return ((*__ptr).*__pmf)(std::forward<_Args>(__args)...); }
-
-      template<typename... _Args>
-       using _RequireValidArgs
-         = _Require<_AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
-
-      template<typename _Tp, typename... _Args>
-       using _RequireValidArgs2
-         = _Require<_NotSame<_Class, _Tp>, _NotSame<const _Class*, _Tp>,
-                    _AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
-
-      template<typename _Tp, typename... _Args>
-       using _RequireValidArgs3
-         = _Require<is_base_of<_Class, _Tp>,
-                    _AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
-
-    public:
-      typedef _Res result_type;
+      using __pmf_type  = _Res (_Class::*)(_ArgTypes...);
+      using __lvalue = true_type;
+      using __rvalue = true_type;
+    };
 
-      explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
+  template<typename _Res, typename _Class, typename... _ArgTypes>
+    struct _Mem_fn_traits<_Res (_Class::*)(_ArgTypes...) const>
+    : _Mem_fn_traits_base<_Res, const _Class, _ArgTypes...>
+    {
+      using __pmf_type  = _Res (_Class::*)(_ArgTypes...) const;
+      using __lvalue = true_type;
+      using __rvalue = true_type;
+    };
 
-      // Handle objects
-      template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
-       _Res
-       operator()(const _Class& __object, _Args&&... __args) const
-       { return (__object.*__pmf)(std::forward<_Args>(__args)...); }
-
-      template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
-       _Res
-       operator()(const _Class&& __object, _Args&&... __args) const
-       {
-         return (std::move(__object).*__pmf)(std::forward<_Args>(__args)...);
-       }
+  template<typename _Res, typename _Class, typename... _ArgTypes>
+    struct _Mem_fn_traits<_Res (_Class::*)(_ArgTypes...) volatile>
+    : _Mem_fn_traits_base<_Res, volatile _Class, _ArgTypes...>
+    {
+      using __pmf_type  = _Res (_Class::*)(_ArgTypes...) volatile;
+      using __lvalue = true_type;
+      using __rvalue = true_type;
+    };
 
-      // Handle pointers
-      template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
-       _Res
-       operator()(const _Class* __object, _Args&&... __args) const
-       { return (__object->*__pmf)(std::forward<_Args>(__args)...); }
+  template<typename _Res, typename _Class, typename... _ArgTypes>
+    struct _Mem_fn_traits<_Res (_Class::*)(_ArgTypes...) const volatile>
+    : _Mem_fn_traits_base<_Res, const volatile _Class, _ArgTypes...>
+    {
+      using __pmf_type  = _Res (_Class::*)(_ArgTypes...) const volatile;
+      using __lvalue = true_type;
+      using __rvalue = true_type;
+    };
 
-      // Handle smart pointers, references and pointers to derived
-      template<typename _Tp, typename... _Args,
-              typename _Req = _RequireValidArgs2<_Tp, _Args...>>
-       _Res operator()(_Tp&& __object, _Args&&... __args) const
-       {
-         return _M_call(std::forward<_Tp>(__object), &__object,
-             std::forward<_Args>(__args)...);
-       }
+  template<typename _Res, typename _Class, typename... _ArgTypes>
+    struct _Mem_fn_traits<_Res (_Class::*)(_ArgTypes...)&>
+    : _Mem_fn_traits_base<_Res, _Class, _ArgTypes...>
+    {
+      using __pmf_type  = _Res (_Class::*)(_ArgTypes...)&;
+      using __lvalue = true_type;
+      using __rvalue = false_type;
+    };
 
-      template<typename _Tp, typename... _Args,
-              typename _Req = _RequireValidArgs3<_Tp, _Args...>>
-       _Res
-       operator()(reference_wrapper<_Tp> __ref, _Args&&... __args) const
-       { return operator()(__ref.get(), std::forward<_Args>(__args)...); }
+  template<typename _Res, typename _Class, typename... _ArgTypes>
+    struct _Mem_fn_traits<_Res (_Class::*)(_ArgTypes...) const&>
+    : _Mem_fn_traits_base<_Res, const _Class, _ArgTypes...>
+    {
+      using __pmf_type  = _Res (_Class::*)(_ArgTypes...) const&;
+      using __lvalue = true_type;
+      using __rvalue = false_type;
+    };
 
-    private:
-      _Functor __pmf;
+  template<typename _Res, typename _Class, typename... _ArgTypes>
+    struct _Mem_fn_traits<_Res (_Class::*)(_ArgTypes...) volatile&>
+    : _Mem_fn_traits_base<_Res, volatile _Class, _ArgTypes...>
+    {
+      using __pmf_type  = _Res (_Class::*)(_ArgTypes...) volatile&;
+      using __lvalue = true_type;
+      using __rvalue = false_type;
     };
 
-  /// Implementation of @c mem_fn for volatile member function pointers.
   template<typename _Res, typename _Class, typename... _ArgTypes>
-    class _Mem_fn<_Res (_Class::*)(_ArgTypes...) volatile>
-    : public _Maybe_unary_or_binary_function<_Res, volatile _Class*,
-                                            _ArgTypes...>
+    struct _Mem_fn_traits<_Res (_Class::*)(_ArgTypes...) const volatile&>
+    : _Mem_fn_traits_base<_Res, const volatile _Class, _ArgTypes...>
     {
-      typedef _Res (_Class::*_Functor)(_ArgTypes...) volatile;
+      using __pmf_type  = _Res (_Class::*)(_ArgTypes...) const volatile&;
+      using __lvalue = true_type;
+      using __rvalue = false_type;
+    };
 
-      template<typename _Tp, typename... _Args>
-       _Res
-       _M_call(_Tp&& __object, const volatile _Class *,
-               _Args&&... __args) const
-       {
-         return (std::forward<_Tp>(__object).*__pmf)
-           (std::forward<_Args>(__args)...);
-       }
+  template<typename _Res, typename _Class, typename... _ArgTypes>
+    struct _Mem_fn_traits<_Res (_Class::*)(_ArgTypes...)&&>
+    : _Mem_fn_traits_base<_Res, _Class, _ArgTypes...>
+    {
+      using __pmf_type  = _Res (_Class::*)(_ArgTypes...)&&;
+      using __lvalue = false_type;
+      using __rvalue = true_type;
+    };
 
-      template<typename _Tp, typename... _Args>
-       _Res
-       _M_call(_Tp&& __ptr, const volatile void *, _Args&&... __args) const
-       { return ((*__ptr).*__pmf)(std::forward<_Args>(__args)...); }
+  template<typename _Res, typename _Class, typename... _ArgTypes>
+    struct _Mem_fn_traits<_Res (_Class::*)(_ArgTypes...) const&&>
+    : _Mem_fn_traits_base<_Res, const _Class, _ArgTypes...>
+    {
+      using __pmf_type  = _Res (_Class::*)(_ArgTypes...) const&&;
+      using __lvalue = false_type;
+      using __rvalue = true_type;
+    };
 
-      template<typename... _Args>
-       using _RequireValidArgs
-         = _Require<_AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
+  template<typename _Res, typename _Class, typename... _ArgTypes>
+    struct _Mem_fn_traits<_Res (_Class::*)(_ArgTypes...) volatile&&>
+    : _Mem_fn_traits_base<_Res, volatile _Class, _ArgTypes...>
+    {
+      using __pmf_type  = _Res (_Class::*)(_ArgTypes...) volatile&&;
+      using __lvalue = false_type;
+      using __rvalue = true_type;
+    };
 
-      template<typename _Tp, typename... _Args>
-       using _RequireValidArgs2
-         = _Require<_NotSame<_Class, _Tp>, _NotSame<volatile _Class*, _Tp>,
-                    _AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
+  template<typename _Res, typename _Class, typename... _ArgTypes>
+    struct _Mem_fn_traits<_Res (_Class::*)(_ArgTypes...) const volatile&&>
+    : _Mem_fn_traits_base<_Res, const volatile _Class, _ArgTypes...>
+    {
+      using __pmf_type  = _Res (_Class::*)(_ArgTypes...) const volatile&&;
+      using __lvalue = false_type;
+      using __rvalue = true_type;
+    };
 
-      template<typename _Tp, typename... _Args>
-       using _RequireValidArgs3
-         = _Require<is_base_of<_Class, _Tp>,
-                    _AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
+  template<typename _MemFunPtr,
+          bool __is_mem_fn = is_member_function_pointer<_MemFunPtr>::value>
+    class _Mem_fn_base
+    : public _Mem_fn_traits<_MemFunPtr>::__maybe_type
+    {
+      using _Traits = _Mem_fn_traits<_MemFunPtr>;
 
     public:
-      typedef _Res result_type;
-
-      explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
-
-      // Handle objects
-      template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
-       _Res
-       operator()(volatile _Class& __object, _Args&&... __args) const
-       { return (__object.*__pmf)(std::forward<_Args>(__args)...); }
-
-      template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
-       _Res
-       operator()(volatile _Class&& __object, _Args&&... __args) const
-       {
-         return (std::move(__object).*__pmf)(std::forward<_Args>(__args)...);
-       }
-
-      // Handle pointers
-      template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
-       _Res
-       operator()(volatile _Class* __object, _Args&&... __args) const
-       { return (__object->*__pmf)(std::forward<_Args>(__args)...); }
-
-      // Handle smart pointers, references and pointers to derived
-      template<typename _Tp, typename... _Args,
-              typename _Req = _RequireValidArgs2<_Tp, _Args...>>
-       _Res
-       operator()(_Tp&& __object, _Args&&... __args) const
-       {
-         return _M_call(std::forward<_Tp>(__object), &__object,
-             std::forward<_Args>(__args)...);
-       }
-
-      template<typename _Tp, typename... _Args,
-              typename _Req = _RequireValidArgs3<_Tp, _Args...>>
-       _Res
-       operator()(reference_wrapper<_Tp> __ref, _Args&&... __args) const
-       { return operator()(__ref.get(), std::forward<_Args>(__args)...); }
+      using result_type = typename _Traits::__result_type;
 
     private:
-      _Functor __pmf;
-    };
-
-  /// Implementation of @c mem_fn for const volatile member function pointers.
-  template<typename _Res, typename _Class, typename... _ArgTypes>
-    class _Mem_fn<_Res (_Class::*)(_ArgTypes...) const volatile>
-    : public _Maybe_unary_or_binary_function<_Res, const volatile _Class*,
-                                            _ArgTypes...>
-    {
-      typedef _Res (_Class::*_Functor)(_ArgTypes...) const volatile;
+      using _Class = typename _Traits::__class_type;
+      using _ArgTypes = typename _Traits::__arg_types;
+      using _Pmf = typename _Traits::__pmf_type;
 
       template<typename _Tp, typename... _Args>
-       _Res
+       result_type
        _M_call(_Tp&& __object, const volatile _Class *,
                _Args&&... __args) const
        {
-         return (std::forward<_Tp>(__object).*__pmf)
+         return (std::forward<_Tp>(__object).*_M_pmf)
            (std::forward<_Args>(__args)...);
        }
 
       template<typename _Tp, typename... _Args>
-       _Res
+       result_type
        _M_call(_Tp&& __ptr, const volatile void *, _Args&&... __args) const
-       { return ((*__ptr).*__pmf)(std::forward<_Args>(__args)...); }
+       { return ((*__ptr).*_M_pmf)(std::forward<_Args>(__args)...); }
 
+      // Require each _Args to be convertible to corresponding _ArgTypes
       template<typename... _Args>
        using _RequireValidArgs
-         = _Require<_AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
+         = _Require<_AllConvertible<_Pack<_Args...>, _ArgTypes>>;
 
+      // Require each _Args to be convertible to corresponding _ArgTypes
+      // and require _Tp is not _Class, _Class& or _Class*
       template<typename _Tp, typename... _Args>
        using _RequireValidArgs2
-         = _Require<_NotSame<_Class, _Tp>,
-                    _NotSame<const volatile _Class*, _Tp>,
-                    _AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
+         = _Require<_NotSame<_Class, _Tp>, _NotSame<_Class*, _Tp>,
+                    _AllConvertible<_Pack<_Args...>, _ArgTypes>>;
 
+      // Require each _Args to be convertible to corresponding _ArgTypes
+      // and require _Tp is _Class or derived from _Class
       template<typename _Tp, typename... _Args>
        using _RequireValidArgs3
          = _Require<is_base_of<_Class, _Tp>,
-                    _AllConvertible<_Pack<_Args...>, _Pack<_ArgTypes...>>>;
+                    _AllConvertible<_Pack<_Args...>, _ArgTypes>>;
 
     public:
-      typedef _Res result_type;
-
-      explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
+      explicit _Mem_fn_base(_Pmf __pmf) : _M_pmf(__pmf) { }
 
       // Handle objects
-      template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
-       _Res
-       operator()(const volatile _Class& __object, _Args&&... __args) const
-       { return (__object.*__pmf)(std::forward<_Args>(__args)...); }
-
-      template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
-       _Res
-       operator()(const volatile _Class&& __object, _Args&&... __args) const
+      template<typename... _Args, typename _Req
+               = _Require<typename _Traits::__lvalue,
+                          _AllConvertible<_Pack<_Args...>, _ArgTypes>>>
+       result_type
+       operator()(_Class& __object, _Args&&... __args) const
+       { return (__object.*_M_pmf)(std::forward<_Args>(__args)...); }
+
+      template<typename... _Args, typename _Req
+               = _Require<typename _Traits::__rvalue,
+                          _AllConvertible<_Pack<_Args...>, _ArgTypes>>>
+       result_type
+       operator()(_Class&& __object, _Args&&... __args) const
        {
-         return (std::move(__object).*__pmf)(std::forward<_Args>(__args)...);
+         return (std::move(__object).*_M_pmf)(std::forward<_Args>(__args)...);
        }
 
       // Handle pointers
-      template<typename... _Args, typename _Req = _RequireValidArgs<_Args...>>
-       _Res
-       operator()(const volatile _Class* __object, _Args&&... __args) const
-       { return (__object->*__pmf)(std::forward<_Args>(__args)...); }
+      template<typename... _Args, typename _Req
+               = _Require<typename _Traits::__lvalue,
+                          _AllConvertible<_Pack<_Args...>, _ArgTypes>>>
+       result_type
+       operator()(_Class* __object, _Args&&... __args) const
+       { return (__object->*_M_pmf)(std::forward<_Args>(__args)...); }
 
       // Handle smart pointers, references and pointers to derived
-      template<typename _Tp, typename... _Args,
-              typename _Req = _RequireValidArgs2<_Tp, _Args...>>
-       _Res operator()(_Tp&& __object, _Args&&... __args) const
+      // TODO how to constrain to lvalue/rvalue here? constrain _M_call?
+      template<typename _Tp, typename... _Args, typename _Req
+               = _Require<_NotSame<_Class, _Tp>, _NotSame<_Class*, _Tp>,
+                          _AllConvertible<_Pack<_Args...>, _ArgTypes>>>
+       result_type
+       operator()(_Tp&& __object, _Args&&... __args) const
        {
          return _M_call(std::forward<_Tp>(__object), &__object,
              std::forward<_Args>(__args)...);
        }
 
-      template<typename _Tp, typename... _Args,
-              typename _Req = _RequireValidArgs3<_Tp, _Args...>>
-       _Res
+      // Handle reference wrappers
+      template<typename _Tp, typename... _Args, typename _Req
+               = _Require<is_base_of<_Class, _Tp>,
+                          typename _Traits::__lvalue,
+                          _AllConvertible<_Pack<_Args...>, _ArgTypes>>>
+       result_type
        operator()(reference_wrapper<_Tp> __ref, _Args&&... __args) const
        { return operator()(__ref.get(), std::forward<_Args>(__args)...); }
 
     private:
-      _Functor __pmf;
-    };
-
-
-  template<typename _Tp, bool>
-    struct _Mem_fn_const_or_non
-    {
-      typedef const _Tp& type;
-    };
-
-  template<typename _Tp>
-    struct _Mem_fn_const_or_non<_Tp, false>
-    {
-      typedef _Tp& type;
+      _Pmf _M_pmf;
     };
 
+  // Partial specialization for member object pointers.
   template<typename _Res, typename _Class>
-    class _Mem_fn<_Res _Class::*>
+    class _Mem_fn_base<_Res _Class::*, false>
     {
       using __pm_type = _Res _Class::*;
 
@@ -852,56 +739,56 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
        auto
        _M_call(_Tp&& __object, const _Class *) const noexcept
        -> decltype(std::forward<_Tp>(__object).*std::declval<__pm_type&>())
-       { return std::forward<_Tp>(__object).*__pm; }
+       { return std::forward<_Tp>(__object).*_M_pm; }
 
       template<typename _Tp, typename _Up>
        auto
        _M_call(_Tp&& __object, _Up * const *) const noexcept
        -> decltype((*std::forward<_Tp>(__object)).*std::declval<__pm_type&>())
-       { return (*std::forward<_Tp>(__object)).*__pm; }
+       { return (*std::forward<_Tp>(__object)).*_M_pm; }
 
       template<typename _Tp>
        auto
        _M_call(_Tp&& __ptr, const volatile void*) const
        noexcept(noexcept((*__ptr).*std::declval<__pm_type&>()))
        -> decltype((*__ptr).*std::declval<__pm_type&>())
-       { return (*__ptr).*__pm; }
+       { return (*__ptr).*_M_pm; }
 
     public:
       explicit
-      _Mem_fn(_Res _Class::*__pm) noexcept : __pm(__pm) { }
+      _Mem_fn_base(_Res _Class::*__pm) noexcept : _M_pm(__pm) { }
 
       // Handle objects
       _Res&
       operator()(_Class& __object) const noexcept
-      { return __object.*__pm; }
+      { return __object.*_M_pm; }
 
       const _Res&
       operator()(const _Class& __object) const noexcept
-      { return __object.*__pm; }
+      { return __object.*_M_pm; }
 
       _Res&&
       operator()(_Class&& __object) const noexcept
-      { return std::forward<_Class>(__object).*__pm; }
+      { return std::forward<_Class>(__object).*_M_pm; }
 
       const _Res&&
       operator()(const _Class&& __object) const noexcept
-      { return std::forward<const _Class>(__object).*__pm; }
+      { return std::forward<const _Class>(__object).*_M_pm; }
 
       // Handle pointers
       _Res&
       operator()(_Class* __object) const noexcept
-      { return __object->*__pm; }
+      { return __object->*_M_pm; }
 
       const _Res&
       operator()(const _Class* __object) const noexcept
-      { return __object->*__pm; }
+      { return __object->*_M_pm; }
 
       // Handle smart pointers and derived
       template<typename _Tp, typename _Req = _Require<_NotSame<_Class*, _Tp>>>
        auto
        operator()(_Tp&& __unknown) const
-       noexcept(noexcept(std::declval<_Mem_fn*>()->_M_call
+       noexcept(noexcept(std::declval<_Mem_fn_base*>()->_M_call
                          (std::forward<_Tp>(__unknown), &__unknown)))
        -> decltype(this->_M_call(std::forward<_Tp>(__unknown), &__unknown))
        { return _M_call(std::forward<_Tp>(__unknown), &__unknown); }
@@ -909,12 +796,19 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
       template<typename _Tp, typename _Req = _Require<is_base_of<_Class, _Tp>>>
        auto
        operator()(reference_wrapper<_Tp> __ref) const
-       noexcept(noexcept(std::declval<_Mem_fn&>()(__ref.get())))
+       noexcept(noexcept(std::declval<_Mem_fn_base&>()(__ref.get())))
        -> decltype((*this)(__ref.get()))
        { return (*this)(__ref.get()); }
 
     private:
-      _Res _Class::*__pm;
+      _Res _Class::*_M_pm;
+    };
+
+  template<typename _Res, typename _Class>
+    struct _Mem_fn<_Res _Class::*>
+    : _Mem_fn_base<_Res _Class::*>
+    {
+      using _Mem_fn_base<_Res _Class::*>::_Mem_fn_base;
     };
 
   // _GLIBCXX_RESOLVE_LIB_DEFECTS
diff --git a/libstdc++-v3/testsuite/20_util/function_objects/mem_fn/refqual.cc b/libstdc++-v3/testsuite/20_util/function_objects/mem_fn/refqual.cc
new file mode 100644 (file)
index 0000000..35a66e5
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+#include <functional>
+
+struct Foo
+{
+  void r()&& { }
+  int l() const& { return 0; }
+};
+
+void test01()
+{
+  Foo f;
+  int i = std::mem_fn(&Foo::l)( f );
+  std::mem_fn(&Foo::r)( std::move(f) );
+}