The use case in mind is dealing with tuples, however it applies to arrays as well.
Most of these are just normal syntax, things that needs magic are with comments;
trait Component<const Idx: usize> {
type Output;
fn get(&self) -> &Self::Output;
fn get_mut(&mut self) -> &mut Self::Output;
}
trait Sequence<const Length: usize> :
Component<{0}>..Component<{Length}> /* <- compiler magic */ {
fn get_component<T, const I: usize>(&self)
-> Option<&dyn Component<I, Output=T>>;
fn get_component_mut<T, const I: usize>(&mut self)
-> Option<&dyn mut Component<I, Output=T>>;
/* more reflection-like methods here */
}
/* compiler autogenerates Sequence impls for arrays and tuples*/
Problem 1: Refering to all tuples. This is quite easy:
trait List {
const Length: usize;
fn as_sequence(&self) -> &dyn Sequence<Self::Length>;
fn as_sequence_mut(&mut self) -> &dyn mut Sequence<Self::Length>;
}
impl<T, const L: usize> List for T where T: Sequence<L> {
const Length: usize = L;
fn as_sequence(&self) -> &dyn Sequence<Self::Length> { self as _ }
fn as_sequence_mut(&mut self) -> &dyn mut Sequence<Self::Length> { self as _}
}
and now impl List
stands for all tuples and arrays. this can be used for variadic parameters and so on.