acme_core/ops/kinds/binary/
specs.rs

1/*
2    Appellation: specs <binary>
3    Contrib: FL03 <jo3mccain@icloud.com>
4*/
5
6pub type BoxedBinOp<A, B = A, C = A> = Box<dyn BinOp<A, B, Output = C>>;
7
8pub trait BinaryOperand<A, B> {
9    type Args: crate::ops::Params<Pattern = (A, B)>;
10    type Output;
11}
12
13pub trait BinOp<A, B = A> {
14    type Output;
15
16    fn eval(&self, lhs: A, rhs: B) -> Self::Output;
17}
18
19pub trait BinaryAssignOp<A, B = A> {
20    fn eval(&self, lhs: A, rhs: B);
21}
22
23impl<S, A, B, C> BinOp<A, B> for S
24where
25    S: Fn(A, B) -> C,
26{
27    type Output = C;
28
29    fn eval(&self, lhs: A, rhs: B) -> Self::Output {
30        self(lhs, rhs)
31    }
32}
33
34impl<A, B, C> BinOp<A, B> for Box<dyn BinOp<A, B, Output = C>> {
35    type Output = C;
36
37    fn eval(&self, lhs: A, rhs: B) -> Self::Output {
38        self.as_ref().eval(lhs, rhs)
39    }
40}
41
42impl<A, B> BinaryAssignOp<A, B> for Box<dyn BinaryAssignOp<A, B>> {
43    fn eval(&self, lhs: A, rhs: B) {
44        self.as_ref().eval(lhs, rhs)
45    }
46}
47
48pub trait Logarithm<T> {
49    type Output;
50
51    fn log(self, base: T) -> Self::Output;
52}
53
54macro_rules! impl_log {
55    ($t:ty) => {
56        impl Logarithm<$t> for $t {
57            type Output = $t;
58
59            fn log(self, base: $t) -> Self::Output {
60                self.log(base)
61            }
62        }
63    };
64    (other $t:ty => $out:ty; $method:ident) => {
65        impl Logarithm<$t> for $t {
66            type Output = $out;
67
68            fn log(self, base: $t) -> Self::Output {
69                self.$method(base)
70            }
71        }
72    };
73    (all [$($t:ty),*]) => {
74        $(
75            impl_log!($t);
76        )*
77    };
78}
79
80impl_log!(all [f32, f64]);
81
82impl_log!(other i8 => u32; ilog);
83impl_log!(other i16 => u32; ilog);
84impl_log!(other i32 => u32; ilog);
85impl_log!(other i64 => u32; ilog);
86impl_log!(other i128 => u32; ilog);
87impl_log!(other isize => u32; ilog);
88impl_log!(other u8 => u32; ilog);
89impl_log!(other u16 => u32; ilog);
90impl_log!(other u32 => u32; ilog);
91impl_log!(other u64 => u32; ilog);
92impl_log!(other u128 => u32; ilog);
93impl_log!(other usize => u32; ilog);