Implement `view[index]` for memory-backed `View`s
Closed this issue · 3 comments
In general, implementations of View
compute their elements using an arbitrary function, but in practice many View
s are just ways of addressing memory. In such cases, it would be useful to implement std::ops::Index
and std::ops::IndexMut
to give read/write access to the memory via Rust borrows.
Furthermore, given a memory-backed View
indexed by I
whose elements are View
s indexed by J
, v.nested()
could return a View
indexed by (I, J)
. I resisted this for Views that are not memory-backed, for fear of exploding costs.
This is now mostly done. As a witness, I've written an empty trait MemoryView
which depends on View
, Index
and IndexMut
. I've written a macro to avoid repetitive boiler-plate implementations.
I've implemented MemoryView
for every View
in the crate type except Diagonal
and Concat
which require special treatment.
View::nested()
is still TODO. It would also be nice to have View::view_ref()
and View::view_mut()
to obtain views whose values are borrows. The former would replace Array::view()
.
View::view_mut()
is not possible, because mutable references don't implement Clone
.
There is a requirement for types such as &mut V
and Arc<V>
(which dereference to V
) to implement MemoryView
when V
does. Without this feature, you cannot wrap a MemoryView
without consuming it.
Unfortunately, &mut V
and Arc<V>
do not implement Index
and IndexMut
, and there's nothing I can do about that because they are defined in the standard library.
So I've had to change the definition of MemoryView
. It cannot depend on Index
and IndexMut
. Instead, it has methods at_ref()
and at_mut()
.
I've written a macro impl_ops_for_memoryview
, analogous to impl_ops_for_view
, which implements Index
and IndexMut
in terms of MemoryView
. This can be used for new types, at least. Rust's auto-dereferencing then allows the ergonomic view[index]
syntax to be used for &mut V
and Arc<V>
.
Work in progress!
View::nested()
and View::view_ref()
are done.