public inbox for libstdc++-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-5784] libstdc++: Simplify emplace member functions in _Rb_tree
@ 2021-12-03 22:53 Jonathan Wakely
  0 siblings, 0 replies; only message in thread
From: Jonathan Wakely @ 2021-12-03 22:53 UTC (permalink / raw)
  To: gcc-cvs, libstdc++-cvs

https://gcc.gnu.org/g:bf548ce3e67276aa429b462cf41e68891fdf40c2

commit r12-5784-gbf548ce3e67276aa429b462cf41e68891fdf40c2
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Fri Dec 3 11:16:30 2021 +0000

    libstdc++: Simplify emplace member functions in _Rb_tree
    
    This introduces a new RAII type to simplify the emplace members which
    currently use try-catch blocks to deallocate a node if an exception is
    thrown by the comparisons done during insertion. The new type is created
    on the stack and manages the allocation of a new node and deallocates it
    in the destructor if it wasn't inserted into the tree. It also provides
    helper functions for doing the insertion, releasing ownership of the
    node to the tree.
    
    Also, we don't need to use long qualified names if we put the return
    type after the nested-name-specifier.
    
    libstdc++-v3/ChangeLog:
    
            * include/bits/stl_tree.h (_Rb_tree::_Auto_node): Define new
            RAII helper for creating and inserting new nodes.
            (_Rb_tree::_M_insert_node): Use trailing-return-type to simplify
            out-of-line definition.
            (_Rb_tree::_M_insert_lower_node): Likewise.
            (_Rb_tree::_M_insert_equal_lower_node): Likewise.
            (_Rb_tree::_M_emplace_unique): Likewise. Use _Auto_node.
            (_Rb_tree::_M_emplace_equal): Likewise.
            (_Rb_tree::_M_emplace_hint_unique): Likewise.
            (_Rb_tree::_M_emplace_hint_equal): Likewise.

Diff:
---
 libstdc++-v3/include/bits/stl_tree.h | 148 ++++++++++++++++++-----------------
 1 file changed, 78 insertions(+), 70 deletions(-)

diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h
index 55b8c9c7cb2..336f4ed97b7 100644
--- a/libstdc++-v3/include/bits/stl_tree.h
+++ b/libstdc++-v3/include/bits/stl_tree.h
@@ -1624,6 +1624,52 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 					    __y.begin(), __y.end());
       }
 #endif
+
+    private:
+#if __cplusplus >= 201103L
+      // An RAII _Node handle
+      struct _Auto_node
+      {
+	template<typename... _Args>
+	  _Auto_node(_Rb_tree& __t, _Args&&... __args)
+	  : _M_t(__t),
+	    _M_node(__t._M_create_node(std::forward<_Args>(__args)...))
+	  { }
+
+	~_Auto_node()
+	{
+	  if (_M_node)
+	    _M_t._M_drop_node(_M_node);
+	}
+
+	_Auto_node(_Auto_node&& __n)
+	: _M_t(__n._M_t), _M_node(__n._M_node)
+	{ __n._M_node = nullptr; }
+
+	const _Key&
+	_M_key() const
+	{ return _S_key(_M_node); }
+
+	iterator
+	_M_insert(pair<_Base_ptr, _Base_ptr> __p)
+	{
+	  auto __it = _M_t._M_insert_node(__p.first, __p.second, _M_node);
+	  _M_node = nullptr;
+	  return __it;
+	}
+
+	iterator
+	_M_insert_equal_lower()
+	{
+	  auto __it = _M_t._M_insert_equal_lower_node(_M_node);
+	  _M_node = nullptr;
+	  return __it;
+	}
+
+	_Rb_tree& _M_t;
+	_Link_type _M_node;
+      };
+#endif // C++11
     };
 
   template<typename _Key, typename _Val, typename _KeyOfValue,
@@ -2326,9 +2372,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #if __cplusplus >= 201103L
   template<typename _Key, typename _Val, typename _KeyOfValue,
 	   typename _Compare, typename _Alloc>
-    typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
+    auto
     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
     _M_insert_node(_Base_ptr __x, _Base_ptr __p, _Link_type __z)
