Patchwork [v3] fix std::result_of support for cv-quals

login
register
mail settings
Submitter Jonathan Wakely
Date March 27, 2012, 9:03 a.m.
Message ID <CAH6eHdT3uDck0r2nhoTQe_=g0m8BHX_F1nsPVVXRb-Zdd4WqRA@mail.gmail.com>
Download mbox | patch
Permalink /patch/148897/
State New
Headers show

Comments

Jonathan Wakely - March 27, 2012, 9:03 a.m.
This fixes a couple of bugs I noticed in std::result_of, the first new
test covers those bugs, the second new test is just taken from the
standard to test result_of a little more thoroughly.

        * include/std/type_traits (result_of): Fix handling of cv-quals.
        * testsuite/20_util/result_of/1.cc: New.
        * testsuite/20_util/result_of/2.cc: New.
        * testsuite/20_util/declval/requirements/1_neg.cc: Adjust dg-error
        line numbers.
        * testsuite/20_util/make_signed/requirements/typedefs_neg.cc:
        Likewise.
        * testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc:
        Likewise.

Tested x86_64-linux, committed to trunk.
commit 49b07e4ef78b549dcca253c276af2b2ba8d41f88
Author: Jonathan Wakely <jwakely.gcc@gmail.com>
Date:   Tue Mar 27 02:58:51 2012 +0100

    	* include/std/type_traits (result_of): Fix handling of cv-quals.
    	* testsuite/20_util/result_of/1.cc: New.
    	* testsuite/20_util/result_of/2.cc: New.
    	* testsuite/20_util/declval/requirements/1_neg.cc: Adjust dg-error
    	line numbers.
    	* testsuite/20_util/make_signed/requirements/typedefs_neg.cc:
    	Likewise.
    	* testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc:
    	Likewise.

Patch

diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index e3ec7ad..4102263 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -1,6 +1,7 @@ 
 // C++11 type_traits -*- C++ -*-
 
-// Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+// Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012
+// 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
@@ -1794,6 +1795,8 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       template<typename _Tp>
 	static _Tp _S_get(const _Class&);
       template<typename _Tp>
+	static _Tp _S_get(const volatile _Class&);
+      template<typename _Tp>
 	static decltype(*std::declval<_Tp>()) _S_get(...);
         
     public:
@@ -1814,6 +1817,8 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       template<typename _Tp>
 	static _Tp _S_get(const _Class&);
       template<typename _Tp>
+	static _Tp _S_get(const volatile _Class&);
+      template<typename _Tp>
 	static decltype(*std::declval<_Tp>()) _S_get(...);
         
     public:
@@ -1836,22 +1841,13 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template<typename _MemPtr, typename _Arg>
     struct _Result_of_impl<true, false, _MemPtr, _Arg>
-    : _Result_of_memobj<typename remove_reference<_MemPtr>::type, _Arg>
-    {
-      typedef typename _Result_of_memobj<
-	typename remove_reference<_MemPtr>::type, _Arg>::__type
-	__type;
-    };
+    : _Result_of_memobj<typename decay<_MemPtr>::type, _Arg>
+    { };
 
   template<typename _MemPtr, typename _Arg, typename... _ArgTypes>
     struct _Result_of_impl<false, true, _MemPtr, _Arg, _ArgTypes...>
-    : _Result_of_memfun<typename remove_reference<_MemPtr>::type, _Arg,
-                        _ArgTypes...>
-    {
-      typedef typename _Result_of_memfun<
-	typename remove_reference<_MemPtr>::type, _Arg, _ArgTypes...>::__type
-	__type;
-    };
+    : _Result_of_memfun<typename decay<_MemPtr>::type, _Arg, _ArgTypes...>
+    { };
 
   template<typename _Functor, typename... _ArgTypes>
     struct result_of<_Functor(_ArgTypes...)>
diff --git a/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc b/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc
index 298e93e..eafbe5f 100644
--- a/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc
@@ -19,7 +19,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-error "static assertion failed" "" { target *-*-* } 1776 }
+// { dg-error "static assertion failed" "" { target *-*-* } 1777 }
 
 #include <utility>
 
