Don't force nodes to store references to other nodes

This commit is contained in:
Dennis
2022-06-05 15:25:07 +02:00
committed by Keavon Chambers
parent fa5345d33f
commit a2703c0fb1
12 changed files with 252 additions and 242 deletions

View File

@@ -1,12 +1,12 @@
use core::marker::PhantomData;
use crate::Node;
pub struct FnNode<'n, T: Fn(<N as Node>::Output) -> O, N: Node<'n>, O: 'n>(
pub struct FnNode<'n, T: Fn(<N as Node<'n>>::Output) -> O, N: Node<'n>, O>(
T,
&'n N,
PhantomData<O>,
N,
PhantomData<&'n O>,
);
impl<'n, T: Fn(<N as Node>::Output) -> O, N: Node<'n>, O> Node<'n> for FnNode<'n, T, N, O> {
impl<'n, T: Fn(<N as Node<'n>>::Output) -> O, N: Node<'n>, O> Node<'n> for FnNode<'n, T, N, O> {
type Output = O;
fn eval(&'n self) -> Self::Output {
@@ -14,19 +14,20 @@ impl<'n, T: Fn(<N as Node>::Output) -> O, N: Node<'n>, O> Node<'n> for FnNode<'n
}
}
impl<'n, T: Fn(<N as Node>::Output) -> O, N: Node<'n>, O> FnNode<'n, T, N, O> {
pub fn new(f: T, input: &'n N) -> Self {
impl<'n, T: Fn(<N as Node<'n>>::Output) -> O, N: Node<'n>, O> FnNode<'n, T, N, O> {
pub fn new(f: T, input: N) -> Self {
FnNode(f, input, PhantomData)
}
}
pub struct FnNodeWithState<'n, T: Fn(N::Output, &State) -> O, N: Node<'n>, O, State>(
T,
&'n N,
State,
PhantomData<O>,
);
impl<'n, T: Fn(N::Output, &State) -> O, N: Node<'n>, O: 'n, State> Node<'n>
pub struct FnNodeWithState<
'n,
T: Fn(<N as Node<'n>>::Output, &State) -> O,
N: Node<'n>,
O,
State: 'n,
>(T, N, State, PhantomData<&'n O>);
impl<'n, T: Fn(<N as Node<'n>>::Output, &State) -> O, N: Node<'n>, O: 'n, State> Node<'n>
for FnNodeWithState<'n, T, N, O, State>
{
type Output = O;
@@ -37,7 +38,7 @@ impl<'n, T: Fn(N::Output, &State) -> O, N: Node<'n>, O: 'n, State> Node<'n>
}
impl<'n, T: Fn(N::Output, &State) -> O, N: Node<'n>, O, State> FnNodeWithState<'n, T, N, O, State> {
pub fn new(f: T, input: &'n N, state: State) -> Self {
pub fn new(f: T, input: N, state: State) -> Self {
FnNodeWithState(f, input, state, PhantomData)
}
}

View File

@@ -1,18 +1,50 @@
#![no_std]
#![cfg_attr(target_arch = "spirv", feature(register_attr), register_attr(spirv))]
#[cfg(feature = "async")]
extern crate alloc;
#[cfg(feature = "async")]
use alloc::boxed::Box;
#[cfg(feature = "async")]
use async_trait::async_trait;
pub mod generic;
pub mod ops;
//pub mod structural;
pub mod value;
#[rustfmt::skip]
pub trait Node<'n> {
type Output: 'n; // TODO: replace with generic associated type
fn eval(&'n self) -> Self::Output;
}
impl<'n, N: Node<'n>> Node<'n> for &'n N {
type Output = N::Output;
fn eval(&'n self) -> Self::Output {
Node::eval(*self)
}
}
#[cfg(feature = "async")]
#[async_trait]
pub trait AsyncNode<'n> {
type Output: 'n; // TODO: replace with generic associated type
async fn eval(&'n self) -> Self::Output;
}
#[cfg(feature = "async")]
#[async_trait]
impl<'n, N: Node<'n> + Sync> AsyncNode<'n> for N {
type Output = N::Output;
async fn eval(&'n self) -> Self::Output {
Node::eval(self)
}
}
pub trait Cache {
fn clear(&mut self);
}

View File

