Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proper iteration over Foundation types #304

Closed
madsmtm opened this issue Dec 10, 2022 · 3 comments · Fixed by #443
Closed

Proper iteration over Foundation types #304

madsmtm opened this issue Dec 10, 2022 · 3 comments · Fixed by #443
Labels
A-framework Affects the framework crates and the translator for them enhancement New feature or request I-unsound A soundness hole
Milestone

Comments

@madsmtm
Copy link
Owner

madsmtm commented Dec 10, 2022

The way we do NSEnumerator and NSFastEnumeration right now is a mess!

Ideally, I don't think NSEnumerator should have a lifetime (it would allow it to be treated normally in icrate). This means that any method that creates an NSEnumerator is inherently unsafe, but instead I think we should just create proper methods and Iterator wrappers where applicable.

Rough sketches below. Note that the iterator must sometimes hold a reference to the array, since otherwise the array could be modified. Luckily the returned items can have the same lifetime as the array (instead of e.g. the same lifetime as the iterator).

impl<T, O> NSArray<T, O> {
    fn iter<'a>(&'a self) -> impl Iterator<&'a T> + 'a;
}

impl<T> NSArray<T, Owned> {
    fn iter_mut<'a>(&'a mut self) -> impl Iterator<&'a mut T> + 'a;
}

impl<T> NSArray<T, Shared> {
    // While the items are immutable, the array may not be, so we still need to bind the lifetime of the iterator to the array
    fn iter_retained<'a>(&'a self) -> impl Iterator<Id<T, Shared>> + '_;
    // But here we know that the array is immutable, so with this design we wouldn't need to
    fn iter_retained2(this: &Id<Self, Shared>) -> impl Iterator<Id<T, Shared>>;
}

impl<T, O> NSArray<T, O> {
    fn into_iter(this: Id<Self, O>) -> impl Iterator<Id<T, O>>;
}
// Or perhaps ideally:
// impl<T> NSArray<T, Shared> {
//     fn into_iter(this: Id<Self, Owned>) -> impl Iterator<Id<T, Shared>>;
//     fn into_iter(this: Id<Self, Shared>) -> impl Iterator<Id<T, Shared>>;
// }
// impl<T> NSArray<T, Owned> {
//     fn into_iter(this: Id<Self, Owned>) -> impl Iterator<Id<T, Owned>>;
//     fn into_iter(this: Id<Self, Shared>) -> impl Iterator<Id<T, Shared>>;
// }
impl<K, V, KO, VO> NSDictionary<K, V, KO, VO> {
    fn iter_keys<'a>(&'a self) -> impl Iterator<&'a K> + 'a;
    fn iter_values<'a>(&'a self) -> impl Iterator<&'a V> + 'a;

    fn iter<'a>(&'a self) -> impl Iterator<(&'a K, &'a V)> + 'a {
        std::iter::zip(self.iter_keys(), self.iter_values())
    }
}

impl<K, V, VO> NSDictionary<K, V, Owned, VO> {
    fn iter_keys_mut<'a>(&'a mut self) -> impl Iterator<&'a mut K> + 'a;
}

impl<K, V, KO> NSDictionary<K, V, KO, Owned> {
    fn iter_values_mut<'a>(&'a mut self) -> impl Iterator<&'a mut V> + 'a;
}

impl<K, V, VO> NSDictionary<K, V, Shared, VO> {
    fn iter_keys_retained<'a>(&'a self) -> impl Iterator<Id<K, Shared>> + 'a;
    fn iter_keys_retained2(this: &Id<Self, Shared>) -> impl Iterator<Id<K, Shared>>;
}

// And so on...

// Unsure if the following is possible?

impl<K, V> NSDictionary<K, V, Owned, Owned> {
    fn iter_mut<'a>(&'a mut self) -> impl Iterator<(&'a mut K, &'a mut V)> + 'a;
}

// And maybe more vairants that return
// - (&'a K, &'a mut V)
// - (&'a mut K, &'a V)
// - (&'a mut K, Id<V, Shared>)
// - ...

See also #29 (comment)

@madsmtm madsmtm added enhancement New feature or request A-framework Affects the framework crates and the translator for them labels Dec 10, 2022
@madsmtm madsmtm added this to the icrate v0.2.0 milestone Jan 27, 2023
@madsmtm
Copy link
Owner Author

madsmtm commented Apr 13, 2023

This broke on GNUStep in a recent nightly, see #436 (failed CI job)

@madsmtm madsmtm added the I-unsound A soundness hole label Apr 13, 2023
@madsmtm
Copy link
Owner Author

madsmtm commented Apr 15, 2023

Some kind of IdIntoIterator and IdFromIterator traits would be useful as well

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-framework Affects the framework crates and the translator for them enhancement New feature or request I-unsound A soundness hole
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant