diff options
Diffstat (limited to '')
-rw-r--r-- | compiler/rustc_data_structures/src/vec_linked_list.rs | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/compiler/rustc_data_structures/src/vec_linked_list.rs b/compiler/rustc_data_structures/src/vec_linked_list.rs new file mode 100644 index 000000000..ce60d40b2 --- /dev/null +++ b/compiler/rustc_data_structures/src/vec_linked_list.rs @@ -0,0 +1,70 @@ +use rustc_index::vec::{Idx, IndexVec}; + +pub fn iter<Ls>( + first: Option<Ls::LinkIndex>, + links: &Ls, +) -> impl Iterator<Item = Ls::LinkIndex> + '_ +where + Ls: Links, +{ + VecLinkedListIterator { links, current: first } +} + +pub struct VecLinkedListIterator<Ls> +where + Ls: Links, +{ + links: Ls, + current: Option<Ls::LinkIndex>, +} + +impl<Ls> Iterator for VecLinkedListIterator<Ls> +where + Ls: Links, +{ + type Item = Ls::LinkIndex; + + fn next(&mut self) -> Option<Ls::LinkIndex> { + if let Some(c) = self.current { + self.current = <Ls as Links>::next(&self.links, c); + Some(c) + } else { + None + } + } +} + +pub trait Links { + type LinkIndex: Copy; + + fn next(links: &Self, index: Self::LinkIndex) -> Option<Self::LinkIndex>; +} + +impl<Ls> Links for &Ls +where + Ls: Links, +{ + type LinkIndex = Ls::LinkIndex; + + fn next(links: &Self, index: Ls::LinkIndex) -> Option<Ls::LinkIndex> { + <Ls as Links>::next(links, index) + } +} + +pub trait LinkElem { + type LinkIndex: Copy; + + fn next(elem: &Self) -> Option<Self::LinkIndex>; +} + +impl<L, E> Links for IndexVec<L, E> +where + E: LinkElem<LinkIndex = L>, + L: Idx, +{ + type LinkIndex = L; + + fn next(links: &Self, index: L) -> Option<L> { + <E as LinkElem>::next(&links[index]) + } +} |