Skip to main content

iddqd/bi_hash_map/
iter.rs

1use super::{RefMut, tables::BiHashMapTables};
2use crate::{
3    BiHashItem, DefaultHashBuilder,
4    support::{
5        alloc::{Allocator, Global},
6        item_set::{self, ItemSet},
7    },
8};
9use core::{hash::BuildHasher, iter::FusedIterator};
10
11/// An iterator over the elements of a [`BiHashMap`] by shared reference.
12/// Created by [`BiHashMap::iter`].
13///
14/// Similar to [`HashMap`], the iteration order is arbitrary and not guaranteed
15/// to be stable.
16///
17/// [`BiHashMap`]: crate::BiHashMap
18/// [`BiHashMap::iter`]: crate::BiHashMap::iter
19/// [`HashMap`]: std::collections::HashMap
20#[derive(Clone, Debug, Default)]
21pub struct Iter<'a, T: BiHashItem> {
22    inner: item_set::Values<'a, T>,
23}
24
25impl<'a, T: BiHashItem> Iter<'a, T> {
26    pub(crate) fn new<A: Allocator>(items: &'a ItemSet<T, A>) -> Self {
27        Self { inner: items.values() }
28    }
29}
30
31impl<'a, T: BiHashItem> Iterator for Iter<'a, T> {
32    type Item = &'a T;
33
34    #[inline]
35    fn next(&mut self) -> Option<Self::Item> {
36        self.inner.next()
37    }
38
39    #[inline]
40    fn size_hint(&self) -> (usize, Option<usize>) {
41        self.inner.size_hint()
42    }
43}
44
45impl<T: BiHashItem> ExactSizeIterator for Iter<'_, T> {
46    #[inline]
47    fn len(&self) -> usize {
48        self.inner.len()
49    }
50}
51
52impl<T: BiHashItem> FusedIterator for Iter<'_, T> {}
53
54/// An iterator over the elements of a [`BiHashMap`] by mutable reference.
55/// Created by [`BiHashMap::iter_mut`].
56///
57/// This iterator returns [`RefMut`] instances.
58///
59/// Similar to [`HashMap`], the iteration order is arbitrary and not guaranteed
60/// to be stable.
61///
62/// [`BiHashMap`]: crate::BiHashMap
63/// [`BiHashMap::iter_mut`]: crate::BiHashMap::iter_mut
64/// [`HashMap`]: std::collections::HashMap
65#[derive(Debug)]
66pub struct IterMut<
67    'a,
68    T: BiHashItem,
69    S = DefaultHashBuilder,
70    A: Allocator = Global,
71> {
72    tables: &'a BiHashMapTables<S, A>,
73    inner: item_set::ValuesMut<'a, T>,
74}
75
76impl<'a, T: BiHashItem, S: Clone + BuildHasher, A: Allocator>
77    IterMut<'a, T, S, A>
78{
79    pub(super) fn new(
80        tables: &'a BiHashMapTables<S, A>,
81        items: &'a mut ItemSet<T, A>,
82    ) -> Self {
83        Self { tables, inner: items.values_mut() }
84    }
85}
86
87impl<'a, T: BiHashItem, S: Clone + BuildHasher, A: Allocator> Iterator
88    for IterMut<'a, T, S, A>
89{
90    type Item = RefMut<'a, T, S>;
91
92    #[inline]
93    fn next(&mut self) -> Option<Self::Item> {
94        let next = self.inner.next()?;
95        let hashes = self.tables.make_hashes::<T>(&next.key1(), &next.key2());
96        Some(RefMut::new(self.tables.state.clone(), hashes, next))
97    }
98
99    #[inline]
100    fn size_hint(&self) -> (usize, Option<usize>) {
101        self.inner.size_hint()
102    }
103}
104
105impl<T: BiHashItem, S: Clone + BuildHasher, A: Allocator> ExactSizeIterator
106    for IterMut<'_, T, S, A>
107{
108    #[inline]
109    fn len(&self) -> usize {
110        self.inner.len()
111    }
112}
113
114impl<T: BiHashItem, S: Clone + BuildHasher, A: Allocator> FusedIterator
115    for IterMut<'_, T, S, A>
116{
117}
118
119/// An iterator over the elements of a [`BiHashMap`] by ownership. Created by
120/// [`BiHashMap::into_iter`].
121///
122/// Similar to [`HashMap`], the iteration order is arbitrary and not guaranteed
123/// to be stable.
124///
125/// [`BiHashMap`]: crate::BiHashMap
126/// [`BiHashMap::into_iter`]: crate::BiHashMap::into_iter
127/// [`HashMap`]: std::collections::HashMap
128#[derive(Debug)]
129pub struct IntoIter<T: BiHashItem, A: Allocator = Global> {
130    inner: item_set::IntoValues<T, A>,
131}
132
133impl<T: BiHashItem, A: Allocator> IntoIter<T, A> {
134    pub(crate) fn new(items: ItemSet<T, A>) -> Self {
135        Self { inner: items.into_values() }
136    }
137}
138
139impl<T: BiHashItem, A: Allocator> Iterator for IntoIter<T, A> {
140    type Item = T;
141
142    #[inline]
143    fn next(&mut self) -> Option<Self::Item> {
144        self.inner.next()
145    }
146
147    #[inline]
148    fn size_hint(&self) -> (usize, Option<usize>) {
149        self.inner.size_hint()
150    }
151}
152
153impl<T: BiHashItem, A: Allocator> ExactSizeIterator for IntoIter<T, A> {
154    #[inline]
155    fn len(&self) -> usize {
156        self.inner.len()
157    }
158}
159
160impl<T: BiHashItem, A: Allocator> FusedIterator for IntoIter<T, A> {}