Patchwork [v3] Add missing specializations for _Weak_result_type_impl and _Reference_wrapper_base

login
register
mail settings
Submitter Paolo Carlini
Date Oct. 6, 2010, 5:22 p.m.
Message ID <4CACB038.8030205@oracle.com>
Download mbox | patch
Permalink /patch/66946/
State New
Headers show

Comments

Paolo Carlini - Oct. 6, 2010, 5:22 p.m.
Hi,

this resolves a relatively old, rather boring issue: we were missing
specializations matching variadic functions (at the time I pointed it
out to Doug) and cv-qualified function types (consistently with the
current std::is_function).

Tested x86_64-linux, committed to mainline.

Paolo.

///////////////////////////
2010-10-06  Paolo Carlini  <paolo.carlini@oracle.com>

	* include/std/functional (struct _Weak_result_type_impl): Add
	specializazions for cv-qualified function types, for variadic
	function types and pointers and references to function types,
	and for pointers to member function types.
	(struct _Reference_wrapper_base): Add specializations for
	cv-qualified unary and binary function types.
	* testsuite/20_util/reference_wrapper/result_type.cc: New.
	* testsuite/20_util/reference_wrapper/typedefs-2.cc: Likewise.

Patch

Index: include/std/functional
===================================================================
--- include/std/functional	(revision 165026)
+++ include/std/functional	(working copy)
@@ -60,9 +60,6 @@ 
 
 namespace std
 {
-  template<typename _MemberPointer>
-    class _Mem_fn;
-
 _GLIBCXX_HAS_NESTED_TYPE(result_type)
 
   /// If we have found a result_type, extract it.
@@ -72,9 +69,7 @@ 
 
   template<typename _Functor>
     struct _Maybe_get_result_type<true, _Functor>
-    {
-      typedef typename _Functor::result_type result_type;
-    };
+    { typedef typename _Functor::result_type result_type; };
 
   /**
    *  Base class for any function object that has a weak result type, as
@@ -88,52 +83,92 @@ 
   /// Retrieve the result type for a function type.
   template<typename _Res, typename... _ArgTypes> 
     struct _Weak_result_type_impl<_Res(_ArgTypes...)>
-    {
-      typedef _Res result_type;
-    };
+    { typedef _Res result_type; };
 
+  template<typename _Res, typename... _ArgTypes> 
+    struct _Weak_result_type_impl<_Res(_ArgTypes......)>
+    { typedef _Res result_type; };
+
+  template<typename _Res, typename... _ArgTypes> 
+    struct _Weak_result_type_impl<_Res(_ArgTypes...) const>
+    { typedef _Res result_type; };
+
+  template<typename _Res, typename... _ArgTypes> 
+    struct _Weak_result_type_impl<_Res(_ArgTypes......) const>
+    { typedef _Res result_type; };
+
+  template<typename _Res, typename... _ArgTypes> 
+    struct _Weak_result_type_impl<_Res(_ArgTypes...) volatile>
+    { typedef _Res result_type; };
+
+  template<typename _Res, typename... _ArgTypes> 
+    struct _Weak_result_type_impl<_Res(_ArgTypes......) volatile>
+    { typedef _Res result_type; };
+
+  template<typename _Res, typename... _ArgTypes> 
+    struct _Weak_result_type_impl<_Res(_ArgTypes...) const volatile>
+    { typedef _Res result_type; };
+
+  template<typename _Res, typename... _ArgTypes> 
+    struct _Weak_result_type_impl<_Res(_ArgTypes......) const volatile>
+    { typedef _Res result_type; };
+
   /// Retrieve the result type for a function reference.
   template<typename _Res, typename... _ArgTypes> 
     struct _Weak_result_type_impl<_Res(&)(_ArgTypes...)>
-    {
-      typedef _Res result_type;
-    };
+    { typedef _Res result_type; };
 
+  template<typename _Res, typename... _ArgTypes> 
+    struct _Weak_result_type_impl<_Res(&)(_ArgTypes......)>
+    { typedef _Res result_type; };
+
   /// Retrieve the result type for a function pointer.
   template<typename _Res, typename... _ArgTypes> 
     struct _Weak_result_type_impl<_Res(*)(_ArgTypes...)>
-    {
-      typedef _Res result_type;
-    };
+    { typedef _Res result_type; };
 
+  template<typename _Res, typename... _ArgTypes> 
+    struct _Weak_result_type_impl<_Res(*)(_ArgTypes......)>
+    { typedef _Res result_type; };
+
   /// Retrieve result type for a member function pointer. 
   template<typename _Res, typename _Class, typename... _ArgTypes> 
     struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...)>
-    {
-      typedef _Res result_type;
-    };
+    { typedef _Res result_type; };
 
+  template<typename _Res, typename _Class, typename... _ArgTypes> 
+    struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes......)>
+    { typedef _Res result_type; };
+
   /// Retrieve result type for a const member function pointer. 
   template<typename _Res, typename _Class, typename... _ArgTypes> 
     struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...) const>
-    {
-      typedef _Res result_type;
-    };
+    { typedef _Res result_type; };
 
+  template<typename _Res, typename _Class, typename... _ArgTypes> 
+    struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes......) const>
+    { typedef _Res result_type; };
+
   /// Retrieve result type for a volatile member function pointer. 
   template<typename _Res, typename _Class, typename... _ArgTypes> 
     struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...) volatile>
-    {
-      typedef _Res result_type;
-    };
+    { typedef _Res result_type; };
 
+  template<typename _Res, typename _Class, typename... _ArgTypes> 
+    struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes......) volatile>
+    { typedef _Res result_type; };
+
   /// Retrieve result type for a const volatile member function pointer. 
   template<typename _Res, typename _Class, typename... _ArgTypes> 
-    struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...)const volatile>
-    {
-      typedef _Res result_type;
-    };
+    struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...) 
+				  const volatile>
+    { typedef _Res result_type; };
 
+  template<typename _Res, typename _Class, typename... _ArgTypes> 
+    struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes......)
+				  const volatile>
+    { typedef _Res result_type; };
+
   /**
    *  Strip top-level cv-qualifiers from the function object and let
    *  _Weak_result_type_impl perform the real work.
@@ -280,12 +315,42 @@ 
     : unary_function<_T1, _Res>
     { };
 
+  template<typename _Res, typename _T1>
+    struct _Reference_wrapper_base<_Res(_T1) const>
+    : unary_function<_T1, _Res>
+    { };
+
+  template<typename _Res, typename _T1>
+    struct _Reference_wrapper_base<_Res(_T1) volatile>
+    : unary_function<_T1, _Res>
+    { };
+
+  template<typename _Res, typename _T1>
+    struct _Reference_wrapper_base<_Res(_T1) const volatile>
+    : unary_function<_T1, _Res>
+    { };
+
   // - a function type (binary)
   template<typename _Res, typename _T1, typename _T2>
     struct _Reference_wrapper_base<_Res(_T1, _T2)>
     : binary_function<_T1, _T2, _Res>
     { };
 
+  template<typename _Res, typename _T1, typename _T2>
+    struct _Reference_wrapper_base<_Res(_T1, _T2) const>
+    : binary_function<_T1, _T2, _Res>
+    { };
+
+  template<typename _Res, typename _T1, typename _T2>
+    struct _Reference_wrapper_base<_Res(_T1, _T2) volatile>
+    : binary_function<_T1, _T2, _Res>
+    { };
+
+  template<typename _Res, typename _T1, typename _T2>
+    struct _Reference_wrapper_base<_Res(_T1, _T2) const volatile>
+    : binary_function<_T1, _T2, _Res>
+    { };
+
   // - a function pointer type (unary)
   template<typename _Res, typename _T1>
     struct _Reference_wrapper_base<_Res(*)(_T1)>
@@ -423,18 +488,9 @@ 
 
   // @} group functors
 
-  template<typename _Tp, bool>
-    struct _Mem_fn_const_or_non
-    {
-      typedef const _Tp& type;
-    };
+  template<typename _MemberPointer>
+    class _Mem_fn;
 
-  template<typename _Tp>
-    struct _Mem_fn_const_or_non<_Tp, false>
-    {
-      typedef _Tp& type;
-    };
-
   /**
    * Derives from @c unary_function or @c binary_function, or perhaps
    * nothing, depending on the number of arguments provided. The
@@ -639,6 +695,18 @@ 
     };
 
 
+  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;
+    };
+
   template<typename _Res, typename _Class>
     class _Mem_fn<_Res _Class::*>
     {
Index: testsuite/20_util/reference_wrapper/result_type.cc
===================================================================
--- testsuite/20_util/reference_wrapper/result_type.cc	(revision 0)
+++ testsuite/20_util/reference_wrapper/result_type.cc	(revision 0)
@@ -0,0 +1,42 @@ 
+// { dg-options "-std=gnu++0x" }
+// { dg-do compile }
+
+// 2010-10-06  Paolo Carlini  <paolo.carlini@oracle.com>
+
+// Copyright (C) 2010 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/>.
+
+#include <functional>
+
+using namespace std;
+
+struct T;
+
+reference_wrapper<int(float, ...)>::result_type                       i01;
+reference_wrapper<int(float, ...) const>::result_type                 i02;
+reference_wrapper<int(float, ...) volatile>::result_type              i03;
+reference_wrapper<int(float, ...) const volatile>::result_type        i04;
+
+reference_wrapper<int(*)(float, ...)>::result_type                    i05;
+reference_wrapper<int(* const)(float, ...)>::result_type              i06;
+reference_wrapper<int(* volatile)(float, ...)>::result_type           i07;
+reference_wrapper<int(* const volatile)(float, ...)>::result_type     i08;
+
+reference_wrapper<int(T::*)(float, ...)>::result_type                 i09;
+reference_wrapper<int(T::*)(float, ...) const>::result_type           i10;
+reference_wrapper<int(T::*)(float, ...) volatile>::result_type        i11;
+reference_wrapper<int(T::*)(float, ...) const volatile>::result_type  i12;
Index: testsuite/20_util/reference_wrapper/typedefs-2.cc
===================================================================
--- testsuite/20_util/reference_wrapper/typedefs-2.cc	(revision 0)
+++ testsuite/20_util/reference_wrapper/typedefs-2.cc	(revision 0)
@@ -0,0 +1,69 @@ 
+// { dg-options "-std=gnu++0x" }
+// { dg-do compile }
+
+// 2010-10-06  Paolo Carlini  <paolo.carlini@oracle.com>
+
+// Copyright (C) 2010 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/>.
+
+#include <functional>
+
+using namespace std;
+
+reference_wrapper<int(float)>::argument_type                               i01;
+reference_wrapper<int(float) const>::argument_type                         i02;
+reference_wrapper<int(float) volatile>::argument_type                      i03;
+reference_wrapper<int(float) const volatile>::argument_type                i04;
+reference_wrapper<int(float)>::result_type                                 i05;
+reference_wrapper<int(float) const>::result_type                           i06;
+reference_wrapper<int(float) volatile>::result_type                        i07;
+reference_wrapper<int(float) const volatile>::result_type                  i08;
+
+reference_wrapper<int(*)(float)>::argument_type                            i09;
+reference_wrapper<int(* const)(float)>::argument_type                      i10;
+reference_wrapper<int(* volatile)(float)>::argument_type                   i11;
+reference_wrapper<int(* const volatile)(float)>::argument_type             i12;
+reference_wrapper<int(*)(float)>::result_type                              i13;
+reference_wrapper<int(* const)(float)>::result_type                        i14;
+reference_wrapper<int(* volatile)(float)>::result_type                     i15;
+reference_wrapper<int(* const volatile)(float)>::result_type               i16;
+
+reference_wrapper<int(float, char)>::first_argument_type                   i17;
+reference_wrapper<int(float, char) const>::first_argument_type             i18;
+reference_wrapper<int(float, char) volatile>::first_argument_type          i19;
+reference_wrapper<int(float, char) const volatile>::first_argument_type    i20;
+reference_wrapper<int(float, char)>::second_argument_type                  i21;
+reference_wrapper<int(float, char) const>::second_argument_type            i22;
+reference_wrapper<int(float, char) volatile>::second_argument_type         i23;
+reference_wrapper<int(float, char) const volatile>::second_argument_type   i24;
+reference_wrapper<int(float, char)>::result_type                           i25;
+reference_wrapper<int(float, char) const>::result_type                     i26;
+reference_wrapper<int(float, char) volatile>::result_type                  i27;
+reference_wrapper<int(float, char) const volatile>::result_type            i28;
+
+reference_wrapper<int(*)(float, char)>::first_argument_type                i29;
+reference_wrapper<int(* const)(float, char)>::first_argument_type          i30;
+reference_wrapper<int(* volatile)(float, char)>::first_argument_type       i31;
+reference_wrapper<int(* const volatile)(float, char)>::first_argument_type i32;
+reference_wrapper<int(*)(float, char)>::second_argument_type               i33;
+reference_wrapper<int(* const)(float, char)>::second_argument_type         i34;
+reference_wrapper<int(* volatile)(float, char)>::second_argument_type      i35;
+reference_wrapper<int(*const volatile)(float, char)>::second_argument_type i36;
+reference_wrapper<int(*)(float, char)>::result_type                        i37;
+reference_wrapper<int(* const)(float, char)>::result_type                  i38;
+reference_wrapper<int(* volatile)(float, char)>::result_type               i39;
+reference_wrapper<int(* const volatile)(float, char)>::result_type         i40;