public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Remove lambdas from _Rb_tree
@ 2020-11-17 20:51 François Dumont
  2020-11-17 23:50 ` Jonathan Wakely
  0 siblings, 1 reply; 7+ messages in thread
From: François Dumont @ 2020-11-17 20:51 UTC (permalink / raw)
  To: libstdc++, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1128 bytes --]

This is a change that has been done to _Hashtable and that I forgot to 
propose for _Rb_tree.

The _GLIBCXX_XREF macro can be easily removed of course.

     libstdc++: _Rb_tree code cleanup, remove lambdas.

     Use an additional template parameter on the clone method to 
propagate if the values must be
     copy or move rather than lambdas.

     libstdc++-v3/ChangeLog:

             * include/bits/move.h (_GLIBCXX_XREF): New.
             * include/bits/stl_tree.h: Adapt to use latter.
             (_Rb_tree<>::_S_fwd_value_for): New.
             (_Rb_tree<>::_M_clone_node): Add _Tree template parameter.
             Use _S_fwd_value_for.
             (_Rb_tree<>::_M_cbegin): New.
             (_Rb_tree<>::_M_begin): Use latter.
             (_Rb_tree<>::_M_copy): Add _Tree template parameter.
             (_Rb_tree<>::_M_move_data): Use rvalue reference for 
_Rb_tree parameter.
             (_Rb_tree<>::_M_move_assign): Likewise.

Tested under Linux x86_64.

Ok to commit ?

François


[-- Attachment #2: tree.patch --]
[-- Type: text/x-patch, Size: 9153 bytes --]

diff --git a/libstdc++-v3/include/bits/move.h b/libstdc++-v3/include/bits/move.h
index 5a4dbdc823c..e0d68ca9108 100644
--- a/libstdc++-v3/include/bits/move.h
+++ b/libstdc++-v3/include/bits/move.h
@@ -158,9 +158,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   /// @} group utilities
 
+#define _GLIBCXX_XREF(_Tp) _Tp&&
 #define _GLIBCXX_MOVE(__val) std::move(__val)
 #define _GLIBCXX_FORWARD(_Tp, __val) std::forward<_Tp>(__val)
 #else
+#define _GLIBCXX_XREF(_Tp) const _Tp&
 #define _GLIBCXX_MOVE(__val) (__val)
 #define _GLIBCXX_FORWARD(_Tp, __val) (__val)
 #endif
diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h
index ec141ea01c7..128c7e2c892 100644
--- a/libstdc++-v3/include/bits/stl_tree.h
+++ b/libstdc++-v3/include/bits/stl_tree.h
@@ -478,11 +478,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 	template<typename _Arg>
 	  _Link_type
-#if __cplusplus < 201103L
-	  operator()(const _Arg& __arg)
-#else
-	  operator()(_Arg&& __arg)
-#endif
+	  operator()(_GLIBCXX_XREF(_Arg) __arg)
 	  {
 	    _Link_type __node = static_cast<_Link_type>(_M_extract());
 	    if (__node)
@@ -544,11 +540,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 	template<typename _Arg>
 	  _Link_type
-#if __cplusplus < 201103L
-	  operator()(const _Arg& __arg) const
-#else
-	  operator()(_Arg&& __arg) const
-#endif
+	  operator()(_GLIBCXX_XREF(_Arg) __arg) const
 	  { return _M_t._M_create_node(_GLIBCXX_FORWARD(_Arg, __arg)); }
 
       private:
@@ -655,11 +647,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	_M_put_node(__p);
       }
 
-      template<typename _NodeGen>
+#if __cplusplus >= 201103L
+      template<typename _Tree>
+	static constexpr
+	typename conditional<std::is_lvalue_reference<_Tree>::value,
+			     const value_type&, value_type&&>::type
+	_S_fwd_value_for(value_type& __val) noexcept
+	{ return std::move(__val); }
+#else
+      template<typename _Tree>
+	static const value_type&
+	_S_fwd_value_for(value_type& __val)
+	{ return __val; }
+#endif
+
+      template<typename _Tree, typename _NodeGen>
 	_Link_type
-	_M_clone_node(_Const_Link_type __x, _NodeGen& __node_gen)
+	_M_clone_node(_GLIBCXX_XREF(_Tree),
+		      _Link_type __x, _NodeGen& __node_gen)
 	{
-	  _Link_type __tmp = __node_gen(*__x->_M_valptr());
+	  _Link_type __tmp
+	    = __node_gen(_S_fwd_value_for<_Tree>(*__x->_M_valptr()));
 	  __tmp->_M_color = __x->_M_color;
 	  __tmp->_M_left = 0;
 	  __tmp->_M_right = 0;
@@ -748,9 +756,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       { return this->_M_impl._M_header._M_right; }
 
       _Link_type
-      _M_begin() _GLIBCXX_NOEXCEPT
+      _M_cbegin() const _GLIBCXX_NOEXCEPT
       { return static_cast<_Link_type>(this->_M_impl._M_header._M_parent); }
 
+      _Link_type
+      _M_begin() _GLIBCXX_NOEXCEPT
+      { return _M_cbegin(); }
+
       _Const_Link_type
       _M_begin() const _GLIBCXX_NOEXCEPT
       {
@@ -889,15 +901,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _M_insert_equal_lower(const value_type& __x);
 #endif
 
-      template<typename _NodeGen>
+      template<typename _Tree, typename _NodeGen>
 	_Link_type
-	_M_copy(_Const_Link_type __x, _Base_ptr __p, _NodeGen&);
+	_M_copy(_GLIBCXX_XREF(_Tree), _Link_type, _Base_ptr, _NodeGen&);
 
-      template<typename _NodeGen>
+      template<typename _Tree, typename _NodeGen>
 	_Link_type
-	_M_copy(const _Rb_tree& __x, _NodeGen& __gen)
+	_M_copy(_GLIBCXX_XREF(_Tree) __x, _NodeGen& __gen)
 	{
-	  _Link_type __root = _M_copy(__x._M_begin(), _M_end(), __gen);
+	  _Link_type __root = _M_copy(_GLIBCXX_FORWARD(_Tree, __x),
+				      __x._M_cbegin(), _M_end(), __gen);
 	  _M_leftmost() = _S_minimum(__root);
 	  _M_rightmost() = _S_maximum(__root);
 	  _M_impl._M_node_count = __x._M_impl._M_node_count;
@@ -977,7 +990,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       : _M_impl(__x._M_impl._M_key_compare, std::move(__a))
       {
 	if (__x._M_root() != nullptr)
-	  _M_move_data(__x, false_type{});
+	  _M_move_data(std::move(__x), false_type{});
       }
 
     public:
@@ -1426,22 +1439,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     private:
       // Move elements from container with equal allocator.
       void
-      _M_move_data(_Rb_tree& __x, true_type)
+      _M_move_data(_Rb_tree&& __x, true_type)
       { _M_impl._M_move_data(__x._M_impl); }
 
       // Move elements from container with possibly non-equal allocator,
       // which might result in a copy not a move.
       void
-      _M_move_data(_Rb_tree&, false_type);
+      _M_move_data(_Rb_tree&&, false_type);
 
       // Move assignment from container with equal allocator.
       void
-      _M_move_assign(_Rb_tree&, true_type);
+      _M_move_assign(_Rb_tree&&, true_type);
 
       // Move assignment from container with possibly non-equal allocator,
       // which might result in a copy not a move.
       void
-      _M_move_assign(_Rb_tree&, false_type);
+      _M_move_assign(_Rb_tree&&, false_type);
 #endif
 
 #if __cplusplus > 201402L
@@ -1648,20 +1661,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	   typename _Compare, typename _Alloc>
     void
     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
-    _M_move_data(_Rb_tree& __x, false_type)
+    _M_move_data(_Rb_tree&& __x, false_type)
     {
       if (_M_get_Node_allocator() == __x._M_get_Node_allocator())
-	_M_move_data(__x, true_type());
+	_M_move_data(std::move(__x), true_type());
       else
 	{
+	  using _Fwd_Rbt = typename
+	    conditional<__move_if_noexcept_cond<value_type>::value,
+			const _Rb_tree&, _Rb_tree&&>::type;
 	  _Alloc_node __an(*this);
-	  auto __lbd =
-	    [&__an](const value_type& __cval)
-	    {
-	      auto& __val = const_cast<value_type&>(__cval);
-	      return __an(std::move_if_noexcept(__val));
-	    };
-	  _M_root() = _M_copy(__x, __lbd);
+	  _M_root() = _M_copy(std::forward<_Fwd_Rbt>(__x), __an);
 	}
     }
 
@@ -1669,11 +1679,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	   typename _Compare, typename _Alloc>
     inline void
     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
-    _M_move_assign(_Rb_tree& __x, true_type)
+    _M_move_assign(_Rb_tree&& __x, true_type)
     {
       clear();
       if (__x._M_root() != nullptr)
-	_M_move_data(__x, true_type());
+	_M_move_data(std::move(__x), true_type());
       std::__alloc_on_move(_M_get_Node_allocator(),
 			   __x._M_get_Node_allocator());
     }
@@ -1682,10 +1692,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	   typename _Compare, typename _Alloc>
     void
     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
-    _M_move_assign(_Rb_tree& __x, false_type)
+    _M_move_assign(_Rb_tree&& __x, false_type)
     {
       if (_M_get_Node_allocator() == __x._M_get_Node_allocator())
-	return _M_move_assign(__x, true_type{});
+	return _M_move_assign(std::move(__x), true_type{});
 
       // Try to move each node reusing existing nodes and copying __x nodes
       // structure.
@@ -1693,13 +1703,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _M_impl._M_reset();
       if (__x._M_root() != nullptr)
 	{
-	  auto __lbd =
-	    [&__roan](const value_type& __cval)
-	    {
-	      auto& __val = const_cast<value_type&>(__cval);
-	      return __roan(std::move(__val));
-	    };
-	  _M_root() = _M_copy(__x, __lbd);
+	  _M_root() = _M_copy(std::move(__x), __roan);
 	  __x.clear();
 	}
     }
@@ -1713,7 +1717,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	     && is_nothrow_move_assignable<_Compare>::value)
     {
       _M_impl._M_key_compare = std::move(__x._M_impl._M_key_compare);
-      _M_move_assign(__x, __bool_constant<_Alloc_traits::_S_nothrow_move()>());
+      _M_move_assign(std::move(__x),
+		     __bool_constant<_Alloc_traits::_S_nothrow_move()>());
       return *this;
     }
 
@@ -1859,29 +1864,34 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template<typename _Key, typename _Val, typename _KoV,
 	   typename _Compare, typename _Alloc>
-    template<typename _NodeGen>
+    template<typename _Tree, typename _NodeGen>
       typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type
       _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::
-      _M_copy(_Const_Link_type __x, _Base_ptr __p, _NodeGen& __node_gen)
+      _M_copy(_GLIBCXX_XREF(_Tree) __t,
+	      _Link_type __x, _Base_ptr __p, _NodeGen& __node_gen)
       {
 	// Structural copy. __x and __p must be non-null.
-	_Link_type __top = _M_clone_node(__x, __node_gen);
+	_Link_type __top = _M_clone_node(_GLIBCXX_FORWARD(_Tree, __t),
+					 __x, __node_gen);
 	__top->_M_parent = __p;
 
 	__try
 	  {
 	    if (__x->_M_right)
-	      __top->_M_right = _M_copy(_S_right(__x), __top, __node_gen);
+	      __top->_M_right = _M_copy(_GLIBCXX_FORWARD(_Tree, __t),
+					_S_right(__x), __top, __node_gen);
 	    __p = __top;
 	    __x = _S_left(__x);
 
 	    while (__x != 0)
 	      {
-		_Link_type __y = _M_clone_node(__x, __node_gen);
+		_Link_type __y = _M_clone_node(_GLIBCXX_FORWARD(_Tree, __t),
+					       __x, __node_gen);
 		__p->_M_left = __y;
 		__y->_M_parent = __p;
 		if (__x->_M_right)
-		  __y->_M_right = _M_copy(_S_right(__x), __y, __node_gen);
+		  __y->_M_right = _M_copy(_GLIBCXX_FORWARD(_Tree, __t),
+					  _S_right(__x), __y, __node_gen);
 		__p = __y;
 		__x = _S_left(__x);
 	      }

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-11-20 10:23 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-17 20:51 [PATCH] Remove lambdas from _Rb_tree François Dumont
2020-11-17 23:50 ` Jonathan Wakely
2020-11-19  6:46   ` François Dumont
2020-11-19 11:31     ` Jonathan Wakely
2020-11-19 13:20       ` François Dumont
2020-11-20  7:17       ` François Dumont
2020-11-20 10:22         ` Jonathan Wakely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).