diff --git a/xo-ordinaltree/include/xo/ordinaltree/RedBlackTree.hpp b/xo-ordinaltree/include/xo/ordinaltree/RedBlackTree.hpp index 36fbad36..b4aec68f 100644 --- a/xo-ordinaltree/include/xo/ordinaltree/RedBlackTree.hpp +++ b/xo-ordinaltree/include/xo/ordinaltree/RedBlackTree.hpp @@ -71,6 +71,9 @@ namespace xo { using allocator_type = Allocator; using allocator_traits = xo::gc::gc_allocator_traits; + /** WARNING: + * - GcObjectInterface is typed + assoc type is pair. + **/ using GcObjectInterface = allocator_traits::object_interface_type; using ReducedValue = typename Reduce::value_type; using RbUtil = detail::RbTreeUtil; diff --git a/xo-ordinaltree/include/xo/ordinaltree/rbtree/Node.hpp b/xo-ordinaltree/include/xo/ordinaltree/rbtree/Node.hpp index 676cabcf..530478aa 100644 --- a/xo-ordinaltree/include/xo/ordinaltree/rbtree/Node.hpp +++ b/xo-ordinaltree/include/xo/ordinaltree/rbtree/Node.hpp @@ -371,13 +371,14 @@ namespace xo { void assign_size(size_t z) { this->size_ = z; } void assign_child_reparent(Direction d, Node *new_x) { - Node *old_x = this->child_v_[d]; + Node * old_x = this->child_v_[d]; // trying to fix old_x can be counterproductive, // since old_x->parent_ may already have been corrected, // - if (old_x && (old_x->parent_ == this)) + if (old_x && (old_x->parent_ == this)) { old_x->parent_ = nullptr; + } this->child_v_[d] = new_x; @@ -386,6 +387,35 @@ namespace xo { } } /*assign_child_reparent*/ + template + void assign_child_reparent_2(NodeAllocator & alloc, + Direction d, + Node * new_x) + { + Node * old_x = this->child_v_[d]; + + using node_allocator_traits = xo::gc::gc_allocator_traits; + using kvpair_allocator_type = node_allocator_traits::template rebind_alloc; + + kvpair_allocator_type assign_alloc(alloc); + + // trying to fix old_x can be counterproductive, + // since old_x->parent_ may already have been corrected, + // + if (old_x && (old_x->parent_ == this)) { + old_x->parent_ = nullptr; + } + + Node ** child_addr = &(this->child_v_[d]); + this->_gc_assign_member(child_addr, new_x, assign_alloc); + //this->child_v_[d] = new_x; + + if (new_x) { + this->_gc_assign_member(&(new_x->parent_), this, assign_alloc); + //new_x->parent_ = this; + } + } /*assign_child_reparent*/ + /* replace child that points to x, with child that points to x_new * and return direction of the child that was replaced * diff --git a/xo-ordinaltree/include/xo/ordinaltree/rbtree/RbTreeUtil.hpp b/xo-ordinaltree/include/xo/ordinaltree/rbtree/RbTreeUtil.hpp index e1c9b74b..22539ff3 100644 --- a/xo-ordinaltree/include/xo/ordinaltree/rbtree/RbTreeUtil.hpp +++ b/xo-ordinaltree/include/xo/ordinaltree/rbtree/RbTreeUtil.hpp @@ -822,7 +822,7 @@ namespace xo { d = ((kv_pair.first < N->key()) ? D_Left : D_Right); /* insert into left subtree somewhere */ - RbNode *C = N->child(d); + RbNode * C = N->child(d); if (!C) break; @@ -835,10 +835,11 @@ namespace xo { if (N) { RbNode * new_node = RbNode::make_leaf(alloc, kv_pair, - reduce_fn.leaf(kv_pair.second)); - N->assign_child_reparent(d, new_node); + N->assign_child_reparent_2(alloc, + d, + new_node); assert(is_red(N->child(d)));