Infer StableInterpolate on tuples (#15931)
# Objective
Make `StableInterpolate` "just work" on tuples whose parts are each
`StableInterpolate` types. These types arise notably through
`Curve::zip` (or just through explicit mapping of a similar form). It
would otherwise be kind of frustrating to stumble upon such a thing and
then realize that, e.g., automatic resampling just doesn't work, even
though there is a very "obvious" way to do it.
## Solution
Infer `StableInterpolate` on tuples of up to size 11. I can make that
number bigger, if desired. Unfortunately, I don't think that our
standard "fake variadics" tools actually work for this; the anonymous
field accessors of tuples are `:tt` for purposes of macro expansion,
which means that you can't simplify away the identifiers by doing
something clever like using recursion (which would work if they were
`:expr`). Maybe someone who knows some incredibly dark magic could chime
in with a better solution.
The expanded impls look like this:
```rust
impl<
T0: StableInterpolate,
T1: StableInterpolate,
T2: StableInterpolate,
T3: StableInterpolate,
T4: StableInterpolate,
> StableInterpolate for (T0, T1, T2, T3, T4)
{
fn interpolate_stable(&self, other: &Self, t: f32) -> Self {
(
<T0 as StableInterpolate>::interpolate_stable(&self.0, &other.0, t),
<T1 as StableInterpolate>::interpolate_stable(&self.1, &other.1, t),
<T2 as StableInterpolate>::interpolate_stable(&self.2, &other.2, t),
<T3 as StableInterpolate>::interpolate_stable(&self.3, &other.3, t),
<T4 as StableInterpolate>::interpolate_stable(&self.4, &other.4, t),
)
}
}
```
## Testing
Expanded macros; it compiles.
## Future
Make a version of the fake variadics workflow that supports this kind of
thing.
This commit is contained in:
parent
c1a4b82762
commit
a09104b62c
@ -309,3 +309,81 @@ impl StableInterpolate for Dir3A {
|
||||
self.slerp(*other, t)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_stable_interpolate_tuple {
|
||||
($(($T:ident, $n:tt)),*) => {
|
||||
impl<$($T: StableInterpolate),*> StableInterpolate for ($($T,)*) {
|
||||
fn interpolate_stable(&self, other: &Self, t: f32) -> Self {
|
||||
(
|
||||
$(
|
||||
<$T as StableInterpolate>::interpolate_stable(&self.$n, &other.$n, t),
|
||||
)*
|
||||
)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// (See `macro_metavar_expr`, which might make this better.)
|
||||
// This currently implements `StableInterpolate` for tuples of up to 11 elements.
|
||||
impl_stable_interpolate_tuple!((T, 0));
|
||||
impl_stable_interpolate_tuple!((T0, 0), (T1, 1));
|
||||
impl_stable_interpolate_tuple!((T0, 0), (T1, 1), (T2, 2));
|
||||
impl_stable_interpolate_tuple!((T0, 0), (T1, 1), (T2, 2), (T3, 3));
|
||||
impl_stable_interpolate_tuple!((T0, 0), (T1, 1), (T2, 2), (T3, 3), (T4, 4));
|
||||
impl_stable_interpolate_tuple!((T0, 0), (T1, 1), (T2, 2), (T3, 3), (T4, 4), (T5, 5));
|
||||
impl_stable_interpolate_tuple!(
|
||||
(T0, 0),
|
||||
(T1, 1),
|
||||
(T2, 2),
|
||||
(T3, 3),
|
||||
(T4, 4),
|
||||
(T5, 5),
|
||||
(T6, 6)
|
||||
);
|
||||
impl_stable_interpolate_tuple!(
|
||||
(T0, 0),
|
||||
(T1, 1),
|
||||
(T2, 2),
|
||||
(T3, 3),
|
||||
(T4, 4),
|
||||
(T5, 5),
|
||||
(T6, 6),
|
||||
(T7, 7)
|
||||
);
|
||||
impl_stable_interpolate_tuple!(
|
||||
(T0, 0),
|
||||
(T1, 1),
|
||||
(T2, 2),
|
||||
(T3, 3),
|
||||
(T4, 4),
|
||||
(T5, 5),
|
||||
(T6, 6),
|
||||
(T7, 7),
|
||||
(T8, 8)
|
||||
);
|
||||
impl_stable_interpolate_tuple!(
|
||||
(T0, 0),
|
||||
(T1, 1),
|
||||
(T2, 2),
|
||||
(T3, 3),
|
||||
(T4, 4),
|
||||
(T5, 5),
|
||||
(T6, 6),
|
||||
(T7, 7),
|
||||
(T8, 8),
|
||||
(T9, 9)
|
||||
);
|
||||
impl_stable_interpolate_tuple!(
|
||||
(T0, 0),
|
||||
(T1, 1),
|
||||
(T2, 2),
|
||||
(T3, 3),
|
||||
(T4, 4),
|
||||
(T5, 5),
|
||||
(T6, 6),
|
||||
(T7, 7),
|
||||
(T8, 8),
|
||||
(T9, 9),
|
||||
(T10, 10)
|
||||
);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user