yoanlcq / vek

Generic 2D-3D math swiss army knife for game engines, with SIMD support and focus on convenience.
https://docs.rs/vek
Apache License 2.0
282 stars 32 forks source link

as_ref and as_mut #62

Open zesterer opened 3 years ago

zesterer commented 3 years ago

I've found myself wanting methods similar to Option's as_ref and as_mut.

Their type signatures would be as follows:

impl<T> VecN<T> {
    fn as_ref(&self) -> VecN<&T>;
    fn as_mut(&mut self) -> VecN<&mut T>;
}

What do you think?

yoanlcq commented 3 years ago

I'm not against the idea, I just wonder if it could cause issues since vectors already implement AsRef<[T]> and AsMut<[T]>.

I also find myself using Option's as_ref quite often, but it doesn't implement AsRef so there is no ambiguity.
If we do choose these names (as_ref and as_mut), then we'd need to be very confident that these wouldn't cause breaking changes... Alternatively we could find other names, but that would be a pity since these ones are very good.

There's always the possibility to do v.map(|x| &x) but I get that it can be tiresome if repeated often.

One thing I'm also thinking about is how that well that would interact with repr_simd vectors; off the top of my head, either that is not supported, or that could cause various bad stuff (although it's the compiler's responsibility rather than ours, and one could argue that users simply shouldn't call as_ref() on SIMD vectors).

So I would say, "why not, let's try it out", and if it breaks something, well, we'll have to find another way.

zesterer commented 3 years ago

There's always the possibility to do v.map(|x| &x) but I get that it can be tiresome if repeated often.

I don't believe that this is possible. VecN::map consumes self, yielding a vector containing references that point to something that no longer exists. This is at the heart of why I think this method (or something with a similar name) should be included: the only other way I've found to do this is to explicitly take a reference to the members like VecN::new(&my_vec.x, &my_vec.y, ...) which becomes very tedious with long vectors.