Skip to content

Commit

Permalink
<xtree>: Use scope guard for node copy failure (#4749)
Browse files Browse the repository at this point in the history
  • Loading branch information
frederick-vs-ja authored Jul 5, 2024
1 parent 8e56d6b commit 153b940
Showing 1 changed file with 23 additions and 13 deletions.
36 changes: 23 additions & 13 deletions stl/inc/xtree
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,20 @@ public:
using _Unchecked_const_iterator = _Tree_unchecked_const_iterator<_Tree_val>;
using const_iterator = _Tree_const_iterator<_Tree_val>;

template <class _AllocNode>
struct _NODISCARD _Erase_tree_and_orphan_guard {
_Tree_val* _Val_ptr;
_AllocNode& _Al;
_Nodeptr _New_root;

_Erase_tree_and_orphan_guard& operator=(const _Erase_tree_and_orphan_guard&) = delete;
~_Erase_tree_and_orphan_guard() noexcept {
if (_Val_ptr != nullptr) {
_Val_ptr->_Erase_tree_and_orphan(_Al, _New_root); // subtree copy failed, bail out
}
}
};

_Tree_val() noexcept : _Myhead(), _Mysize(0) {}

enum _Redbl { // colors for link to parent
Expand Down Expand Up @@ -1661,20 +1675,16 @@ protected:
_Nodeptr _Newroot = _Scary->_Myhead; // point at nil node

if (!_Rootnode->_Isnil) { // copy or move a node, then any subtrees
_Nodeptr _Pnode = _Copy_or_move<_Strat>(_Rootnode->_Myval);
_Pnode->_Parent = _Wherenode;
_Pnode->_Color = _Rootnode->_Color;
if (_Newroot->_Isnil) {
_Newroot = _Pnode; // memorize new root
}
_Newroot = _Copy_or_move<_Strat>(_Rootnode->_Myval); // memorize new root
_Newroot->_Parent = _Wherenode;
_Newroot->_Color = _Rootnode->_Color;

typename _Scary_val::template _Erase_tree_and_orphan_guard<_Alnode> _Guard{_Scary, _Getal(), _Newroot};

_Newroot->_Left = _Copy_nodes<_Strat>(_Rootnode->_Left, _Newroot);
_Newroot->_Right = _Copy_nodes<_Strat>(_Rootnode->_Right, _Newroot);

_TRY_BEGIN
_Pnode->_Left = _Copy_nodes<_Strat>(_Rootnode->_Left, _Pnode);
_Pnode->_Right = _Copy_nodes<_Strat>(_Rootnode->_Right, _Pnode);
_CATCH_ALL
_Scary->_Erase_tree_and_orphan(_Getal(), _Newroot); // subtree copy failed, bail out
_RERAISE;
_CATCH_END
_Guard._Val_ptr = nullptr;
}

return _Newroot; // return newly constructed tree
Expand Down

0 comments on commit 153b940

Please sign in to comment.