@@ -621,6 +621,52 @@ where
621
621
622
622
#[ cfg( feature = "alloc" ) ]
623
623
mod seal {
624
+ //! The logic in this section enables the [`super::GetAll::get_all_mut`] implementation.
625
+ //!
626
+ //! This works by treating tuple lists like queues; first, we convert a mutable ref to a tuple
627
+ //! list into a tuple list of mutable refs. With this, we then check each member of the tuple
628
+ //! list against the head of the handle list. If the head doesn't match, we append the head to
629
+ //! a list of already visited nodes. If the head matches, we extract the head and restart
630
+ //! traversal _without_ the head by merging the visited list with the tail of the current list.
631
+ //! If we ever hit the tail of the current list, we pop the top handle off and continue the
632
+ //! search from the start.
633
+ //!
634
+ //! Visualised, you can think of this something like this:
635
+ //!
636
+ //! ```text
637
+ //! handles: [a, c, e]
638
+ //! tuple list: [a, b, c, d]
639
+ //! visited: []
640
+ //!
641
+ //! 'a' matches 'a', so we stash 'a' continue with:
642
+ //! handles: [c, e]
643
+ //! tuple list: [b, c, d]
644
+ //! visited: []
645
+ //!
646
+ //! 'c' does not match 'b', so we push to the visited list and continue with:
647
+ //! handles: [c, e]
648
+ //! tuple list: [c, d]
649
+ //! visited: [b]
650
+ //!
651
+ //! 'c' matches; stash 'c', merge visited to list, and continue:
652
+ //! handles: [e]
653
+ //! tuple list: [b, d]
654
+ //! visited: []
655
+ //!
656
+ //! 'b' and 'd' do not match, so we make it to the base case:
657
+ //! handles: [e]
658
+ //! tuple list: []
659
+ //! visited: [b, d]
660
+ //!
661
+ //! We set the 'e' match to None, merge visited to list, then continue:
662
+ //! handles: []
663
+ //! tuple list: [b, d]
664
+ //! visited: []
665
+ //!
666
+ //! Handles is now empty, so we return () (list terminator) and end up with:
667
+ //! [Some(a), Some(c), None]
668
+ //! ```
669
+
624
670
use tuple_list:: tuple_list;
625
671
626
672
use crate :: {
0 commit comments