Skip to content

Commit

Permalink
Implement IntoIterator for LiteMap by splitting StoreIterableMut trait (
Browse files Browse the repository at this point in the history
#4359)

Requires a breaking LiteMap version bump
  • Loading branch information
sffc committed Feb 9, 2024
1 parent 9f4fb64 commit 92356d1
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 14 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
- Add Keviyah/Four Gates based optimized calculations module for the Hebrew calendar. (https://github.com/unicode-org/icu4x/pull/4504)
- Expose `Hebrew` as a unit struct, add `Date::try_new_hebrew_date()`, `DateTime::try_new_hebrew_datetime()`. (https://github.com/unicode-org/icu4x/pulls/4532)
- Deprecate `Hebrew::new_always_precomputing()`, `Date::try_new_hebrew_date_with_calendar()`, `DateTime::try_new_hebrew_datetime_with_calendar()`. The new implementation of the Hebrew calendar is faster and we do not need APIs for precomputation. (https://github.com/unicode-org/icu4x/pulls/4532)
- `litemap`
- Add `impl IntoIterator for LiteMap` by splitting `StoreIterableMut` trait (https://github.com/unicode-org/icu4x/pull/4359)
- `yoke`
- Remove `StableDeref` bound from `Yoke<Y, Option<C>>` methods (https://github.com/unicode-org/icu4x/pull/4457)
- Added `CartableOptionPointer` and function to convert from `Yoke<Y, Option<C>>` (https://github.com/unicode-org/icu4x/pull/4449)\
Expand Down
14 changes: 9 additions & 5 deletions components/locid/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,19 +316,23 @@ impl<'a, K: 'a, V: 'a> StoreIterableMut<'a, K, V> for ShortSlice<(K, V)> {
for<'r> fn(&'r mut (K, V)) -> (&'r K, &'r mut V),
>;

type KeyValueIntoIter = ShortSliceIntoIter<(K, V)>;

fn lm_iter_mut(
&'a mut self,
) -> <Self as litemap::store::StoreIterableMut<'a, K, V>>::KeyValueIterMut {
self.iter_mut().map(|elt| (&elt.0, &mut elt.1))
}
}

fn lm_into_iter(
self,
) -> <Self as litemap::store::StoreIterableMut<'a, K, V>>::KeyValueIntoIter {
impl<K, V> StoreIntoIterator<K, V> for ShortSlice<(K, V)> {
type KeyValueIntoIter = ShortSliceIntoIter<(K, V)>;

fn lm_into_iter(self) -> Self::KeyValueIntoIter {
self.into_iter()
}

// leave lm_extend_end as default

// leave lm_extend_start as default
}

impl<K, V> StoreFromIterator<K, V> for ShortSlice<(K, V)> {}
Expand Down
28 changes: 27 additions & 1 deletion utils/litemap/src/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -747,7 +747,7 @@ where
impl<'a, K: 'a, V: 'a, S> LiteMap<K, V, S>
where
K: Ord,
S: StoreIterableMut<'a, K, V> + StoreFromIterator<K, V>,
S: StoreIntoIterator<K, V> + StoreFromIterator<K, V>,
{
/// Insert all elements from `other` into this `LiteMap`.
///
Expand Down Expand Up @@ -898,6 +898,18 @@ where
}
}

impl<K, V, S> IntoIterator for LiteMap<K, V, S>
where
S: StoreIntoIterator<K, V>,
{
type Item = (K, V);
type IntoIter = S::KeyValueIntoIter;

fn into_iter(self) -> Self::IntoIter {
self.values.lm_into_iter()
}
}

impl<K, V, S> LiteMap<K, V, S>
where
S: StoreMut<K, V>,
Expand Down Expand Up @@ -1245,4 +1257,18 @@ mod test {
}
}
}

#[test]
fn into_iterator() {
let mut map = LiteMap::<_, _, Vec<(_, _)>>::new();
map.insert(4, "four");
map.insert(6, "six");
let mut reference = vec![(6, "six"), (4, "four")];

for i in map {
let r = reference.pop().unwrap();
assert_eq!(r, i);
}
assert!(reference.is_empty());
}
}
5 changes: 4 additions & 1 deletion utils/litemap/src/store/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,13 @@ pub trait StoreIterable<'a, K: 'a + ?Sized, V: 'a + ?Sized>: Store<K, V> {

pub trait StoreIterableMut<'a, K: 'a, V: 'a>: StoreMut<K, V> + StoreIterable<'a, K, V> {
type KeyValueIterMut: Iterator<Item = (&'a K, &'a mut V)> + DoubleEndedIterator + 'a;
type KeyValueIntoIter: Iterator<Item = (K, V)>;

/// Returns an iterator over key/value pairs, with a mutable value.
fn lm_iter_mut(&'a mut self) -> Self::KeyValueIterMut;
}

pub trait StoreIntoIterator<K, V>: StoreMut<K, V> {
type KeyValueIntoIter: Iterator<Item = (K, V)>;

/// Returns an iterator that moves every item from this store.
fn lm_into_iter(self) -> Self::KeyValueIntoIter;
Expand Down
5 changes: 4 additions & 1 deletion utils/litemap/src/store/vec_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,12 +150,15 @@ impl<'a, K: 'a, V: 'a> StoreIterable<'a, K, V> for Vec<(K, V)> {

impl<'a, K: 'a, V: 'a> StoreIterableMut<'a, K, V> for Vec<(K, V)> {
type KeyValueIterMut = core::iter::Map<core::slice::IterMut<'a, (K, V)>, MapFMut<K, V>>;
type KeyValueIntoIter = alloc::vec::IntoIter<(K, V)>;

#[inline]
fn lm_iter_mut(&'a mut self) -> Self::KeyValueIterMut {
self.as_mut_slice().iter_mut().map(map_f_mut)
}
}

impl<K, V> StoreIntoIterator<K, V> for Vec<(K, V)> {
type KeyValueIntoIter = alloc::vec::IntoIter<(K, V)>;

#[inline]
fn lm_into_iter(self) -> Self::KeyValueIntoIter {
Expand Down
11 changes: 6 additions & 5 deletions utils/litemap/src/testing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@ where

// Test code
#[allow(clippy::expect_used)]
fn check_into_iter_equivalence<'a, K, V, S0, S1>(a: S0, b: S1)
fn check_into_iter_equivalence<K, V, S0, S1>(a: S0, b: S1)
where
K: Ord + Debug + PartialEq + 'a,
V: Debug + PartialEq + 'a,
S0: StoreIterableMut<'a, K, V>,
S1: StoreIterableMut<'a, K, V>,
K: Ord + Debug + PartialEq,
V: Debug + PartialEq,
S0: StoreIntoIterator<K, V>,
S1: StoreIntoIterator<K, V>,
{
let a_vec = a.lm_into_iter().collect::<Vec<_>>();
let b_vec = b.lm_into_iter().collect::<Vec<_>>();
Expand Down Expand Up @@ -175,6 +175,7 @@ pub fn check_store_full<'a, S>()
where
S: StoreConstEmpty<u32, u64>
+ StoreIterableMut<'a, u32, u64>
+ StoreIntoIterator<u32, u64>
+ StoreFromIterator<u32, u64>
+ Clone
+ Debug
Expand Down
5 changes: 4 additions & 1 deletion utils/litemap/tests/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,15 @@ impl<'a, K: 'a, V: 'a> StoreIterable<'a, K, V> for VecWithDefaults<(K, V)> {

impl<'a, K: 'a, V: 'a> StoreIterableMut<'a, K, V> for VecWithDefaults<(K, V)> {
type KeyValueIterMut = core::iter::Map<core::slice::IterMut<'a, (K, V)>, MapFMut<K, V>>;
type KeyValueIntoIter = std::vec::IntoIter<(K, V)>;

#[inline]
fn lm_iter_mut(&'a mut self) -> Self::KeyValueIterMut {
self.0.as_mut_slice().iter_mut().map(map_f_mut)
}
}

impl<K, V> StoreIntoIterator<K, V> for VecWithDefaults<(K, V)> {
type KeyValueIntoIter = std::vec::IntoIter<(K, V)>;

#[inline]
fn lm_into_iter(self) -> Self::KeyValueIntoIter {
Expand Down

0 comments on commit 92356d1

Please sign in to comment.