|
| 1 | +// Copyright (c) 2022-present INESC-ID. |
| 2 | +// Distributed under the MIT license that can be found in the LICENSE file. |
| 3 | + |
| 4 | +use crate::Value; |
| 5 | + |
| 6 | +pub trait TupleElement<const N: usize> { |
| 7 | + type Type; |
| 8 | + |
| 9 | + fn element(&self) -> &Self::Type; |
| 10 | + |
| 11 | + fn element_mut(&mut self) -> &mut Self::Type; |
| 12 | +} |
| 13 | + |
| 14 | +pub trait TupleGet { |
| 15 | + fn get<const N: usize>(&self) -> &<Self as TupleElement<N>>::Type |
| 16 | + where |
| 17 | + Self: TupleElement<N>, |
| 18 | + { |
| 19 | + TupleElement::<N>::element(self) |
| 20 | + } |
| 21 | + |
| 22 | + fn get_mut<const N: usize>(&mut self) -> &mut <Self as TupleElement<N>>::Type |
| 23 | + where |
| 24 | + Self: TupleElement<N>, |
| 25 | + { |
| 26 | + TupleElement::<N>::element_mut(self) |
| 27 | + } |
| 28 | +} |
| 29 | + |
| 30 | +pub trait TupleElementValue<const N: usize>: TupleElement<N> { |
| 31 | + type Values; |
| 32 | + |
| 33 | + fn value(values: &Self::Values) -> &Value<Self::Type>; |
| 34 | +} |
| 35 | + |
| 36 | +pub trait ValueTupleGet { |
| 37 | + type Plain; |
| 38 | + |
| 39 | + fn get_value<const N: usize>(&self) -> &Value<<Self::Plain as TupleElement<N>>::Type> |
| 40 | + where |
| 41 | + Self::Plain: TupleElementValue<N, Values = Self>, |
| 42 | + { |
| 43 | + <Self::Plain as TupleElementValue<N>>::value(self) |
| 44 | + } |
| 45 | +} |
| 46 | + |
| 47 | +macro_rules! impl_tuple_get { |
| 48 | + (@element ($($t:ident),+) $n:tt $element:ident) => { |
| 49 | + impl<$($t),+> TupleElement<$n> for ($($t,)+) { |
| 50 | + type Type = $element; |
| 51 | + |
| 52 | + fn element(&self) -> &$element { |
| 53 | + &self.$n |
| 54 | + } |
| 55 | + |
| 56 | + fn element_mut(&mut self) -> &mut $element { |
| 57 | + &mut self.$n |
| 58 | + } |
| 59 | + } |
| 60 | + |
| 61 | + impl<$($t),+> TupleElementValue<$n> for ($($t,)+) { |
| 62 | + type Values = ($(Value<$t>,)+); |
| 63 | + |
| 64 | + fn value(values: &Self::Values) -> &Value<$element> { |
| 65 | + &values.$n |
| 66 | + } |
| 67 | + } |
| 68 | + }; |
| 69 | + ($tuple:tt; $($n:tt $element:ident),+) => { |
| 70 | + impl<$($element),+> TupleGet for ($($element,)+) {} |
| 71 | + impl<$($element),+> ValueTupleGet for ($(Value<$element>,)+) { |
| 72 | + type Plain = ($($element,)+); |
| 73 | + } |
| 74 | + $(impl_tuple_get!(@element $tuple $n $element);)+ |
| 75 | + }; |
| 76 | +} |
| 77 | + |
| 78 | +impl_tuple_get!((T0, T1); 0 T0, 1 T1); |
0 commit comments