Iterate over &[T], T, &[T], T, T

Suppose I have something like:

a: &[T],
b: T
c: &[T],
d: T
e: T
f: &[T]

Is there a easy way to iterate over the VIRTUAL vector defined by a ++ [b] ++ c ++ [d] ++ [e] ++ f ? I want an iterator over that expression.

Iterator::chain and std::iter::once.

4 Likes

It doesn't sound like it is necessary in this case, but one interesting tool is to use std::array::from_ref to convert your &T references into &[T] references. That way, you only need to concatenate &[T] slices.

5 Likes
pub const fn from_ref<T>(s: &T) -> &[T; 1] {
    // SAFETY: Converting `&T` to `&[T; 1]` is sound.
    unsafe { &*(s as *const T).cast::<[T; 1]>() }
}

Interesting. I would not have expected this to be sound.

As a mild aside, note that the standard library crates (core, alloc and std, shipped with a matching toolchain version) have a special dispensation when it comes to soundness; they are allowed to rely on implementation details that can change in future versions of the toolchain.

While, in this case, I think the code in question is guaranteed sound by the type layout rules, it's something to watch out for when reading unsafe code from the standard libraries; it could be sound only on a certain subset of toolchain versions, and unsound on later or earlier versions.

3 Likes

there's also std::slice::from_ref() too

2 Likes

There's usually a comment pointing it out when the standard library does something other libraries can't.

2 Likes