Patchwork [v3] Update std::forward to N3092

login
register
mail settings
Submitter Paolo Carlini
Date Aug. 11, 2010, 4:59 p.m.
Message ID <4C62D701.5010506@oracle.com>
Download mbox | patch
Permalink /patch/61488/
State New
Headers show

Comments

Paolo Carlini - Aug. 11, 2010, 4:59 p.m.
... apparently US 90 is actually getting support, thus to avoid ping -
pongs between different versions, I'm reinstating the N2835 version of
std::forward which we have in 4_5-branch too (with common_type replacing
of course identity, because the latter is gone). Tested x86_64-linux.

Paolo.

///////////////////////
2010-08-11  Paolo Carlini  <paolo.carlini@oracle.com>

	* include/bits/move.h (forward): Reinstate the N2835 version.

Patch

Index: include/bits/move.h
===================================================================
--- include/bits/move.h	(revision 163100)
+++ include/bits/move.h	(working copy)
@@ -51,17 +51,30 @@ 
 
 _GLIBCXX_BEGIN_NAMESPACE(std)
   
-  /// forward
-  template<typename _Tp, typename _Up>
-    inline typename
-    enable_if<((std::is_convertible<
-		typename std::remove_reference<_Up>::type*,
-		typename std::remove_reference<_Tp>::type*>::value)
-	       && (!std::is_lvalue_reference<_Tp>::value
-		   || std::is_lvalue_reference<_Up>::value)), _Tp&&>::type
-    forward(_Up&& __u)
-    { return static_cast<_Tp&&>(__u); }
+  /// forward (as per N2835)
+  /// Forward lvalues as rvalues.
+  template<typename _Tp>
+    inline typename enable_if<!is_lvalue_reference<_Tp>::value, _Tp&&>::type
+    forward(typename std::common_type<_Tp>::type& __t)
+    { return static_cast<_Tp&&>(__t); }
 
+  /// Forward rvalues as rvalues.
+  template<typename _Tp>
+    inline typename enable_if<!is_lvalue_reference<_Tp>::value, _Tp&&>::type
+    forward(typename std::common_type<_Tp>::type&& __t)
+    { return static_cast<_Tp&&>(__t); }
+
+  // Forward lvalues as lvalues.
+  template<typename _Tp>
+    inline typename enable_if<is_lvalue_reference<_Tp>::value, _Tp>::type
+    forward(typename std::common_type<_Tp>::type __t)
+    { return __t; }
+
+  // Prevent forwarding rvalues as const lvalues.
+  template<typename _Tp>
+    inline typename enable_if<is_lvalue_reference<_Tp>::value, _Tp>::type
+    forward(typename std::remove_reference<_Tp>::type&& __t) = delete;
+
   /**
    *  @brief Move a value.
    *  @ingroup mutating_algorithms