1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
#![feature(fn_traits, unboxed_closures)] #![feature(const_fn)] #![feature(const_generics)] #![feature(unsized_locals)] #![feature(trivial_bounds)] #![allow(incomplete_features)] use std::marker::PhantomData; use tuple_list::{Tuple, TupleList}; pub trait Monoid<N> { fn identity() -> Self; fn operator(first: Self, second: Self) -> Self; } pub trait RepeatedOperation<T, N> { fn operation(self) -> T; } impl<T, N> RepeatedOperation<T, N> for () where T: Monoid<N>, { #[inline(always)] fn operation(self) -> T { T::identity() } } impl<T, R, N> RepeatedOperation<T, N> for (T, R) where T: Monoid<N>, R: RepeatedOperation<T, N>, Self: TupleList, { #[inline(always)] fn operation(self) -> T { Monoid::operator(self.0, self.1.operation()) } } pub struct VariFunc<T: ?Sized, N: ?Sized> { a: PhantomData<T>, b: PhantomData<N>, } impl<I, T, N> FnOnce<I> for VariFunc<T, N> where I: tuple_list::Tuple, <I as Tuple>::TupleList: RepeatedOperation<T, N>, { type Output = T; #[inline(always)] extern "rust-call" fn call_once(self, args: I) -> T { RepeatedOperation::operation(Tuple::into_tuple_list(args)) } } pub const fn gen_function<T: ?Sized+ PartialEq+ Eq, N>() -> VariFunc<T, N> { VariFunc::<T, N> { a: PhantomData, b: PhantomData } }