Skip to main content

vildrose_core/word/
logic.rs

1use super::Word;
2use crate::trit::Trit;
3
4impl<const N: usize> Word<N> {
5    /// Returns the component-wise ternary minimum.
6    #[must_use]
7    pub fn tmin(self, rhs: Self) -> Self {
8        Self(core::array::from_fn(|index| {
9            self.0[index].tmin(rhs.0[index])
10        }))
11    }
12
13    /// Returns the component-wise ternary maximum.
14    #[must_use]
15    pub fn tmax(self, rhs: Self) -> Self {
16        Self(core::array::from_fn(|index| {
17            self.0[index].tmax(rhs.0[index])
18        }))
19    }
20
21    /// Returns the tritwise ternary negation.
22    ///
23    /// Each `N` becomes `P`, each `P` becomes `N`, and `Z` remains `Z`.
24    #[must_use]
25    pub fn tnot(self) -> Self {
26        Self(self.0.map(Trit::negate))
27    }
28
29    /// Returns the tritwise clipping of this word.
30    #[must_use]
31    pub fn tclip(self) -> Self {
32        Self(self.0.map(Trit::clip))
33    }
34
35    /// Returns a word-valued numeric sign: -1, 0, or +1.
36    #[must_use]
37    pub fn signum(self) -> Self {
38        Self(core::array::from_fn(|index| {
39            if index == 0 { self.sign() } else { Trit::Z }
40        }))
41    }
42
43    /// Returns the tritwise consensus of two words.
44    #[must_use]
45    pub fn tconsensus(self, rhs: Self) -> Self {
46        Self(core::array::from_fn(|index| {
47            self.0[index].consensus(rhs.0[index])
48        }))
49    }
50
51    /// Shifts trits left by `count`, filling low trits with zero.
52    ///
53    /// If `count >= Self::TRIT_COUNT`, returns zero.
54    #[must_use]
55    pub fn tshl(self, count: usize) -> Self {
56        Self(core::array::from_fn(|index| {
57            index
58                .checked_sub(count)
59                .and_then(|source| self.0.get(source).copied())
60                .unwrap_or(Trit::Z)
61        }))
62    }
63
64    /// Returns the arithmetic right shift by `count` trits.
65    ///
66    /// Vacated most-significant trits are filled with the numeric sign.
67    /// If `count >= Self::TRIT_COUNT`, every trit becomes the sign trit.
68    #[must_use]
69    pub fn tshr(self, count: usize) -> Self {
70        let sign = self.sign();
71
72        Self(core::array::from_fn(|index| {
73            self.0
74                .get(index.saturating_add(count))
75                .copied()
76                .unwrap_or(sign)
77        }))
78    }
79
80    /// Returns the logical right shift by `count` trits.
81    ///
82    /// Vacated most-significant trits are filled with zero.
83    /// If `count >= Self::TRIT_COUNT`, returns zero.
84    #[must_use]
85    pub fn tlshr(self, count: usize) -> Self {
86        Self(core::array::from_fn(|index| {
87            self.0
88                .get(index.saturating_add(count))
89                .copied()
90                .unwrap_or(Trit::Z)
91        }))
92    }
93}