coremem_types: implement a list type wherein we can hope to implement enum-like types on gpu
This commit is contained in:
141
crates/types/src/compound.rs
Normal file
141
crates/types/src/compound.rs
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
|
||||||
|
#[derive(Copy, Clone, Default, PartialEq)]
|
||||||
|
struct Null;
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Default, PartialEq)]
|
||||||
|
struct LLNode<E, N> {
|
||||||
|
e: E,
|
||||||
|
// Null or LLNode
|
||||||
|
next: N,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E> LLNode<E, Null> {
|
||||||
|
fn new(e: E) -> Self {
|
||||||
|
Self {
|
||||||
|
e,
|
||||||
|
next: Null,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E, N> LLNode<E, N> {
|
||||||
|
fn prepend<P>(self, e: P) -> LLNode<P, Self> {
|
||||||
|
LLNode {
|
||||||
|
e,
|
||||||
|
next: self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trait ListOp<F, L> {
|
||||||
|
fn apply(&self, f: F);
|
||||||
|
}
|
||||||
|
|
||||||
|
trait ElemCallable<T> {
|
||||||
|
fn call(&self, el: &T);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F: ElemCallable<E>, E, N: ListOp<F, N>> ListOp<F, LLNode<E, N>> for LLNode<E, N> {
|
||||||
|
fn apply(&self, f: F) {
|
||||||
|
f.call(&self.e);
|
||||||
|
self.next.apply(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F> ListOp<F, Null> for Null {
|
||||||
|
fn apply(&self, _f: F) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
use core::cell::Cell;
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct ApplyAccumulator<T> {
|
||||||
|
delayed0: Cell<T>,
|
||||||
|
delayed1: Cell<T>,
|
||||||
|
delayed2: Cell<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ElemCallable<u32> for &ApplyAccumulator<u32> {
|
||||||
|
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<T: Variant> ElemCallable<T> for &ApplyAccumulator<Flat> {
|
||||||
|
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());
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -1,6 +1,7 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![feature(core_intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
|
|
||||||
|
mod compound;
|
||||||
pub mod mat;
|
pub mod mat;
|
||||||
pub mod real;
|
pub mod real;
|
||||||
pub mod vec;
|
pub mod vec;
|
||||||
|
Reference in New Issue
Block a user