@@ -1,35 +1,36 @@
use core::ops::Add;
use core::{marker::PhantomData, ops::Add};
use crate::Node;
#[repr(C)]
struct AddNode<'n, T: Add, I1: Node<'n, Output = T>, I2: Node<'n, Output = T>>(
pub &'n I1,
pub &'n I2,
struct AddNode<'n, L: Add<R>, R, I1: Node<'n, Output = L>, I2: Node<'n, Output = R>>(
pub I1,
pub I2,
PhantomData<&'n (L, R)>,
);
impl<'n, T: Add + 'n, I1: Node<'n, Output = T>, I2: Node<'n, Output = T>> Node<'n>
for AddNode<'n, T, I1, I2>
impl<'n, L: Add<R>, R, I1: Node<'n, Output = L>, I2: Node<'n, Output = R>> Node<'n>
for AddNode<'n, L, R, I1, I2>
{
type Output = <T as Add>::Output;
fn eval(&self) -> T::Output {
type Output = <L as Add<R>>::Output;
fn eval(&'n self) -> Self::Output {
self.0.eval() + self.1.eval()
}
}
#[repr(C)]
pub struct CloneNode<'n, N: Node<'n, Output = &'n O>, O: Clone + 'n>(pub &'n N);
pub struct CloneNode<'n, N: Node<'n, Output = &'n O>, O: Clone + 'n>(pub N, PhantomData<&'n ()>);
impl<'n, N: Node<'n, Output = &'n O>, O: Clone> Node<'n> for CloneNode<'n, N, O> {
type Output = O;
fn eval(&self) -> Self::Output {
fn eval(&'n self) -> Self::Output {
self.0.eval().clone()
}
}
#[repr(C)]
pub struct FstNode<'n, N: Node<'n>>(pub &'n N);
pub struct FstNode<'n, N: Node<'n>>(pub N, PhantomData<&'n ()>);
impl<'n, T: 'n, U, N: Node<'n, Output = (T, U)>> Node<'n> for FstNode<'n, N> {
type Output = T;
fn eval(&self) -> Self::Output {
fn eval(&'n self) -> Self::Output {
let (a, _) = self.0.eval();
a
}
@@ -37,10 +38,10 @@ impl<'n, T: 'n, U, N: Node<'n, Output = (T, U)>> Node<'n> for FstNode<'n, N> {
#[repr(C)]
/// Destructures a Tuple of two values and returns the first one
pub struct SndNode<'n, N: Node<'n>>(pub &'n N);
pub struct SndNode<'n, N: Node<'n>>(pub N, PhantomData<&'n ()>);
impl<'n, T, U: 'n, N: Node<'n, Output = (T, U)>> Node<'n> for SndNode<'n, N> {
type Output = U;
fn eval(&self) -> Self::Output {
fn eval(&'n self) -> Self::Output {
let (_, b) = self.0.eval();
b
}
@@ -48,34 +49,26 @@ impl<'n, T, U: 'n, N: Node<'n, Output = (T, U)>> Node<'n> for SndNode<'n, N> {
#[repr(C)]
/// Destructures a Tuple of two values and returns the first one
pub struct SndRefNode<'n, N: Node<'n>>(pub &'n N);
impl<'n, T: 'n, U: 'n, N: Node<'n, Output = &'n (T, U)>> Node<'n> for SndRefNode<'n, N> {
type Output = &'n U;
fn eval(&self) -> Self::Output {
let (_, ref b) = self.0.eval();
b
}
}
#[repr(C)]
/// Destructures a Tuple of two values and returns the first one
pub struct DupNode<'n, N: Node<'n>>(&'n N);
pub struct DupNode<'n, N: Node<'n>>(N, PhantomData<&'n ()>);
impl<'n, N: Node<'n>> Node<'n> for DupNode<'n, N> {
type Output = (N::Output, N::Output);
fn eval(&self) -> Self::Output {
fn eval(&'n self) -> Self::Output {
(self.0.eval(), self.0.eval()) //TODO: use Copy/Clone implementation
}
}
pub fn foo() {
let value = crate::value::ValueNode::new(2u32);
let dup = DupNode(&value);
let value2 = crate::value::ValueNode::new(4u32);
let dup = DupNode(value, PhantomData);
fn swap<'n>(input: (&'n u32, &'n u32)) -> (&'n u32, &'n u32) {
(input.1, input.0)
}
//let fnn = crate::generic::FnNode::new(swap, &dup); TODO fix types
let snd = SndNode(&dup);
let add = AddNode(&snd, &value);
let fnn = crate::generic::FnNode::new(swap, &dup);
let _ = fnn.eval();
let snd = SndNode(&fnn, PhantomData);
let _ = snd.eval();
let add = AddNode(&snd, value2, PhantomData);
let _ = add.eval();
}

View File

@@ -2,9 +2,9 @@ use core::marker::PhantomData;
use crate::Node;
pub struct ComposeNode<'n, Input, Inter, FIRST, SECOND> {
first: &'n FIRST,
second: &'n SECOND,
pub struct ComposeNode<'n, Inter, First, Second> {
first: &'n First,
second: &'n Second,
_phantom: PhantomData<&'n Input>,
_phantom2: PhantomData<Inter>,
}
@@ -26,7 +26,6 @@ where
}
}
#[cfg(feature = "nightly")]
impl<'n, Input, Inter, FIRST, SECOND> ComposeNode<'n, Input, Inter, FIRST, SECOND>
where
FIRST: Node<'n, Input>,
@@ -41,20 +40,6 @@ where
}
}
#[cfg(not(feature = "nightly"))]
impl<'n, Input, Inter, FIRST, SECOND> ComposeNode<'n, Input, Inter, FIRST, SECOND>
where
FIRST: Node<'n, Input>,
{
pub fn new(first: &'n FIRST, second: &'n SECOND) -> Self {
ComposeNode::<'n, Input, Inter, FIRST, SECOND> {
first,
second,
_phantom: PhantomData,
_phantom2: PhantomData,
}
}
}
#[repr(C)]
pub struct ComposeNodeOwned<'n, Input, Inter, FIRST, SECOND> {
first: FIRST,