use super::{Adjoints, Symbol, Value};
use crate::Element;
pub trait Detach {
type Detached;
fn detach(self) -> Self::Detached;
}
impl<E: Element> Detach for Value<'_, E> {
type Detached = Symbol;
fn detach(self) -> Symbol {
self.symbol()
}
}
impl Detach for Symbol {
type Detached = Symbol;
fn detach(self) -> Symbol {
self
}
}
impl Detach for Adjoints {
type Detached = Adjoints;
fn detach(self) -> Adjoints {
self
}
}
impl Detach for () {
type Detached = ();
fn detach(self) {}
}
impl<T: Detach, const N: usize> Detach for [T; N] {
type Detached = [T::Detached; N];
fn detach(self) -> Self::Detached {
self.map(Detach::detach)
}
}
impl<T: Detach> Detach for Vec<T> {
type Detached = Vec<T::Detached>;
fn detach(self) -> Self::Detached {
self.into_iter().map(Detach::detach).collect()
}
}
macro_rules! detach_tuples {
($(($($name:ident),+))+) => {$(
impl<$($name: Detach),+> Detach for ($($name,)+) {
type Detached = ($($name::Detached,)+);
#[allow(non_snake_case)]
fn detach(self) -> Self::Detached {
let ($($name,)+) = self;
($($name.detach(),)+)
}
}
)+};
}
detach_tuples! {
(A)
(A, B)
(A, B, C)
(A, B, C, D)
(A, B, C, D, E)
(A, B, C, D, E, F)
}
#[cfg(test)]
#[path = "tests/detach_tests.rs"]
mod tests;