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