PR libstdc++/86127 avoid unnecessary allocator conversions

Message ID 20180613151352.GA8928@redhat.com
State New
Headers show
Series
  • PR libstdc++/86127 avoid unnecessary allocator conversions
Related show

Commit Message

Jonathan Wakely June 13, 2018, 3:13 p.m.
There is no need to use an allocator of the correct value_type when
calling allocator_traits::construct and allocator_traits::destroy. The
existing node allocator can be used, instead of constructing a new
allocator object every time.

There's also no benefit to using __gnu_cxx::__alloc_traits instead of
std::allocator_traits to get the pointer and const_pointer types.
std::forward_list is only available for C++11 and later, when
std::allocator_traits is available too.

	PR libstdc++/86127
	* include/bits/forward_list.h (_Fwd_list_base::_Tp_alloc_type): Remove
	unused typedef.
	(_Fwd_list_base::_Node_alloc_traits): Use allocator_traits instead of
	__gnu_cxx::__alloc_traits.
	(_Fwd_list_base::_M_create_node, _Fwd_list_base::_M_erase_after):
	Use node allocator to create and destroy elements.
	(forward_list::_Tp_alloc_type): Remove unused typedef.
	(forward_list::_Alloc_traits): Use allocator_traits instead of
	__gnu_cxx::__alloc_traits.

Tested powerpc64le-linux, committed to trunk.
commit 777e063c0bb527a72539169ea25f06d7ad3de536
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Jun 13 13:54:47 2018 +0100

    PR libstdc++/86127 avoid unnecessary allocator conversions
    
    There is no need to use an allocator of the correct value_type when
    calling allocator_traits::construct and allocator_traits::destroy. The
    existing node allocator can be used, instead of constructing a new
    allocator object every time.
    
    There's also no benefit to using __gnu_cxx::__alloc_traits instead of
    std::allocator_traits to get the pointer and const_pointer types.
    std::forward_list is only available for C++11 and later, when
    std::allocator_traits is available too.
    
            PR libstdc++/86127
            * include/bits/forward_list.h (_Fwd_list_base::_Tp_alloc_type): Remove
            unused typedef.
            (_Fwd_list_base::_Node_alloc_traits): Use allocator_traits instead of
            __gnu_cxx::__alloc_traits.
            (_Fwd_list_base::_M_create_node, _Fwd_list_base::_M_erase_after):
            Use node allocator to create and destroy elements.
            (forward_list::_Tp_alloc_type): Remove unused typedef.
            (forward_list::_Alloc_traits): Use allocator_traits instead of
            __gnu_cxx::__alloc_traits.

Patch

diff --git a/libstdc++-v3/include/bits/forward_list.h b/libstdc++-v3/include/bits/forward_list.h
index b40256bd104..8c4c074e454 100644
--- a/libstdc++-v3/include/bits/forward_list.h
+++ b/libstdc++-v3/include/bits/forward_list.h
@@ -289,7 +289,6 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
     struct _Fwd_list_base
     {
     protected:
-      typedef __alloc_rebind<_Alloc, _Tp> 		  _Tp_alloc_type;
       typedef __alloc_rebind<_Alloc, _Fwd_list_node<_Tp>> _Node_alloc_type;
       typedef __gnu_cxx::__alloc_traits<_Node_alloc_type> _Node_alloc_traits;
 
@@ -363,11 +362,10 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 	  _Node* __node = this->_M_get_node();
 	  __try
 	    {
-	      _Tp_alloc_type __a(_M_get_Node_allocator());
-	      typedef allocator_traits<_Tp_alloc_type> _Alloc_traits;
 	      ::new ((void*)__node) _Node;
-	      _Alloc_traits::construct(__a, __node->_M_valptr(),
-				       std::forward<_Args>(__args)...);
+	      _Node_alloc_traits::construct(_M_get_Node_allocator(),
+					    __node->_M_valptr(),
+					    std::forward<_Args>(__args)...);
 	    }
 	  __catch(...)
 	    {
@@ -437,10 +435,9 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       typedef _Fwd_list_base<_Tp, _Alloc>		_Base;
       typedef _Fwd_list_node<_Tp>			_Node;
       typedef _Fwd_list_node_base			_Node_base;
-      typedef typename _Base::_Tp_alloc_type		_Tp_alloc_type;
       typedef typename _Base::_Node_alloc_type		_Node_alloc_type;
       typedef typename _Base::_Node_alloc_traits	_Node_alloc_traits;
-      typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type>	_Alloc_traits;
+      typedef allocator_traits<__alloc_rebind<_Alloc, _Tp>>	_Alloc_traits;
 
     public:
       // types:
diff --git a/libstdc++-v3/include/bits/forward_list.tcc b/libstdc++-v3/include/bits/forward_list.tcc
index 3e12cd531d4..b41fbbb52f2 100644
--- a/libstdc++-v3/include/bits/forward_list.tcc
+++ b/libstdc++-v3/include/bits/forward_list.tcc
@@ -65,8 +65,8 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
     {
       _Node* __curr = static_cast<_Node*>(__pos->_M_next);
       __pos->_M_next = __curr->_M_next;
-      _Tp_alloc_type __a(_M_get_Node_allocator());
-      allocator_traits<_Tp_alloc_type>::destroy(__a, __curr->_M_valptr());
+      _Node_alloc_traits::destroy(_M_get_Node_allocator(),
+				  __curr->_M_valptr());
       __curr->~_Node();
       _M_put_node(__curr);
       return __pos->_M_next;
@@ -83,8 +83,8 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 	{
 	  _Node* __temp = __curr;
 	  __curr = static_cast<_Node*>(__curr->_M_next);
-	  _Tp_alloc_type __a(_M_get_Node_allocator());
-	  allocator_traits<_Tp_alloc_type>::destroy(__a, __temp->_M_valptr());
+	  _Node_alloc_traits::destroy(_M_get_Node_allocator(),
+				      __temp->_M_valptr());
 	  __temp->~_Node();
 	  _M_put_node(__temp);
 	}