commit d2fd02daab715c79c766bc0a476d1d01da1fc305
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Thu Jun 26 12:28:56 2014 +0100
* include/bits/hashtable_policy.h (_ReuseOrAllocNode::operator()): Use
__allocated_ptr.
(_Hashtable_alloc::_M_allocate_node): Likewise.
(_Hashtable_alloc::_M_deallocate_node): Likewise.
@@ -31,6 +31,8 @@
#ifndef _HASHTABLE_POLICY_H
#define _HASHTABLE_POLICY_H 1
+#include <bits/allocated_ptr.h>
+
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -137,20 +139,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__node_type* __node = _M_nodes;
_M_nodes = _M_nodes->_M_next();
__node->_M_nxt = nullptr;
- __value_alloc_type __a(_M_h._M_node_allocator());
- __value_alloc_traits::destroy(__a, __node->_M_valptr());
- __try
- {
- __value_alloc_traits::construct(__a, __node->_M_valptr(),
- std::forward<_Arg>(__arg));
- }
- __catch(...)
- {
- __node->~__node_type();
- __node_alloc_traits::deallocate(_M_h._M_node_allocator(),
- __node, 1);
- __throw_exception_again;
- }
+ auto& __a = _M_h._M_node_allocator();
+ __node_alloc_traits::destroy(__a, __node->_M_valptr());
+ __allocated_ptr<_NodeAlloc> __guard{__a, __node};
+ __node_alloc_traits::construct(__a, __node->_M_valptr(),
+ std::forward<_Arg>(__arg));
+ __guard = nullptr;
return __node;
}
return _M_h._M_allocate_node(std::forward<_Arg>(__arg));
@@ -1947,33 +1941,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename _Hashtable_alloc<_NodeAlloc>::__node_type*
_Hashtable_alloc<_NodeAlloc>::_M_allocate_node(_Args&&... __args)
{
- auto __nptr = __node_alloc_traits::allocate(_M_node_allocator(), 1);
- __node_type* __n = std::__addressof(*__nptr);
- __try
- {
- __value_alloc_type __a(_M_node_allocator());
- ::new ((void*)__n) __node_type;
- __value_alloc_traits::construct(__a, __n->_M_valptr(),
- std::forward<_Args>(__args)...);
- return __n;
- }
- __catch(...)
- {
- __node_alloc_traits::deallocate(_M_node_allocator(), __nptr, 1);
- __throw_exception_again;
- }
+ auto& __a = _M_node_allocator();
+ auto __guard = std::__allocate_guarded(__a);
+ __node_type* __n = __guard.get();
+ ::new ((void*)__n) __node_type;
+ __node_alloc_traits::construct(__a, __n->_M_valptr(),
+ std::forward<_Args>(__args)...);
+ __guard = nullptr;
+ return __n;
}
template<typename _NodeAlloc>
void
_Hashtable_alloc<_NodeAlloc>::_M_deallocate_node(__node_type* __n)
{
- typedef typename __node_alloc_traits::pointer _Ptr;
- auto __ptr = std::pointer_traits<_Ptr>::pointer_to(*__n);
- __value_alloc_type __a(_M_node_allocator());
- __value_alloc_traits::destroy(__a, __n->_M_valptr());
- __n->~__node_type();
- __node_alloc_traits::deallocate(_M_node_allocator(), __ptr, 1);
+ static_assert(std::is_trivially_destructible<__node_type>::value,
+ "Nodes must not require non-trivial destruction");
+ auto& __alloc = _M_node_allocator();
+ __allocated_ptr<__node_alloc_type> __guard{__alloc, __n};
+ __node_alloc_traits::destroy(__alloc, __n->_M_valptr());
}
template<typename _NodeAlloc>