acme_core/ops/kinds/ternary/
kinds.rs

1/*
2    Appellation: kinds <mod>
3    Contrib: FL03 <jo3mccain@icloud.com>
4*/
5use crate::ops::ternary::ApplyTernary;
6use crate::ops::{OpKind, Operator};
7use strum::{Display, EnumCount, EnumDiscriminants, EnumIs, EnumIter, EnumString, VariantNames};
8
9#[derive(
10    Clone,
11    Copy,
12    Debug,
13    Display,
14    EnumCount,
15    EnumDiscriminants,
16    EnumIs,
17    Eq,
18    Hash,
19    Ord,
20    PartialEq,
21    PartialOrd,
22    VariantNames,
23)]
24#[cfg_attr(
25    feature = "serde",
26    derive(serde::Deserialize, serde::Serialize,),
27    serde(rename_all = "lowercase", untagged),
28    strum_discriminants(derive(serde::Deserialize, serde::Serialize))
29)]
30#[strum(serialize_all = "lowercase")]
31#[strum_discriminants(
32    derive(
33        Display,
34        EnumCount,
35        EnumIs,
36        EnumIter,
37        EnumString,
38        Hash,
39        Ord,
40        PartialOrd,
41        VariantNames
42    ),
43    name(TernaryOp),
44    strum(serialize_all = "lowercase")
45)]
46pub enum TernaryExpr {
47    Affine(Affine),
48}
49
50impl Operator for TernaryExpr {
51    fn kind(&self) -> OpKind {
52        OpKind::Ternary
53    }
54
55    fn name(&self) -> &str {
56        match self {
57            TernaryExpr::Affine(op) => op.name(),
58        }
59    }
60}
61
62impl Operator for TernaryOp {
63    fn kind(&self) -> OpKind {
64        OpKind::Ternary
65    }
66
67    fn name(&self) -> &str {
68        match self {
69            Self::Affine => "affine",
70        }
71    }
72}
73
74#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
75#[cfg_attr(
76    feature = "serde",
77    derive(serde::Deserialize, serde::Serialize),
78    serde(rename_all = "lowercase")
79)]
80#[repr(C)]
81pub struct Affine;
82
83impl Operator for Affine {
84    fn kind(&self) -> OpKind {
85        OpKind::Ternary
86    }
87
88    fn name(&self) -> &str {
89        "affine"
90    }
91}
92
93impl<A, B, C> ApplyTernary<A, B, C> for Affine
94where
95    A: core::ops::Mul<B, Output = C>,
96    C: core::ops::Add<Output = C>,
97{
98    type Output = C;
99
100    fn apply(&self, a: A, b: B, c: C) -> Self::Output {
101        a * b + c
102    }
103}