|
| 1 | +// build-pass |
| 2 | + |
| 3 | +#![allow(incomplete_features)] |
| 4 | +#![feature(generic_const_exprs)] |
| 5 | + |
| 6 | +trait Collate<Op> { |
| 7 | + type Pass; |
| 8 | + type Fail; |
| 9 | + |
| 10 | + fn collate(self) -> (Self::Pass, Self::Fail); |
| 11 | +} |
| 12 | + |
| 13 | +impl<Op> Collate<Op> for () { |
| 14 | + type Pass = (); |
| 15 | + type Fail = (); |
| 16 | + |
| 17 | + fn collate(self) -> ((), ()) { |
| 18 | + ((), ()) |
| 19 | + } |
| 20 | +} |
| 21 | + |
| 22 | +trait CollateStep<X, Prev> { |
| 23 | + type Pass; |
| 24 | + type Fail; |
| 25 | + fn collate_step(x: X, prev: Prev) -> (Self::Pass, Self::Fail); |
| 26 | +} |
| 27 | + |
| 28 | +impl<X, P, F> CollateStep<X, (P, F)> for () { |
| 29 | + type Pass = (X, P); |
| 30 | + type Fail = F; |
| 31 | + |
| 32 | + fn collate_step(x: X, (p, f): (P, F)) -> ((X, P), F) { |
| 33 | + ((x, p), f) |
| 34 | + } |
| 35 | +} |
| 36 | + |
| 37 | +struct CollateOpImpl<const MASK: u32>; |
| 38 | +trait CollateOpStep { |
| 39 | + type NextOp; |
| 40 | + type Apply; |
| 41 | +} |
| 42 | + |
| 43 | +impl<const MASK: u32> CollateOpStep for CollateOpImpl<MASK> |
| 44 | +where |
| 45 | + CollateOpImpl<{ MASK >> 1 }>: Sized, |
| 46 | +{ |
| 47 | + type NextOp = CollateOpImpl<{ MASK >> 1 }>; |
| 48 | + type Apply = (); |
| 49 | +} |
| 50 | + |
| 51 | +impl<H, T, Op: CollateOpStep> Collate<Op> for (H, T) |
| 52 | +where |
| 53 | + T: Collate<Op::NextOp>, |
| 54 | + Op::Apply: CollateStep<H, (T::Pass, T::Fail)>, |
| 55 | +{ |
| 56 | + type Pass = <Op::Apply as CollateStep<H, (T::Pass, T::Fail)>>::Pass; |
| 57 | + type Fail = <Op::Apply as CollateStep<H, (T::Pass, T::Fail)>>::Fail; |
| 58 | + |
| 59 | + fn collate(self) -> (Self::Pass, Self::Fail) { |
| 60 | + <Op::Apply as CollateStep<H, (T::Pass, T::Fail)>>::collate_step(self.0, self.1.collate()) |
| 61 | + } |
| 62 | +} |
| 63 | + |
| 64 | +fn collate<X, const MASK: u32>(x: X) -> (X::Pass, X::Fail) |
| 65 | +where |
| 66 | + X: Collate<CollateOpImpl<MASK>>, |
| 67 | +{ |
| 68 | + x.collate() |
| 69 | +} |
| 70 | + |
| 71 | +fn main() { |
| 72 | + dbg!(collate::<_, 5>(("Hello", (42, ('!', ()))))); |
| 73 | +} |
0 commit comments