Add another example, add call_as!
This commit is contained in:
parent
42f2118834
commit
c7b95ea0eb
4 changed files with 77 additions and 14 deletions
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "type-fn"
|
||||
version = "0.1.1"
|
||||
version = "0.1.2"
|
||||
edition = "2021"
|
||||
description = "Allows for simpler coding of type-level logic, e.g. for type-number systems."
|
||||
license = "MIT"
|
||||
|
|
|
@ -28,19 +28,13 @@ fn main() {
|
|||
struct World;
|
||||
|
||||
type MyListA = EmptyList;
|
||||
type MyListB = <AddElement<MyListA, World> as TypeFn>::Ret;
|
||||
type MyListC = <AddElement<MyListB, Hello> as TypeFn>::Ret;
|
||||
type MyListB = call!(AddElement<MyListA, World>);
|
||||
type MyListC = call!(AddElement<MyListB, Hello>);
|
||||
|
||||
type RemovalA = <RemoveLastElement<MyListC> as TypeFn>::Ret;
|
||||
println!(
|
||||
"{}",
|
||||
any::type_name::<<GetRemoved<RemovalA> as TypeFn>::Ret>()
|
||||
);
|
||||
type RemovalA = call!(RemoveLastElement<MyListC>);
|
||||
println!("{}", any::type_name::<call!(GetRemoved<RemovalA>)>());
|
||||
|
||||
type MyListD = <GetChangedList<RemovalA> as TypeFn>::Ret;
|
||||
type RemovalB = <RemoveLastElement<MyListD> as TypeFn>::Ret;
|
||||
println!(
|
||||
"{}",
|
||||
any::type_name::<<GetRemoved<RemovalB> as TypeFn>::Ret>()
|
||||
);
|
||||
type MyListD = call!(GetChangedList<RemovalA>);
|
||||
type RemovalB = call!(RemoveLastElement<MyListD>);
|
||||
println!("{}", any::type_name::<call!(GetRemoved<RemovalB>)>());
|
||||
}
|
||||
|
|
62
examples/math.rs
Normal file
62
examples/math.rs
Normal file
|
@ -0,0 +1,62 @@
|
|||
use std::marker::PhantomData;
|
||||
|
||||
use type_fn::*;
|
||||
|
||||
pub struct Zero;
|
||||
pub struct Succ<T>(PhantomData<T>);
|
||||
pub trait ToNum<NumType> {
|
||||
const RESULT: NumType;
|
||||
}
|
||||
impl ToNum<usize> for Zero {
|
||||
const RESULT: usize = 0;
|
||||
}
|
||||
impl<T> ToNum<usize> for Succ<T>
|
||||
where
|
||||
T: ToNum<usize>,
|
||||
{
|
||||
const RESULT: usize = T::RESULT + 1;
|
||||
}
|
||||
type_fn! {
|
||||
pub fn Add<Lhs, Rhs>;
|
||||
pub fn Sub<Lhs, Rhs>;
|
||||
pub fn Mul<Lhs, Rhs>;
|
||||
pub fn Pow<N, Exponent>;
|
||||
|
||||
pub fn Root<V, N>;
|
||||
|
||||
pub fn DistanceDirect<DistX, DistY>;
|
||||
}
|
||||
type_fn_impl! {
|
||||
fn<TypeFn> Add< => Zero, Rhs> => Rhs;
|
||||
fn<TypeFn> Add<N => Succ<N>, Rhs>
|
||||
where
|
||||
Add<N, Rhs>: + TypeFn,
|
||||
=> Succ<call!(Add<N, Rhs>)>;
|
||||
|
||||
fn<TypeFn> Sub<Lhs, => Zero> => Lhs;
|
||||
fn<TypeFn> Sub<Lhs => Succ<Lhs>, Rhs => Succ<Rhs>>
|
||||
where
|
||||
Sub<Lhs, Rhs> : + TypeFn,
|
||||
=> call!(Sub<Lhs, Rhs>);
|
||||
|
||||
fn<TypeFn> Mul< => Zero, Rhs> => Zero;
|
||||
fn<TypeFn> Mul<Lhs => Succ<Lhs>, Rhs>
|
||||
where
|
||||
Mul<Lhs, Rhs>: + TypeFn,
|
||||
Add<Rhs, call!(Mul<Lhs, Rhs>)>: + TypeFn,
|
||||
=> call!(Add<Rhs, call!(Mul<Lhs, Rhs>)>);
|
||||
|
||||
fn<TypeFn> Pow<N, => Zero> => Succ<Zero>;
|
||||
fn<TypeFn> Pow<N, Exp => Succ<Exp>>
|
||||
where
|
||||
Pow<N, Exp>: + TypeFn,
|
||||
Mul<N, call!(Pow<N, Exp>)>: + TypeFn,
|
||||
=> call!(Mul<N, call!(Pow<N, Exp>)>);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
type One = Succ<Zero>;
|
||||
type Two = call!(Add<One, One>);
|
||||
type Five = call!(Add<One, call!(Add<Two, Two>)>);
|
||||
println!("2^5: {}", <call!(Pow<Two, Five>) as ToNum<usize>>::RESULT);
|
||||
}
|
|
@ -13,6 +13,13 @@ macro_rules! call {
|
|||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! call_as {
|
||||
($fty:ty => $($fn:tt)+) => {
|
||||
<$($fn)+ as $fty>::Ret
|
||||
};
|
||||
}
|
||||
|
||||
/// Verifies equality between two types at compile-time.
|
||||
#[macro_export]
|
||||
macro_rules! assert_types_eq {
|
||||
|
|
Loading…
Add table
Reference in a new issue