Skip to content

Commit a09104b

Browse files
authored
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.
1 parent c1a4b82 commit a09104b

File tree

1 file changed

+78
-0
lines changed

1 file changed

+78
-0
lines changed

crates/bevy_math/src/common_traits.rs

+78
Original file line numberDiff line numberDiff line change
@@ -309,3 +309,81 @@ impl StableInterpolate for Dir3A {
309309
self.slerp(*other, t)
310310
}
311311
}
312+
313+
macro_rules! impl_stable_interpolate_tuple {
314+
($(($T:ident, $n:tt)),*) => {
315+
impl<$($T: StableInterpolate),*> StableInterpolate for ($($T,)*) {
316+
fn interpolate_stable(&self, other: &Self, t: f32) -> Self {
317+
(
318+
$(
319+
<$T as StableInterpolate>::interpolate_stable(&self.$n, &other.$n, t),
320+
)*
321+
)
322+
}
323+
}
324+
};
325+
}
326+
327+
// (See `macro_metavar_expr`, which might make this better.)
328+
// This currently implements `StableInterpolate` for tuples of up to 11 elements.
329+
impl_stable_interpolate_tuple!((T, 0));
330+
impl_stable_interpolate_tuple!((T0, 0), (T1, 1));
331+
impl_stable_interpolate_tuple!((T0, 0), (T1, 1), (T2, 2));
332+
impl_stable_interpolate_tuple!((T0, 0), (T1, 1), (T2, 2), (T3, 3));
333+
impl_stable_interpolate_tuple!((T0, 0), (T1, 1), (T2, 2), (T3, 3), (T4, 4));
334+
impl_stable_interpolate_tuple!((T0, 0), (T1, 1), (T2, 2), (T3, 3), (T4, 4), (T5, 5));
335+
impl_stable_interpolate_tuple!(
336+
(T0, 0),
337+
(T1, 1),
338+
(T2, 2),
339+
(T3, 3),
340+
(T4, 4),
341+
(T5, 5),
342+
(T6, 6)
343+
);
344+
impl_stable_interpolate_tuple!(
345+
(T0, 0),
346+
(T1, 1),
347+
(T2, 2),
348+
(T3, 3),
349+
(T4, 4),
350+
(T5, 5),
351+
(T6, 6),
352+
(T7, 7)
353+
);
354+
impl_stable_interpolate_tuple!(
355+
(T0, 0),
356+
(T1, 1),
357+
(T2, 2),
358+
(T3, 3),
359+
(T4, 4),
360+
(T5, 5),
361+
(T6, 6),
362+
(T7, 7),
363+
(T8, 8)
364+
);
365+
impl_stable_interpolate_tuple!(
366+
(T0, 0),
367+
(T1, 1),
368+
(T2, 2),
369+
(T3, 3),
370+
(T4, 4),
371+
(T5, 5),
372+
(T6, 6),
373+
(T7, 7),
374+
(T8, 8),
375+
(T9, 9)
376+
);
377+
impl_stable_interpolate_tuple!(
378+
(T0, 0),
379+
(T1, 1),
380+
(T2, 2),
381+
(T3, 3),
382+
(T4, 4),
383+
(T5, 5),
384+
(T6, 6),
385+
(T7, 7),
386+
(T8, 8),
387+
(T9, 9),
388+
(T10, 10)
389+
);

0 commit comments

Comments
 (0)