Skip to content

Commit 54fdeab

Browse files
committed
Return concrete types from LiteMap iter methods
This closes #8054. Considerations -------------- * Not sure if it's ideal to just shove in map.rs the new iter types * I considered using derive for the Debug impls, but opted for explicit impl because the type parameter is S, while the thing being stored is S::KeyValueIter, not S. * The Clone impl is explicit for the same reasons * No Copy impl, because that's against API guidelines for Iterators * I parametrize over S, rather than S::KeyValueIter because I found it prettier, it doesn't introduce new types in the signature. * I use function pointer (fn(In) -> Out) over a type parameter so that we don't have to explicit the closure type on output. I think it might be possible to parametrize over the function, to avoid using a function pointer, but it might be at the expanse of clarity: pub fn values(&'a self) -> ValuesIter< 'a, K, V, S::KeyValueIter, impl Fn((&'a K, &'a V)) -> &'a V + Send + Sync + 'static, > { ValuesIter { iter: self.values.lm_iter().map(|val| val.1), } }
1 parent d4c6ddf commit 54fdeab

1 file changed

Lines changed: 110 additions & 6 deletions

File tree

utils/litemap/src/map.rs

Lines changed: 110 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -901,7 +901,7 @@ where
901901
S: StoreIterable<'a, K, V>,
902902
{
903903
/// Produce an ordered iterator over key-value pairs
904-
pub fn iter(&'a self) -> impl DoubleEndedIterator<Item = (&'a K, &'a V)> {
904+
pub fn iter(&'a self) -> S::KeyValueIter {
905905
self.values.lm_iter()
906906
}
907907

@@ -918,13 +918,17 @@ where
918918
}
919919

920920
/// Produce an ordered iterator over keys
921-
pub fn keys(&'a self) -> impl DoubleEndedIterator<Item = &'a K> {
922-
self.values.lm_iter().map(|val| val.0)
921+
pub fn keys(&'a self) -> KeysIter<'a, K, V, S> {
922+
KeysIter {
923+
iter: self.values.lm_iter().map(|val| val.0),
924+
}
923925
}
924926

925927
/// Produce an iterator over values, ordered by their keys
926-
pub fn values(&'a self) -> impl DoubleEndedIterator<Item = &'a V> {
927-
self.values.lm_iter().map(|val| val.1)
928+
pub fn values(&'a self) -> ValuesIter<'a, K, V, S> {
929+
ValuesIter {
930+
iter: self.values.lm_iter().map(|val| val.1),
931+
}
928932
}
929933
}
930934

@@ -933,7 +937,7 @@ where
933937
S: StoreIterableMut<'a, K, V>,
934938
{
935939
/// Produce an ordered mutable iterator over key-value pairs
936-
pub fn iter_mut(&'a mut self) -> impl DoubleEndedIterator<Item = (&'a K, &'a mut V)> {
940+
pub fn iter_mut(&'a mut self) -> S::KeyValueIterMut {
937941
self.values.lm_iter_mut()
938942
}
939943
}
@@ -1217,6 +1221,106 @@ impl_const_get_with_index_for_integer!(i64);
12171221
impl_const_get_with_index_for_integer!(i128);
12181222
impl_const_get_with_index_for_integer!(isize);
12191223

1224+
type MapKv<'a, I, K, V, Out> = core::iter::Map<I, fn((&'a K, &'a V)) -> &'a Out>;
1225+
1226+
pub struct KeysIter<'a, K, V, S: StoreIterable<'a, K, V>> {
1227+
iter: MapKv<'a, S::KeyValueIter, K, V, K>,
1228+
}
1229+
1230+
pub struct ValuesIter<'a, K, V, S: StoreIterable<'a, K, V>> {
1231+
iter: MapKv<'a, S::KeyValueIter, K, V, V>,
1232+
}
1233+
1234+
impl<'a, K, V, S: StoreIterable<'a, K, V>> Iterator for KeysIter<'a, K, V, S> {
1235+
type Item = &'a K;
1236+
1237+
fn size_hint(&self) -> (usize, Option<usize>) {
1238+
self.iter.size_hint()
1239+
}
1240+
fn next(&mut self) -> Option<Self::Item> {
1241+
self.iter.next()
1242+
}
1243+
fn fold<B, F>(self, init: B, f: F) -> B
1244+
where
1245+
Self: Sized,
1246+
F: FnMut(B, Self::Item) -> B,
1247+
{
1248+
self.iter.fold(init, f)
1249+
}
1250+
fn nth(&mut self, n: usize) -> Option<Self::Item> {
1251+
self.iter.nth(n)
1252+
}
1253+
}
1254+
impl<'a, K, V, S: StoreIterable<'a, K, V>> ExactSizeIterator for KeysIter<'a, K, V, S> {}
1255+
impl<'a, K, V, S: StoreIterable<'a, K, V>> DoubleEndedIterator for KeysIter<'a, K, V, S> {
1256+
fn next_back(&mut self) -> Option<Self::Item> {
1257+
self.iter.next_back()
1258+
}
1259+
}
1260+
impl<'a, K, V, S: StoreIterable<'a, K, V>> Clone for KeysIter<'a, K, V, S>
1261+
where
1262+
S::KeyValueIter: Clone,
1263+
{
1264+
fn clone(&self) -> Self {
1265+
Self {
1266+
iter: self.iter.clone(),
1267+
}
1268+
}
1269+
}
1270+
impl<'a, K, V, S: StoreIterable<'a, K, V>> Debug for KeysIter<'a, K, V, S>
1271+
where
1272+
S::KeyValueIter: Debug,
1273+
{
1274+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1275+
f.debug_tuple("KeysIter").field(&self.iter).finish()
1276+
}
1277+
}
1278+
1279+
impl<'a, K, V, S: StoreIterable<'a, K, V>> Iterator for ValuesIter<'a, K, V, S> {
1280+
type Item = &'a V;
1281+
1282+
fn size_hint(&self) -> (usize, Option<usize>) {
1283+
self.iter.size_hint()
1284+
}
1285+
fn next(&mut self) -> Option<Self::Item> {
1286+
self.iter.next()
1287+
}
1288+
fn fold<B, F>(self, init: B, f: F) -> B
1289+
where
1290+
Self: Sized,
1291+
F: FnMut(B, Self::Item) -> B,
1292+
{
1293+
self.iter.fold(init, f)
1294+
}
1295+
fn nth(&mut self, n: usize) -> Option<Self::Item> {
1296+
self.iter.nth(n)
1297+
}
1298+
}
1299+
impl<'a, K, V, S: StoreIterable<'a, K, V>> ExactSizeIterator for ValuesIter<'a, K, V, S> {}
1300+
impl<'a, K, V, S: StoreIterable<'a, K, V>> DoubleEndedIterator for ValuesIter<'a, K, V, S> {
1301+
fn next_back(&mut self) -> Option<Self::Item> {
1302+
self.iter.next_back()
1303+
}
1304+
}
1305+
impl<'a, K, V, S: StoreIterable<'a, K, V>> Clone for ValuesIter<'a, K, V, S>
1306+
where
1307+
S::KeyValueIter: Clone,
1308+
{
1309+
fn clone(&self) -> Self {
1310+
Self {
1311+
iter: self.iter.clone(),
1312+
}
1313+
}
1314+
}
1315+
impl<'a, K, V, S: StoreIterable<'a, K, V>> Debug for ValuesIter<'a, K, V, S>
1316+
where
1317+
S::KeyValueIter: Debug,
1318+
{
1319+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1320+
f.debug_tuple("ValuesIter").field(&self.iter).finish()
1321+
}
1322+
}
1323+
12201324
/// An entry in a `LiteMap`, which may be either occupied or vacant.
12211325
#[allow(clippy::exhaustive_enums)]
12221326
pub enum Entry<'a, K, V, S> {

0 commit comments

Comments
 (0)