summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_data_structures/src/vec_linked_list.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_data_structures/src/vec_linked_list.rs')
-rw-r--r--compiler/rustc_data_structures/src/vec_linked_list.rs70
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])
+ }
+}