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