diff --git a/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc b/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc
index d2ebf16..6358d72 100644
--- a/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc
@@ -48,5 +48,5 @@  void test01()
 // { dg-error "required from here" "" { target *-*-* } 40 }
 // { dg-error "required from here" "" { target *-*-* } 42 }
 
-// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1565 }
-// { dg-error "declaration of" "" { target *-*-* } 1529 }
+// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1566 }
+// { dg-error "declaration of" "" { target *-*-* } 1530 }
diff --git a/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc b/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc
index c0ef55b..d9a0f17 100644
--- a/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc
@@ -48,5 +48,5 @@  void test01()
 // { dg-error "required from here" "" { target *-*-* } 40 }
 // { dg-error "required from here" "" { target *-*-* } 42 }
 
-// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1483 }
-// { dg-error "declaration of" "" { target *-*-* } 1447 }
+// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1484 }
+// { dg-error "declaration of" "" { target *-*-* } 1448 }
diff --git a/libstdc++-v3/testsuite/20_util/result_of/1.cc b/libstdc++-v3/testsuite/20_util/result_of/1.cc
new file mode 100644
index 0000000..0d53f7c
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/result_of/1.cc
@@ -0,0 +1,53 @@ 
+// { dg-options "-std=gnu++0x" }
+// { dg-do compile }
+
+// Copyright (C) 2012 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>
+#include <type_traits>
+
+struct X {
+  int i;
+  void f1() { }
+  void f2() volatile { }
+};
+
+typedef int X::*pm;
+typedef void (X::*pmf1)();
+typedef void (X::*pmf2)() volatile;
+
+typedef std::result_of<pm const&(X&)>::type result;
+static_assert(std::is_same<result, int&>::value,
+              "invoking cv-qualified pointer-to-member-object");
+
+typedef std::result_of<pmf1 const&(X&)>::type result1;
+static_assert(std::is_void<result1>::value,
+              "invoking cv-qualified pointer-to-member-function");
+
+typedef std::result_of<pmf2 const&(X&)>::type result2;
+static_assert(std::is_void<result2>::value,
+              "invoking cv-qualified pointer-to-member-function");
+
+typedef std::result_of<pm(volatile X&)>::type result3;
+static_assert(std::is_same<result3, volatile int&>::value,
+              "invoking pointer-to-member-object on volatile object");
+
+typedef std::result_of<pmf2(volatile X&)>::type result4;
+static_assert(std::is_void<result4>::value,
+              "invoking pointer-to-member-function on volatile object");
+
diff --git a/libstdc++-v3/testsuite/20_util/result_of/2.cc b/libstdc++-v3/testsuite/20_util/result_of/2.cc
new file mode 100644
index 0000000..9fc80f7
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/result_of/2.cc
@@ -0,0 +1,47 @@ 
+// { dg-options "-std=gnu++0x" }
+// { dg-do compile }
+
+// Copyright (C) 2012 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 <type_traits>
+#include <memory>
+
+using std::is_same;
+using std::result_of;
+using std::unique_ptr;
+
+// Taken from example in [meta.trans.other]
+
+typedef bool (&PF1)();
+typedef short (*PF2)(long);
+struct S {
+  operator PF2() const;
+  double operator()(char, int&);
+  void fn(long) const;
+  char data;
+};
+
+typedef void (S::*PMF)(long) const;
+typedef char S::*PMD;
+
+static_assert( is_same<result_of<S(int)>::type, short>::value, "!");
+static_assert( is_same<result_of<S&(unsigned char, int&)>::type, double>::value, "!");
+static_assert( is_same<result_of<PF1()>::type, bool>::value, "!");
+static_assert( is_same<result_of<PMF(unique_ptr<S>, int)>::type, void>::value, "!");
+static_assert( is_same<result_of<PMD(S)>::type, char&&>::value, "!");
+static_assert( is_same<result_of<PMD(const S*)>::type, const char&>::value, "!");