@@ -205,6 +205,30 @@ impl<T> Tree<T> {
205
205
self . vec . push ( Node :: new ( value) ) ;
206
206
unsafe { self . get_unchecked_mut ( id) }
207
207
}
208
+
209
+ /// Merge with another tree as orphan, returning the new root of tree being merged.
210
+ // Allowing this for compactness.
211
+ #[ allow( clippy:: option_map_unit_fn) ]
212
+ pub fn extend_tree ( & mut self , mut other_tree : Tree < T > ) -> NodeMut < T > {
213
+ let offset = self . vec . len ( ) ;
214
+ let offset_id = |id : NodeId | -> NodeId {
215
+ let old_index = id. to_index ( ) ;
216
+ let new_index = old_index + offset;
217
+ unsafe { NodeId :: from_index ( new_index) }
218
+ } ;
219
+ let other_tree_root_id = offset_id ( other_tree. root ( ) . id ) ;
220
+ for node in other_tree. vec . iter_mut ( ) {
221
+ node. parent . as_mut ( ) . map ( |id| * id = offset_id ( * id) ) ;
222
+ node. prev_sibling . as_mut ( ) . map ( |id| * id = offset_id ( * id) ) ;
223
+ node. next_sibling . as_mut ( ) . map ( |id| * id = offset_id ( * id) ) ;
224
+ node. children . as_mut ( ) . map ( |( id1, id2) | {
225
+ * id1 = offset_id ( * id1) ;
226
+ * id2 = offset_id ( * id2) ;
227
+ } ) ;
228
+ }
229
+ self . vec . extend ( other_tree. vec ) ;
230
+ unsafe { self . get_unchecked_mut ( other_tree_root_id) }
231
+ }
208
232
}
209
233
210
234
impl < ' a , T : ' a > NodeRef < ' a , T > {
@@ -341,6 +365,18 @@ impl<'a, T: 'a> NodeMut<'a, T> {
341
365
self . prepend_id ( id)
342
366
}
343
367
368
+ /// Appends a subtree, return the root of the merged subtree.
369
+ pub fn append_subtree ( & mut self , subtree : Tree < T > ) -> NodeMut < T > {
370
+ let root_id = self . tree . extend_tree ( subtree) . id ;
371
+ self . append_id ( root_id)
372
+ }
373
+
374
+ /// Prepends a subtree, return the root of the merged subtree.
375
+ pub fn prepend_subtree ( & mut self , subtree : Tree < T > ) -> NodeMut < T > {
376
+ let root_id = self . tree . extend_tree ( subtree) . id ;
377
+ self . prepend_id ( root_id)
378
+ }
379
+
344
380
/// Inserts a new sibling before this node.
345
381
///
346
382
/// # Panics
0 commit comments