diff mbox series

PR libstdc++/71187 reimplement declval without add_rvalue_reference

Message ID 20170918114124.GA12232@redhat.com
State New
Headers show
Series PR libstdc++/71187 reimplement declval without add_rvalue_reference | expand

Commit Message

Jonathan Wakely Sept. 18, 2017, 11:41 a.m. UTC
This implements Eric Niebler's suggestion of a more lightweight
std::declval, which doesn't need to instantiate
std::add_rvalue_reference (and its base class and helpers).

	PR libstdc++/71187
	* include/std/type_traits (__declval): New function to deduce return
	type of declval.
	(__declval_protector::_delegate): Remove.
	(declval): Use __declval instead of add_rvalue_reference and
	__declval_protector::__delegate.
	* testsuite/20_util/declval/requirements/1_neg.cc: Adjust dg-error
	lineno.
	* testsuite/20_util/make_signed/requirements/typedefs_neg.cc:
	Likewise.
	* testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc:
	Likewise.

Tested powerpc64le-linux, committed to trunk.
commit 05558f97c64247cf421eff8b17570a0844794cbc
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Fri Sep 15 14:49:08 2017 +0100

    PR libstdc++/71187 reimplement declval without add_rvalue_reference
    
            PR libstdc++/71187
            * include/std/type_traits (__declval): New function to deduce return
            type of declval.
            (__declval_protector::_delegate): Remove.
            (declval): Use __declval instead of add_rvalue_reference and
            __declval_protector::__delegate.
            * testsuite/20_util/declval/requirements/1_neg.cc: Adjust dg-error
            lineno.
            * testsuite/20_util/make_signed/requirements/typedefs_neg.cc:
            Likewise.
            * testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc:
            Likewise.
diff mbox series

Patch

diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index f021c42396c..15b0d92bcb6 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -754,15 +754,21 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   // Destructible and constructible type properties.
 
-  template<typename>
-    struct add_rvalue_reference;
-
   /**
    *  @brief  Utility to simplify expressions used in unevaluated operands
    *  @ingroup utilities
    */
+
+  template<typename _Tp, typename _Up = _Tp&&>
+    _Up
+    __declval(int);
+
   template<typename _Tp>
-    typename add_rvalue_reference<_Tp>::type declval() noexcept;
+    _Tp
+    __declval(long);
+
+  template<typename _Tp>
+    auto declval() noexcept -> decltype(__declval<_Tp>(0));
 
   template<typename, unsigned = 0>
     struct extent;
@@ -2079,16 +2085,14 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     struct __declval_protector
     {
       static const bool __stop = false;
-      static typename add_rvalue_reference<_Tp>::type __delegate();
     };
 
   template<typename _Tp>
-    inline typename add_rvalue_reference<_Tp>::type
-    declval() noexcept
+    auto declval() noexcept -> decltype(__declval<_Tp>(0))
     {
       static_assert(__declval_protector<_Tp>::__stop,
 		    "declval() must not be used!");
-      return __declval_protector<_Tp>::__delegate();
+      return __declval<_Tp>(0);
     }
 
   /// result_of
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 4e254e89191..17b41a007db 100644
--- a/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc
@@ -18,7 +18,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-error "static assertion failed" "" { target *-*-* } 2089 }
+// { dg-error "static assertion failed" "" { target *-*-* } 2093 }
 
 #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 e3e80f91979..308155383f0 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
@@ -47,4 +47,4 @@  void test01()
 // { dg-error "required from here" "" { target *-*-* } 39 }
 // { dg-error "required from here" "" { target *-*-* } 41 }
 
-// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1754 }
+// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1760 }
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 86b0c2d6da7..412608e5669 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
@@ -47,5 +47,5 @@  void test01()
 // { dg-error "required from here" "" { target *-*-* } 39 }
 // { dg-error "required from here" "" { target *-*-* } 41 }
 
-// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1650 }
+// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1656 }