diff --git a/libstdc++-v3/include/bits/hashtable_policy.h b/libstdc++-v3/include/bits/hashtable_policy.h index cd8943d8d05..c67eebd3b2b 100644 --- a/libstdc++-v3/include/bits/hashtable_policy.h +++ b/libstdc++-v3/include/bits/hashtable_policy.h @@ -173,6 +173,19 @@ namespace __detail { return __node_gen(std::forward<_Kt>(__k)); } }; + template + struct _NodePtrGuard + { + _HashtableAlloc& _M_h; + _NodePtr _M_ptr; + + ~_NodePtrGuard() + { + if (_M_ptr) + _M_h._M_deallocate_node_ptr(_M_ptr); + } + }; + template struct _Hashtable_alloc; @@ -201,27 +214,20 @@ namespace __detail __node_ptr operator()(_Args&&... __args) const { - if (_M_nodes) - { + 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()); - __try - { + _NodePtrGuard<__hashtable_alloc, __node_ptr> __guard { _M_h, __node }; __node_alloc_traits::construct(__a, __node->_M_valptr(), std::forward<_Args>(__args)...); - } - __catch(...) - { - _M_h._M_deallocate_node_ptr(__node); - __throw_exception_again; - } + __guard._M_ptr = nullptr; return __node; } - return _M_h._M_allocate_node(std::forward<_Args>(__args)...); - } private: mutable __node_ptr _M_nodes;