Skip to main content

fbl/
wavl_tree.rs

1// Copyright 2026 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::ptr_traits::{ManagedPtr, PtrTraits};
6use crate::sentinel::{is_sentinel_ptr, make_sentinel, make_sentinel_null, valid_sentinel_ptr};
7use crate::size_tracker::{NonTrackingSize, SizeTracker};
8use crate::tag::DefaultObjectTag;
9use core::borrow::Borrow;
10use core::cell::UnsafeCell;
11use core::marker::PhantomData;
12use core::pin::Pin;
13use pin_init::{PinInit, pin_data, pin_init, pinned_drop};
14
15/// Trait defining an observer for a `WavlTree`.
16///
17/// Observers are used by the test framework to record the number of insert,
18/// erase, rank-promote, rank-demote, and rotation operations performed during
19/// usage. The default implementation does nothing and is optimized away.
20///
21/// Observers may also be used to maintain additional application-specific per-node
22/// invariants. For example, maintaining subtree min/max values is useful for multikey
23/// partition searching.
24///
25/// Note: Records of promotions and demotions are used by tests to demonstrate
26/// that the computational complexity of insert/erase rebalancing is amortized
27/// constant. Promotions and demotions which are side effects of the rotation
28/// phase of rebalancing are considered to be part of the cost of rotation and
29/// are not tallied in the overall promote/demote accounting.
30pub trait WavlTreeObserver {
31    /// The type pointed to by the tree pointers.
32    type Target;
33
34    /// Invoked on the newly inserted node before rebalancing.
35    fn record_insert(&self, _node: *mut Self::Target) {}
36
37    /// Invoked on the node to be inserted and each ancestor node while traversing
38    /// the tree to find the initial insertion point.
39    fn record_insert_traverse(&self, _node: *mut Self::Target, _ancestor: *mut Self::Target) {}
40
41    /// Invoked on the node to be inserted and the colliding node with the same
42    /// key, during an insert-or-find operation. This method is mutually exclusive
43    /// with `record_insert_replace`, only one or the other is invoked during an
44    /// insert operation.
45    fn record_insert_collision(&self, _node: *mut Self::Target, _collision: *mut Self::Target) {}
46
47    /// Invoked on an existing node and its replacement, before swapping the
48    /// replacement into the tree, during an insert-or-replace operation. This
49    /// method is mutually exclusive with `record_insert_collision`, only one or the
50    /// other is invoked during an insert operation.
51    fn record_insert_replace(&self, _node: *mut Self::Target, _replacement: *mut Self::Target) {}
52
53    /// Invoked after each promotion during post-insert rebalancing.
54    fn record_insert_promote(&self) {}
55
56    /// Invoked after a single rotation during post-insert rebalancing.
57    fn record_insert_rotation(&self) {}
58
59    /// Invoked after a double rotation during post-insert rebalancing.
60    fn record_insert_double_rotation(&self) {}
61
62    /// Invoked on the pivot node, its parent, children, and sibling before a
63    /// rotation, just before updating the pointers in the relevant nodes. The
64    /// chirality of the children and sibling is relative to the direction of
65    /// rotation. The direction of rotation can be determined by comparing these
66    /// arguments with the values returned by the left and right child properties
67    /// of the pivot or parent arguments.
68    ///
69    /// The following diagrams the relationship of the nodes in a left rotation:
70    ///
71    /// ```text
72    ///             pivot                          parent                             |
73    ///            /     \                         /    \                             |
74    ///        parent  rl_child  <-----------  sibling  pivot                         |
75    ///        /    \                                   /   \                         |
76    ///   sibling  lr_child                       lr_child  rl_child                  |
77    /// ```
78    ///
79    /// In a right rotation, all of the relationships are reflected.
80    fn record_rotation(
81        &self,
82        _pivot: *mut Self::Target,
83        _lr_child: *mut Self::Target,
84        _rl_child: *mut Self::Target,
85        _parent: *mut Self::Target,
86        _sibling: *mut Self::Target,
87    ) {
88    }
89
90    /// Invoked on the node to be erased and the node in the tree where the
91    /// augmented invariants become invalid, leading up to the root. Called just
92    /// after updating the pointers in the relevant nodes, but before rebalancing.
93    ///
94    /// The following diagrams the relationship of the erased and invalidated
95    /// nodes:
96    ///
97    /// ```text
98    ///        root                                                                   |
99    ///       /    \                                                                  |
100    ///      A      B    <---- Invalidated starting here on up to the root            |
101    ///     / \    / \                                                                |
102    ///    C   D  E   F  <---- Erased node                                            |
103    /// ```
104    ///
105    /// When the node to be erased has two children, it is first swapped with the
106    /// leftmost child of the righthand subtree. In this case the invalidated node
107    /// is the parent of the original leftmost child of the righthand subtree, as
108    /// this is the deepest node to change after erasure.
109    ///
110    /// ```text
111    ///        root                       root                                        |
112    ///       /    \                     /    \                                       |
113    ///      A      B                   A      B                                      |
114    ///     / \    / \                 / \    / \                                     |
115    ///    C   D  E   F  <--+         C   D  E   H    <---- Invalidated starting here |
116    ///              / \    | Swap              / \                                   |
117    ///             G   H <-+                  G   F  <---- Erased node               |
118    /// ```
119    fn record_erase(&self, _node: *mut Self::Target, _invalidated: *mut Self::Target) {}
120
121    /// Invoked after each demotion during post-erase rebalancing.
122    fn record_erase_demote(&self) {}
123
124    /// Invoked after each single rotation during post-erase rebalancing.
125    fn record_erase_rotation(&self) {}
126
127    /// Invoked after each double rotation during post-erase rebalancing.
128    fn record_erase_double_rotation(&self) {}
129
130    /// Invoked during testing to verify WAVL tree rank rules for a given node.
131    fn verify_rank_rule(
132        &self,
133        _node: *mut Self::Target,
134        _left_most: *mut Self::Target,
135        _right_most: *mut Self::Target,
136        _sentinel: *mut Self::Target,
137    ) {
138    }
139
140    /// Invoked during testing to verify tree balance properties given the tree size and depth.
141    fn verify_balance(&self, _size: usize, _depth: usize) {}
142}
143
144pub struct DefaultWavlTreeObserver<T>(PhantomData<T>);
145impl<T> Default for DefaultWavlTreeObserver<T> {
146    fn default() -> Self {
147        Self(PhantomData)
148    }
149}
150impl<T> WavlTreeObserver for DefaultWavlTreeObserver<T> {
151    type Target = T;
152}
153
154/// Traits to implement to use `WavlTreeAugmentedInvariantObserver`.
155pub trait WavlTreeAugmentedInvariantObserverTraits {
156    /// The type of the node.
157    type Target;
158    /// The type of the invariant value.
159    type Value: Copy;
160
161    /// Returns the invariant value for the given node.
162    fn get_node_value(node: &Self::Target) -> Self::Value;
163
164    /// Returns the invariant value for the given node's subtree.
165    fn get_subtree_value(node: &Self::Target) -> Self::Value;
166
167    /// Combines subtree and node invariant values to produce a new subtree invariant value.
168    ///
169    /// Values are combined in in-order (left-to-right) sequence:
170    /// `left_subtree_value` is combined with `node_value`, and the result is combined
171    /// with `right_subtree_value`.
172    ///
173    /// The operation must be associative: `(a ∘ b) ∘ c == a ∘ (b ∘ c)`.
174    /// Non-commutative operations (such as string concatenation or sequence tracking)
175    /// are supported because child and node values are strictly combined in
176    /// in-order sequence across insertions, erasures, and rotations.
177    fn combine_values(a: Self::Value, b: Self::Value) -> Self::Value;
178
179    /// Sets the node's subtree invariant value.
180    fn set_subtree_value(node: &mut Self::Target, val: Self::Value);
181
182    /// Resets the node's subtree invariant value.
183    fn reset_subtree_value(node: &mut Self::Target);
184}
185
186/// A WAVL tree observer that maintains augmented invariants.
187pub struct WavlTreeAugmentedInvariantObserver<
188    Tag,
189    Traits,
190    const ALLOW_FIND_COLLISION: bool = true,
191    const ALLOW_REPLACE_COLLISION: bool = true,
192> {
193    _phantom: PhantomData<(Tag, Traits)>,
194}
195
196impl<Tag, Traits, const ALLOW_FIND_COLLISION: bool, const ALLOW_REPLACE_COLLISION: bool> Default
197    for WavlTreeAugmentedInvariantObserver<
198        Tag,
199        Traits,
200        ALLOW_FIND_COLLISION,
201        ALLOW_REPLACE_COLLISION,
202    >
203{
204    fn default() -> Self {
205        Self { _phantom: PhantomData }
206    }
207}
208
209impl<Tag, Traits, const ALLOW_FIND_COLLISION: bool, const ALLOW_REPLACE_COLLISION: bool>
210    WavlTreeAugmentedInvariantObserver<Tag, Traits, ALLOW_FIND_COLLISION, ALLOW_REPLACE_COLLISION>
211where
212    Traits: WavlTreeAugmentedInvariantObserverTraits,
213    Traits::Target: WavlTreeContainable<Traits::Target, Tag>,
214{
215    unsafe fn recompute_until_root(&self, mut current: *mut Traits::Target) {
216        while valid_sentinel_ptr(current) {
217            let current_ref = unsafe { &*current };
218            let node_value = Traits::get_node_value(current_ref);
219            let parent = current_ref.get_node().get_parent();
220            unsafe {
221                self.update_subtree_value(node_value, current);
222            }
223            current = parent;
224        }
225    }
226
227    unsafe fn update_subtree_value(&self, mut value: Traits::Value, node: *mut Traits::Target) {
228        let node_ref = unsafe { &*node };
229        let ns = node_ref.get_node();
230
231        let left = ns.get_left();
232        if valid_sentinel_ptr(left) {
233            let left_ref = unsafe { &*left };
234            let left_val = Traits::get_subtree_value(left_ref);
235            value = Traits::combine_values(left_val, value);
236        }
237
238        let right = ns.get_right();
239        if valid_sentinel_ptr(right) {
240            let right_ref = unsafe { &*right };
241            let right_val = Traits::get_subtree_value(right_ref);
242            value = Traits::combine_values(value, right_val);
243        }
244
245        let node_mut = unsafe { &mut *node };
246        Traits::set_subtree_value(node_mut, value);
247    }
248}
249
250#[allow(clippy::not_unsafe_ptr_arg_deref)]
251impl<Tag, Traits, const ALLOW_FIND_COLLISION: bool, const ALLOW_REPLACE_COLLISION: bool>
252    WavlTreeObserver
253    for WavlTreeAugmentedInvariantObserver<
254        Tag,
255        Traits,
256        ALLOW_FIND_COLLISION,
257        ALLOW_REPLACE_COLLISION,
258    >
259where
260    Traits: WavlTreeAugmentedInvariantObserverTraits,
261    Traits::Target: WavlTreeContainable<Traits::Target, Tag>,
262{
263    type Target = Traits::Target;
264
265    fn record_insert(&self, node: *mut Self::Target) {
266        let node_ref = unsafe { &*node };
267        let parent = node_ref.get_node().get_parent();
268        let val = Traits::get_node_value(node_ref);
269        let node_mut = unsafe { &mut *node };
270        Traits::set_subtree_value(node_mut, val);
271        if valid_sentinel_ptr(parent) {
272            unsafe { self.recompute_until_root(parent) };
273        }
274    }
275
276    fn record_insert_traverse(&self, _node: *mut Self::Target, _ancestor: *mut Self::Target) {}
277
278    fn record_insert_collision(&self, _node: *mut Self::Target, _collision: *mut Self::Target) {
279        debug_assert!(ALLOW_FIND_COLLISION);
280    }
281
282    fn record_insert_replace(&self, node: *mut Self::Target, replacement: *mut Self::Target) {
283        debug_assert!(ALLOW_REPLACE_COLLISION);
284        let replacement_ref = unsafe { &*replacement };
285
286        let parent = unsafe {
287            self.update_subtree_value(Traits::get_node_value(replacement_ref), node);
288            let ns = (*node).get_node();
289            ns.get_parent()
290        };
291        if valid_sentinel_ptr(parent) {
292            unsafe {
293                self.recompute_until_root(parent);
294            }
295        }
296
297        let replacement_mut = unsafe { &mut *replacement };
298        let node_mut = unsafe { &mut *node };
299        Traits::set_subtree_value(replacement_mut, Traits::get_subtree_value(node_mut));
300        Traits::reset_subtree_value(node_mut);
301    }
302
303    fn record_rotation(
304        &self,
305        pivot: *mut Self::Target,
306        lr_child: *mut Self::Target,
307        _rl_child: *mut Self::Target,
308        parent: *mut Self::Target,
309        sibling: *mut Self::Target,
310    ) {
311        let parent_ref = unsafe { &*parent };
312        let parent_subtree_val = Traits::get_subtree_value(parent_ref);
313        let parent_ns = parent_ref.get_node();
314
315        // Determine rotation direction before links are updated.
316        // If pivot is parent's right child, it is a left rotation; otherwise a right rotation.
317        let is_left_rotation = parent_ns.get_right() == pivot;
318        let (left_child, right_child) = if is_left_rotation {
319            // Left rotation: sibling remains left child, lr_child becomes right child
320            (sibling, lr_child)
321        } else {
322            // Right rotation: lr_child becomes left child, sibling remains right child
323            (lr_child, sibling)
324        };
325
326        let mut parent_value = Traits::get_node_value(parent_ref);
327
328        if valid_sentinel_ptr(left_child) {
329            let left_ref = unsafe { &*left_child };
330            let left_val = Traits::get_subtree_value(left_ref);
331            parent_value = Traits::combine_values(left_val, parent_value);
332        }
333
334        if valid_sentinel_ptr(right_child) {
335            let right_ref = unsafe { &*right_child };
336            let right_val = Traits::get_subtree_value(right_ref);
337            parent_value = Traits::combine_values(parent_value, right_val);
338        }
339
340        let pivot_mut = unsafe { &mut *pivot };
341        Traits::set_subtree_value(pivot_mut, parent_subtree_val);
342
343        let parent_mut = unsafe { &mut *parent };
344        Traits::set_subtree_value(parent_mut, parent_value);
345    }
346
347    fn record_erase(&self, node: *mut Self::Target, invalidated: *mut Self::Target) {
348        if valid_sentinel_ptr(invalidated) {
349            unsafe { self.recompute_until_root(invalidated) };
350        }
351        let node_mut = unsafe { &mut *node };
352        Traits::reset_subtree_value(node_mut);
353    }
354}
355
356/// Trait abstracting WAVL rank operations.
357pub trait WavlTreeRank: Copy {
358    /// The default rank value for a new node.
359    const DEFAULT: Self;
360    /// Returns the rank parity (true if odd, false if even).
361    fn rank_parity(rank: Self) -> bool;
362    /// Promotes the rank by 1.
363    fn promote_rank(rank: &mut Self);
364    /// Promotes the rank by 2.
365    fn double_promote_rank(rank: &mut Self);
366    /// Demotes the rank by 1.
367    fn demote_rank(rank: &mut Self);
368    /// Demotes the rank by 2.
369    fn double_demote_rank(rank: &mut Self);
370}
371
372impl WavlTreeRank for bool {
373    const DEFAULT: Self = false;
374    fn rank_parity(rank: Self) -> bool {
375        rank
376    }
377    fn promote_rank(rank: &mut Self) {
378        *rank = !*rank;
379    }
380    fn double_promote_rank(_rank: &mut Self) {} // no-op
381    fn demote_rank(rank: &mut Self) {
382        *rank = !*rank;
383    }
384    fn double_demote_rank(_rank: &mut Self) {} // no-op
385}
386
387impl WavlTreeRank for i32 {
388    const DEFAULT: Self = 0;
389    fn rank_parity(rank: Self) -> bool {
390        (rank & 1) != 0
391    }
392    fn promote_rank(rank: &mut Self) {
393        *rank += 1;
394    }
395    fn double_promote_rank(rank: &mut Self) {
396        *rank += 2;
397    }
398    fn demote_rank(rank: &mut Self) {
399        *rank -= 1;
400    }
401    fn double_demote_rank(rank: &mut Self) {
402        *rank -= 2;
403    }
404}
405
406/// A node in a Weak AVL (WAVL) Tree.
407#[repr(C)]
408pub struct WavlTreeNode<T, R: WavlTreeRank = bool> {
409    /// The parent element in the tree.
410    pub parent: UnsafeCell<*mut T>,
411    /// The left child element in the tree.
412    pub left: UnsafeCell<*mut T>,
413    /// The right child element in the tree.
414    pub right: UnsafeCell<*mut T>,
415    /// The integer rank of this node.
416    pub rank: UnsafeCell<R>,
417}
418
419impl<T, R: WavlTreeRank> WavlTreeNode<T, R> {
420    /// Creates a new, unlinked node.
421    pub const fn new() -> Self {
422        Self {
423            parent: UnsafeCell::new(core::ptr::null_mut()),
424            left: UnsafeCell::new(core::ptr::null_mut()),
425            right: UnsafeCell::new(core::ptr::null_mut()),
426            rank: UnsafeCell::new(R::DEFAULT),
427        }
428    }
429
430    /// Returns true if the node is currently in a tree.
431    pub fn in_container(&self) -> bool {
432        // SAFETY: Accessing parent pointer from UnsafeCell is safe because WavlTree coordinates
433        // exclusive mutations on containment states, ensuring no data races.
434        !unsafe { *self.parent.get() }.is_null()
435    }
436
437    fn get_parent(&self) -> *mut T {
438        // SAFETY: Accessing parent pointer from UnsafeCell is safe because it is only read sequentially
439        // or under logical exclusive containment borrow.
440        unsafe { *self.parent.get() }
441    }
442
443    fn set_parent(&self, parent: *mut T) {
444        // SAFETY: Mutating parent pointer in UnsafeCell is safe because the parent container holds
445        // exclusive mutable borrow of the containing tree structure.
446        unsafe {
447            *self.parent.get() = parent;
448        }
449    }
450
451    fn get_left(&self) -> *mut T {
452        // SAFETY: Accessing left pointer from UnsafeCell is safe because it is only read sequentially
453        // or under logical exclusive containment borrow.
454        unsafe { *self.left.get() }
455    }
456
457    fn set_left(&self, left: *mut T) {
458        // SAFETY: Mutating left pointer in UnsafeCell is safe because the parent container holds
459        // exclusive mutable borrow of the containing tree structure.
460        unsafe {
461            *self.left.get() = left;
462        }
463    }
464
465    fn get_right(&self) -> *mut T {
466        // SAFETY: Accessing right pointer from UnsafeCell is safe because it is only read sequentially
467        // or under logical exclusive containment borrow.
468        unsafe { *self.right.get() }
469    }
470
471    fn set_right(&self, right: *mut T) {
472        // SAFETY: Mutating right pointer in UnsafeCell is safe because the parent container holds
473        // exclusive mutable borrow of the containing tree structure.
474        unsafe {
475            *self.right.get() = right;
476        }
477    }
478
479    fn rank_parity(&self) -> bool {
480        // SAFETY: Reading rank from UnsafeCell is safe because it is only read sequentially or
481        // under logical exclusive container borrow.
482        unsafe { R::rank_parity(*self.rank.get()) }
483    }
484
485    /// Returns the rank value of this node.
486    pub fn rank(&self) -> R {
487        // SAFETY: Reading rank from UnsafeCell is safe because it is only read sequentially or
488        // under logical exclusive container borrow.
489        unsafe { *self.rank.get() }
490    }
491
492    fn promote_rank(&self) {
493        // SAFETY: Mutating rank in UnsafeCell is safe because the parent container holds
494        // exclusive mutable borrow of the containing tree structure.
495        unsafe {
496            R::promote_rank(&mut *self.rank.get());
497        }
498    }
499
500    fn double_promote_rank(&self) {
501        // SAFETY: Mutating rank in UnsafeCell is safe because the parent container holds
502        // exclusive mutable borrow of the containing tree structure.
503        unsafe {
504            R::double_promote_rank(&mut *self.rank.get());
505        }
506    }
507
508    fn demote_rank(&self) {
509        // SAFETY: Mutating rank in UnsafeCell is safe because the parent container holds
510        // exclusive mutable borrow of the containing tree structure.
511        unsafe {
512            R::demote_rank(&mut *self.rank.get());
513        }
514    }
515
516    fn double_demote_rank(&self) {
517        // SAFETY: Mutating rank in UnsafeCell is safe because the parent container holds
518        // exclusive mutable borrow of the containing tree structure.
519        unsafe {
520            R::double_demote_rank(&mut *self.rank.get());
521        }
522    }
523
524    /// Returns true if the node state invariants are currently valid.
525    pub fn is_valid(&self) -> bool {
526        let parent = self.get_parent();
527        let left = self.get_left();
528        let right = self.get_right();
529        !parent.is_null() || (parent.is_null() && left.is_null() && right.is_null())
530    }
531}
532
533impl<T, R: WavlTreeRank> core::fmt::Debug for WavlTreeNode<T, R> {
534    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
535        f.debug_struct("WavlTreeNode").field("in_container", &self.in_container()).finish()
536    }
537}
538
539impl<T, R: WavlTreeRank> Default for WavlTreeNode<T, R> {
540    fn default() -> Self {
541        Self::new()
542    }
543}
544
545impl<T, R: WavlTreeRank> Drop for WavlTreeNode<T, R> {
546    fn drop(&mut self) {
547        debug_assert!(!self.in_container(), "Object destroyed while still in container");
548    }
549}
550
551/// Trait that types must implement to be contained in a `WavlTree`.
552pub trait WavlTreeContainable<T, Tag = DefaultObjectTag> {
553    /// The rank type used by this node.
554    type Rank: WavlTreeRank;
555    /// Returns a reference to the tree node.
556    fn get_node(&self) -> &WavlTreeNode<T, Self::Rank>;
557}
558
559/// Trait that types must implement to expose a key for `WavlTree` sorting and lookup.
560pub trait WavlTreeKeyable<K: ?Sized> {
561    /// The type of key yielded by `get_key`, borrowing `K`.
562    ///
563    /// Implementations may return an owned/by-value key (e.g. `(u64, usize)` or `i32`)
564    /// or a borrowed/by-reference key (e.g. `&'a KeyStruct`).
565    type Key<'a>: Borrow<K>
566    where
567        Self: 'a;
568
569    /// Returns the key of this object.
570    fn get_key(&self) -> Self::Key<'_>;
571}
572
573#[allow(dead_code)]
574trait LrTraits {
575    type Inverse: LrTraits;
576
577    fn lr_child<T, R: WavlTreeRank>(ns: &WavlTreeNode<T, R>) -> *mut T;
578    fn rl_child<T, R: WavlTreeRank>(ns: &WavlTreeNode<T, R>) -> *mut T;
579
580    fn lr_child_ptr<T, R: WavlTreeRank>(ns: &WavlTreeNode<T, R>) -> *mut *mut T;
581    fn rl_child_ptr<T, R: WavlTreeRank>(ns: &WavlTreeNode<T, R>) -> *mut *mut T;
582
583    fn lr_most<K, P, Tag, S, O>(tree: &WavlTree<K, P, Tag, S, O>) -> *mut P::Target
584    where
585        P: PtrTraits,
586        P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
587        K: Ord,
588        S: SizeTracker,
589        O: WavlTreeObserver<Target = P::Target>;
590
591    fn rl_most<K, P, Tag, S, O>(tree: &WavlTree<K, P, Tag, S, O>) -> *mut P::Target
592    where
593        P: PtrTraits,
594        P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
595        K: Ord,
596        S: SizeTracker,
597        O: WavlTreeObserver<Target = P::Target>;
598
599    unsafe fn set_lr_most<K, P, Tag, S, O>(
600        tree: &mut WavlTree<K, P, Tag, S, O>,
601        val: *mut P::Target,
602    ) where
603        P: PtrTraits,
604        P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
605        K: Ord,
606        S: SizeTracker,
607        O: WavlTreeObserver<Target = P::Target>;
608
609    unsafe fn set_rl_most<K, P, Tag, S, O>(
610        tree: &mut WavlTree<K, P, Tag, S, O>,
611        val: *mut P::Target,
612    ) where
613        P: PtrTraits,
614        P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
615        K: Ord,
616        S: SizeTracker,
617        O: WavlTreeObserver<Target = P::Target>;
618}
619
620struct ForwardTraits;
621struct ReverseTraits;
622
623impl LrTraits for ForwardTraits {
624    type Inverse = ReverseTraits;
625
626    fn lr_child<T, R: WavlTreeRank>(ns: &WavlTreeNode<T, R>) -> *mut T {
627        ns.get_left()
628    }
629    fn rl_child<T, R: WavlTreeRank>(ns: &WavlTreeNode<T, R>) -> *mut T {
630        ns.get_right()
631    }
632
633    fn lr_child_ptr<T, R: WavlTreeRank>(ns: &WavlTreeNode<T, R>) -> *mut *mut T {
634        ns.left.get()
635    }
636    fn rl_child_ptr<T, R: WavlTreeRank>(ns: &WavlTreeNode<T, R>) -> *mut *mut T {
637        ns.right.get()
638    }
639
640    fn lr_most<K, P, Tag, S, O>(tree: &WavlTree<K, P, Tag, S, O>) -> *mut P::Target
641    where
642        P: PtrTraits,
643        P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
644        K: Ord,
645        S: SizeTracker,
646        O: WavlTreeObserver<Target = P::Target>,
647    {
648        tree.left_most
649    }
650
651    fn rl_most<K, P, Tag, S, O>(tree: &WavlTree<K, P, Tag, S, O>) -> *mut P::Target
652    where
653        P: PtrTraits,
654        P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
655        K: Ord,
656        S: SizeTracker,
657        O: WavlTreeObserver<Target = P::Target>,
658    {
659        tree.right_most
660    }
661
662    unsafe fn set_lr_most<K, P, Tag, S, O>(
663        tree: &mut WavlTree<K, P, Tag, S, O>,
664        val: *mut P::Target,
665    ) where
666        P: PtrTraits,
667        P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
668        K: Ord,
669        S: SizeTracker,
670        O: WavlTreeObserver<Target = P::Target>,
671    {
672        tree.left_most = val;
673    }
674
675    unsafe fn set_rl_most<K, P, Tag, S, O>(
676        tree: &mut WavlTree<K, P, Tag, S, O>,
677        val: *mut P::Target,
678    ) where
679        P: PtrTraits,
680        P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
681        K: Ord,
682        S: SizeTracker,
683        O: WavlTreeObserver<Target = P::Target>,
684    {
685        tree.right_most = val;
686    }
687}
688
689impl LrTraits for ReverseTraits {
690    type Inverse = ForwardTraits;
691
692    fn lr_child<T, R: WavlTreeRank>(ns: &WavlTreeNode<T, R>) -> *mut T {
693        ns.get_right()
694    }
695    fn rl_child<T, R: WavlTreeRank>(ns: &WavlTreeNode<T, R>) -> *mut T {
696        ns.get_left()
697    }
698
699    fn lr_child_ptr<T, R: WavlTreeRank>(ns: &WavlTreeNode<T, R>) -> *mut *mut T {
700        ns.right.get()
701    }
702    fn rl_child_ptr<T, R: WavlTreeRank>(ns: &WavlTreeNode<T, R>) -> *mut *mut T {
703        ns.left.get()
704    }
705
706    fn lr_most<K, P, Tag, S, O>(tree: &WavlTree<K, P, Tag, S, O>) -> *mut P::Target
707    where
708        P: PtrTraits,
709        P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
710        K: Ord,
711        S: SizeTracker,
712        O: WavlTreeObserver<Target = P::Target>,
713    {
714        tree.right_most
715    }
716
717    fn rl_most<K, P, Tag, S, O>(tree: &WavlTree<K, P, Tag, S, O>) -> *mut P::Target
718    where
719        P: PtrTraits,
720        P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
721        K: Ord,
722        S: SizeTracker,
723        O: WavlTreeObserver<Target = P::Target>,
724    {
725        tree.left_most
726    }
727
728    unsafe fn set_lr_most<K, P, Tag, S, O>(
729        tree: &mut WavlTree<K, P, Tag, S, O>,
730        val: *mut P::Target,
731    ) where
732        P: PtrTraits,
733        P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
734        K: Ord,
735        S: SizeTracker,
736        O: WavlTreeObserver<Target = P::Target>,
737    {
738        tree.right_most = val;
739    }
740
741    unsafe fn set_rl_most<K, P, Tag, S, O>(
742        tree: &mut WavlTree<K, P, Tag, S, O>,
743        val: *mut P::Target,
744    ) where
745        P: PtrTraits,
746        P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
747        K: Ord,
748        S: SizeTracker,
749        O: WavlTreeObserver<Target = P::Target>,
750    {
751        tree.left_most = val;
752    }
753}
754
755/// A Weak AVL (WAVL) Tree associative container.
756///
757/// Implementation Notes:
758///
759/// WAVLTree<> is an implementation of a "Weak AVL" tree; a self
760/// balancing binary search tree whose rebalancing algorithm was
761/// originally described in
762///
763/// Bernhard Haeupler, Siddhartha Sen, and Robert E. Tarjan. 2015.
764/// Rank-Balanced Trees. ACM Trans. Algorithms 11, 4, Article 30 (June 2015), 26 pages.
765/// DOI=http://dx.doi.org/10.1145/2689412
766///
767/// See also
768/// https://en.wikipedia.org/wiki/WAVL_tree
769/// http://sidsen.azurewebsites.net/papers/rb-trees-talg.pdf
770///
771/// WAVLTree<>s, like HashTables, are associative containers and support all of
772/// the same key-centric operations (such as find() and insert_or_find()) that
773/// HashTables support.
774///
775/// Additionally, WAVLTree's are internally ordered by key (unlike HashTables
776/// which are un-ordered).  Iteration forwards or backwards runs in amortized
777/// constant time, but in O(log) time in an individual worst case.  Forward
778/// iteration will enumerate the elements in monotonically increasing order (as
779/// defined by the KeyTraits::LessThan operation).
780///
781/// Two additional operations are supported because of the ordered nature of a
782/// WAVLTree:
783/// upper_bound(key)        : Returns a cursor positioned at the first element (E) in the tree such that E.key > key.
784/// lower_bound(key)        : Returns a cursor positioned at the first element (E) in the tree such that E.key >= key.
785///
786/// The worst depth of a WAVL tree depends on whether or not the tree has ever
787/// been subject to erase operations.
788///
789/// ++ If the tree has seen only insert operations, the worst case depth of the
790///    tree is log_phi(N), where phi is the golden ratio.  This is the same bound
791///    as that of an AVL tree.
792/// ++ If the tree has seen erase operations in addition to insert operations,
793///    the worst case depth of the tree is 2*log_2(N).  This is the same bound as
794///    a Red-Black tree.
795///
796/// Insertion runs in O(log) time; finding the location takes O(log) time while
797/// post-insert rebalancing runs in amortized constant time.
798///
799/// Erase-by-key runs in O(log) time; finding the node to erase takes O(log) time
800/// while post-erase rebalancing runs in amortized constant time.
801///
802/// Because of the intrusive nature of the container, direct-erase operations
803/// (AKA, erase operations where the reference to the element to be erased is
804/// already known) run in amortized constant time.
805type TargetRank<P, Tag> =
806    <<P as PtrTraits>::Target as WavlTreeContainable<<P as PtrTraits>::Target, Tag>>::Rank;
807
808#[repr(C)]
809#[pin_data(PinnedDrop)]
810pub struct WavlTree<
811    K,
812    P,
813    Tag = DefaultObjectTag,
814    S = NonTrackingSize,
815    O = DefaultWavlTreeObserver<<P as PtrTraits>::Target>,
816> where
817    P: PtrTraits,
818    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
819    K: Ord,
820    S: SizeTracker,
821    O: WavlTreeObserver<Target = P::Target>,
822{
823    root: *mut P::Target,
824    left_most: *mut P::Target,
825    right_most: *mut P::Target,
826    size: S,
827    observer: O,
828    #[pin]
829    _pin: core::marker::PhantomPinned,
830    _phantom: core::marker::PhantomData<(K, P, Tag)>,
831}
832
833impl<K, P, Tag, S, O> WavlTree<K, P, Tag, S, O>
834where
835    P: PtrTraits,
836    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
837    K: Ord,
838    S: SizeTracker,
839    O: WavlTreeObserver<Target = P::Target>,
840{
841    /// Creates a new, empty tree with a custom observer.
842    pub fn new_with_observer(observer: O) -> impl PinInit<Self, core::convert::Infallible> {
843        pin_init!(&this in Self {
844            root: core::ptr::null_mut(),
845            left_most: make_sentinel(this.as_ptr()),
846            right_most: make_sentinel(this.as_ptr()),
847            size: S::INIT,
848            observer,
849            _pin: core::marker::PhantomPinned,
850            _phantom: core::marker::PhantomData,
851        })
852    }
853
854    /// Creates a new, empty tree.
855    pub fn new() -> impl PinInit<Self, core::convert::Infallible>
856    where
857        O: Default,
858    {
859        Self::new_with_observer(O::default())
860    }
861
862    fn get_sentinel(&self) -> *mut P::Target {
863        make_sentinel(self as *const Self as *mut Self)
864    }
865
866    /// Returns a reference to the node state of `ptr`.
867    ///
868    /// # Safety
869    ///
870    /// The caller must ensure that `ptr` is a valid, aligned, and dereferenceable pointer
871    /// to an initialized `P::Target` object that is alive for the lifetime `'a`.
872    unsafe fn get_node_ref<'a>(
873        ptr: *mut P::Target,
874    ) -> &'a WavlTreeNode<P::Target, TargetRank<P, Tag>> {
875        // SAFETY: The caller guarantees that `ptr` is valid, aligned, and dereferenceable.
876        unsafe { &(*ptr) }.get_node()
877    }
878
879    /// Returns true if the tree is empty.
880    pub fn is_empty(&self) -> bool {
881        self.root.is_null()
882    }
883
884    /// Returns a reference to the first (smallest) element of the tree, or `None` if it is empty.
885    pub fn front(&self) -> Option<&P::Target> {
886        // SAFETY: `self.left_most` is a valid pointer to a node in the tree or the sentinel.
887        // If `self.is_empty()` is false, it is guaranteed to be a valid, dereferenceable
888        // pointer to a node.
889        if self.is_empty() { None } else { unsafe { Some(&*self.left_most) } }
890    }
891
892    /// Returns a reference to the last (largest) element of the tree, or `None` if it is empty.
893    pub fn back(&self) -> Option<&P::Target> {
894        // SAFETY: `self.right_most` is a valid pointer to a node in the tree or the sentinel.
895        // If `self.is_empty()` is false, it is guaranteed to be a valid, dereferenceable
896        // pointer to a node.
897        if self.is_empty() { None } else { unsafe { Some(&*self.right_most) } }
898    }
899
900    /// Returns a mutable pointer to the pointer linking `node` into the tree.
901    ///
902    /// # Safety
903    ///
904    /// The caller must ensure that `node` is a valid, aligned, and dereferenceable pointer
905    /// to a node that is currently contained within this tree instance.
906    unsafe fn get_link_ptr_to_node(&mut self, node: *mut P::Target) -> *mut *mut P::Target {
907        debug_assert!(valid_sentinel_ptr(node));
908
909        // SAFETY: The caller guarantees that `node` is a valid pointer to a node currently in the tree.
910        let ns = unsafe { Self::get_node_ref(node) };
911        let parent = ns.get_parent();
912        if is_sentinel_ptr(parent) {
913            debug_assert_eq!(parent, self.get_sentinel());
914            debug_assert_eq!(self.root, node);
915            &mut self.root as *mut _
916        } else {
917            debug_assert!(!parent.is_null());
918            // SAFETY: `parent` is not a sentinel and is not null, so it must be a valid,
919            // dereferenceable pointer to a node in the tree.
920            let parent_ns = unsafe { Self::get_node_ref(parent) };
921            if parent_ns.get_left() == node {
922                parent_ns.left.get()
923            } else {
924                debug_assert_eq!(parent_ns.get_right(), node);
925                parent_ns.right.get()
926            }
927        }
928    }
929
930    /// Performs a tree rotation in the direction specified by `LR`.
931    ///
932    /// # Safety
933    ///
934    /// The caller must ensure that `node` and `parent` are valid, aligned, and dereferenceable
935    /// pointers to nodes currently contained within this tree instance, and that `node` is
936    /// a child of `parent` in the direction specified by `LR::Inverse`.
937    unsafe fn rotate_lr<LR: LrTraits>(&mut self, node: *mut P::Target, parent: *mut P::Target) {
938        // SAFETY: The caller guarantees that `node` and `parent` are valid pointers to nodes
939        // currently in the tree. The structural modifications (rotations) correctly permute the
940        // parent/child links while maintaining BST structural validity.
941        unsafe {
942            debug_assert!(valid_sentinel_ptr(node));
943            debug_assert!(valid_sentinel_ptr(parent));
944
945            let x = node;
946            let z = parent;
947
948            let x_ns = Self::get_node_ref(x);
949            let z_ns = Self::get_node_ref(z);
950
951            debug_assert_eq!(LR::rl_child(z_ns), x);
952
953            let x_link = LR::rl_child_ptr(z_ns);
954            let y_link = LR::lr_child_ptr(x_ns);
955            let z_link = self.get_link_ptr_to_node(z);
956
957            let g = z_ns.get_parent();
958            let y = *y_link;
959
960            debug_assert!(!is_sentinel_ptr(y));
961
962            // Permute the downstream links.
963            self.observer.record_rotation(x, y, LR::rl_child(x_ns), z, LR::lr_child(z_ns));
964            let tmp = *x_link;
965            *x_link = *y_link;
966            *y_link = *z_link;
967            *z_link = tmp;
968
969            // Update parent pointers.
970            x_ns.set_parent(g);
971            z_ns.set_parent(x);
972            if !y.is_null() {
973                Self::get_node_ref(y).set_parent(z);
974            }
975        }
976    }
977
978    /// Performs post-insertion balancing fixups.
979    ///
980    /// # Safety
981    ///
982    /// The caller must ensure that `node` and `parent` are valid, aligned, and dereferenceable
983    /// pointers to nodes currently contained within this tree instance, and that `node` is
984    /// a child of `parent` in the direction specified by `LR`.
985    unsafe fn post_insert_fixup_lr<LR: LrTraits>(
986        &mut self,
987        node: *mut P::Target,
988        parent: *mut P::Target,
989    ) {
990        type RL<LR> = <LR as LrTraits>::Inverse;
991
992        // SAFETY: The caller guarantees `node` and `parent` are valid pointers to nodes currently
993        // in the tree. The subsequent operations (including rotations and rank updates) correctly
994        // rebalance the tree according to WAVL insertion balance algorithms.
995        unsafe {
996            debug_assert!(valid_sentinel_ptr(node));
997            debug_assert!(valid_sentinel_ptr(parent));
998
999            let node_ns = Self::get_node_ref(node);
1000            let parent_ns = Self::get_node_ref(parent);
1001
1002            debug_assert_eq!(LR::lr_child(parent_ns), node);
1003
1004            let rl_child = LR::rl_child(node_ns);
1005            let rl_child_ns = if valid_sentinel_ptr(rl_child) {
1006                Some(Self::get_node_ref(rl_child))
1007            } else {
1008                None
1009            };
1010
1011            if let Some(rl_child_ns) = rl_child_ns
1012                && rl_child_ns.rank_parity() != node_ns.rank_parity()
1013            {
1014                // Case #1: double rotation.
1015                self.rotate_lr::<LR>(rl_child, node);
1016                self.rotate_lr::<RL<LR>>(rl_child, parent);
1017
1018                rl_child_ns.promote_rank();
1019                node_ns.demote_rank();
1020                parent_ns.demote_rank();
1021                self.observer.record_insert_double_rotation();
1022            } else {
1023                // Case #2: single rotation.
1024                self.rotate_lr::<RL<LR>>(node, parent);
1025                parent_ns.demote_rank();
1026                self.observer.record_insert_rotation();
1027            }
1028        }
1029    }
1030
1031    /// Rebalances the tree after an element is inserted.
1032    ///
1033    /// # Safety
1034    ///
1035    /// The caller must ensure that `node` is a valid, aligned, and dereferenceable pointer
1036    /// to a node that has just been inserted into this tree instance, and that the tree
1037    /// is structurally valid except for potential balance violations at `node` and its ancestors.
1038    unsafe fn balance_post_insert(&mut self, mut node: *mut P::Target) {
1039        // SAFETY: The caller guarantees `node` is a valid pointer to a node in the tree.
1040        // The loop climbs the tree, updating ranks and performing rotations as needed, maintaining
1041        // tree integrity.
1042        unsafe {
1043            let mut node_ns = Self::get_node_ref(node);
1044            debug_assert!(valid_sentinel_ptr(node_ns.get_parent()));
1045
1046            let mut parent = node_ns.get_parent();
1047            let mut parent_ns = Self::get_node_ref(parent);
1048
1049            if valid_sentinel_ptr(parent_ns.get_left()) && valid_sentinel_ptr(parent_ns.get_right())
1050            {
1051                return;
1052            }
1053
1054            let mut node_parity;
1055            let mut parent_parity;
1056            let mut sibling_parity;
1057            let mut is_left_child;
1058
1059            loop {
1060                // Promote.
1061                parent_ns.promote_rank();
1062                self.observer.record_insert_promote();
1063
1064                // Climb.
1065                node = parent;
1066                node_ns = Self::get_node_ref(node);
1067                parent = node_ns.get_parent();
1068
1069                if !valid_sentinel_ptr(parent) {
1070                    return;
1071                }
1072
1073                parent_ns = Self::get_node_ref(parent);
1074                is_left_child = parent_ns.get_left() == node;
1075                if is_left_child {
1076                    sibling_parity = if valid_sentinel_ptr(parent_ns.get_right()) {
1077                        Self::get_node_ref(parent_ns.get_right()).rank_parity()
1078                    } else {
1079                        true
1080                    };
1081                } else {
1082                    debug_assert_eq!(parent_ns.get_right(), node);
1083                    sibling_parity = if valid_sentinel_ptr(parent_ns.get_left()) {
1084                        Self::get_node_ref(parent_ns.get_left()).rank_parity()
1085                    } else {
1086                        true
1087                    };
1088                }
1089
1090                node_parity = node_ns.rank_parity();
1091                parent_parity = parent_ns.rank_parity();
1092
1093                if !((!node_parity && !parent_parity && sibling_parity)
1094                    || (node_parity && parent_parity && !sibling_parity))
1095                {
1096                    break;
1097                }
1098            }
1099
1100            if (node_parity != parent_parity) || (node_parity != sibling_parity) {
1101                return;
1102            }
1103
1104            if is_left_child {
1105                self.post_insert_fixup_lr::<ForwardTraits>(node, parent);
1106            } else {
1107                self.post_insert_fixup_lr::<ReverseTraits>(node, parent);
1108            }
1109        }
1110    }
1111
1112    /// Performs balance adjustments for a "2-2 leaf" node after erasure.
1113    ///
1114    /// # Safety
1115    ///
1116    /// The caller must ensure that `node` is a valid, aligned, and dereferenceable pointer
1117    /// to a node currently contained within this tree instance, and that the tree is structurally
1118    /// valid except for potential balance violations after an erasure at `node`.
1119    unsafe fn balance_post_erase_fix_22_leaf(&mut self, node: *mut P::Target) {
1120        // SAFETY: The caller guarantees `node` is a valid pointer to a node in the tree.
1121        // The function safely demotes the rank and propagates rebalancing up the tree.
1122        unsafe {
1123            debug_assert!(valid_sentinel_ptr(node));
1124
1125            let ns = Self::get_node_ref(node);
1126            if !ns.rank_parity()
1127                || valid_sentinel_ptr(ns.get_left())
1128                || valid_sentinel_ptr(ns.get_right())
1129            {
1130                return;
1131            }
1132
1133            ns.demote_rank();
1134            self.observer.record_erase_demote();
1135
1136            let parent = ns.get_parent();
1137            debug_assert!(!parent.is_null());
1138            if is_sentinel_ptr(parent) {
1139                return;
1140            }
1141
1142            let parent_ns = Self::get_node_ref(parent);
1143            let is_left_child = parent_ns.get_left() == node;
1144            debug_assert!(is_left_child || parent_ns.get_right() == node);
1145
1146            if is_left_child {
1147                self.balance_post_erase_fix_lr_3_child::<ForwardTraits>(parent);
1148            } else {
1149                self.balance_post_erase_fix_lr_3_child::<ReverseTraits>(parent);
1150            }
1151        }
1152    }
1153
1154    /// Rebalances the tree after an element is erased, resolving violations of the 3-child rule.
1155    ///
1156    /// # Safety
1157    ///
1158    /// The caller must ensure that `node` is a valid, aligned, and dereferenceable pointer
1159    /// to a node currently contained within this tree instance, and that `node` is the parent
1160    /// of a subtree that has just seen an erasure and violates the 3-child balance rule.
1161    unsafe fn balance_post_erase_fix_lr_3_child<LR: LrTraits>(&mut self, node: *mut P::Target) {
1162        type RL<LR> = <LR as LrTraits>::Inverse;
1163        // SAFETY: The caller guarantees `node` is a valid pointer to a node in the tree.
1164        // The loop walks up the tree performing rank adjustments and triggers rotations as required
1165        // by the WAVL erase balancing algorithms.
1166        unsafe {
1167            debug_assert!(valid_sentinel_ptr(node));
1168
1169            let mut z = node;
1170            let mut z_ns = Self::get_node_ref(z);
1171            let mut x = LR::lr_child(z_ns);
1172
1173            if valid_sentinel_ptr(x) != z_ns.rank_parity() {
1174                return;
1175            }
1176
1177            let mut x_is_lr_child = true;
1178            let mut y = LR::rl_child(z_ns);
1179
1180            loop {
1181                debug_assert!(valid_sentinel_ptr(y));
1182
1183                let y_ns = Self::get_node_ref(y);
1184                let y_is_2_child = y_ns.rank_parity() == z_ns.rank_parity();
1185
1186                if !y_is_2_child {
1187                    let y_is_22_node = if y_ns.rank_parity() {
1188                        (!valid_sentinel_ptr(y_ns.get_left())
1189                            || Self::get_node_ref(y_ns.get_left()).rank_parity())
1190                            && (!valid_sentinel_ptr(y_ns.get_right())
1191                                || Self::get_node_ref(y_ns.get_right()).rank_parity())
1192                    } else {
1193                        valid_sentinel_ptr(y_ns.get_left())
1194                            && valid_sentinel_ptr(y_ns.get_right())
1195                            && !Self::get_node_ref(y_ns.get_left()).rank_parity()
1196                            && !Self::get_node_ref(y_ns.get_right()).rank_parity()
1197                    };
1198
1199                    if !y_is_22_node {
1200                        break;
1201                    }
1202                }
1203
1204                z_ns.demote_rank();
1205                self.observer.record_erase_demote();
1206                if !y_is_2_child {
1207                    y_ns.demote_rank();
1208                    self.observer.record_erase_demote();
1209                }
1210
1211                if !valid_sentinel_ptr(z_ns.get_parent()) {
1212                    return;
1213                }
1214
1215                let x_rank_parity = z_ns.rank_parity();
1216                x = z;
1217                z = z_ns.get_parent();
1218                z_ns = Self::get_node_ref(z);
1219
1220                if z_ns.rank_parity() == x_rank_parity {
1221                    return;
1222                }
1223
1224                x_is_lr_child = LR::lr_child(z_ns) == x;
1225                y = if x_is_lr_child { LR::rl_child(z_ns) } else { LR::lr_child(z_ns) };
1226            }
1227
1228            if x_is_lr_child {
1229                self.balance_post_erase_do_rotations::<LR>(y, z);
1230            } else {
1231                self.balance_post_erase_do_rotations::<RL<LR>>(y, z);
1232            }
1233        }
1234    }
1235
1236    /// Performs necessary rotations during post-erase rebalancing.
1237    ///
1238    /// # Safety
1239    ///
1240    /// The caller must ensure that `y` and `z` are valid, aligned, and dereferenceable
1241    /// pointers to nodes currently contained within this tree instance, and that `y` is the
1242    /// right child of `z` in the direction specified by `LR`.
1243    unsafe fn balance_post_erase_do_rotations<LR: LrTraits>(
1244        &mut self,
1245        y: *mut P::Target,
1246        z: *mut P::Target,
1247    ) {
1248        type RL<LR> = <LR as LrTraits>::Inverse;
1249        // SAFETY: The caller guarantees `y` and `z` are valid pointers to nodes in the tree.
1250        // The rotations correctly rebalance the tree at `z` and update ranks accordingly.
1251        unsafe {
1252            debug_assert!(valid_sentinel_ptr(y));
1253            debug_assert!(valid_sentinel_ptr(z));
1254
1255            let y_ns = Self::get_node_ref(y);
1256            let z_ns = Self::get_node_ref(z);
1257
1258            let w = LR::rl_child(y_ns);
1259            let w_rank_parity =
1260                if valid_sentinel_ptr(w) { Self::get_node_ref(w).rank_parity() } else { true };
1261
1262            if y_ns.rank_parity() != w_rank_parity {
1263                self.rotate_lr::<LR>(y, z);
1264                y_ns.promote_rank();
1265
1266                if !valid_sentinel_ptr(z_ns.get_left()) && !valid_sentinel_ptr(z_ns.get_right()) {
1267                    z_ns.double_demote_rank();
1268                } else {
1269                    z_ns.demote_rank();
1270                }
1271                self.observer.record_erase_rotation();
1272            } else {
1273                let v = LR::lr_child(y_ns);
1274                debug_assert!(valid_sentinel_ptr(v));
1275                let v_ns = Self::get_node_ref(v);
1276                debug_assert_ne!(v_ns.rank_parity(), y_ns.rank_parity());
1277
1278                self.rotate_lr::<RL<LR>>(v, y);
1279                self.rotate_lr::<LR>(v, z);
1280
1281                v_ns.double_promote_rank();
1282                y_ns.demote_rank();
1283                z_ns.double_demote_rank();
1284                self.observer.record_erase_double_rotation();
1285            }
1286        }
1287    }
1288
1289    /// Promotes the single child of `node` (in direction `LR`) to take `node`'s place in the tree.
1290    ///
1291    /// # Safety
1292    ///
1293    /// - `owner` must be a valid, aligned, dereferenceable pointer to a `*mut P::Target`.
1294    /// - `*owner` must be `null_mut()`.
1295    /// - `node` must be a valid, aligned, dereferenceable pointer to a node currently in the tree.
1296    /// - `node` must have exactly one child in the direction specified by `LR` (which must be
1297    ///   a valid non-null, non-sentinel node), and must NOT have a valid child in the opposite direction.
1298    unsafe fn promote_lr_child<LR: LrTraits>(
1299        &mut self,
1300        owner: *mut *mut P::Target,
1301        node: *mut P::Target,
1302    ) {
1303        // SAFETY: The caller must guarantee that `owner` is a valid, aligned, dereferenceable pointer
1304        // to `*mut P::Target` containing `null_mut()`, that `node` is a valid node in the tree,
1305        // and that the node has exactly one child in the `LR` direction to promote.
1306        unsafe {
1307            debug_assert!((*owner).is_null());
1308            debug_assert!(valid_sentinel_ptr(node));
1309
1310            let ns = Self::get_node_ref(node);
1311            let lr_child_ptr = LR::lr_child_ptr(ns);
1312            let rl_child_ptr = LR::rl_child_ptr(ns);
1313
1314            debug_assert!(valid_sentinel_ptr(*lr_child_ptr) && !valid_sentinel_ptr(*rl_child_ptr));
1315
1316            *owner = *lr_child_ptr;
1317            *lr_child_ptr = core::ptr::null_mut();
1318            Self::get_node_ref(*owner).set_parent(ns.get_parent());
1319
1320            let rl_most = LR::rl_most(self);
1321            debug_assert_eq!(rl_most == node, is_sentinel_ptr(*rl_child_ptr));
1322
1323            if is_sentinel_ptr(*rl_child_ptr) {
1324                let mut replacement = *owner;
1325                let mut next_rl_child_ptr;
1326
1327                loop {
1328                    let replacement_ns = Self::get_node_ref(replacement);
1329                    next_rl_child_ptr = LR::rl_child_ptr(replacement_ns);
1330
1331                    debug_assert!(!is_sentinel_ptr(*next_rl_child_ptr));
1332                    if (*next_rl_child_ptr).is_null() {
1333                        break;
1334                    }
1335                    replacement = *next_rl_child_ptr;
1336                }
1337
1338                LR::set_rl_most(self, replacement);
1339                *next_rl_child_ptr = self.get_sentinel();
1340                *rl_child_ptr = core::ptr::null_mut();
1341            }
1342
1343            ns.set_parent(core::ptr::null_mut());
1344            debug_assert!(ns.get_left().is_null());
1345            debug_assert!(ns.get_right().is_null());
1346        }
1347    }
1348
1349    /// Physically swaps the position of `node1` (pointed to by `ptr_ref1`) with `node2`
1350    /// (pointed to by `ptr_ref2`) in the tree's pointer structure.
1351    ///
1352    /// E.g. `node2` must be the leftmost descendant of the right child of `node1`.
1353    ///
1354    /// Returns the pointer to the slot originally containing `node2` (which now contains `node1`).
1355    ///
1356    /// # Safety
1357    ///
1358    /// - `ptr_ref1` must be a valid, aligned, dereferenceable pointer to `*mut P::Target`
1359    ///   which contains a valid, aligned, dereferenceable pointer to `node1`.
1360    /// - `ptr_ref2` must be a valid, aligned, dereferenceable pointer to `*mut P::Target`
1361    ///   which contains a valid, aligned, dereferenceable pointer to `node2`.
1362    /// - `node2` must be a descendant of `node1`'s right subtree.
1363    /// - Both `node1` and `node2` must reside within the same tree.
1364    unsafe fn swap_with_right_descendant(
1365        &mut self,
1366        ptr_ref1: *mut *mut P::Target,
1367        ptr_ref2: *mut *mut P::Target,
1368    ) -> *mut *mut P::Target {
1369        // SAFETY: The caller must guarantee that `ptr_ref1` and `ptr_ref2` are valid, aligned
1370        // pointers pointing to valid nodes in the tree, and that `node2` is a descendant in the
1371        // right subtree of `node1`. This method performs structural pointer manipulation to swap
1372        // the nodes physically, preserving local tree structure.
1373        unsafe {
1374            let node1 = *ptr_ref1;
1375            let node2 = *ptr_ref2;
1376
1377            let ns1 = Self::get_node_ref(node1);
1378            let ns2 = Self::get_node_ref(node2);
1379
1380            if ns1.get_right().is_null() {
1381                panic!("node1 right is NULL inside swap");
1382            }
1383
1384            let ns1_lp = if valid_sentinel_ptr(ns1.get_left()) {
1385                Self::get_node_ref(ns1.get_left()).parent.get()
1386            } else {
1387                core::ptr::null_mut()
1388            };
1389
1390            let ns2_lp = if valid_sentinel_ptr(ns2.get_left()) {
1391                Self::get_node_ref(ns2.get_left()).parent.get()
1392            } else {
1393                core::ptr::null_mut()
1394            };
1395
1396            let ns2_rp = if valid_sentinel_ptr(ns2.get_right()) {
1397                Self::get_node_ref(ns2.get_right()).parent.get()
1398            } else {
1399                core::ptr::null_mut()
1400            };
1401
1402            let r1 = ns1.get_right();
1403            if !valid_sentinel_ptr(r1) {
1404                if r1.is_null() {
1405                    panic!("ns1.get_right() is NULL");
1406                } else if is_sentinel_ptr(r1) {
1407                    panic!("ns1.get_right() is SENTINEL");
1408                } else {
1409                    panic!("ns1.get_right() is OTHER INVALID");
1410                }
1411            }
1412            let ns1_rp = Self::get_node_ref(ns1.get_right()).parent.get();
1413
1414            if node1 == self.left_most {
1415                self.left_most = node2;
1416            }
1417            if node2 == self.right_most {
1418                self.right_most = node1;
1419            }
1420
1421            // Swap parent.
1422            let parent_tmp = ns1.get_parent();
1423            ns1.set_parent(ns2.get_parent());
1424            ns2.set_parent(parent_tmp);
1425
1426            // Swap left.
1427            let left_tmp = ns1.get_left();
1428            ns1.set_left(ns2.get_left());
1429            ns2.set_left(left_tmp);
1430
1431            // Swap right.
1432            let right_tmp = ns1.get_right();
1433            ns1.set_right(ns2.get_right());
1434            ns2.set_right(right_tmp);
1435
1436            // Swap rank.
1437            let rank_tmp = *ns1.rank.get();
1438            *ns1.rank.get() = *ns2.rank.get();
1439            *ns2.rank.get() = rank_tmp;
1440
1441            if !ns1_lp.is_null() {
1442                *ns1_lp = node2;
1443            }
1444            if !ns2_lp.is_null() {
1445                *ns2_lp = node1;
1446            }
1447            if !ns2_rp.is_null() {
1448                *ns2_rp = node1;
1449            }
1450
1451            if ptr_ref2 != ns1.right.get() {
1452                #[allow(clippy::swap_ptr_to_ref)]
1453                core::mem::swap(&mut *ptr_ref1, &mut *ptr_ref2);
1454                *ns1_rp = node2;
1455                ptr_ref2
1456            } else {
1457                debug_assert_eq!(*ns1.parent.get(), node1);
1458                debug_assert_eq!(*ns2.right.get(), node2);
1459                #[allow(clippy::swap_ptr_to_ref)]
1460                core::mem::swap(&mut *ptr_ref1, &mut *ns2.right.get());
1461                *ns1.parent.get() = node2;
1462                ns2.right.get()
1463            }
1464        }
1465    }
1466
1467    /// Inserts a new node `ptr` into the WAVL tree.
1468    ///
1469    /// If a node with an identical key already exists, does not insert it, stores the colliding node's
1470    /// pointer in `collision`, and returns the original `ptr` as `Err(ptr)`.
1471    ///
1472    /// # Safety
1473    ///
1474    /// - `ptr` must wrap a valid, properly aligned, dereferenceable node.
1475    /// - The node must NOT be currently contained in this or any other intrusive container.
1476    /// - `collision` must be a valid, aligned, dereferenceable pointer to `*mut P::Target`.
1477    unsafe fn internal_insert(&mut self, ptr: P, collision: &mut *mut P::Target) -> Result<(), P> {
1478        // SAFETY: The caller guarantees that `ptr` represents a valid, unlinked node, and that
1479        // `collision` is a valid slot. Dereferencing pointers and mutating the parent/child links
1480        // preserves tree structure.
1481        unsafe {
1482            let raw = P::into_raw(ptr);
1483            debug_assert!(!raw.is_null());
1484
1485            let ns = Self::get_node_ref(raw);
1486            debug_assert!(ns.is_valid() && !ns.in_container());
1487
1488            *ns.rank.get() = <TargetRank<P, Tag>>::DEFAULT;
1489
1490            if self.root.is_null() {
1491                ns.set_parent(self.get_sentinel());
1492                ns.set_left(self.get_sentinel());
1493                ns.set_right(self.get_sentinel());
1494
1495                debug_assert!(is_sentinel_ptr(self.left_most) && is_sentinel_ptr(self.right_most));
1496                self.left_most = raw;
1497                self.right_most = raw;
1498
1499                self.root = raw;
1500                self.size.increment();
1501                self.observer.record_insert(raw);
1502                return Ok(());
1503            }
1504
1505            let key = (*raw).get_key();
1506            let key_borrow = key.borrow();
1507            let mut is_left_most = true;
1508            let mut is_right_most = true;
1509            let mut parent = self.root;
1510            let mut owner: *mut *mut P::Target;
1511
1512            loop {
1513                let parent_key = (*parent).get_key();
1514                let parent_key_borrow = parent_key.borrow();
1515                self.observer.record_insert_traverse(raw, parent);
1516
1517                if key_borrow == parent_key_borrow {
1518                    *collision = parent;
1519                    self.observer.record_insert_collision(raw, parent);
1520                    return Err(P::from_raw(raw));
1521                }
1522
1523                let parent_ns = Self::get_node_ref(parent);
1524
1525                if key_borrow < parent_key_borrow {
1526                    owner = parent_ns.left.get();
1527                    is_right_most = false;
1528                } else {
1529                    owner = parent_ns.right.get();
1530                    is_left_most = false;
1531                }
1532
1533                if !valid_sentinel_ptr(*owner) {
1534                    break;
1535                }
1536
1537                parent = *owner;
1538            }
1539
1540            debug_assert!(!is_left_most || !is_right_most);
1541
1542            if is_right_most {
1543                debug_assert!(is_sentinel_ptr(*owner));
1544                ns.set_right(self.get_sentinel());
1545                self.right_most = raw;
1546            } else if is_left_most {
1547                debug_assert!(is_sentinel_ptr(*owner));
1548                ns.set_left(self.get_sentinel());
1549                self.left_most = raw;
1550            }
1551
1552            debug_assert!(!valid_sentinel_ptr(*owner));
1553            ns.set_parent(parent);
1554
1555            *owner = raw;
1556            self.size.increment();
1557            self.observer.record_insert(raw);
1558
1559            self.balance_post_insert(*owner);
1560            Ok(())
1561        }
1562    }
1563
1564    /// Removes the node `ptr` from the WAVL tree, rebalancing if necessary.
1565    ///
1566    /// Returns the node wrapped in `P` if it was successfully erased and returned.
1567    ///
1568    /// # Safety
1569    ///
1570    /// - `ptr` must be a valid, properly aligned, dereferenceable raw pointer to a node.
1571    /// - If the node is not null or sentinel, it MUST be currently contained within this tree.
1572    unsafe fn internal_erase(&mut self, ptr: *mut P::Target) -> Option<P> {
1573        // SAFETY: The caller guarantees that `ptr` points to a valid node belonging to this tree.
1574        // Removing it involves swapping it out structurally, repairing BST/WAVL invariants,
1575        // and reclaiming ownership via `P::from_raw`.
1576        unsafe {
1577            if !valid_sentinel_ptr(ptr) {
1578                return None;
1579            }
1580
1581            let ns = Self::get_node_ref(ptr);
1582            let mut owner = self.get_link_ptr_to_node(ptr);
1583            debug_assert_eq!(*owner, ptr);
1584
1585            if valid_sentinel_ptr(ns.get_left()) && valid_sentinel_ptr(ns.get_right()) {
1586                let mut new_owner = ns.right.get();
1587                let mut new_ns = Self::get_node_ref(ns.get_right());
1588
1589                while !new_ns.get_left().is_null() {
1590                    debug_assert!(!is_sentinel_ptr(new_ns.get_left()));
1591                    new_owner = new_ns.left.get();
1592                    new_ns = Self::get_node_ref(*new_owner);
1593                }
1594
1595                owner = self.swap_with_right_descendant(owner, new_owner);
1596                debug_assert_eq!(*owner, ptr);
1597            }
1598
1599            let parent = ns.get_parent();
1600            debug_assert!(!parent.is_null());
1601            let (was_one_child, was_left_child) = if !is_sentinel_ptr(parent) {
1602                let parent_ns = Self::get_node_ref(parent);
1603                (ns.rank_parity() != parent_ns.rank_parity(), parent_ns.left.get() == owner)
1604            } else {
1605                (false, false)
1606            };
1607
1608            *owner = core::ptr::null_mut();
1609
1610            let target = ptr;
1611            if valid_sentinel_ptr(ns.get_left()) {
1612                self.promote_lr_child::<ForwardTraits>(owner, target);
1613            } else if valid_sentinel_ptr(ns.get_right()) {
1614                self.promote_lr_child::<ReverseTraits>(owner, target);
1615            } else {
1616                debug_assert_eq!(is_sentinel_ptr(ns.get_left()), self.left_most == target);
1617                debug_assert_eq!(is_sentinel_ptr(ns.get_right()), self.right_most == target);
1618
1619                if is_sentinel_ptr(ns.get_left()) {
1620                    if is_sentinel_ptr(ns.get_right()) {
1621                        if S::IS_TRACKING {
1622                            debug_assert_eq!(self.size.get(), 1);
1623                        }
1624                        debug_assert!(is_sentinel_ptr(ns.get_parent()));
1625                        self.left_most = self.get_sentinel();
1626                        self.right_most = self.get_sentinel();
1627                        ns.set_left(core::ptr::null_mut());
1628                        ns.set_right(core::ptr::null_mut());
1629                    } else {
1630                        debug_assert!(valid_sentinel_ptr(ns.get_parent()));
1631                        debug_assert!(ns.get_right().is_null());
1632                        self.left_most = ns.get_parent();
1633                        *owner = ns.get_left();
1634                        ns.set_left(core::ptr::null_mut());
1635                    }
1636                } else if is_sentinel_ptr(ns.get_right()) {
1637                    debug_assert!(valid_sentinel_ptr(ns.get_parent()));
1638                    debug_assert!(ns.get_left().is_null());
1639                    self.right_most = ns.get_parent();
1640                    *owner = ns.get_right();
1641                    ns.set_right(core::ptr::null_mut());
1642                }
1643
1644                ns.set_parent(core::ptr::null_mut());
1645            }
1646
1647            debug_assert!(ns.is_valid() && !ns.in_container());
1648            self.observer.record_erase(target, parent);
1649
1650            self.size.decrement();
1651
1652            if !is_sentinel_ptr(parent) {
1653                if was_one_child {
1654                    self.balance_post_erase_fix_22_leaf(parent);
1655                } else {
1656                    if was_left_child {
1657                        self.balance_post_erase_fix_lr_3_child::<ForwardTraits>(parent);
1658                    } else {
1659                        self.balance_post_erase_fix_lr_3_child::<ReverseTraits>(parent);
1660                    }
1661                }
1662            }
1663
1664            Some(P::from_raw(target))
1665        }
1666    }
1667
1668    /// Replaces `old_node` with `new_node` in the tree's pointer structure.
1669    ///
1670    /// Returns the `old_node` wrapped in `P`.
1671    ///
1672    /// # Safety
1673    ///
1674    /// - `old_node` must be a valid, aligned, dereferenceable pointer to a node currently
1675    ///   contained within this tree.
1676    /// - `new_node` must be a valid node not currently contained in this or any other tree.
1677    /// - The key of `new_node` must exactly match the key of `old_node` to preserve the
1678    ///   Binary Search Tree (BST) ordering invariant.
1679    unsafe fn internal_swap(&mut self, old_node: *mut P::Target, new_node: P) -> Option<P> {
1680        // SAFETY: The caller must guarantee that `old_node` is in this tree, that `new_node`
1681        // is unlinked, and that their keys match. This method updates all parent and child
1682        // links to point to the new node, and reclaims ownership of `old_node`.
1683        unsafe {
1684            debug_assert!(!old_node.is_null());
1685            let new_raw = P::into_raw(new_node);
1686            debug_assert!(!new_raw.is_null());
1687            debug_assert!((*old_node).get_key().borrow() == (*new_raw).get_key().borrow());
1688
1689            let old_ns = Self::get_node_ref(old_node);
1690            let new_ns = Self::get_node_ref(new_raw);
1691
1692            debug_assert!(old_ns.in_container());
1693            debug_assert!(!new_ns.in_container());
1694            self.observer.record_insert_replace(old_node, new_raw);
1695
1696            if valid_sentinel_ptr(old_ns.get_left()) {
1697                Self::get_node_ref(old_ns.get_left()).set_parent(new_raw);
1698            } else {
1699                if is_sentinel_ptr(old_ns.get_left()) {
1700                    debug_assert_eq!(self.left_most, old_node);
1701                    self.left_most = new_raw;
1702                }
1703            }
1704            new_ns.set_left(old_ns.get_left());
1705            old_ns.set_left(core::ptr::null_mut());
1706
1707            if valid_sentinel_ptr(old_ns.get_right()) {
1708                Self::get_node_ref(old_ns.get_right()).set_parent(new_raw);
1709            } else {
1710                if is_sentinel_ptr(old_ns.get_right()) {
1711                    debug_assert_eq!(self.right_most, old_node);
1712                    self.right_most = new_raw;
1713                }
1714            }
1715            new_ns.set_right(old_ns.get_right());
1716            old_ns.set_right(core::ptr::null_mut());
1717
1718            *new_ns.rank.get() = *old_ns.rank.get();
1719
1720            *self.get_link_ptr_to_node(old_node) = new_raw;
1721            new_ns.set_parent(old_ns.get_parent());
1722            old_ns.set_parent(core::ptr::null_mut());
1723
1724            Some(P::from_raw(old_node))
1725        }
1726    }
1727
1728    /// Advances the node pointer `node` in-place to the next node in-order
1729    /// (according to the direction specified by `LR`).
1730    ///
1731    /// # Safety
1732    ///
1733    /// - `node` must be a valid, aligned, dereferenceable pointer to a raw pointer `*node`.
1734    /// - `*node` must point to a valid node currently contained within this tree.
1735    unsafe fn advance<LR: LrTraits>(node: &mut *mut P::Target) {
1736        // SAFETY: The caller must ensure that `*node` is a valid pointer to a node in this tree.
1737        // Traveling through parent/child links is safe as long as the tree structure is valid
1738        // and the node belongs to the tree.
1739        unsafe {
1740            debug_assert!(valid_sentinel_ptr(*node));
1741
1742            let mut ns = Self::get_node_ref(*node);
1743            let rl_child = LR::rl_child(ns);
1744            if !rl_child.is_null() {
1745                *node = rl_child;
1746
1747                if is_sentinel_ptr(*node) {
1748                    return;
1749                }
1750
1751                let mut lr_child = LR::lr_child(Self::get_node_ref(*node));
1752                while !lr_child.is_null() {
1753                    debug_assert!(!is_sentinel_ptr(lr_child));
1754                    *node = lr_child;
1755                    lr_child = LR::lr_child(Self::get_node_ref(*node));
1756                }
1757                return;
1758            }
1759
1760            let mut done;
1761            ns = Self::get_node_ref(*node);
1762            loop {
1763                debug_assert!(valid_sentinel_ptr(ns.get_parent()));
1764
1765                let parent_ns = Self::get_node_ref(ns.get_parent());
1766                done = LR::lr_child(parent_ns) == *node;
1767
1768                debug_assert!(done || LR::rl_child(parent_ns) == *node);
1769
1770                *node = ns.get_parent();
1771                ns = parent_ns;
1772
1773                if done {
1774                    break;
1775                }
1776            }
1777        }
1778    }
1779
1780    /// Advances `node` in-place to its in-order successor in the tree (setting `*node` to null
1781    /// once the end of the tree is reached), or sets `*node` to null if `*node` is already null
1782    /// or a sentinel pointer.
1783    ///
1784    /// # Safety
1785    ///
1786    /// - `node` must be a valid, aligned, dereferenceable mutable reference to a raw pointer.
1787    /// - `*node` must either be null/sentinel or point to a valid node currently contained within
1788    ///   a `WavlTree` whose structure is not being concurrently modified.
1789    pub unsafe fn successor_raw(node: &mut *mut P::Target) {
1790        if valid_sentinel_ptr(*node) {
1791            // SAFETY: `*node` is verified to be non-null and non-sentinel, and the caller
1792            // guarantees it points to a valid node in an unmodified WavlTree.
1793            unsafe {
1794                Self::advance::<ForwardTraits>(node);
1795            }
1796            if is_sentinel_ptr(*node) {
1797                *node = core::ptr::null_mut();
1798            }
1799        } else {
1800            *node = core::ptr::null_mut();
1801        }
1802    }
1803
1804    /// Inserts an element into the tree.
1805    ///
1806    /// For raw pointers, use [`insert_raw`] instead.
1807    pub fn insert(&mut self, ptr: P)
1808    where
1809        P: ManagedPtr,
1810    {
1811        // SAFETY: `P` is a `ManagedPtr`, which guarantees that the pointer is valid and that the
1812        // object will outlive its reference from this tree.
1813        unsafe { self.insert_raw(ptr) }
1814    }
1815
1816    /// Inserts an element into the tree.
1817    ///
1818    /// # Safety
1819    ///
1820    /// The caller must ensure that `ptr` is a valid pointer to a `T` and that the object outlives
1821    /// the reference from the tree.
1822    pub unsafe fn insert_raw(&mut self, ptr: P) {
1823        let mut collision = core::ptr::null_mut();
1824        // SAFETY: The caller guarantees `ptr` is valid and outlives the tree registration.
1825        let _ = unsafe { self.internal_insert(ptr, &mut collision) };
1826    }
1827
1828    /// Inserts the object pointed to by `ptr` if it is not already in the tree,
1829    /// or finds the object that `ptr` collided with instead.
1830    ///
1831    /// For raw pointers, use [`insert_or_find_raw`] instead.
1832    ///
1833    /// # Returns
1834    ///
1835    /// * `Ok(())` if there was no collision and the item was successfully inserted.
1836    ///   In this case, the tree takes ownership of `ptr`.
1837    /// * `Err((ptr, cursor))` if there was a collision. In this case, the
1838    ///   passed pointer `ptr` is returned back to the caller (not consumed), along with
1839    ///   a `CursorMut` positioned at the colliding node already in the tree.
1840    pub fn insert_or_find<'a>(&'a mut self, ptr: P) -> InsertOrFindResult<'a, K, P, Tag, S, O>
1841    where
1842        P: ManagedPtr,
1843    {
1844        // SAFETY: `P` is a `ManagedPtr`, which guarantees that the pointer is valid and that the
1845        // object will outlive its reference from this tree.
1846        unsafe { self.insert_or_find_raw(ptr) }
1847    }
1848
1849    /// Inserts the object pointed to by `ptr` if it is not already in the tree,
1850    /// or finds the object that `ptr` collided with instead.
1851    ///
1852    /// # Safety
1853    ///
1854    /// The caller must ensure that `ptr` is a valid pointer to a `T` and that the object outlives
1855    /// the reference from the tree.
1856    pub unsafe fn insert_or_find_raw<'a>(
1857        &'a mut self,
1858        ptr: P,
1859    ) -> InsertOrFindResult<'a, K, P, Tag, S, O> {
1860        let mut collision = core::ptr::null_mut();
1861        // SAFETY: The caller guarantees `ptr` is valid and outlives the tree registration.
1862        // If a collision occurs, `collision` is guaranteed to be a valid pointer to the colliding
1863        // node in this tree, which allows us to safely construct a `CursorMut` pointing to it.
1864        unsafe {
1865            match self.internal_insert(ptr, &mut collision) {
1866                Ok(()) => Ok(()),
1867                Err(ptr) => Err((ptr, CursorMut { tree: self, current: collision })),
1868            }
1869        }
1870    }
1871
1872    /// Finds the element in the tree with the same key as `*ptr` and replaces
1873    /// it with `ptr`, returning the element which was replaced.
1874    ///
1875    /// If no element in the tree shares a key with `*ptr`, simply adds `ptr` to
1876    /// the tree and returns `None`.
1877    ///
1878    /// In both cases, the input pointer `ptr` is consumed.
1879    ///
1880    /// For raw pointers, use [`insert_or_replace_raw`] instead.
1881    ///
1882    /// # Returns
1883    ///
1884    /// `Some(replaced)` containing the previous element if a collision occurred,
1885    /// or `None` if the element was newly inserted.
1886    pub fn insert_or_replace(&mut self, ptr: P) -> Option<P>
1887    where
1888        P: ManagedPtr,
1889    {
1890        // SAFETY: `P` is a `ManagedPtr`, which guarantees that the pointer is valid and that the
1891        // object will outlive its reference from this tree.
1892        unsafe { self.insert_or_replace_raw(ptr) }
1893    }
1894
1895    /// Finds the element in the tree with the same key as `*ptr` and replaces
1896    /// it with `ptr`, returning the element which was replaced.
1897    ///
1898    /// If no element in the tree shares a key with `*ptr`, simply adds `ptr` to
1899    /// the tree and returns `None`.
1900    ///
1901    /// # Safety
1902    ///
1903    /// The caller must ensure that `ptr` is a valid pointer to a `T` and that the object outlives
1904    /// the reference from the tree.
1905    pub unsafe fn insert_or_replace_raw(&mut self, ptr: P) -> Option<P> {
1906        let mut collision = core::ptr::null_mut();
1907        // SAFETY: The caller guarantees `ptr` is valid and outlives the tree registration.
1908        // If a collision occurs, `collision` points to a valid node in the tree sharing the same key,
1909        // making it safe to swap `collision` with `ptr` via `internal_swap`.
1910        unsafe {
1911            match self.internal_insert(ptr, &mut collision) {
1912                Ok(()) => None,
1913                Err(ptr) => self.internal_swap(collision, ptr),
1914            }
1915        }
1916    }
1917
1918    /// Removes and returns the first (smallest) element of the tree, or `None` if it is empty.
1919    pub fn pop_front(&mut self) -> Option<P> {
1920        if self.is_empty() {
1921            None
1922        } else {
1923            // SAFETY: If `self.is_empty()` is false, `self.left_most` is guaranteed to be a valid
1924            // pointer to a node currently contained in this tree instance.
1925            unsafe { self.internal_erase(self.left_most) }
1926        }
1927    }
1928
1929    /// Removes and returns the last (largest) element of the tree, or `None` if it is empty.
1930    pub fn pop_back(&mut self) -> Option<P> {
1931        if self.is_empty() {
1932            None
1933        } else {
1934            // SAFETY: If `self.is_empty()` is false, `self.right_most` is guaranteed to be a valid
1935            // pointer to a node currently contained in this tree instance.
1936            unsafe { self.internal_erase(self.right_most) }
1937        }
1938    }
1939
1940    /// Removes all elements from the tree.
1941    pub fn clear(&mut self) {
1942        while !self.is_empty() {
1943            self.pop_front();
1944        }
1945    }
1946
1947    /// Swaps the contents of this tree with another tree.
1948    ///
1949    /// This runs in O(1) time.
1950    pub fn swap(&mut self, other: &mut Self) {
1951        // Swap all fields except _pin and _phantom.
1952        core::mem::swap(&mut self.root, &mut other.root);
1953        core::mem::swap(&mut self.left_most, &mut other.left_most);
1954        core::mem::swap(&mut self.right_most, &mut other.right_most);
1955        core::mem::swap(&mut self.size, &mut other.size);
1956        core::mem::swap(&mut self.observer, &mut other.observer);
1957
1958        // Now repair the sentinel pointers which are self-referential.
1959        self.fix_sentinels_after_swap(other);
1960    }
1961
1962    fn fix_sentinels_after_swap(&mut self, other: &mut Self) {
1963        let self_sentinel = self.get_sentinel();
1964        let other_sentinel = other.get_sentinel();
1965
1966        // For `self` (which currently contains `other`'s old nodes):
1967        // The old sentinel in these nodes is `other_sentinel`. We update them to `self_sentinel`.
1968        if self.root.is_null() {
1969            self.left_most = self_sentinel;
1970            self.right_most = self_sentinel;
1971        } else {
1972            // SAFETY: Sentinels are verified to be valid and correspond to the correct node locations.
1973            unsafe {
1974                let root_ns = Self::get_node_ref(self.root);
1975                debug_assert_eq!(root_ns.get_parent(), other_sentinel);
1976                root_ns.set_parent(self_sentinel);
1977
1978                let left_ns = Self::get_node_ref(self.left_most);
1979                debug_assert_eq!(left_ns.get_left(), other_sentinel);
1980                left_ns.set_left(self_sentinel);
1981
1982                let right_ns = Self::get_node_ref(self.right_most);
1983                debug_assert_eq!(right_ns.get_right(), other_sentinel);
1984                right_ns.set_right(self_sentinel);
1985            }
1986        }
1987
1988        // For `other` (which currently contains `self`'s old nodes):
1989        // The old sentinel in these nodes is `self_sentinel`. We update them to `other_sentinel`.
1990        if other.root.is_null() {
1991            other.left_most = other_sentinel;
1992            other.right_most = other_sentinel;
1993        } else {
1994            // SAFETY: Sentinels are verified to be valid and correspond to the correct node locations.
1995            unsafe {
1996                let root_ns = Self::get_node_ref(other.root);
1997                debug_assert_eq!(root_ns.get_parent(), self_sentinel);
1998                root_ns.set_parent(other_sentinel);
1999
2000                let left_ns = Self::get_node_ref(other.left_most);
2001                debug_assert_eq!(left_ns.get_left(), self_sentinel);
2002                left_ns.set_left(other_sentinel);
2003
2004                let right_ns = Self::get_node_ref(other.right_most);
2005                debug_assert_eq!(right_ns.get_right(), self_sentinel);
2006                right_ns.set_right(other_sentinel);
2007            }
2008        }
2009    }
2010
2011    /// Traverses the tree to find the node with the given key.
2012    ///
2013    /// Returns a raw pointer to the matching node, or a sentinel pointer if not found.
2014    ///
2015    /// # Safety
2016    ///
2017    /// The returned raw pointer is only valid as long as the tree structure is not modified
2018    /// and no elements are deleted.
2019    unsafe fn find_raw(&self, key: &K) -> *mut P::Target {
2020        // SAFETY: Accessing node keys and traversing child pointers is safe since we only
2021        // traverse nodes contained inside this tree and ensure they are valid via `valid_sentinel_ptr`.
2022        unsafe {
2023            let mut node = self.root;
2024            while valid_sentinel_ptr(node) {
2025                let node_key = (*node).get_key();
2026                let b = node_key.borrow();
2027                if key == b {
2028                    return node;
2029                }
2030                let ns = Self::get_node_ref(node);
2031                node = if key < b { ns.get_left() } else { ns.get_right() };
2032            }
2033            self.get_sentinel()
2034        }
2035    }
2036
2037    /// Traverses the tree to find either the lower bound or upper bound node pointer.
2038    ///
2039    /// # Safety
2040    ///
2041    /// The returned raw pointer is only valid as long as the tree structure is not modified
2042    /// and no elements are deleted.
2043    unsafe fn bound_raw(&self, key: &K, strictly_greater: bool) -> *mut P::Target {
2044        // SAFETY: Accessing node keys and traversing child pointers is safe since we only
2045        // traverse nodes contained inside this tree and ensure they are valid via `valid_sentinel_ptr`.
2046        unsafe {
2047            let mut node = self.root;
2048            let mut found = self.get_sentinel();
2049
2050            while valid_sentinel_ptr(node) {
2051                let node_key = (*node).get_key();
2052                let b = node_key.borrow();
2053                let is_eligible = if strictly_greater { b > key } else { b >= key };
2054                if is_eligible {
2055                    found = node;
2056                    node = Self::get_node_ref(node).get_left();
2057                } else {
2058                    node = Self::get_node_ref(node).get_right();
2059                }
2060            }
2061            found
2062        }
2063    }
2064
2065    /// Finds an element in the tree by key.
2066    pub fn find(&self, key: &K) -> Option<&P::Target> {
2067        // SAFETY: find_raw returns either a sentinel pointer or a valid node in the tree.
2068        // If it is valid, returning a reference is safe for the lifetime of the borrow of `self`.
2069        unsafe {
2070            let node = self.find_raw(key);
2071            if valid_sentinel_ptr(node) { Some(&*node) } else { None }
2072        }
2073    }
2074
2075    /// Finds an element in the tree by key and returns a cursor positioned at it.
2076    ///
2077    /// If the key is not found, the returned cursor is positioned at the sentinel
2078    /// (i.e. `cursor.get()` will return `None`).
2079    pub fn find_cursor(&mut self, key: &K) -> CursorMut<'_, K, P, Tag, S, O> {
2080        // SAFETY: find_raw returns a valid node pointer or sentinel pointer belonging to this tree.
2081        let node = unsafe { self.find_raw(key) };
2082        CursorMut { tree: self, current: node }
2083    }
2084
2085    /// Returns a cursor positioned at the lower bound of the key (the first element
2086    /// in the tree whose key is greater than or equal to `key`).
2087    ///
2088    /// If no such element exists (e.g. all elements in the tree are smaller than `key`),
2089    /// the returned cursor is positioned at the sentinel.
2090    pub fn lower_bound(&mut self, key: &K) -> CursorMut<'_, K, P, Tag, S, O> {
2091        // SAFETY: bound_raw returns a valid node pointer or sentinel pointer in the tree.
2092        let node = unsafe { self.bound_raw(key, false) };
2093        CursorMut { tree: self, current: node }
2094    }
2095
2096    /// Returns a cursor positioned at the upper bound of the key (the first element
2097    /// in the tree whose key is strictly greater than `key`).
2098    ///
2099    /// If no such element exists (e.g. all elements in the tree are smaller than or
2100    /// equal to `key`), the returned cursor is positioned at the sentinel.
2101    pub fn upper_bound(&mut self, key: &K) -> CursorMut<'_, K, P, Tag, S, O> {
2102        // SAFETY: bound_raw returns a valid node pointer or sentinel pointer in the tree.
2103        let node = unsafe { self.bound_raw(key, true) };
2104        CursorMut { tree: self, current: node }
2105    }
2106
2107    /// Erases an element by key.
2108    pub fn erase(&mut self, key: &K) -> Option<P> {
2109        let mut cursor = self.find_cursor(key);
2110        cursor.erase()
2111    }
2112
2113    /// Erases an element by raw pointer.
2114    ///
2115    /// # Safety
2116    ///
2117    /// The caller must ensure that `obj` is a valid pointer to an object that is currently
2118    /// contained within this tree instance.
2119    pub unsafe fn erase_raw(&mut self, obj: *mut P::Target) -> Option<P> {
2120        // SAFETY: The caller guarantees that `obj` is currently contained in this WavlTree.
2121        // `internal_erase` is safe to execute on a contained pointer.
2122        unsafe {
2123            let node = (*obj).get_node();
2124            if !node.in_container() {
2125                return None;
2126            }
2127            self.internal_erase(obj)
2128        }
2129    }
2130
2131    /// Returns a cursor positioned at the front (smallest element) of the tree.
2132    pub fn cursor_mut(&mut self) -> CursorMut<'_, K, P, Tag, S, O> {
2133        let left_most = self.left_most;
2134        CursorMut { tree: self, current: left_most }
2135    }
2136
2137    /// Returns a read-only cursor positioned at the given element.
2138    ///
2139    /// # Safety
2140    ///
2141    /// The caller must ensure that `obj` is a member of this tree.
2142    /// It is undefined behavior to use the returned cursor if `obj` is not in the tree,
2143    /// or if it is in a different tree.
2144    pub unsafe fn cursor_at(&self, obj: &P::Target) -> Cursor<'_, K, P, Tag, S, O> {
2145        assert!(obj.get_node().in_container(), "Object must be in a container");
2146        Cursor { tree: self, current: obj as *const P::Target as *mut P::Target }
2147    }
2148
2149    /// Returns a mutable cursor positioned at the given element.
2150    ///
2151    /// # Safety
2152    ///
2153    /// The caller must ensure that `obj` is a member of this tree.
2154    /// It is undefined behavior to use the returned cursor if `obj` is not in the tree,
2155    /// or if it is in a different tree.
2156    pub unsafe fn cursor_mut_at(&mut self, obj: &P::Target) -> CursorMut<'_, K, P, Tag, S, O> {
2157        assert!(obj.get_node().in_container(), "Object must be in a container");
2158        CursorMut { tree: self, current: obj as *const P::Target as *mut P::Target }
2159    }
2160
2161    /// Returns an iterator over the elements of the tree.
2162    pub fn iter(&self) -> Iterator<'_, K, P, Tag, S, O> {
2163        Iterator::new(self)
2164    }
2165
2166    /// Returns a unidirectional forward iterator over the elements of the tree.
2167    pub fn forward_iter(&self) -> ForwardIterator<'_, K, P, Tag, S, O> {
2168        ForwardIterator::new(self.left_most)
2169    }
2170
2171    /// Returns a unidirectional reverse iterator over the elements of the tree.
2172    pub fn reverse_iter(&self) -> ReverseIterator<'_, K, P, Tag, S, O> {
2173        ReverseIterator::new(self.right_most)
2174    }
2175
2176    /// Returns a read-only cursor positioned at the root of the tree.
2177    pub fn root_cursor(&self) -> Cursor<'_, K, P, Tag, S, O> {
2178        Cursor { tree: self, current: self.root }
2179    }
2180
2181    /// Returns a read-only cursor positioned at the first (smallest) element.
2182    pub fn front_cursor(&self) -> Cursor<'_, K, P, Tag, S, O> {
2183        Cursor { tree: self, current: self.left_most }
2184    }
2185
2186    /// Returns a read-only cursor positioned at the last (largest) element.
2187    pub fn back_cursor(&self) -> Cursor<'_, K, P, Tag, S, O> {
2188        Cursor { tree: self, current: self.right_most }
2189    }
2190
2191    /// Returns the number of elements in the tree.
2192    pub fn len(&self) -> usize {
2193        self.size.get()
2194    }
2195}
2196
2197#[pinned_drop]
2198impl<K, P, Tag, S, O> PinnedDrop for WavlTree<K, P, Tag, S, O>
2199where
2200    P: PtrTraits,
2201    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2202    K: Ord,
2203    S: SizeTracker,
2204    O: WavlTreeObserver<Target = P::Target>,
2205{
2206    fn drop(self: Pin<&mut Self>) {
2207        if P::IS_MANAGED {
2208            let me = unsafe { self.get_unchecked_mut() };
2209            me.clear();
2210        } else {
2211            debug_assert!(self.is_empty(), "Tree must be empty on destruction");
2212            if S::IS_TRACKING {
2213                debug_assert_eq!(self.size.get(), 0, "Size must be zero on destruction");
2214            }
2215        }
2216    }
2217}
2218
2219/// A read-only cursor positioned in a `WavlTree`.
2220pub struct Cursor<
2221    'a,
2222    K,
2223    P,
2224    Tag = DefaultObjectTag,
2225    S = NonTrackingSize,
2226    O = DefaultWavlTreeObserver<<P as PtrTraits>::Target>,
2227> where
2228    P: PtrTraits,
2229    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2230    K: Ord,
2231    S: SizeTracker,
2232    O: WavlTreeObserver<Target = P::Target>,
2233{
2234    tree: &'a WavlTree<K, P, Tag, S, O>,
2235    current: *mut P::Target,
2236}
2237
2238impl<'a, K, P, Tag, S, O> Clone for Cursor<'a, K, P, Tag, S, O>
2239where
2240    P: PtrTraits,
2241    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2242    K: Ord,
2243    S: SizeTracker,
2244    O: WavlTreeObserver<Target = P::Target>,
2245{
2246    fn clone(&self) -> Self {
2247        *self
2248    }
2249}
2250
2251impl<'a, K, P, Tag, S, O> Copy for Cursor<'a, K, P, Tag, S, O>
2252where
2253    P: PtrTraits,
2254    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2255    K: Ord,
2256    S: SizeTracker,
2257    O: WavlTreeObserver<Target = P::Target>,
2258{
2259}
2260
2261impl<'a, K, P, Tag, S, O> PartialEq for Cursor<'a, K, P, Tag, S, O>
2262where
2263    P: PtrTraits,
2264    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2265    K: Ord,
2266    S: SizeTracker,
2267    O: WavlTreeObserver<Target = P::Target>,
2268{
2269    fn eq(&self, other: &Self) -> bool {
2270        self.current == other.current
2271    }
2272}
2273
2274impl<'a, K, P, Tag, S, O> core::fmt::Debug for Cursor<'a, K, P, Tag, S, O>
2275where
2276    P: PtrTraits,
2277    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2278    K: Ord,
2279    S: SizeTracker,
2280    O: WavlTreeObserver<Target = P::Target>,
2281{
2282    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2283        f.debug_struct("Cursor").field("current", &self.current).finish()
2284    }
2285}
2286
2287impl<'a, K, P, Tag, S, O> Cursor<'a, K, P, Tag, S, O>
2288where
2289    P: PtrTraits,
2290    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2291    K: Ord,
2292    S: SizeTracker,
2293    O: WavlTreeObserver<Target = P::Target>,
2294{
2295    /// Returns a reference to the current element, or `None` if the cursor is at the sentinel.
2296    pub fn get(&self) -> Option<&'a P::Target> {
2297        if is_sentinel_ptr(self.current) {
2298            None
2299        } else {
2300            // SAFETY: `self.current` is checked to be non-sentinel.
2301            // The lifetime `'a` is tied to the `WavlTree` borrow.
2302            unsafe { Some(&*self.current) }
2303        }
2304    }
2305
2306    /// Returns true if the cursor is positioned at a valid element (not the sentinel).
2307    pub fn is_valid(&self) -> bool {
2308        valid_sentinel_ptr(self.current)
2309    }
2310
2311    /// Returns a cursor positioned at the left child of the current element.
2312    /// If the current element is the sentinel, returns a cursor at the sentinel.
2313    pub fn left(&self) -> Self {
2314        if !self.is_valid() {
2315            *self
2316        } else {
2317            // SAFETY: `self.current` is checked to be non-sentinel (which implies it is a valid,
2318            // non-null node in the tree because `current` is never null). Accessing the tree node state is safe.
2319            let ns = unsafe { WavlTree::<K, P, Tag, S, O>::get_node_ref(self.current) };
2320            Self { tree: self.tree, current: ns.get_left() }
2321        }
2322    }
2323
2324    /// Returns a cursor positioned at the right child of the current element.
2325    pub fn right(&self) -> Self {
2326        if !self.is_valid() {
2327            *self
2328        } else {
2329            // SAFETY: `self.current` is checked to be non-sentinel (which implies it is a valid,
2330            // non-null node in the tree because `current` is never null). Accessing the tree node state is safe.
2331            let ns = unsafe { WavlTree::<K, P, Tag, S, O>::get_node_ref(self.current) };
2332            Self { tree: self.tree, current: ns.get_right() }
2333        }
2334    }
2335
2336    /// Returns a cursor positioned at the parent of the current element.
2337    pub fn parent(&self) -> Self {
2338        if !self.is_valid() {
2339            *self
2340        } else {
2341            // SAFETY: `self.current` is checked to be non-sentinel (which implies it is a valid,
2342            // non-null node in the tree because `current` is never null). Accessing the tree node state is safe.
2343            let ns = unsafe { WavlTree::<K, P, Tag, S, O>::get_node_ref(self.current) };
2344            let parent = ns.get_parent();
2345            Self { tree: self.tree, current: parent }
2346        }
2347    }
2348
2349    /// Returns the raw pointer to the current element.
2350    /// This may be a sentinel pointer if the cursor is at the sentinel.
2351    pub fn as_raw_ptr(&self) -> *mut P::Target {
2352        self.current
2353    }
2354}
2355
2356pub type InsertOrFindResult<'a, K, P, Tag, S, O> = Result<(), (P, CursorMut<'a, K, P, Tag, S, O>)>;
2357
2358/// A cursor over elements in a `WavlTree`.
2359pub struct CursorMut<
2360    'a,
2361    K,
2362    P,
2363    Tag = DefaultObjectTag,
2364    S = NonTrackingSize,
2365    O = DefaultWavlTreeObserver<<P as PtrTraits>::Target>,
2366> where
2367    P: PtrTraits,
2368    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2369    K: Ord,
2370    S: SizeTracker,
2371    O: WavlTreeObserver<Target = P::Target>,
2372{
2373    tree: &'a mut WavlTree<K, P, Tag, S, O>,
2374    current: *mut P::Target,
2375}
2376
2377impl<'a, K, P, Tag, S, O> CursorMut<'a, K, P, Tag, S, O>
2378where
2379    P: PtrTraits,
2380    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2381    K: Ord,
2382    S: SizeTracker,
2383    O: WavlTreeObserver<Target = P::Target>,
2384{
2385    /// Returns a reference to the current element.
2386    pub fn get(&self) -> Option<&P::Target> {
2387        if is_sentinel_ptr(self.current) {
2388            None
2389        } else {
2390            // SAFETY: `self.current` is checked to be non-sentinel (which implies it is a valid,
2391            // non-null node in the tree because `current` is never null). Since `CursorMut` mutably
2392            // borrows the tree, the node is guaranteed to be valid and dereferenceable for the
2393            // lifetime of the reference.
2394            unsafe { Some(&*self.current) }
2395        }
2396    }
2397
2398    /// Moves the cursor to the next (larger) element.
2399    pub fn move_next(&mut self) {
2400        if valid_sentinel_ptr(self.current) {
2401            // SAFETY: `self.current` is verified to be a valid node in the tree. Advancing through
2402            // tree pointers is safe.
2403            unsafe {
2404                WavlTree::<K, P, Tag, S, O>::advance::<ForwardTraits>(&mut self.current);
2405            }
2406        }
2407    }
2408
2409    /// Moves the cursor to the previous (smaller) element.
2410    pub fn move_prev(&mut self) {
2411        if valid_sentinel_ptr(self.current) {
2412            // SAFETY: `self.current` is verified to be a valid node in the tree. Advancing through
2413            // tree pointers is safe.
2414            unsafe {
2415                WavlTree::<K, P, Tag, S, O>::advance::<ReverseTraits>(&mut self.current);
2416            }
2417        } else if is_sentinel_ptr(self.current) {
2418            self.current = self.tree.right_most;
2419        }
2420    }
2421
2422    /// Erases the current element and moves the cursor to the next element.
2423    pub fn erase(&mut self) -> Option<P> {
2424        if !valid_sentinel_ptr(self.current) {
2425            return None;
2426        }
2427
2428        let to_erase = self.current;
2429        // SAFETY: `to_erase` is verified to be a valid, non-sentinel node in the tree.
2430        // `advance` moves the cursor to a safe position before `internal_erase` physically removes
2431        // `to_erase` from the tree.
2432        unsafe {
2433            WavlTree::<K, P, Tag, S, O>::advance::<ForwardTraits>(&mut self.current);
2434            self.tree.internal_erase(to_erase)
2435        }
2436    }
2437}
2438
2439/// A unidirectional forward iterator over the elements of a `WavlTree`.
2440pub struct ForwardIterator<
2441    'a,
2442    K,
2443    P,
2444    Tag = DefaultObjectTag,
2445    S = NonTrackingSize,
2446    O = DefaultWavlTreeObserver<<P as PtrTraits>::Target>,
2447> where
2448    P: PtrTraits,
2449    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2450    K: Ord,
2451    S: SizeTracker,
2452    O: WavlTreeObserver<Target = P::Target>,
2453{
2454    current: *mut P::Target,
2455    _phantom: core::marker::PhantomData<&'a WavlTree<K, P, Tag, S, O>>,
2456}
2457
2458impl<'a, K, P, Tag, S, O> ForwardIterator<'a, K, P, Tag, S, O>
2459where
2460    P: PtrTraits,
2461    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2462    K: Ord,
2463    S: SizeTracker,
2464    O: WavlTreeObserver<Target = P::Target>,
2465{
2466    fn new(current: *mut P::Target) -> Self {
2467        Self { current, _phantom: core::marker::PhantomData }
2468    }
2469
2470    /// Creates an iterator starting from a specific element.
2471    ///
2472    /// # Panics
2473    ///
2474    /// Panics if the object is not in a container.
2475    pub fn from_element(obj: &'a P::Target) -> Self {
2476        assert!(obj.get_node().in_container(), "Object must be in a container");
2477        Self { current: obj as *const _ as *mut _, _phantom: core::marker::PhantomData }
2478    }
2479
2480    fn get_current(&self) -> Option<&'a P::Target> {
2481        if is_sentinel_ptr(self.current) {
2482            None
2483        } else {
2484            // SAFETY: `self.current` is checked to be non-sentinel (which implies it is a valid,
2485            // non-null node in the tree because `current` is never null). Since the iterator
2486            // holds a lifetime borrow of the `WavlTree`, and the tree remains unmodified,
2487            // the node is guaranteed to be valid and dereferenceable for `'a`.
2488            unsafe { Some(&*self.current) }
2489        }
2490    }
2491}
2492
2493impl<'a, K, P, Tag, S, O> Clone for ForwardIterator<'a, K, P, Tag, S, O>
2494where
2495    P: PtrTraits,
2496    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2497    K: Ord,
2498    S: SizeTracker,
2499    O: WavlTreeObserver<Target = P::Target>,
2500{
2501    fn clone(&self) -> Self {
2502        Self { current: self.current, _phantom: core::marker::PhantomData }
2503    }
2504}
2505
2506impl<'a, K, P, Tag, S, O> core::iter::Iterator for ForwardIterator<'a, K, P, Tag, S, O>
2507where
2508    P: PtrTraits,
2509    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2510    K: Ord,
2511    S: SizeTracker,
2512    O: WavlTreeObserver<Target = P::Target>,
2513{
2514    type Item = &'a P::Target;
2515
2516    fn next(&mut self) -> Option<Self::Item> {
2517        let current = self.get_current()?;
2518        // SAFETY: `self.current` is validated as non-sentinel by `get_current`.
2519        // Moving through tree pointers is safe.
2520        unsafe {
2521            WavlTree::<K, P, Tag, S, O>::advance::<ForwardTraits>(&mut self.current);
2522        }
2523        Some(current)
2524    }
2525}
2526
2527/// A unidirectional reverse iterator over the elements of a `WavlTree`.
2528pub struct ReverseIterator<
2529    'a,
2530    K,
2531    P,
2532    Tag = DefaultObjectTag,
2533    S = NonTrackingSize,
2534    O = DefaultWavlTreeObserver<<P as PtrTraits>::Target>,
2535> where
2536    P: PtrTraits,
2537    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2538    K: Ord,
2539    S: SizeTracker,
2540    O: WavlTreeObserver<Target = P::Target>,
2541{
2542    current: *mut P::Target,
2543    _phantom: core::marker::PhantomData<&'a WavlTree<K, P, Tag, S, O>>,
2544}
2545
2546impl<'a, K, P, Tag, S, O> ReverseIterator<'a, K, P, Tag, S, O>
2547where
2548    P: PtrTraits,
2549    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2550    K: Ord,
2551    S: SizeTracker,
2552    O: WavlTreeObserver<Target = P::Target>,
2553{
2554    fn new(current: *mut P::Target) -> Self {
2555        Self { current, _phantom: core::marker::PhantomData }
2556    }
2557
2558    /// Creates an iterator starting from a specific element.
2559    ///
2560    /// # Panics
2561    ///
2562    /// Panics if the object is not in a container.
2563    pub fn from_element(obj: &'a P::Target) -> Self {
2564        assert!(obj.get_node().in_container(), "Object must be in a container");
2565        Self { current: obj as *const _ as *mut _, _phantom: core::marker::PhantomData }
2566    }
2567
2568    fn get_current(&self) -> Option<&'a P::Target> {
2569        if is_sentinel_ptr(self.current) {
2570            None
2571        } else {
2572            // SAFETY: `self.current` is checked to be non-sentinel (which implies it is a valid,
2573            // non-null node in the tree because `current` is never null). Since the iterator
2574            // holds a lifetime borrow of the `WavlTree`, and the tree remains unmodified,
2575            // the node is guaranteed to be valid and dereferenceable for `'a`.
2576            unsafe { Some(&*self.current) }
2577        }
2578    }
2579}
2580
2581impl<'a, K, P, Tag, S, O> Clone for ReverseIterator<'a, K, P, Tag, S, O>
2582where
2583    P: PtrTraits,
2584    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2585    K: Ord,
2586    S: SizeTracker,
2587    O: WavlTreeObserver<Target = P::Target>,
2588{
2589    fn clone(&self) -> Self {
2590        Self { current: self.current, _phantom: core::marker::PhantomData }
2591    }
2592}
2593
2594impl<'a, K, P, Tag, S, O> core::iter::Iterator for ReverseIterator<'a, K, P, Tag, S, O>
2595where
2596    P: PtrTraits,
2597    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2598    K: Ord,
2599    S: SizeTracker,
2600    O: WavlTreeObserver<Target = P::Target>,
2601{
2602    type Item = &'a P::Target;
2603
2604    fn next(&mut self) -> Option<Self::Item> {
2605        let current = self.get_current()?;
2606        // SAFETY: `self.current` is validated as non-sentinel by `get_current`.
2607        // Moving through tree pointers is safe.
2608        unsafe {
2609            WavlTree::<K, P, Tag, S, O>::advance::<ReverseTraits>(&mut self.current);
2610        }
2611        Some(current)
2612    }
2613}
2614
2615/// An iterator over the elements of a `WavlTree`.
2616pub struct Iterator<
2617    'a,
2618    K,
2619    P,
2620    Tag = DefaultObjectTag,
2621    S = NonTrackingSize,
2622    O = DefaultWavlTreeObserver<<P as PtrTraits>::Target>,
2623> where
2624    P: PtrTraits,
2625    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2626    K: Ord,
2627    S: SizeTracker,
2628    O: WavlTreeObserver<Target = P::Target>,
2629{
2630    front: ForwardIterator<'a, K, P, Tag, S, O>,
2631    back: ReverseIterator<'a, K, P, Tag, S, O>,
2632}
2633
2634impl<'a, K, P, Tag, S, O> Iterator<'a, K, P, Tag, S, O>
2635where
2636    P: PtrTraits,
2637    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2638    K: Ord,
2639    S: SizeTracker,
2640    O: WavlTreeObserver<Target = P::Target>,
2641{
2642    fn new(tree: &'a WavlTree<K, P, Tag, S, O>) -> Self {
2643        if tree.is_empty() {
2644            Self {
2645                front: ForwardIterator::new(make_sentinel_null()),
2646                back: ReverseIterator::new(make_sentinel_null()),
2647            }
2648        } else {
2649            Self {
2650                front: ForwardIterator::new(tree.left_most),
2651                back: ReverseIterator::new(tree.right_most),
2652            }
2653        }
2654    }
2655}
2656
2657impl<'a, K, P, Tag, S, O> Clone for Iterator<'a, K, P, Tag, S, O>
2658where
2659    P: PtrTraits,
2660    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2661    K: Ord,
2662    S: SizeTracker,
2663    O: WavlTreeObserver<Target = P::Target>,
2664{
2665    fn clone(&self) -> Self {
2666        Self { front: self.front.clone(), back: self.back.clone() }
2667    }
2668}
2669
2670impl<'a, K, P, Tag, S, O> core::iter::Iterator for Iterator<'a, K, P, Tag, S, O>
2671where
2672    P: PtrTraits,
2673    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2674    K: Ord,
2675    S: SizeTracker,
2676    O: WavlTreeObserver<Target = P::Target>,
2677{
2678    type Item = &'a P::Target;
2679
2680    fn next(&mut self) -> Option<Self::Item> {
2681        let met = self.front.current == self.back.current;
2682        let item = self.front.next();
2683        if item.is_some() && met {
2684            self.front.current = make_sentinel_null();
2685            self.back.current = make_sentinel_null();
2686        }
2687        item
2688    }
2689}
2690
2691impl<'a, K, P, Tag, S, O> core::iter::DoubleEndedIterator for Iterator<'a, K, P, Tag, S, O>
2692where
2693    P: PtrTraits,
2694    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2695    K: Ord,
2696    S: SizeTracker,
2697    O: WavlTreeObserver<Target = P::Target>,
2698{
2699    fn next_back(&mut self) -> Option<Self::Item> {
2700        let met = self.front.current == self.back.current;
2701        let item = self.back.next();
2702        if item.is_some() && met {
2703            self.front.current = make_sentinel_null();
2704            self.back.current = make_sentinel_null();
2705        }
2706        item
2707    }
2708}
2709
2710impl<K, T, Tag, S, O> WavlTree<K, *mut T, Tag, S, O>
2711where
2712    T: WavlTreeContainable<T, Tag> + WavlTreeKeyable<K>,
2713    K: Ord,
2714    S: SizeTracker,
2715    O: WavlTreeObserver<Target = T>,
2716{
2717    /// Unsafely removes all elements from the tree without modifying node memory.
2718    ///
2719    /// This method resets the tree's internal pointers, effectively emptying it, but does
2720    /// NOT modify the node state of the elements that were in the tree.
2721    ///
2722    /// # Safety
2723    ///
2724    /// Because the nodes are not modified, they will still believe they are in a container
2725    /// (i.e. `in_container()` will return `true` for them). If these elements are subsequently
2726    /// dropped, they will trigger a `debug_assert` panic (as `WavlTreeNode` asserts on drop
2727    /// that it is not in a container).
2728    ///
2729    /// The caller is responsible for manually clearing the node state of the elements, or
2730    /// ensuring they are never dropped while in this "dirty" state.
2731    ///
2732    /// Only usable with containers of unmanaged pointers. Think carefully before calling this!
2733    pub fn clear_unsafe(&mut self) {
2734        self.root = core::ptr::null_mut();
2735        self.left_most = self.get_sentinel();
2736        self.right_most = self.get_sentinel();
2737        self.size.set(0);
2738    }
2739}
2740
2741impl<K, P, Tag, S, O> core::fmt::Debug for WavlTree<K, P, Tag, S, O>
2742where
2743    P: PtrTraits,
2744    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K> + core::fmt::Debug,
2745    K: Ord,
2746    S: SizeTracker,
2747    O: WavlTreeObserver<Target = P::Target>,
2748{
2749    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2750        f.debug_list().entries(self.iter()).finish()
2751    }
2752}
2753
2754#[cfg(test)]
2755mod tests {
2756    use super::*;
2757    use crate::intrusive_container_test_support::*;
2758    use crate::ref_counted::HasRefCount;
2759    use crate::ref_ptr::RefPtr;
2760    use crate::size_tracker::TrackingSize;
2761    use crate::unique_ptr::UniquePtr;
2762    use crate::{Recyclable, WavlTreeContainable};
2763    use core::ffi::c_void;
2764    use pin_init::stack_pin_init;
2765
2766    trait AsTargetRef {
2767        type Target;
2768        unsafe fn as_target_ref(&self) -> &Self::Target;
2769    }
2770
2771    impl<T> AsTargetRef for *mut T {
2772        type Target = T;
2773        unsafe fn as_target_ref(&self) -> &T {
2774            unsafe { &**self }
2775        }
2776    }
2777
2778    impl<T: Recyclable> AsTargetRef for UniquePtr<T> {
2779        type Target = T;
2780        unsafe fn as_target_ref(&self) -> &T {
2781            &**self
2782        }
2783    }
2784
2785    impl<T: HasRefCount + Recyclable> AsTargetRef for RefPtr<T> {
2786        type Target = T;
2787        unsafe fn as_target_ref(&self) -> &T {
2788            &**self
2789        }
2790    }
2791
2792    #[derive(crate::WavlTreeContainable, crate::Recyclable)]
2793    struct TestObject {
2794        value: i32,
2795        #[wavl_node]
2796        node: WavlTreeNode<TestObject>,
2797    }
2798
2799    impl TestObject {
2800        fn new(value: i32) -> Self {
2801            Self { value, node: WavlTreeNode::new() }
2802        }
2803    }
2804
2805    impl WavlTreeKeyable<i32> for TestObject {
2806        type Key<'a> = i32;
2807        fn get_key(&self) -> i32 {
2808            self.value
2809        }
2810    }
2811
2812    impl TestValue for TestObject {
2813        fn new(value: i32) -> Self {
2814            Self::new(value)
2815        }
2816    }
2817
2818    ::zr::static_assert!(
2819        core::mem::size_of::<WavlTree<i32, *mut TestObject>>()
2820            == 3 * core::mem::size_of::<*mut TestObject>()
2821    );
2822    ::zr::static_assert!(
2823        core::mem::align_of::<WavlTree<i32, *mut TestObject>>()
2824            == core::mem::align_of::<*mut TestObject>()
2825    );
2826
2827    ::zr::static_assert!(
2828        core::mem::size_of::<WavlTree<i32, *mut TestObject, DefaultObjectTag, TrackingSize>>()
2829            == 4 * core::mem::size_of::<*mut TestObject>()
2830    );
2831    ::zr::static_assert!(
2832        core::mem::align_of::<WavlTree<i32, *mut TestObject, DefaultObjectTag, TrackingSize>>()
2833            == core::mem::align_of::<*mut TestObject>()
2834    );
2835
2836    #[derive(crate::WavlTreeContainable, crate::Recyclable)]
2837    struct UniqueTestObject {
2838        value: i32,
2839        #[wavl_node]
2840        node: WavlTreeNode<UniqueTestObject>,
2841    }
2842
2843    impl UniqueTestObject {
2844        fn new(value: i32) -> Self {
2845            Self { value, node: WavlTreeNode::new() }
2846        }
2847    }
2848
2849    impl WavlTreeKeyable<i32> for UniqueTestObject {
2850        type Key<'a> = i32;
2851        fn get_key(&self) -> i32 {
2852            self.value
2853        }
2854    }
2855
2856    impl TestValue for UniqueTestObject {
2857        fn new(value: i32) -> Self {
2858            Self::new(value)
2859        }
2860    }
2861
2862    #[fbl::ref_counted]
2863    #[derive(crate::WavlTreeContainable, crate::Recyclable)]
2864    #[repr(C)]
2865    pub struct RefTestObject {
2866        value: i32,
2867        #[wavl_node]
2868        node: WavlTreeNode<RefTestObject>,
2869    }
2870
2871    impl WavlTreeKeyable<i32> for RefTestObject {
2872        type Key<'a> = i32;
2873        fn get_key(&self) -> i32 {
2874            self.value
2875        }
2876    }
2877
2878    impl TestValue for RefTestObject {
2879        fn new_ref_counted(value: i32) -> RefPtr<Self> {
2880            crate::make_ref_counted!(RefTestObject { value: value, node: WavlTreeNode::new() })
2881                .unwrap()
2882        }
2883    }
2884
2885    macro_rules! generate_tree_tests {
2886        ($mod_name:ident, $ptr_type:ty, $factory_type:ty, $get_val:expr, $insert:expr, $insert_or_find:expr, $insert_or_replace:expr) => {
2887            mod $mod_name {
2888                use super::*;
2889
2890                #[test]
2891                fn test_basic_sorting() {
2892                    let mut factory = <$factory_type>::new();
2893                    stack_pin_init!(let tree = WavlTree::<i32, $ptr_type>::new());
2894                    let tree = unsafe { tree.get_unchecked_mut() };
2895                    assert!(tree.is_empty());
2896
2897                    // Insert in scrambled order
2898                    $insert(tree, factory.create(3));
2899                    $insert(tree, factory.create(1));
2900                    $insert(tree, factory.create(4));
2901                    $insert(tree, factory.create(2));
2902
2903                    assert!(!tree.is_empty());
2904
2905                    // Iteration should be sorted
2906                    let mut iter = tree.iter();
2907                    assert_eq!($get_val(iter.next().unwrap()), 1);
2908                    assert_eq!($get_val(iter.next().unwrap()), 2);
2909                    assert_eq!($get_val(iter.next().unwrap()), 3);
2910                    assert_eq!($get_val(iter.next().unwrap()), 4);
2911                    assert!(iter.next().is_none());
2912
2913                    tree.clear();
2914                    assert!(tree.is_empty());
2915                }
2916
2917                #[test]
2918                fn test_double_ended_iterator() {
2919                    let mut factory = <$factory_type>::new();
2920                    stack_pin_init!(let tree = WavlTree::<i32, $ptr_type>::new());
2921                    let tree = unsafe { tree.get_unchecked_mut() };
2922                    $insert(tree, factory.create(30));
2923                    $insert(tree, factory.create(10));
2924                    $insert(tree, factory.create(20));
2925
2926                    let mut iter = tree.iter();
2927                    assert_eq!($get_val(iter.next().unwrap()), 10);
2928                    assert_eq!($get_val(iter.next_back().unwrap()), 30);
2929                    assert_eq!($get_val(iter.next().unwrap()), 20);
2930                    assert!(iter.next().is_none());
2931                    assert!(iter.next_back().is_none());
2932
2933                    tree.clear();
2934                }
2935
2936                #[test]
2937                fn test_find() {
2938                    let mut factory = <$factory_type>::new();
2939                    stack_pin_init!(let tree = WavlTree::<i32, $ptr_type>::new());
2940                    let tree = unsafe { tree.get_unchecked_mut() };
2941                    $insert(tree, factory.create(3));
2942                    $insert(tree, factory.create(1));
2943                    $insert(tree, factory.create(2));
2944
2945                    assert!(tree.find(&2).is_some());
2946                    assert_eq!($get_val(tree.find(&2).unwrap()), 2);
2947                    assert!(tree.find(&4).is_none());
2948
2949                    tree.clear();
2950                }
2951
2952                #[test]
2953                fn test_bounds() {
2954                    let mut factory = <$factory_type>::new();
2955                    stack_pin_init!(let tree = WavlTree::<i32, $ptr_type>::new());
2956                    let tree = unsafe { tree.get_unchecked_mut() };
2957                    $insert(tree, factory.create(10));
2958                    $insert(tree, factory.create(30));
2959                    $insert(tree, factory.create(20));
2960
2961                    // lower_bound(>=)
2962                    assert_eq!($get_val(tree.lower_bound(&15).get().unwrap()), 20);
2963                    assert_eq!($get_val(tree.lower_bound(&20).get().unwrap()), 20);
2964                    assert!(tree.lower_bound(&35).get().is_none());
2965
2966                    // upper_bound(>)
2967                    assert_eq!($get_val(tree.upper_bound(&15).get().unwrap()), 20);
2968                    assert_eq!($get_val(tree.upper_bound(&20).get().unwrap()), 30);
2969                    assert!(tree.upper_bound(&30).get().is_none());
2970
2971                    tree.clear();
2972                }
2973
2974                #[test]
2975                fn test_pops() {
2976                    let mut factory = <$factory_type>::new();
2977                    stack_pin_init!(let tree = WavlTree::<i32, $ptr_type>::new());
2978                    let tree = unsafe { tree.get_unchecked_mut() };
2979                    $insert(tree, factory.create(10));
2980                    $insert(tree, factory.create(30));
2981                    $insert(tree, factory.create(20));
2982
2983                    let popped = tree.pop_front();
2984                    assert!(popped.is_some());
2985                    let val = popped.unwrap();
2986                    assert_eq!($get_val(unsafe { val.as_target_ref() }), 10);
2987
2988                    let popped = tree.pop_back();
2989                    assert!(popped.is_some());
2990                    let val = popped.unwrap();
2991                    assert_eq!($get_val(unsafe { val.as_target_ref() }), 30);
2992
2993                    let popped = tree.pop_front();
2994                    assert!(popped.is_some());
2995                    let val = popped.unwrap();
2996                    assert_eq!($get_val(unsafe { val.as_target_ref() }), 20);
2997
2998                    assert!(tree.pop_front().is_none());
2999                }
3000
3001                #[test]
3002                fn test_erase_cursor() {
3003                    let mut factory = <$factory_type>::new();
3004                    stack_pin_init!(let tree = WavlTree::<i32, $ptr_type>::new());
3005                    let tree = unsafe { tree.get_unchecked_mut() };
3006                    $insert(tree, factory.create(10));
3007                    $insert(tree, factory.create(30));
3008                    $insert(tree, factory.create(20));
3009
3010                    let mut cursor = tree.find_cursor(&20);
3011                    let erased = cursor.erase();
3012                    assert!(erased.is_some());
3013                    let val = erased.unwrap();
3014                    assert_eq!($get_val(unsafe { val.as_target_ref() }), 20);
3015
3016                    // Cursor should advance to next element (30)
3017                    assert_eq!($get_val(cursor.get().unwrap()), 30);
3018
3019                    let mut iter = tree.iter();
3020                    assert_eq!($get_val(iter.next().unwrap()), 10);
3021                    assert_eq!($get_val(iter.next().unwrap()), 30);
3022                    assert!(iter.next().is_none());
3023
3024                    tree.clear();
3025                }
3026
3027                #[test]
3028                fn test_insert_or_find() {
3029                    let mut factory = <$factory_type>::new();
3030                    stack_pin_init!(let tree = WavlTree::<i32, $ptr_type>::new());
3031                    let tree = unsafe { tree.get_unchecked_mut() };
3032                    $insert(tree, factory.create(10));
3033
3034                    let new_item = factory.create(10); // Duplicate key
3035                    let res = $insert_or_find(tree, new_item);
3036                    assert!(res.is_err());
3037                    let (failed_ptr, collision) = res.err().unwrap();
3038                    assert_eq!($get_val(unsafe { failed_ptr.as_target_ref() }), 10);
3039                    assert_eq!($get_val(collision.get().unwrap()), 10);
3040
3041                    let ok_item = factory.create(20);
3042                    assert!($insert_or_find(tree, ok_item).is_ok());
3043
3044                    tree.clear();
3045                }
3046
3047                #[test]
3048                fn test_insert_or_replace() {
3049                    let mut factory = <$factory_type>::new();
3050                    stack_pin_init!(let tree = WavlTree::<i32, $ptr_type>::new());
3051                    let tree = unsafe { tree.get_unchecked_mut() };
3052                    $insert(tree, factory.create(10));
3053
3054                    let replacement = factory.create(10);
3055                    let res = $insert_or_replace(tree, replacement);
3056                    assert!(res.is_some());
3057                    let old_item = res.unwrap();
3058                    assert_eq!($get_val(unsafe { old_item.as_target_ref() }), 10);
3059
3060                    let found = tree.find(&10);
3061                    assert!(found.is_some());
3062                    assert_eq!($get_val(found.unwrap()), 10);
3063
3064                    tree.clear();
3065                }
3066
3067                #[test]
3068                fn test_from_element() {
3069                    let mut factory = <$factory_type>::new();
3070                    stack_pin_init!(let tree = WavlTree::<i32, $ptr_type>::new());
3071                    let tree = unsafe { tree.get_unchecked_mut() };
3072
3073                    $insert(tree, factory.create(10));
3074                    $insert(tree, factory.create(20));
3075                    $insert(tree, factory.create(30));
3076
3077                    let target_ref = tree.find(&20).unwrap();
3078
3079                    let mut forward_iter: ForwardIterator<'_, i32, $ptr_type> = ForwardIterator::from_element(target_ref);
3080                    assert_eq!($get_val(forward_iter.next().unwrap()), 20);
3081                    assert_eq!($get_val(forward_iter.next().unwrap()), 30);
3082                    assert!(forward_iter.next().is_none());
3083
3084                    let mut reverse_iter: ReverseIterator<'_, i32, $ptr_type> = ReverseIterator::from_element(target_ref);
3085                    assert_eq!($get_val(reverse_iter.next().unwrap()), 20);
3086                    assert_eq!($get_val(reverse_iter.next().unwrap()), 10);
3087                    assert!(reverse_iter.next().is_none());
3088
3089                    tree.clear();
3090                }
3091
3092                #[test]
3093                fn test_cursor_at() {
3094                    let mut factory = <$factory_type>::new();
3095                    stack_pin_init!(let tree = WavlTree::<i32, $ptr_type>::new());
3096                    let tree = unsafe { tree.get_unchecked_mut() };
3097
3098                    $insert(tree, factory.create(10));
3099                    $insert(tree, factory.create(20));
3100                    $insert(tree, factory.create(30));
3101
3102                    let target_ptr = tree.find(&20).unwrap() as *const <$ptr_type as PtrTraits>::Target;
3103                    // SAFETY: target_ptr is a valid pointer to an object currently in the tree.
3104                    // Using a raw pointer bypasses the borrow checker, allowing us to obtain an unbound reference
3105                    // and borrow the tree mutably afterward.
3106                    let target_ref = unsafe { &*target_ptr };
3107
3108                    // Test read-only cursor_at
3109                    let cursor = unsafe { tree.cursor_at(target_ref) };
3110                    assert!(cursor.is_valid());
3111                    assert_eq!($get_val(cursor.get().unwrap()), 20);
3112                    assert_eq!($get_val(cursor.left().get().unwrap()), 10);
3113                    assert_eq!($get_val(cursor.right().get().unwrap()), 30);
3114
3115                    // Test mutable cursor_mut_at
3116                    let mut cursor_mut = unsafe { tree.cursor_mut_at(target_ref) };
3117                    assert_eq!($get_val(cursor_mut.get().unwrap()), 20);
3118
3119                    // Verify we can erase using the cursor returned by cursor_mut_at
3120                    let erased = cursor_mut.erase();
3121                    assert!(erased.is_some());
3122                    let val = erased.unwrap();
3123                    assert_eq!($get_val(unsafe { val.as_target_ref() }), 20);
3124
3125                    // Cursor should now be at the next element (30)
3126                    assert_eq!($get_val(cursor_mut.get().unwrap()), 30);
3127
3128                    tree.clear();
3129                }
3130
3131                #[test]
3132                fn test_iterator_clone() {
3133                    let mut factory = <$factory_type>::new();
3134                    stack_pin_init!(let tree = WavlTree::<i32, $ptr_type>::new());
3135                    let tree = unsafe { tree.get_unchecked_mut() };
3136                    $insert(tree, factory.create(10));
3137                    $insert(tree, factory.create(20));
3138                    $insert(tree, factory.create(30));
3139
3140                    let mut iter = tree.iter();
3141                    assert_eq!($get_val(iter.next().unwrap()), 10);
3142
3143                    let mut cloned_iter = iter.clone();
3144
3145                    assert_eq!($get_val(iter.next().unwrap()), 20);
3146                    assert_eq!($get_val(iter.next().unwrap()), 30);
3147                    assert!(iter.next().is_none());
3148
3149                    assert_eq!($get_val(cloned_iter.next().unwrap()), 20);
3150                    assert_eq!($get_val(cloned_iter.next().unwrap()), 30);
3151                    assert!(cloned_iter.next().is_none());
3152
3153                    tree.clear();
3154                }
3155
3156                #[test]
3157                fn test_swap() {
3158                    let mut factory = <$factory_type>::new();
3159                    stack_pin_init!(let tree1 = WavlTree::<i32, $ptr_type>::new());
3160                    let tree1 = unsafe { tree1.get_unchecked_mut() };
3161                    stack_pin_init!(let tree2 = WavlTree::<i32, $ptr_type>::new());
3162                    let tree2 = unsafe { tree2.get_unchecked_mut() };
3163
3164                    $insert(tree1, factory.create(1));
3165                    $insert(tree1, factory.create(3));
3166
3167                    $insert(tree2, factory.create(2));
3168                    $insert(tree2, factory.create(4));
3169
3170                    tree1.swap(tree2);
3171
3172                    let mut iter1 = tree1.iter();
3173                    assert_eq!($get_val(iter1.next().unwrap()), 2);
3174                    assert_eq!($get_val(iter1.next().unwrap()), 4);
3175                    assert!(iter1.next().is_none());
3176
3177                    let mut iter2 = tree2.iter();
3178                    assert_eq!($get_val(iter2.next().unwrap()), 1);
3179                    assert_eq!($get_val(iter2.next().unwrap()), 3);
3180                    assert!(iter2.next().is_none());
3181
3182                    tree1.clear();
3183                    tree2.clear();
3184                }
3185            }
3186        };
3187    }
3188
3189    generate_tree_tests!(
3190        raw_ptr_tests,
3191        *mut TestObject,
3192        RawFactory<TestObject>,
3193        |p: &TestObject| p.value,
3194        |tree, obj| unsafe { WavlTree::<i32, *mut TestObject>::insert_raw(tree, obj) },
3195        |tree, obj| unsafe { WavlTree::<i32, *mut TestObject>::insert_or_find_raw(tree, obj) },
3196        |tree, obj| unsafe { WavlTree::<i32, *mut TestObject>::insert_or_replace_raw(tree, obj) }
3197    );
3198
3199    generate_tree_tests!(
3200        unique_ptr_tests,
3201        UniquePtr<UniqueTestObject>,
3202        UniqueFactory<UniqueTestObject>,
3203        |p: &UniqueTestObject| p.value,
3204        |tree, obj| WavlTree::<i32, UniquePtr<UniqueTestObject>>::insert(tree, obj),
3205        |tree, obj| WavlTree::<i32, UniquePtr<UniqueTestObject>>::insert_or_find(tree, obj),
3206        |tree, obj| WavlTree::<i32, UniquePtr<UniqueTestObject>>::insert_or_replace(tree, obj)
3207    );
3208
3209    generate_tree_tests!(
3210        ref_ptr_tests,
3211        RefPtr<RefTestObject>,
3212        RefFactory<RefTestObject>,
3213        |p: &RefTestObject| p.value,
3214        |tree, obj| WavlTree::<i32, RefPtr<RefTestObject>>::insert(tree, obj),
3215        |tree, obj| WavlTree::<i32, RefPtr<RefTestObject>>::insert_or_find(tree, obj),
3216        |tree, obj| WavlTree::<i32, RefPtr<RefTestObject>>::insert_or_replace(tree, obj)
3217    );
3218
3219    #[test]
3220    fn test_erase_by_raw_pointer() {
3221        stack_pin_init!(let tree = WavlTree::<i32, *mut TestObject, DefaultObjectTag, TrackingSize>::new());
3222        let tree = unsafe { tree.get_unchecked_mut() };
3223        let mut obj1 = TestObject::new(10);
3224        let mut obj2 = TestObject::new(20);
3225        let mut obj3 = TestObject::new(30);
3226
3227        unsafe {
3228            tree.insert_raw(core::ptr::addr_of_mut!(obj1));
3229            tree.insert_raw(core::ptr::addr_of_mut!(obj2));
3230            tree.insert_raw(core::ptr::addr_of_mut!(obj3));
3231        }
3232
3233        assert_eq!(tree.len(), 3);
3234
3235        // Erase obj2 directly
3236        let erased = unsafe { tree.erase_raw(core::ptr::addr_of_mut!(obj2)) };
3237        assert!(erased.is_some());
3238        assert_eq!(unsafe { &*erased.unwrap() }.value, 20);
3239        assert_eq!(tree.len(), 2);
3240
3241        let mut iter = tree.iter();
3242        assert_eq!(iter.next().unwrap().value, 10);
3243        assert_eq!(iter.next().unwrap().value, 30);
3244        assert!(iter.next().is_none());
3245
3246        tree.clear();
3247    }
3248
3249    #[test]
3250    fn test_clear_unsafe() {
3251        stack_pin_init!(let tree = WavlTree::<i32, *mut TestObject, DefaultObjectTag, TrackingSize>::new());
3252        let tree = unsafe { tree.get_unchecked_mut() };
3253        let mut obj1 = TestObject::new(10);
3254        let mut obj2 = TestObject::new(20);
3255        let mut obj3 = TestObject::new(30);
3256
3257        unsafe {
3258            tree.insert_raw(core::ptr::addr_of_mut!(obj1));
3259            tree.insert_raw(core::ptr::addr_of_mut!(obj2));
3260            tree.insert_raw(core::ptr::addr_of_mut!(obj3));
3261        }
3262
3263        assert_eq!(tree.len(), 3);
3264        assert!(!tree.is_empty());
3265
3266        tree.clear_unsafe();
3267
3268        assert_eq!(tree.len(), 0);
3269        assert!(tree.is_empty());
3270
3271        // Clean up the nodes manually so that they can be safely dropped.
3272        unsafe {
3273            (*obj1.get_node().parent.get()) = core::ptr::null_mut();
3274            (*obj1.get_node().left.get()) = core::ptr::null_mut();
3275            (*obj1.get_node().right.get()) = core::ptr::null_mut();
3276
3277            (*obj2.get_node().parent.get()) = core::ptr::null_mut();
3278            (*obj2.get_node().left.get()) = core::ptr::null_mut();
3279            (*obj2.get_node().right.get()) = core::ptr::null_mut();
3280
3281            (*obj3.get_node().parent.get()) = core::ptr::null_mut();
3282            (*obj3.get_node().left.get()) = core::ptr::null_mut();
3283            (*obj3.get_node().right.get()) = core::ptr::null_mut();
3284        }
3285    }
3286
3287    #[test]
3288    fn test_tracking_size() {
3289        stack_pin_init!(let tree = WavlTree::<i32, UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
3290        let tree = unsafe { tree.get_unchecked_mut() };
3291
3292        assert_eq!(tree.len(), 0);
3293        tree.insert(UniquePtr::try_new(UniqueTestObject::new(10)).unwrap());
3294        assert_eq!(tree.len(), 1);
3295        tree.insert(UniquePtr::try_new(UniqueTestObject::new(20)).unwrap());
3296        assert_eq!(tree.len(), 2);
3297        tree.pop_front();
3298        assert_eq!(tree.len(), 1);
3299        tree.clear();
3300        assert_eq!(tree.len(), 0);
3301    }
3302
3303    struct Tag2;
3304
3305    #[fbl::ref_counted]
3306    #[derive(crate::WavlTreeContainable, crate::Recyclable)]
3307    #[repr(C)]
3308    struct MultiTreeObject {
3309        value: i32,
3310        #[wavl_node]
3311        node1: WavlTreeNode<MultiTreeObject>,
3312        #[wavl_node(tag = Tag2)]
3313        node2: WavlTreeNode<MultiTreeObject>,
3314    }
3315
3316    impl WavlTreeKeyable<i32> for MultiTreeObject {
3317        type Key<'a> = i32;
3318        fn get_key(&self) -> i32 {
3319            self.value
3320        }
3321    }
3322
3323    #[test]
3324    fn test_multiple_containers() {
3325        stack_pin_init!(let tree1 = WavlTree::<i32, RefPtr<MultiTreeObject>, DefaultObjectTag>::new());
3326        let tree1 = unsafe { tree1.get_unchecked_mut() };
3327        stack_pin_init!(let tree2 = WavlTree::<i32, RefPtr<MultiTreeObject>, Tag2>::new());
3328        let tree2 = unsafe { tree2.get_unchecked_mut() };
3329
3330        let obj1 = fbl::make_ref_counted!(MultiTreeObject {
3331            value: 10,
3332            node1: WavlTreeNode::new(),
3333            node2: WavlTreeNode::new(),
3334        })
3335        .unwrap();
3336
3337        let obj2 = fbl::make_ref_counted!(MultiTreeObject {
3338            value: 20,
3339            node1: WavlTreeNode::new(),
3340            node2: WavlTreeNode::new(),
3341        })
3342        .unwrap();
3343
3344        tree1.insert(obj1.clone());
3345        tree1.insert(obj2.clone());
3346
3347        tree2.insert(obj1.clone());
3348        tree2.insert(obj2.clone());
3349
3350        let mut iter1 = tree1.iter();
3351        assert_eq!(iter1.next().unwrap().value, 10);
3352        assert_eq!(iter1.next().unwrap().value, 20);
3353
3354        let mut iter2 = tree2.iter();
3355        assert_eq!(iter2.next().unwrap().value, 10);
3356        assert_eq!(iter2.next().unwrap().value, 20);
3357
3358        tree1.clear();
3359        tree2.clear();
3360    }
3361
3362    extern crate alloc;
3363    use alloc::boxed::Box;
3364    use alloc::sync::Arc;
3365    use alloc::vec::Vec;
3366    use core::sync::atomic::{AtomicUsize, Ordering};
3367
3368    struct Lfsr {
3369        core: u64,
3370    }
3371
3372    impl Lfsr {
3373        fn new(initial_core: u64) -> Self {
3374            Self { core: initial_core }
3375        }
3376
3377        fn set_core(&mut self, val: u64) {
3378            self.core = val;
3379        }
3380
3381        fn get_next(&mut self) -> u64 {
3382            let mut ret = 0u64;
3383            let mut flag = 1u64;
3384            let generator = 0xD800000000000000u64;
3385
3386            for _ in 0..(core::mem::size_of::<usize>() * 8) {
3387                let bit = (self.core & 1) != 0;
3388                self.core >>= 1;
3389                if bit {
3390                    self.core ^= generator;
3391                    ret |= flag;
3392                }
3393                flag <<= 1;
3394            }
3395
3396            ret
3397        }
3398    }
3399
3400    struct OpCounts {
3401        insert_ops: AtomicUsize,
3402        insert_promotes: AtomicUsize,
3403        insert_rotations: AtomicUsize,
3404        insert_double_rotations: AtomicUsize,
3405        insert_collisions: AtomicUsize,
3406        insert_replacements: AtomicUsize,
3407        insert_traversals: AtomicUsize,
3408        inspected_rotations: AtomicUsize,
3409        erase_ops: AtomicUsize,
3410        erase_demotes: AtomicUsize,
3411        erase_rotations: AtomicUsize,
3412        erase_double_rotations: AtomicUsize,
3413    }
3414
3415    impl OpCounts {
3416        const fn new() -> Self {
3417            Self {
3418                insert_ops: AtomicUsize::new(0),
3419                insert_promotes: AtomicUsize::new(0),
3420                insert_rotations: AtomicUsize::new(0),
3421                insert_double_rotations: AtomicUsize::new(0),
3422                insert_collisions: AtomicUsize::new(0),
3423                insert_replacements: AtomicUsize::new(0),
3424                insert_traversals: AtomicUsize::new(0),
3425                inspected_rotations: AtomicUsize::new(0),
3426                erase_ops: AtomicUsize::new(0),
3427                erase_demotes: AtomicUsize::new(0),
3428                erase_rotations: AtomicUsize::new(0),
3429                erase_double_rotations: AtomicUsize::new(0),
3430            }
3431        }
3432    }
3433
3434    #[derive(crate::WavlTreeContainable)]
3435    #[repr(C)]
3436    struct BalanceTestObj {
3437        key: u64,
3438        min_subtree_key: u64,
3439        max_subtree_key: u64,
3440        erase_deck_ptr: core::cell::Cell<*mut BalanceTestObj>,
3441        #[wavl_node(rank = i32)]
3442        node: WavlTreeNode<BalanceTestObj, i32>,
3443    }
3444
3445    impl BalanceTestObj {
3446        fn new(key: u64) -> Self {
3447            Self {
3448                key,
3449                min_subtree_key: 0,
3450                max_subtree_key: 0,
3451                erase_deck_ptr: core::cell::Cell::new(core::ptr::null_mut()),
3452                node: WavlTreeNode::new(),
3453            }
3454        }
3455
3456        fn swap_erase_deck_ptr(a: &BalanceTestObj, b: &BalanceTestObj) {
3457            let tmp = a.erase_deck_ptr.get();
3458            a.erase_deck_ptr.set(b.erase_deck_ptr.get());
3459            b.erase_deck_ptr.set(tmp);
3460        }
3461    }
3462
3463    impl WavlTreeKeyable<u64> for BalanceTestObj {
3464        type Key<'a> = u64;
3465        fn get_key(&self) -> u64 {
3466            self.key
3467        }
3468    }
3469
3470    struct WavlBalanceTestObserver {
3471        op_counts: Arc<OpCounts>,
3472    }
3473    impl WavlTreeObserver for WavlBalanceTestObserver {
3474        type Target = BalanceTestObj;
3475
3476        fn record_insert(&self, node: *mut BalanceTestObj) {
3477            self.op_counts.insert_ops.fetch_add(1, Ordering::Relaxed);
3478            unsafe {
3479                (*node).min_subtree_key = (*node).key;
3480                (*node).max_subtree_key = (*node).key;
3481            }
3482        }
3483
3484        fn record_insert_traverse(&self, node: *mut BalanceTestObj, ancestor: *mut BalanceTestObj) {
3485            self.op_counts.insert_traversals.fetch_add(1, Ordering::Relaxed);
3486            unsafe {
3487                (*ancestor).min_subtree_key =
3488                    core::cmp::min((*ancestor).min_subtree_key, (*node).key);
3489                (*ancestor).max_subtree_key =
3490                    core::cmp::max((*ancestor).max_subtree_key, (*node).key);
3491            }
3492        }
3493
3494        fn record_insert_collision(
3495            &self,
3496            _node: *mut BalanceTestObj,
3497            _collision: *mut BalanceTestObj,
3498        ) {
3499            self.op_counts.insert_collisions.fetch_add(1, Ordering::Relaxed);
3500        }
3501
3502        fn record_insert_replace(
3503            &self,
3504            node: *mut BalanceTestObj,
3505            replacement: *mut BalanceTestObj,
3506        ) {
3507            self.op_counts.insert_replacements.fetch_add(1, Ordering::Relaxed);
3508            unsafe {
3509                (*replacement).min_subtree_key = (*node).min_subtree_key;
3510                (*replacement).max_subtree_key = (*node).max_subtree_key;
3511            }
3512        }
3513
3514        fn record_insert_promote(&self) {
3515            self.op_counts.insert_promotes.fetch_add(1, Ordering::Relaxed);
3516        }
3517
3518        fn record_insert_rotation(&self) {
3519            self.op_counts.insert_rotations.fetch_add(1, Ordering::Relaxed);
3520        }
3521
3522        fn record_insert_double_rotation(&self) {
3523            self.op_counts.insert_double_rotations.fetch_add(1, Ordering::Relaxed);
3524        }
3525
3526        fn record_rotation(
3527            &self,
3528            pivot: *mut BalanceTestObj,
3529            lr_child: *mut BalanceTestObj,
3530            _rl_child: *mut BalanceTestObj,
3531            parent: *mut BalanceTestObj,
3532            sibling: *mut BalanceTestObj,
3533        ) {
3534            self.op_counts.inspected_rotations.fetch_add(1, Ordering::Relaxed);
3535            unsafe {
3536                (*pivot).min_subtree_key = (*parent).min_subtree_key;
3537                (*pivot).max_subtree_key = (*parent).max_subtree_key;
3538
3539                (*parent).min_subtree_key = (*parent).key;
3540                (*parent).max_subtree_key = (*parent).key;
3541
3542                if valid_sentinel_ptr(sibling) {
3543                    (*parent).min_subtree_key =
3544                        core::cmp::min((*parent).min_subtree_key, (*sibling).min_subtree_key);
3545                    (*parent).max_subtree_key =
3546                        core::cmp::max((*parent).max_subtree_key, (*sibling).max_subtree_key);
3547                }
3548                if valid_sentinel_ptr(lr_child) {
3549                    (*parent).min_subtree_key =
3550                        core::cmp::min((*parent).min_subtree_key, (*lr_child).min_subtree_key);
3551                    (*parent).max_subtree_key =
3552                        core::cmp::max((*parent).max_subtree_key, (*lr_child).max_subtree_key);
3553                }
3554            }
3555        }
3556
3557        fn record_erase(&self, _node: *mut BalanceTestObj, invalidated: *mut BalanceTestObj) {
3558            self.op_counts.erase_ops.fetch_add(1, Ordering::Relaxed);
3559            unsafe {
3560                let mut current = invalidated;
3561                while valid_sentinel_ptr(current) {
3562                    (*current).min_subtree_key = (*current).key;
3563                    (*current).max_subtree_key = (*current).key;
3564
3565                    let ns = (*current).get_node();
3566                    let left = ns.get_left();
3567                    if valid_sentinel_ptr(left) {
3568                        (*current).min_subtree_key =
3569                            core::cmp::min((*current).min_subtree_key, (*left).min_subtree_key);
3570                        (*current).max_subtree_key =
3571                            core::cmp::max((*current).max_subtree_key, (*left).max_subtree_key);
3572                    }
3573                    let right = ns.get_right();
3574                    if valid_sentinel_ptr(right) {
3575                        (*current).min_subtree_key =
3576                            core::cmp::min((*current).min_subtree_key, (*right).min_subtree_key);
3577                        (*current).max_subtree_key =
3578                            core::cmp::max((*current).max_subtree_key, (*right).max_subtree_key);
3579                    }
3580                    current = ns.get_parent();
3581                }
3582            }
3583        }
3584
3585        fn record_erase_demote(&self) {
3586            self.op_counts.erase_demotes.fetch_add(1, Ordering::Relaxed);
3587        }
3588
3589        fn record_erase_rotation(&self) {
3590            self.op_counts.erase_rotations.fetch_add(1, Ordering::Relaxed);
3591        }
3592
3593        fn record_erase_double_rotation(&self) {
3594            self.op_counts.erase_double_rotations.fetch_add(1, Ordering::Relaxed);
3595        }
3596
3597        fn verify_rank_rule(
3598            &self,
3599            node: *mut BalanceTestObj,
3600            _left_most: *mut BalanceTestObj,
3601            _right_most: *mut BalanceTestObj,
3602            _sentinel: *mut BalanceTestObj,
3603        ) {
3604            unsafe {
3605                let ns = (*node).get_node();
3606                let rank = ns.rank();
3607                assert!(rank >= 0, "All ranks must be non-negative.");
3608
3609                let left = ns.get_left();
3610                let right = ns.get_right();
3611
3612                if !valid_sentinel_ptr(left) && !valid_sentinel_ptr(right) {
3613                    assert_eq!(rank, 0i32, "Leaf nodes must have rank 0!");
3614                } else {
3615                    if valid_sentinel_ptr(left) {
3616                        let left_ns = (*left).get_node();
3617                        let delta = rank - left_ns.rank();
3618                        assert!(
3619                            delta >= 1 && delta <= 2,
3620                            "Left hand rank difference not in range [1, 2]"
3621                        );
3622                    }
3623
3624                    if valid_sentinel_ptr(right) {
3625                        let right_ns = (*right).get_node();
3626                        let delta = rank - right_ns.rank();
3627                        assert!(
3628                            delta >= 1 && delta <= 2,
3629                            "Right hand rank difference not in range [1, 2]"
3630                        );
3631                    }
3632                }
3633            }
3634        }
3635
3636        fn verify_balance(&self, size: usize, depth: usize) {
3637            if size > 0 {
3638                let log2_n = (size as f64).log2();
3639                let erase_ops = self.op_counts.erase_ops.load(Ordering::Relaxed);
3640                let scale = if erase_ops > 0 { 2.0 } else { 1.4404200904125564 };
3641                let max_depth = (log2_n * scale) as usize + 1;
3642                assert!(
3643                    max_depth >= depth,
3644                    "Depth bound exceeded! max_depth: {}, actual depth: {}",
3645                    max_depth,
3646                    depth
3647                );
3648
3649                let insert_rotations = self.op_counts.insert_rotations.load(Ordering::Relaxed);
3650                let insert_double_rotations =
3651                    self.op_counts.insert_double_rotations.load(Ordering::Relaxed);
3652                let insert_promotes = self.op_counts.insert_promotes.load(Ordering::Relaxed);
3653                let insert_ops = self.op_counts.insert_ops.load(Ordering::Relaxed);
3654
3655                let total_insert_rotations = insert_rotations + insert_double_rotations;
3656                assert!(
3657                    insert_promotes <= (3 * insert_ops) + (2 * erase_ops),
3658                    "#insert promotes must be <= (3 * #inserts) + (2 * #erases)"
3659                );
3660                assert!(
3661                    total_insert_rotations <= insert_ops,
3662                    "#insert_rotations must be <= #inserts"
3663                );
3664
3665                let erase_demotes = self.op_counts.erase_demotes.load(Ordering::Relaxed);
3666                let erase_rotations = self.op_counts.erase_rotations.load(Ordering::Relaxed);
3667                let erase_double_rotations =
3668                    self.op_counts.erase_double_rotations.load(Ordering::Relaxed);
3669
3670                let total_erase_rotations = erase_rotations + erase_double_rotations;
3671                assert!(erase_demotes <= erase_ops, "#erase demotes must be <= #erases");
3672                assert!(total_erase_rotations <= erase_ops, "#erase_rotations must be <= #erases");
3673
3674                let inspected_rotations =
3675                    self.op_counts.inspected_rotations.load(Ordering::Relaxed);
3676                let total_inspected_rotations = insert_rotations
3677                    + erase_rotations
3678                    + 2 * insert_double_rotations
3679                    + 2 * erase_double_rotations;
3680                assert_eq!(
3681                    total_inspected_rotations, inspected_rotations,
3682                    "#inspected rotations must be == #rotations"
3683                );
3684            }
3685        }
3686    }
3687
3688    struct WavlTreeChecker;
3689    impl WavlTreeChecker {
3690        fn verify_parent_back_links<K, P, Tag, S, O>(cursor: Cursor<'_, K, P, Tag, S, O>)
3691        where
3692            P: PtrTraits,
3693            P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
3694            K: Ord,
3695            S: SizeTracker,
3696            O: WavlTreeObserver<Target = P::Target>,
3697        {
3698            assert!(cursor.is_valid());
3699            let left = cursor.left();
3700            if left.is_valid() {
3701                assert_eq!(
3702                    cursor.as_raw_ptr(),
3703                    left.parent().as_raw_ptr(),
3704                    "Corrupt left-side parent back-link!"
3705                );
3706            }
3707
3708            let right = cursor.right();
3709            if right.is_valid() {
3710                assert_eq!(
3711                    cursor.as_raw_ptr(),
3712                    right.parent().as_raw_ptr(),
3713                    "Corrupt right-side parent back-link!"
3714                );
3715            }
3716        }
3717
3718        fn sanity_check<K, P, Tag, S, O>(tree: &WavlTree<K, P, Tag, S, O>)
3719        where
3720            P: PtrTraits,
3721            P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
3722            K: Ord,
3723            S: SizeTracker,
3724            O: WavlTreeObserver<Target = P::Target>,
3725        {
3726            let is_empty = tree.is_empty();
3727            let root = tree.root_cursor();
3728            let front = tree.front_cursor();
3729            let back = tree.back_cursor();
3730
3731            let sentinel_ptr =
3732                if is_empty { front.as_raw_ptr() } else { front.left().as_raw_ptr() };
3733
3734            if is_empty {
3735                assert!(!root.is_valid());
3736                assert!(!front.is_valid());
3737                assert!(!back.is_valid());
3738                if S::IS_TRACKING {
3739                    assert_eq!(tree.len(), 0);
3740                }
3741            } else {
3742                assert!(root.is_valid());
3743                assert!(front.is_valid());
3744                assert!(back.is_valid());
3745                assert!(!front.left().is_valid());
3746                assert!(!back.right().is_valid());
3747                if S::IS_TRACKING {
3748                    assert!(tree.len() > 0);
3749                }
3750            }
3751
3752            let mut cur_depth = 0;
3753            let mut depth = 0;
3754            let mut size = 0;
3755
3756            let mut cursor = root;
3757
3758            while cursor.is_valid() {
3759                Self::verify_parent_back_links(cursor);
3760                cur_depth += 1;
3761
3762                let left = cursor.left();
3763                if !left.is_valid() {
3764                    break;
3765                }
3766                cursor = left;
3767            }
3768
3769            while cursor.is_valid() {
3770                if depth < cur_depth {
3771                    depth = cur_depth;
3772                }
3773                size += 1;
3774
3775                Self::verify_parent_back_links(cursor);
3776                tree.observer.verify_rank_rule(
3777                    cursor.as_raw_ptr(),
3778                    front.as_raw_ptr(),
3779                    back.as_raw_ptr(),
3780                    sentinel_ptr,
3781                );
3782
3783                let right = cursor.right();
3784                if right.is_valid() {
3785                    cur_depth += 1;
3786                    cursor = right;
3787                    Self::verify_parent_back_links(cursor);
3788
3789                    loop {
3790                        let left = cursor.left();
3791                        if !left.is_valid() {
3792                            break;
3793                        }
3794                        cur_depth += 1;
3795                        cursor = left;
3796                        Self::verify_parent_back_links(cursor);
3797                    }
3798                    continue;
3799                }
3800
3801                let mut parent = cursor.parent();
3802                let mut keep_going = false;
3803                while parent.is_valid() {
3804                    let is_left = parent.left() == cursor;
3805                    let is_right = parent.right() == cursor;
3806
3807                    assert!(is_left != is_right);
3808                    assert!(is_left || is_right);
3809
3810                    cursor = parent;
3811                    cur_depth -= 1;
3812
3813                    if is_left {
3814                        keep_going = true;
3815                        break;
3816                    }
3817
3818                    parent = parent.parent();
3819                }
3820
3821                if !keep_going {
3822                    break;
3823                }
3824            }
3825
3826            if S::IS_TRACKING {
3827                assert_eq!(tree.len(), size);
3828            }
3829            tree.observer.verify_balance(size, depth);
3830        }
3831    }
3832
3833    fn shuffle_erase_deck(objects: &[Box<BalanceTestObj>], rng: &mut Lfsr, size: usize) {
3834        for i in (2..size).rev() {
3835            let ndx = (rng.get_next() as usize) % i;
3836            if ndx != i {
3837                BalanceTestObj::swap_erase_deck_ptr(&objects[i], &objects[ndx]);
3838            }
3839        }
3840    }
3841
3842    fn check_augmented_invariants<K, P, Tag, S, O>(tree: &WavlTree<K, P, Tag, S, O>)
3843    where
3844        P: PtrTraits,
3845        P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
3846        K: Ord,
3847        S: SizeTracker,
3848        O: WavlTreeObserver<Target = P::Target>,
3849    {
3850        if tree.is_empty() {
3851            return;
3852        }
3853        let root = tree.root_cursor().as_raw_ptr() as *mut BalanceTestObj;
3854        let left = tree.front_cursor().as_raw_ptr() as *mut BalanceTestObj;
3855        let right = tree.back_cursor().as_raw_ptr() as *mut BalanceTestObj;
3856
3857        unsafe {
3858            assert_eq!((*root).min_subtree_key, (*left).key, "Min subtree key invariant violated!");
3859            assert_eq!(
3860                (*root).max_subtree_key,
3861                (*right).key,
3862                "Max subtree key invariant violated!"
3863            );
3864        }
3865    }
3866
3867    fn check_iterators<K, P, Tag, S, O>(tree: &WavlTree<K, P, Tag, S, O>)
3868    where
3869        P: PtrTraits,
3870        P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
3871        K: Ord,
3872        S: SizeTracker,
3873        O: WavlTreeObserver<Target = P::Target>,
3874    {
3875        if tree.is_empty() {
3876            return;
3877        }
3878        let root = tree.root_cursor();
3879        let left_most = tree.front_cursor();
3880        let right_most = tree.back_cursor();
3881
3882        let mut left_cursor = root;
3883        let mut right_cursor = root;
3884        let mut i = 0;
3885
3886        let limit = if S::IS_TRACKING { tree.len() } else { 10000 };
3887
3888        while (left_cursor != left_most || right_cursor != right_most) && i < limit {
3889            assert!(left_cursor.is_valid());
3890            if left_cursor == left_most {
3891                assert!(!left_cursor.left().is_valid());
3892            } else {
3893                left_cursor = left_cursor.left();
3894            }
3895
3896            assert!(right_cursor.is_valid());
3897            if right_cursor == right_most {
3898                assert!(!right_cursor.right().is_valid());
3899            } else {
3900                right_cursor = right_cursor.right();
3901            }
3902
3903            i += 1;
3904        }
3905
3906        assert_eq!(left_cursor, left_most);
3907        assert_eq!(right_cursor, right_most);
3908
3909        let limit = i;
3910        left_cursor = left_most;
3911        right_cursor = right_most;
3912        i = 0;
3913
3914        while (left_cursor != root || right_cursor != root) && i < limit {
3915            assert!(left_cursor.is_valid());
3916            if left_cursor == root {
3917                assert!(!left_cursor.parent().is_valid());
3918            } else {
3919                left_cursor = left_cursor.parent();
3920            }
3921
3922            assert!(right_cursor.is_valid());
3923            if right_cursor == root {
3924                assert!(!right_cursor.parent().is_valid());
3925            } else {
3926                right_cursor = right_cursor.parent();
3927            }
3928
3929            i += 1;
3930        }
3931
3932        assert_eq!(left_cursor, root);
3933        assert_eq!(right_cursor, root);
3934    }
3935
3936    #[test]
3937    fn test_balance_and_invariants() {
3938        let seeds = [0xe87e1062fc1f4f80u64, 0x03d6bffb124b4918u64, 0x8f7d83e8d10b4765u64];
3939        let test_size = 128;
3940        let replacement_count = test_size / 8;
3941        let mut rng = Lfsr::new(1);
3942
3943        for seed_ndx in 0..seeds.len() {
3944            let seed = seeds[seed_ndx];
3945            rng.set_core(seed);
3946
3947            let op_counts = Arc::new(OpCounts::new());
3948            let observer = WavlBalanceTestObserver { op_counts: Arc::clone(&op_counts) };
3949
3950            stack_pin_init!(let tree = WavlTree::<u64, *mut BalanceTestObj, DefaultObjectTag, TrackingSize, WavlBalanceTestObserver>::new_with_observer(observer));
3951            let tree = unsafe { tree.get_unchecked_mut() };
3952
3953            let mut objects = Vec::with_capacity(test_size);
3954            let mut replacements = Vec::with_capacity(replacement_count);
3955
3956            match seed_ndx {
3957                0 => {
3958                    for i in 0..test_size {
3959                        let obj = Box::new(BalanceTestObj::new(i as u64));
3960                        let raw = &*obj as *const BalanceTestObj as *mut BalanceTestObj;
3961                        obj.erase_deck_ptr.set(raw);
3962                        objects.push(obj);
3963
3964                        if i < replacement_count {
3965                            let rep = Box::new(BalanceTestObj::new(i as u64));
3966                            let raw = &*rep as *const BalanceTestObj as *mut BalanceTestObj;
3967                            rep.erase_deck_ptr.set(raw);
3968                            replacements.push(rep);
3969                        }
3970                    }
3971                }
3972                1 => {
3973                    for i in 0..test_size {
3974                        let obj = Box::new(BalanceTestObj::new((test_size - i) as u64));
3975                        let raw = &*obj as *const BalanceTestObj as *mut BalanceTestObj;
3976                        obj.erase_deck_ptr.set(raw);
3977                        objects.push(obj);
3978
3979                        if i < replacement_count {
3980                            let rep = Box::new(BalanceTestObj::new((test_size - i) as u64));
3981                            let raw = &*rep as *const BalanceTestObj as *mut BalanceTestObj;
3982                            rep.erase_deck_ptr.set(raw);
3983                            replacements.push(rep);
3984                        }
3985                    }
3986                }
3987                _ => {
3988                    for i in 0..test_size {
3989                        let val = rng.get_next();
3990                        let obj = Box::new(BalanceTestObj::new(val));
3991                        let raw = &*obj as *const BalanceTestObj as *mut BalanceTestObj;
3992                        obj.erase_deck_ptr.set(raw);
3993                        objects.push(obj);
3994
3995                        if i < replacement_count {
3996                            let rep = Box::new(BalanceTestObj::new(val));
3997                            let raw = &*rep as *const BalanceTestObj as *mut BalanceTestObj;
3998                            rep.erase_deck_ptr.set(raw);
3999                            replacements.push(rep);
4000                        }
4001                    }
4002                }
4003            }
4004
4005            // 1. Insert all objects
4006            for i in 0..test_size {
4007                unsafe {
4008                    check_augmented_invariants(tree);
4009                    WavlTreeChecker::sanity_check(tree);
4010                    let raw = &mut *objects[i] as *mut BalanceTestObj;
4011                    tree.insert_raw(raw);
4012                    check_augmented_invariants(tree);
4013                    WavlTreeChecker::sanity_check(tree);
4014                }
4015            }
4016
4017            check_iterators(tree);
4018
4019            // 2. Collide replacements
4020            for i in 0..replacement_count {
4021                unsafe {
4022                    check_augmented_invariants(tree);
4023                    WavlTreeChecker::sanity_check(tree);
4024                    let raw = &mut *replacements[i] as *mut BalanceTestObj;
4025                    assert!(tree.insert_or_find_raw(raw).is_err());
4026                    check_augmented_invariants(tree);
4027                    WavlTreeChecker::sanity_check(tree);
4028                }
4029            }
4030
4031            // 3. Replace original nodes with replacements
4032            for i in 0..replacement_count {
4033                unsafe {
4034                    check_augmented_invariants(tree);
4035                    WavlTreeChecker::sanity_check(tree);
4036                    let raw = &mut *replacements[i] as *mut BalanceTestObj;
4037                    assert!(tree.insert_or_replace_raw(raw).is_some());
4038                    check_augmented_invariants(tree);
4039                    WavlTreeChecker::sanity_check(tree);
4040                }
4041            }
4042
4043            check_iterators(tree);
4044
4045            // 4. Swap them back
4046            for i in 0..replacement_count {
4047                unsafe {
4048                    check_augmented_invariants(tree);
4049                    WavlTreeChecker::sanity_check(tree);
4050                    let raw = &mut *objects[i] as *mut BalanceTestObj;
4051                    assert!(tree.insert_or_replace_raw(raw).is_some());
4052                    check_augmented_invariants(tree);
4053                    WavlTreeChecker::sanity_check(tree);
4054                }
4055            }
4056
4057            check_iterators(tree);
4058
4059            // Shuffle erase deck
4060            shuffle_erase_deck(&objects, &mut rng, test_size);
4061
4062            // 5. Erase half the elements
4063            for i in 0..(test_size / 2) {
4064                unsafe {
4065                    check_augmented_invariants(tree);
4066                    WavlTreeChecker::sanity_check(tree);
4067                    let raw_target = objects[i].erase_deck_ptr.get();
4068                    let erased = tree.erase_raw(raw_target);
4069                    assert!(erased.is_some());
4070                    assert_eq!(erased.unwrap(), raw_target);
4071                    check_augmented_invariants(tree);
4072                    WavlTreeChecker::sanity_check(tree);
4073                }
4074            }
4075
4076            check_iterators(tree);
4077
4078            // 6. Put them back
4079            for i in 0..(test_size / 2) {
4080                unsafe {
4081                    check_augmented_invariants(tree);
4082                    WavlTreeChecker::sanity_check(tree);
4083                    let raw_target = objects[i].erase_deck_ptr.get();
4084                    tree.insert_raw(raw_target);
4085                    check_augmented_invariants(tree);
4086                    WavlTreeChecker::sanity_check(tree);
4087                }
4088            }
4089
4090            check_iterators(tree);
4091
4092            // Shuffle erase deck again
4093            shuffle_erase_deck(&objects, &mut rng, test_size);
4094
4095            // 7. Erase everything
4096            for i in 0..test_size {
4097                unsafe {
4098                    check_augmented_invariants(tree);
4099                    WavlTreeChecker::sanity_check(tree);
4100                    let raw_target = objects[i].erase_deck_ptr.get();
4101                    let erased = tree.erase_raw(raw_target);
4102                    assert!(erased.is_some());
4103                    assert_eq!(erased.unwrap(), raw_target);
4104                    check_augmented_invariants(tree);
4105                    WavlTreeChecker::sanity_check(tree);
4106                }
4107            }
4108
4109            check_iterators(tree);
4110            assert_eq!(tree.size.get(), 0);
4111
4112            assert!(op_counts.insert_ops.load(Ordering::Relaxed) > 0);
4113            assert!(op_counts.insert_promotes.load(Ordering::Relaxed) > 0);
4114            assert!(op_counts.insert_rotations.load(Ordering::Relaxed) > 0);
4115            assert!(op_counts.insert_traversals.load(Ordering::Relaxed) > 0);
4116            assert!(op_counts.erase_ops.load(Ordering::Relaxed) > 0);
4117            assert!(op_counts.erase_demotes.load(Ordering::Relaxed) > 0);
4118            assert!(op_counts.erase_rotations.load(Ordering::Relaxed) > 0);
4119        }
4120    }
4121
4122    // WavlTree FFI Declarations
4123    unsafe extern "C" {
4124        // UniqueTree Helpers
4125        fn cpp_create_unique_tree() -> *mut c_void;
4126        fn cpp_destroy_unique_tree(tree: *mut c_void);
4127        fn cpp_unique_tree_insert(tree: *mut c_void, item: *mut c_void);
4128        fn cpp_unique_tree_erase(tree: *mut c_void, key: i32) -> *mut c_void;
4129        fn cpp_unique_tree_find(tree: *mut c_void, key: i32) -> *mut c_void;
4130        fn cpp_unique_tree_is_empty(tree: *mut c_void) -> bool;
4131
4132        // RefTree Helpers
4133        fn cpp_create_ref_tree() -> *mut c_void;
4134        fn cpp_destroy_ref_tree(tree: *mut c_void);
4135        fn cpp_ref_tree_insert(tree: *mut c_void, item: *mut c_void);
4136        fn cpp_ref_tree_erase(tree: *mut c_void, key: i32) -> *mut c_void;
4137        fn cpp_ref_tree_find(tree: *mut c_void, key: i32) -> *mut c_void;
4138        fn cpp_ref_tree_is_empty(tree: *mut c_void) -> bool;
4139
4140        // SharedUniqueObject Helpers (Defined in intrusive_container_test_support.cc)
4141        fn cpp_create_unique_object(value: i32, destruction_flag: *mut bool) -> *mut c_void;
4142        fn cpp_get_unique_object_value(obj: *mut c_void) -> i32;
4143
4144        // SharedRefObject Helpers (Defined in intrusive_container_test_support.cc)
4145        fn cpp_create_ref_object(value: i32, destruction_flag: *mut bool) -> *mut c_void;
4146        fn cpp_get_ref_object_value(obj: *mut c_void) -> i32;
4147    }
4148
4149    #[test]
4150    fn test_interop_rust_tree_cpp_unique_objects() {
4151        use core::sync::atomic::{AtomicBool, Ordering};
4152
4153        let destroyed1 = AtomicBool::new(false);
4154        let destroyed2 = AtomicBool::new(false);
4155
4156        unsafe {
4157            stack_pin_init!(let tree = WavlTree::<i32, UniquePtr<SharedUniqueObject>>::new());
4158            let tree = tree.get_unchecked_mut();
4159
4160            let cpp_raw1 = cpp_create_unique_object(10, destroyed1.as_ptr() as *mut bool);
4161            let cpp_raw2 = cpp_create_unique_object(20, destroyed2.as_ptr() as *mut bool);
4162
4163            let obj1 = UniquePtr::from_raw(cpp_raw1 as *mut SharedUniqueObject);
4164            let obj2 = UniquePtr::from_raw(cpp_raw2 as *mut SharedUniqueObject);
4165
4166            tree.insert(obj1);
4167            tree.insert(obj2);
4168
4169            assert!(!destroyed1.load(Ordering::Relaxed));
4170            assert!(!destroyed2.load(Ordering::Relaxed));
4171
4172            // Find one
4173            let found = tree.find(&10);
4174            assert!(found.is_some());
4175            assert_eq!(found.unwrap().value, 10);
4176
4177            // Erase one
4178            let popped = tree.erase(&20);
4179            assert!(popped.is_some());
4180            assert_eq!(popped.as_ref().unwrap().value, 20);
4181
4182            // Drop popped -> should destroy in C++!
4183            drop(popped);
4184            assert!(!destroyed1.load(Ordering::Relaxed));
4185            assert!(destroyed2.load(Ordering::Relaxed));
4186
4187            // Drop tree -> should destroy remaining in C++!
4188        }
4189        assert!(destroyed1.load(Ordering::Relaxed));
4190    }
4191
4192    #[test]
4193    fn test_interop_cpp_tree_rust_unique_objects() {
4194        use alloc::sync::Arc;
4195        use core::sync::atomic::{AtomicBool, Ordering};
4196
4197        let destroyed1 = Arc::new(AtomicBool::new(false));
4198        let destroyed2 = Arc::new(AtomicBool::new(false));
4199
4200        unsafe {
4201            let cpp_tree = cpp_create_unique_tree();
4202            assert!(cpp_unique_tree_is_empty(cpp_tree));
4203
4204            let obj1 = UniquePtr::try_new(SharedUniqueObject::new(10)).unwrap();
4205            let obj2 = UniquePtr::try_new(SharedUniqueObject::new(20)).unwrap();
4206
4207            // Set destruction flags
4208            let raw1 = UniquePtr::as_ptr(&obj1) as *mut SharedUniqueObject;
4209            (*raw1).destruction_flag = destroyed1.as_ptr() as *mut bool;
4210            let raw2 = UniquePtr::as_ptr(&obj2) as *mut SharedUniqueObject;
4211            (*raw2).destruction_flag = destroyed2.as_ptr() as *mut bool;
4212
4213            // Push to C++ tree (transfers ownership)
4214            cpp_unique_tree_insert(cpp_tree, UniquePtr::into_raw(obj1) as *mut c_void);
4215            cpp_unique_tree_insert(cpp_tree, UniquePtr::into_raw(obj2) as *mut c_void);
4216
4217            assert!(!destroyed1.load(Ordering::Relaxed));
4218            assert!(!destroyed2.load(Ordering::Relaxed));
4219
4220            // Find in C++
4221            let found = cpp_unique_tree_find(cpp_tree, 10);
4222            assert!(!found.is_null());
4223            assert_eq!(cpp_get_unique_object_value(found), 10);
4224
4225            // Erase one from C++
4226            let popped = cpp_unique_tree_erase(cpp_tree, 20);
4227            assert!(!popped.is_null());
4228            assert_eq!(cpp_get_unique_object_value(popped), 20);
4229
4230            // Convert back to Rust UniquePtr and drop -> should free in Rust!
4231            let popped_rust = UniquePtr::from_raw(popped as *mut SharedUniqueObject);
4232            drop(popped_rust);
4233            assert!(!destroyed1.load(Ordering::Relaxed));
4234            assert!(destroyed2.load(Ordering::Relaxed));
4235
4236            // Destroy C++ tree -> should destroy remaining in Rust!
4237            cpp_destroy_unique_tree(cpp_tree);
4238        }
4239        assert!(destroyed1.load(Ordering::Relaxed));
4240    }
4241
4242    #[test]
4243    fn test_interop_rust_tree_cpp_ref_objects() {
4244        use core::sync::atomic::{AtomicBool, Ordering};
4245
4246        let destroyed1 = AtomicBool::new(false);
4247        let destroyed2 = AtomicBool::new(false);
4248
4249        unsafe {
4250            stack_pin_init!(let tree = WavlTree::<i32, RefPtr<SharedRefObject>>::new());
4251            let tree = tree.get_unchecked_mut();
4252
4253            let cpp_raw1 = cpp_create_ref_object(10, destroyed1.as_ptr() as *mut bool);
4254            let cpp_raw2 = cpp_create_ref_object(20, destroyed2.as_ptr() as *mut bool);
4255
4256            let obj1 = RefPtr::from_raw(cpp_raw1 as *mut SharedRefObject);
4257            let obj2 = RefPtr::from_raw(cpp_raw2 as *mut SharedRefObject);
4258
4259            tree.insert(obj1);
4260            tree.insert(obj2);
4261
4262            assert!(!destroyed1.load(Ordering::Relaxed));
4263            assert!(!destroyed2.load(Ordering::Relaxed));
4264
4265            // Find one
4266            let found = tree.find(&10);
4267            assert!(found.is_some());
4268            assert_eq!(found.unwrap().value, 10);
4269
4270            // Erase one
4271            let popped = tree.erase(&20);
4272            assert!(popped.is_some());
4273            assert_eq!(popped.as_ref().unwrap().value, 20);
4274
4275            // Drop popped -> should destroy in C++!
4276            drop(popped);
4277            assert!(!destroyed1.load(Ordering::Relaxed));
4278            assert!(destroyed2.load(Ordering::Relaxed));
4279
4280            // Drop tree -> should destroy remaining in C++!
4281        }
4282        assert!(destroyed1.load(Ordering::Relaxed));
4283    }
4284
4285    #[test]
4286    fn test_interop_cpp_tree_rust_ref_objects() {
4287        use alloc::sync::Arc;
4288        use core::sync::atomic::{AtomicBool, Ordering};
4289
4290        let destroyed1 = Arc::new(AtomicBool::new(false));
4291        let destroyed2 = Arc::new(AtomicBool::new(false));
4292
4293        unsafe {
4294            let cpp_tree = cpp_create_ref_tree();
4295            assert!(cpp_ref_tree_is_empty(cpp_tree));
4296
4297            let obj1 = SharedRefObject::new_ref_counted(10);
4298            let obj2 = SharedRefObject::new_ref_counted(20);
4299
4300            // Set destruction flags
4301            let raw1 = RefPtr::as_ptr(&obj1) as *mut SharedRefObject;
4302            (*raw1).destruction_flag = destroyed1.as_ptr() as *mut bool;
4303            let raw2 = RefPtr::as_ptr(&obj2) as *mut SharedRefObject;
4304            (*raw2).destruction_flag = destroyed2.as_ptr() as *mut bool;
4305
4306            // Insert to C++ tree (transfers ownership)
4307            cpp_ref_tree_insert(
4308                cpp_tree,
4309                RefPtr::into_raw(obj1) as *mut SharedRefObject as *mut c_void,
4310            );
4311            cpp_ref_tree_insert(
4312                cpp_tree,
4313                RefPtr::into_raw(obj2) as *mut SharedRefObject as *mut c_void,
4314            );
4315
4316            assert!(!destroyed1.load(Ordering::Relaxed));
4317            assert!(!destroyed2.load(Ordering::Relaxed));
4318
4319            // Find in C++
4320            let found = cpp_ref_tree_find(cpp_tree, 10);
4321            assert!(!found.is_null());
4322            assert_eq!(cpp_get_ref_object_value(found), 10);
4323
4324            // Erase one from C++
4325            let popped = cpp_ref_tree_erase(cpp_tree, 20);
4326            assert!(!popped.is_null());
4327            assert_eq!(cpp_get_ref_object_value(popped), 20);
4328
4329            // Convert back to Rust RefPtr and drop -> should free in Rust!
4330            let popped_rust = RefPtr::from_raw(popped as *mut SharedRefObject);
4331            drop(popped_rust);
4332            assert!(!destroyed1.load(Ordering::Relaxed));
4333            assert!(destroyed2.load(Ordering::Relaxed));
4334
4335            // Destroy C++ tree -> should destroy remaining in Rust!
4336            cpp_destroy_ref_tree(cpp_tree);
4337        }
4338        assert!(destroyed1.load(Ordering::Relaxed));
4339    }
4340
4341    #[derive(PartialEq, Eq, PartialOrd, Ord, Debug)]
4342    struct LargeKey {
4343        name: [u8; 32],
4344    }
4345
4346    #[derive(crate::WavlTreeContainable, crate::Recyclable)]
4347    struct TestRefKeyObject {
4348        key: LargeKey,
4349        #[wavl_node]
4350        node: WavlTreeNode<TestRefKeyObject>,
4351    }
4352
4353    impl TestRefKeyObject {
4354        fn new(name: [u8; 32]) -> Self {
4355            Self { key: LargeKey { name }, node: WavlTreeNode::new() }
4356        }
4357    }
4358
4359    impl WavlTreeKeyable<LargeKey> for TestRefKeyObject {
4360        type Key<'a> = &'a LargeKey;
4361        fn get_key(&self) -> &LargeKey {
4362            &self.key
4363        }
4364    }
4365
4366    #[test]
4367    fn test_by_reference_key() {
4368        use crate::UniquePtr;
4369
4370        type TestTree = WavlTree<LargeKey, UniquePtr<TestRefKeyObject>>;
4371        stack_pin_init!(let tree = TestTree::new());
4372        let tree = unsafe { tree.get_unchecked_mut() };
4373
4374        let mut key1 = [0u8; 32];
4375        key1[0] = 10;
4376        let mut key2 = [0u8; 32];
4377        key2[0] = 20;
4378
4379        let obj1 = UniquePtr::try_new(TestRefKeyObject::new(key1)).unwrap();
4380        let obj2 = UniquePtr::try_new(TestRefKeyObject::new(key2)).unwrap();
4381        tree.insert(obj1);
4382        tree.insert(obj2);
4383
4384        let query = LargeKey { name: key1 };
4385        let found = tree.find(&query);
4386        assert!(found.is_some());
4387        assert_eq!(found.unwrap().key, query);
4388
4389        let erased = tree.erase(&query);
4390        assert!(erased.is_some());
4391        assert_eq!(erased.unwrap().key, query);
4392    }
4393
4394    #[derive(WavlTreeContainable, Recyclable)]
4395    struct TestAugmentedObject {
4396        value: i32,
4397        subtree_sum: i32,
4398        #[wavl_node]
4399        node: WavlTreeNode<TestAugmentedObject>,
4400    }
4401
4402    impl TestAugmentedObject {
4403        fn new(value: i32) -> Self {
4404            Self { value, subtree_sum: 0, node: WavlTreeNode::new() }
4405        }
4406    }
4407
4408    impl WavlTreeKeyable<i32> for TestAugmentedObject {
4409        type Key<'a> = i32;
4410        fn get_key(&self) -> i32 {
4411            self.value
4412        }
4413    }
4414
4415    struct SubtreeSumTraits;
4416    impl WavlTreeAugmentedInvariantObserverTraits for SubtreeSumTraits {
4417        type Target = TestAugmentedObject;
4418        type Value = i32;
4419
4420        fn get_node_value(node: &Self::Target) -> Self::Value {
4421            node.value
4422        }
4423
4424        fn get_subtree_value(node: &Self::Target) -> Self::Value {
4425            node.subtree_sum
4426        }
4427
4428        fn combine_values(a: Self::Value, b: Self::Value) -> Self::Value {
4429            a + b
4430        }
4431
4432        fn set_subtree_value(node: &mut Self::Target, val: Self::Value) {
4433            node.subtree_sum = val;
4434        }
4435
4436        fn reset_subtree_value(node: &mut Self::Target) {
4437            node.subtree_sum = 0;
4438        }
4439    }
4440
4441    #[test]
4442    fn test_augmented_invariant_observer() {
4443        type TestObserver = WavlTreeAugmentedInvariantObserver<DefaultObjectTag, SubtreeSumTraits>;
4444        type TestTree = WavlTree<
4445            i32,
4446            UniquePtr<TestAugmentedObject>,
4447            DefaultObjectTag,
4448            TrackingSize,
4449            TestObserver,
4450        >;
4451
4452        stack_pin_init!(let tree = TestTree::new_with_observer(TestObserver::default()));
4453        let tree = unsafe { tree.get_unchecked_mut() };
4454
4455        // Helper to verify subtree sums recursively
4456        fn verify_subtree_sums(node: *mut TestAugmentedObject) -> i32 {
4457            if !valid_sentinel_ptr(node) {
4458                return 0;
4459            }
4460            let node_ref = unsafe { &*node };
4461            let ns = node_ref.get_node();
4462            let left_sum = verify_subtree_sums(ns.get_left());
4463            let right_sum = verify_subtree_sums(ns.get_right());
4464            let expected_sum = node_ref.value + left_sum + right_sum;
4465            assert_eq!(
4466                node_ref.subtree_sum, expected_sum,
4467                "Subtree sum mismatch at node {}",
4468                node_ref.value
4469            );
4470            expected_sum
4471        }
4472
4473        // Insert some nodes
4474        let values = [10, 20, 5, 15, 25, 2, 7];
4475        for &val in &values {
4476            let obj = UniquePtr::try_new(TestAugmentedObject::new(val)).unwrap();
4477            tree.insert(obj);
4478            // Verify after each insert
4479            if !tree.root.is_null() {
4480                verify_subtree_sums(tree.root);
4481            }
4482        }
4483
4484        // Verify final sum at root
4485        let expected_total_sum: i32 = values.iter().sum();
4486        assert_eq!(unsafe { &*tree.root }.subtree_sum, expected_total_sum);
4487
4488        // Erase some nodes
4489        let to_erase = [15, 5, 20];
4490        let mut current_sum = expected_total_sum;
4491        for &val in &to_erase {
4492            let erased = tree.erase(&val);
4493            assert!(erased.is_some());
4494            assert_eq!(erased.as_ref().unwrap().value, val);
4495            current_sum -= val;
4496            if !tree.root.is_null() {
4497                assert_eq!(unsafe { &*tree.root }.subtree_sum, current_sum);
4498                verify_subtree_sums(tree.root);
4499            }
4500        }
4501    }
4502
4503    #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
4504    struct NonCommutativeVal {
4505        hash: u64,
4506        len: u32,
4507    }
4508
4509    impl NonCommutativeVal {
4510        fn single(val: i32) -> Self {
4511            Self { hash: (val as u64) & 0xffff, len: 1 }
4512        }
4513
4514        fn combine(left: Self, right: Self) -> Self {
4515            if left.len == 0 {
4516                return right;
4517            }
4518            if right.len == 0 {
4519                return left;
4520            }
4521            let mut power = 1u64;
4522            for _ in 0..right.len {
4523                power = power.wrapping_mul(31);
4524            }
4525            Self {
4526                hash: left.hash.wrapping_mul(power).wrapping_add(right.hash),
4527                len: left.len + right.len,
4528            }
4529        }
4530    }
4531
4532    #[derive(WavlTreeContainable, Recyclable)]
4533    struct TestNonCommutativeObject {
4534        value: i32,
4535        subtree_val: NonCommutativeVal,
4536        #[wavl_node]
4537        node: WavlTreeNode<TestNonCommutativeObject>,
4538    }
4539
4540    impl TestNonCommutativeObject {
4541        fn new(value: i32) -> Self {
4542            Self { value, subtree_val: NonCommutativeVal::default(), node: WavlTreeNode::new() }
4543        }
4544    }
4545
4546    impl WavlTreeKeyable<i32> for TestNonCommutativeObject {
4547        type Key<'a> = i32;
4548        fn get_key(&self) -> i32 {
4549            self.value
4550        }
4551    }
4552
4553    struct NonCommutativeTraits;
4554    impl WavlTreeAugmentedInvariantObserverTraits for NonCommutativeTraits {
4555        type Target = TestNonCommutativeObject;
4556        type Value = NonCommutativeVal;
4557
4558        fn get_node_value(node: &Self::Target) -> Self::Value {
4559            NonCommutativeVal::single(node.value)
4560        }
4561
4562        fn get_subtree_value(node: &Self::Target) -> Self::Value {
4563            node.subtree_val
4564        }
4565
4566        fn combine_values(a: Self::Value, b: Self::Value) -> Self::Value {
4567            NonCommutativeVal::combine(a, b)
4568        }
4569
4570        fn set_subtree_value(node: &mut Self::Target, val: Self::Value) {
4571            node.subtree_val = val;
4572        }
4573
4574        fn reset_subtree_value(node: &mut Self::Target) {
4575            node.subtree_val = NonCommutativeVal::default();
4576        }
4577    }
4578
4579    #[test]
4580    fn test_augmented_invariant_observer_non_commutative() {
4581        type TestObserver =
4582            WavlTreeAugmentedInvariantObserver<DefaultObjectTag, NonCommutativeTraits>;
4583        type TestTree = WavlTree<
4584            i32,
4585            UniquePtr<TestNonCommutativeObject>,
4586            DefaultObjectTag,
4587            TrackingSize,
4588            TestObserver,
4589        >;
4590
4591        stack_pin_init!(let tree = TestTree::new_with_observer(TestObserver::default()));
4592        let tree = unsafe { tree.get_unchecked_mut() };
4593
4594        // Helper to verify non-commutative subtree values recursively
4595        fn verify_subtree_values(node: *mut TestNonCommutativeObject) -> NonCommutativeVal {
4596            if !valid_sentinel_ptr(node) {
4597                return NonCommutativeVal::default();
4598            }
4599            let node_ref = unsafe { &*node };
4600            let ns = node_ref.get_node();
4601            let left_val = verify_subtree_values(ns.get_left());
4602            let node_val = NonCommutativeVal::single(node_ref.value);
4603            let right_val = verify_subtree_values(ns.get_right());
4604            let expected = NonCommutativeVal::combine(
4605                NonCommutativeVal::combine(left_val, node_val),
4606                right_val,
4607            );
4608            assert_eq!(
4609                node_ref.subtree_val, expected,
4610                "Subtree non-commutative value mismatch at node {}",
4611                node_ref.value
4612            );
4613            expected
4614        }
4615
4616        // Helper to compute expected in-order value from a list of sorted keys
4617        fn expected_in_order(keys: &[i32]) -> NonCommutativeVal {
4618            let mut sorted: alloc::vec::Vec<i32> = keys.iter().copied().collect();
4619            sorted.sort();
4620            let mut acc = NonCommutativeVal::default();
4621            for &k in &sorted {
4622                acc = NonCommutativeVal::combine(acc, NonCommutativeVal::single(k));
4623            }
4624            acc
4625        }
4626
4627        // Insert nodes in an order that triggers single and double rotations in both directions
4628        let values = [10, 20, 5, 15, 25, 2, 7, 1, 3, 6, 8, 12, 17, 22, 30];
4629        for (i, &val) in values.iter().enumerate() {
4630            let obj = UniquePtr::try_new(TestNonCommutativeObject::new(val)).unwrap();
4631            tree.insert(obj);
4632            if !tree.root.is_null() {
4633                verify_subtree_values(tree.root);
4634                let expected = expected_in_order(&values[..=i]);
4635                assert_eq!(unsafe { &*tree.root }.subtree_val, expected);
4636            }
4637        }
4638
4639        // Erase nodes causing rebalancings/rotations
4640        let to_erase = [5, 20, 15, 2, 25];
4641        let mut remaining: alloc::vec::Vec<i32> = values.iter().copied().collect();
4642        for &val in &to_erase {
4643            let erased = tree.erase(&val);
4644            assert!(erased.is_some());
4645            assert_eq!(erased.as_ref().unwrap().value, val);
4646            remaining.retain(|&x| x != val);
4647            if !tree.root.is_null() {
4648                verify_subtree_values(tree.root);
4649                let expected = expected_in_order(&remaining);
4650                assert_eq!(unsafe { &*tree.root }.subtree_val, expected);
4651            }
4652        }
4653    }
4654
4655    #[test]
4656    fn test_successor_raw() {
4657        type TestTree = WavlTree<i32, *mut TestObject>;
4658        stack_pin_init!(let tree = TestTree::new());
4659        let tree = unsafe { tree.get_unchecked_mut() };
4660
4661        let mut cur: *mut TestObject = core::ptr::null_mut();
4662        unsafe { TestTree::successor_raw(&mut cur) };
4663        assert!(cur.is_null());
4664
4665        let mut cur = tree.front_cursor().as_raw_ptr();
4666        assert!(is_sentinel_ptr(cur));
4667        unsafe { TestTree::successor_raw(&mut cur) };
4668        assert!(cur.is_null());
4669
4670        let mut objs =
4671            [TestObject::new(20), TestObject::new(10), TestObject::new(30), TestObject::new(15)];
4672        for obj in &mut objs {
4673            unsafe { tree.insert_raw(obj) };
4674        }
4675
4676        let mut visited = alloc::vec::Vec::new();
4677        let mut cur = tree.front_cursor().as_raw_ptr();
4678        while !cur.is_null() {
4679            visited.push(unsafe { (*cur).value });
4680            unsafe { TestTree::successor_raw(&mut cur) };
4681        }
4682        assert_eq!(visited, alloc::vec![10, 15, 20, 30]);
4683
4684        for obj in &mut objs {
4685            unsafe { tree.erase_raw(obj) };
4686        }
4687    }
4688}