libstdc++: [_Hashtable] Use RAII type to guard node while constructing value

libstdc++-v3/ChangeLog:

	* include/bits/hashtable_policy.h
	(struct _NodePtrGuard<_HashtableAlloc, _NodePtr>): New.
	(_ReuseAllocNode::operator()(_Args&&...)): Use latter to guard allocated node
	pointer while constructing in place the value_type instance.
This commit is contained in:
François Dumont 2023-10-30 06:39:00 +01:00
parent 5b6f4e6f05
commit 04d8a47608

View file

@ -173,6 +173,19 @@ namespace __detail
{ return __node_gen(std::forward<_Kt>(__k)); }
};
template<typename _HashtableAlloc, typename _NodePtr>
struct _NodePtrGuard
{
_HashtableAlloc& _M_h;
_NodePtr _M_ptr;
~_NodePtrGuard()
{
if (_M_ptr)
_M_h._M_deallocate_node_ptr(_M_ptr);
}
};
template<typename _NodeAlloc>
struct _Hashtable_alloc;
@ -201,26 +214,19 @@ namespace __detail
__node_ptr
operator()(_Args&&... __args) const
{
if (_M_nodes)
{
__node_ptr __node = _M_nodes;
_M_nodes = _M_nodes->_M_next();
__node->_M_nxt = nullptr;
auto& __a = _M_h._M_node_allocator();
__node_alloc_traits::destroy(__a, __node->_M_valptr());
__try
{
__node_alloc_traits::construct(__a, __node->_M_valptr(),
std::forward<_Args>(__args)...);
}
__catch(...)
{
_M_h._M_deallocate_node_ptr(__node);
__throw_exception_again;
}
return __node;
}
return _M_h._M_allocate_node(std::forward<_Args>(__args)...);
if (!_M_nodes)
return _M_h._M_allocate_node(std::forward<_Args>(__args)...);
__node_ptr __node = _M_nodes;
_M_nodes = _M_nodes->_M_next();
__node->_M_nxt = nullptr;
auto& __a = _M_h._M_node_allocator();
__node_alloc_traits::destroy(__a, __node->_M_valptr());
_NodePtrGuard<__hashtable_alloc, __node_ptr> __guard { _M_h, __node };
__node_alloc_traits::construct(__a, __node->_M_valptr(),
std::forward<_Args>(__args)...);
__guard._M_ptr = nullptr;
return __node;
}
private: