#Impl `IntoIterator` for Cow slice

1 messages · Page 1 of 1 (latest)

empty knoll
#

I could just use std::vec::IntoIter for the associated type IntoIter, but then I'd have to (unnecessarily?) convert a potential &[T] into a Vec<T>, i.e. allocation.

lilac eagle
#

there is nowhere to borrow from

#

you can for example do this: ```rs
impl<'a> IntoIterator for &'a S<'a> {
type Item = &'a usize;
type IntoIter = std::slice::Iter<'a, usize>;

fn into_iter(self) -> Self::IntoIter {
    self.0.iter()
}

}

#

this is also possible: ```rs
use either::Either;
use std::borrow::Cow;
use std::{iter, vec};

fn main() {
let s1 = S(Cow::Owned(vec![1, 2, 3]));
let s2 = S(Cow::Borrowed(&s1.0));
for i in s2 {
print!("{i} ");
}
println!();
for i in s1 {
print!("{i} ");
}
}

struct S<'a>(Cow<'a, [usize]>);

impl<'a> IntoIterator for S<'a> {
type Item = usize;
type IntoIter = Either<iter::Copied<std::slice::Iter<'a, usize>>, vec::IntoIter<usize>>;

fn into_iter(self) -> Self::IntoIter {
    match self.0 {
        Cow::Borrowed(s) => Either::Left(s.iter().copied()),
        Cow::Owned(v) => Either::Right(v.into_iter()),
    }
}

}

empty knoll
#

I think you misunderstood me. I'm not trying to return a &T. I'm just trying to implement the ordinary IntoIterator, but without uselessly allocating, since that's the whole purpose of Cow AFAIK.

lilac eagle
#

yes, I showed you in the second example

empty knoll
#

Ok, will try that out, 1 moment.

lilac eagle
#

the first one is also an "ordinary" IntoIterator

empty knoll
#

The 2nd example still seems to be copying the data though, right? Which to me seems just like calling Cow::Borrowed(slice) => slice.to_vec().into_iter(), and using type IntoIter = std::vec::IntoIter<Self::Item>;

#

In my real world project, my value isn't actually Copy. I thought this wouldn't matter so I left it out.

#

I would like to avoid cloning/copying if that's possible

lilac eagle
#

it's not

#

there is literally no way to get a T from &[T] if it's not Clone

empty knoll
#

Well, but Cow accepts a &[T] via Cow::Borrowed(slice)

lilac eagle
#

exactly

lilac eagle
#

slice.to_vec() requires T: Clone too

empty knoll
#

Ok, whatever. It seems like my approach was fundamentally flawed for what I was trying to achieve...

#

Thanks for your help anyway! 🙂

acoustic badge
lilac eagle
#

wow it's that dead