use crate::prelude::*;
pub trait Variables
{
fn fill(self, vector: &mut Vec<Variable>);
}
impl Variables for Variable
{
fn fill(self, vector: &mut Vec<Variable>)
{
vector.push(self);
}
}
impl Variables for Vec<Variable>
{
fn fill(mut self, vector: &mut Vec<Variable>)
{
vector.append(&mut self);
}
}
pub trait TypedVariables: Variables
{
type Output;
fn from_value_vector(vector: Vec<graphcore::Value>) -> Result<Self::Output>;
}
macro_rules! impl_variables {
($n:tt $($idx:tt $t:ident),*) => {
impl Variables
for ($(__variable!($idx),)*)
{
fn fill(self, vector: &mut Vec<Variable>) {
$(
vector.push(self.$idx);
)*
}
}
impl<$($t,)*> Variables
for ($(TypedVariable<$t>,)*)
where $($t: TryFrom<graphcore::Value>),*
{
fn fill(self, vector: &mut Vec<Variable>) {
$(
vector.push(self.$idx.into());
)*
}
}
impl<$($t,)*> TypedVariables
for ($(TypedVariable<$t>,)*)
where $($t: TryFrom<graphcore::Value, Error = graphcore::Error>),*
{
type Output = ($($t,)*);
fn from_value_vector(vector: Vec<graphcore::Value>) -> Result<Self::Output>
{
if vector.len() != $n
{
return Err(crate::Error::MissingEntryInTable)
}
let mut it = vector.into_iter();
Ok((
$(
$t::try_from(it.next().unwrap())?,
)*
))
}
}
};
}
macro_rules! impl_all_variables {
($($n:tt $($idx:tt $t:ident),*;)*) => {
$(impl_variables!($n $($idx $t),*);)*
};
}
impl_all_variables! {
1 0 T0;
2 0 T0, 1 T1;
3 0 T0, 1 T1, 2 T2;
4 0 T0, 1 T1, 2 T2, 3 T3;
5 0 T0, 1 T1, 2 T2, 3 T3, 4 T4;
6 0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5;
7 0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6;
8 0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7;
9 0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7, 8 T8;
10 0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7, 8 T8, 9 T9;
11 0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7, 8 T8, 9 T9, 10 T10;
12 0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7, 8 T8, 9 T9, 10 T10, 11 T11;
13 0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7, 8 T8, 9 T9, 10 T10, 11 T11, 12 T12;
14 0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7, 8 T8, 9 T9, 10 T10, 11 T11, 12 T12, 13 T13;
15 0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7, 8 T8, 9 T9, 10 T10, 11 T11, 12 T12, 13 T13, 14 T14;
16 0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7, 8 T8, 9 T9, 10 T10, 11 T11, 12 T12, 13 T13, 14 T14, 15 T15;
17 0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7, 8 T8, 9 T9, 10 T10, 11 T11, 12 T12, 13 T13, 14 T14, 15 T15, 16 T16;
18 0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7, 8 T8, 9 T9, 10 T10, 11 T11, 12 T12, 13 T13, 14 T14, 15 T15, 16 T16, 17 T17;
19 0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7, 8 T8, 9 T9, 10 T10, 11 T11, 12 T12, 13 T13, 14 T14, 15 T15, 16 T16, 17 T17, 18 T18;
20 0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7, 8 T8, 9 T9, 10 T10, 11 T11, 12 T12, 13 T13, 14 T14, 15 T15, 16 T16, 17 T17, 18 T18, 19 T19;
}
impl<T> Variables for TypedVariable<T>
where
T: TryFrom<graphcore::Value>,
{
fn fill(self, vector: &mut Vec<Variable>)
{
vector.push(self.into());
}
}
impl<T> TypedVariables for TypedVariable<T>
where
T: TryFrom<graphcore::Value>,
Error: From<<T as TryFrom<graphcore::Value>>::Error>,
{
type Output = T;
fn from_value_vector(vector: Vec<graphcore::Value>) -> Result<Self::Output>
{
if vector.len() != 1
{
return Err(crate::Error::MissingEntryInTable);
}
let mut it = vector.into_iter();
Ok(T::try_from(it.next().unwrap())?)
}
}