From 225d1d7f3a047d696b671078e09a15cc8dd2654c Mon Sep 17 00:00:00 2001 From: colin Date: Wed, 20 Jul 2022 01:37:33 -0700 Subject: [PATCH] coremem_types: implement a list type wherein we can hope to implement enum-like types on gpu --- crates/types/src/compound.rs | 141 +++++++++++++++++++++++++++++++++++ crates/types/src/lib.rs | 1 + 2 files changed, 142 insertions(+) create mode 100644 crates/types/src/compound.rs diff --git a/crates/types/src/compound.rs b/crates/types/src/compound.rs new file mode 100644 index 0000000..064f876 --- /dev/null +++ b/crates/types/src/compound.rs @@ -0,0 +1,141 @@ + +#[derive(Copy, Clone, Default, PartialEq)] +struct Null; + +#[derive(Copy, Clone, Default, PartialEq)] +struct LLNode { + e: E, + // Null or LLNode + next: N, +} + +impl LLNode { + fn new(e: E) -> Self { + Self { + e, + next: Null, + } + } +} + +impl LLNode { + fn prepend

(self, e: P) -> LLNode { + LLNode { + e, + next: self + } + } +} + +trait ListOp { + fn apply(&self, f: F); +} + +trait ElemCallable { + fn call(&self, el: &T); +} + +impl, E, N: ListOp> ListOp> for LLNode { + fn apply(&self, f: F) { + f.call(&self.e); + self.next.apply(f) + } +} + +impl ListOp for Null { + fn apply(&self, _f: F) { } +} + +#[cfg(test)] +mod test { + use super::*; + use core::cell::Cell; + + #[derive(Default)] + struct ApplyAccumulator { + delayed0: Cell, + delayed1: Cell, + delayed2: Cell, + } + + impl ElemCallable for &ApplyAccumulator { + fn call(&self, el: &u32) { + self.delayed2.set( + self.delayed1.replace( + self.delayed0.replace(*el) + ) + ) + } + + } + + #[test] + fn test_apply_single() { + let list = LLNode::new(5u32); + let acc = ApplyAccumulator::default(); + list.apply(&acc); + + assert_eq!(acc.delayed1.into_inner(), 0); + assert_eq!(acc.delayed0.into_inner(), 5); + } + + #[derive(Copy, Clone, Default, Debug, PartialEq)] + struct V0(u32); + #[derive(Copy, Clone, Default, Debug, PartialEq)] + struct V1(f32); + #[derive(Copy, Clone, Default, Debug, PartialEq)] + struct Flat { + v0: V0, + v1: V1, + } + + trait Variant { + fn to_flat(&self) -> Flat; + } + impl Variant for V0 { + fn to_flat(&self) -> Flat { + Flat { v0: *self, ..Default::default() } + } + } + impl Variant for V1 { + fn to_flat(&self) -> Flat { + Flat { v1: *self, ..Default::default() } + } + } + + impl ElemCallable for &ApplyAccumulator { + fn call(&self, el: &T) { + self.delayed2.set( + self.delayed1.replace( + self.delayed0.replace(el.to_flat()) + ) + ) + } + } + + #[test] + fn test_apply_2() { + let list = LLNode::new(V0(5u32)) + .prepend(V1(4f32)); + let acc = ApplyAccumulator::default(); + list.apply(&acc); + + assert_eq!(acc.delayed2.into_inner(), Flat::default()); + assert_eq!(acc.delayed1.into_inner(), V1(4f32).to_flat()); + assert_eq!(acc.delayed0.into_inner(), V0(5u32).to_flat()); + } + + #[test] + fn test_apply_3() { + let list = LLNode::new(V0(5u32)) + .prepend(V1(4f32)) + .prepend(V0(2u32)); + let acc = ApplyAccumulator::default(); + list.apply(&acc); + + assert_eq!(acc.delayed2.into_inner(), V0(2u32).to_flat()); + assert_eq!(acc.delayed1.into_inner(), V1(4f32).to_flat()); + assert_eq!(acc.delayed0.into_inner(), V0(5u32).to_flat()); + + } +} diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs index f2e1c48..08c81b0 100644 --- a/crates/types/src/lib.rs +++ b/crates/types/src/lib.rs @@ -1,6 +1,7 @@ #![no_std] #![feature(core_intrinsics)] +mod compound; pub mod mat; pub mod real; pub mod vec;