+    -> iterator
     {
       bool __insert_left = (__x != 0 || __p == _M_end()
 			    || _M_impl._M_key_compare(_S_key(__z),
@@ -2342,9 +2389,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template<typename _Key, typename _Val, typename _KeyOfValue,
 	   typename _Compare, typename _Alloc>
-    typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
+    auto
     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
     _M_insert_lower_node(_Base_ptr __p, _Link_type __z)
+    -> iterator
     {
       bool __insert_left = (__p == _M_end()
 			    || !_M_impl._M_key_compare(_S_key(__p),
@@ -2358,9 +2406,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template<typename _Key, typename _Val, typename _KeyOfValue,
 	   typename _Compare, typename _Alloc>
-    typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
+    auto
     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
     _M_insert_equal_lower_node(_Link_type __z)
+    -> iterator
     {
       _Link_type __x = _M_begin();
       _Base_ptr __y = _M_end();
@@ -2376,100 +2425,59 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Key, typename _Val, typename _KeyOfValue,
 	   typename _Compare, typename _Alloc>
     template<typename... _Args>
-      pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
-			     _Compare, _Alloc>::iterator, bool>
+      auto
       _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
       _M_emplace_unique(_Args&&... __args)
+      -> pair<iterator, bool>
       {
-	_Link_type __z = _M_create_node(std::forward<_Args>(__args)...);
-
-	__try
-	  {
-	    typedef pair<iterator, bool> _Res;
-	    auto __res = _M_get_insert_unique_pos(_S_key(__z));
-	    if (__res.second)
-	      return _Res(_M_insert_node(__res.first, __res.second, __z), true);
-	
-	    _M_drop_node(__z);
-	    return _Res(iterator(__res.first), false);
-	  }
-	__catch(...)
-	  {
-	    _M_drop_node(__z);
-	    __throw_exception_again;
-	  }
+	_Auto_node __z(*this, std::forward<_Args>(__args)...);
+	auto __res = _M_get_insert_unique_pos(__z._M_key());
+	if (__res.second)
+	  return {__z._M_insert(__res), true};
+	return {iterator(__res.first), false};
       }
 
   template<typename _Key, typename _Val, typename _KeyOfValue,
 	   typename _Compare, typename _Alloc>
     template<typename... _Args>
-      typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
+      auto
       _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
       _M_emplace_equal(_Args&&... __args)
+      -> iterator
       {
-	_Link_type __z = _M_create_node(std::forward<_Args>(__args)...);
-
-	__try
-	  {
-	    auto __res = _M_get_insert_equal_pos(_S_key(__z));
-	    return _M_insert_node(__res.first, __res.second, __z);
-	  }
-	__catch(...)
-	  {
-	    _M_drop_node(__z);
-	    __throw_exception_again;
-	  }
+	_Auto_node __z(*this, std::forward<_Args>(__args)...);
+	auto __res = _M_get_insert_equal_pos(__z._M_key());
+	return __z._M_insert(__res);
       }
 
   template<typename _Key, typename _Val, typename _KeyOfValue,
 	   typename _Compare, typename _Alloc>
     template<typename... _Args>
-      typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
+      auto
       _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
       _M_emplace_hint_unique(const_iterator __pos, _Args&&... __args)
+      -> iterator
       {
-	_Link_type __z = _M_create_node(std::forward<_Args>(__args)...);
-
-	__try
-	  {
-	    auto __res = _M_get_insert_hint_unique_pos(__pos, _S_key(__z));
-
-	    if (__res.second)
-	      return _M_insert_node(__res.first, __res.second, __z);
-
-	    _M_drop_node(__z);
-	    return iterator(__res.first);
-	  }
-	__catch(...)
-	  {
-	    _M_drop_node(__z);
-	    __throw_exception_again;
-	  }
+	_Auto_node __z(*this, std::forward<_Args>(__args)...);
+	auto __res = _M_get_insert_hint_unique_pos(__pos, __z._M_key());
+	if (__res.second)
+	  return __z._M_insert(__res);
+	return iterator(__res.first);
       }
 
   template<typename _Key, typename _Val, typename _KeyOfValue,
 	   typename _Compare, typename _Alloc>
     template<typename... _Args>
-      typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
+      auto
       _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
       _M_emplace_hint_equal(const_iterator __pos, _Args&&... __args)
+      -> iterator
       {
-	_Link_type __z = _M_create_node(std::forward<_Args>(__args)...);
-
-	__try
-	  {
-	    auto __res = _M_get_insert_hint_equal_pos(__pos, _S_key(__z));
-
-	    if (__res.second)
-	      return _M_insert_node(__res.first, __res.second, __z);
-
-	    return _M_insert_equal_lower_node(__z);
-	  }
-	__catch(...)
-	  {
-	    _M_drop_node(__z);
-	    __throw_exception_again;
-	  }
+	_Auto_node __z(*this, std::forward<_Args>(__args)...);
+	auto __res = _M_get_insert_hint_equal_pos(__pos, __z._M_key());
+	if (__res.second)
+	  return __z._M_insert(__res);
+	return __z._M_insert_equal_lower();
       }
 #endif


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-12-03 22:53 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-03 22:53 [gcc r12-5784] libstdc++: Simplify emplace member functions in _Rb_tree 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).