Let's imagine I want to implement efficient read-only SoA fat pointer. It can look like this:
// acts as [&'a [T]; N], but guarantees that
// all slices have the same length
struct Foo<'a, T, const N: usize> {
ptrs: [*const T; N],
len: usize,
_pd: PhantomData<&'a T>,
}
It's quite easy to make it behave as &T
by simply deriving Copy
for it. But what if we want to work with mutable pointers instead?
struct FooMut<'a, T, const N: usize> {
ptrs: [*mut T; N],
len: usize,
_pd: PhantomData<&'a mut T>,
}
impl<'a, T, const N: usize> FooMut<'a, T, N> {
fn get_slices(&mut self) -> [&'a mut [T]; N] { .. }
}
Ideally it would be nice to be able to write the following code:
let val: FooMut<u32, 4> = get_foo();
use_foo1(val);
use_foo2(val);
But obviously it will not work, since val
gets moved into use_foo1
. And we can not implement Copy
for FooMut
, since it would allow creation of two mutable references pointing to the same memory.
Is it possible to somehow make FooMut
behave as &mut
? AFAIK the answer is no. How feasible in your opinion would be it to add to the language a marker trait or an attribute, which would make custom types behave as &mut
?
We could of course simply pass &mut FooMut<'a, T, N>
around, but not only it's a bit cumbersome, but also may result in undesired indirection.