I already see many variadic generics designs for Rust that want to inherit the pack expansion syntax ...
in C++. However, the expansion syntax is less powerful because it has small fine-grained control over the template packs, such as accessing the specific index element in the pack or reversing the pack, which must be with the help of partial specialization and function overloading to achieve the target, which brings complex.
We can totally abandon the design ...
, instead, we can use static for
and static if
to manipulate the variadic generics.
For example, reverse the type pack:
type Reverse<..T> = (
static for i in 0 .. T::len(){
T[T::len() - 1 - i]
}
) // form the tuple
Reverse<i8,i16,i32>
would form the type (i32,i16, i8)
. We even can skip certain elements in the pack:
type Skip<..T> = (
static for i in 0..T::len(){
static if i == 1{
continue !;
}else if T[i]:Copy{
continue A
}else{
T[i]
}
}
)
So, Skip<B,C, i32>
would form the type (B, A)
where C is removed because continue
has nothing(implied by !
) and i32
is replaced with type A
because it satisfies Copy
.
This syntax can also be used in function calls or any other legal context, what is formed depends on where context the syntax is used.
fn fun<..T:Default>(v:..T){
show(static for i in v{ v }); // show(v0,v1,v2,...,vn);
}
The syntax let us manipulate variadic generics in Turing complete way.