1use core::fmt::{self, Display, Formatter};
8use core::str::FromStr;
9
10#[cfg(feature = "enable-serde")]
11use serde_derive::{Deserialize, Serialize};
12
13pub trait CondCode: Copy {
15 #[must_use]
20 fn complement(self) -> Self;
21
22 #[must_use]
27 fn swap_args(self) -> Self;
28}
29
30#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
36#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
37pub enum IntCC {
38 Equal,
40 NotEqual,
42 SignedLessThan,
44 SignedGreaterThanOrEqual,
46 SignedGreaterThan,
48 SignedLessThanOrEqual,
50 UnsignedLessThan,
52 UnsignedGreaterThanOrEqual,
54 UnsignedGreaterThan,
56 UnsignedLessThanOrEqual,
58}
59
60impl CondCode for IntCC {
61 fn complement(self) -> Self {
62 use self::IntCC::*;
63 match self {
64 Equal => NotEqual,
65 NotEqual => Equal,
66 SignedLessThan => SignedGreaterThanOrEqual,
67 SignedGreaterThanOrEqual => SignedLessThan,
68 SignedGreaterThan => SignedLessThanOrEqual,
69 SignedLessThanOrEqual => SignedGreaterThan,
70 UnsignedLessThan => UnsignedGreaterThanOrEqual,
71 UnsignedGreaterThanOrEqual => UnsignedLessThan,
72 UnsignedGreaterThan => UnsignedLessThanOrEqual,
73 UnsignedLessThanOrEqual => UnsignedGreaterThan,
74 }
75 }
76
77 fn swap_args(self) -> Self {
78 use self::IntCC::*;
79 match self {
80 Equal => Equal,
81 NotEqual => NotEqual,
82 SignedGreaterThan => SignedLessThan,
83 SignedGreaterThanOrEqual => SignedLessThanOrEqual,
84 SignedLessThan => SignedGreaterThan,
85 SignedLessThanOrEqual => SignedGreaterThanOrEqual,
86 UnsignedGreaterThan => UnsignedLessThan,
87 UnsignedGreaterThanOrEqual => UnsignedLessThanOrEqual,
88 UnsignedLessThan => UnsignedGreaterThan,
89 UnsignedLessThanOrEqual => UnsignedGreaterThanOrEqual,
90 }
91 }
92}
93
94impl IntCC {
95 pub fn all() -> &'static [IntCC] {
97 &[
98 IntCC::Equal,
99 IntCC::NotEqual,
100 IntCC::SignedLessThan,
101 IntCC::SignedGreaterThanOrEqual,
102 IntCC::SignedGreaterThan,
103 IntCC::SignedLessThanOrEqual,
104 IntCC::UnsignedLessThan,
105 IntCC::UnsignedGreaterThanOrEqual,
106 IntCC::UnsignedGreaterThan,
107 IntCC::UnsignedLessThanOrEqual,
108 ]
109 }
110
111 pub fn without_equal(self) -> Self {
114 use self::IntCC::*;
115 match self {
116 SignedGreaterThan | SignedGreaterThanOrEqual => SignedGreaterThan,
117 SignedLessThan | SignedLessThanOrEqual => SignedLessThan,
118 UnsignedGreaterThan | UnsignedGreaterThanOrEqual => UnsignedGreaterThan,
119 UnsignedLessThan | UnsignedLessThanOrEqual => UnsignedLessThan,
120 _ => self,
121 }
122 }
123
124 pub fn unsigned(self) -> Self {
127 use self::IntCC::*;
128 match self {
129 SignedGreaterThan | UnsignedGreaterThan => UnsignedGreaterThan,
130 SignedGreaterThanOrEqual | UnsignedGreaterThanOrEqual => UnsignedGreaterThanOrEqual,
131 SignedLessThan | UnsignedLessThan => UnsignedLessThan,
132 SignedLessThanOrEqual | UnsignedLessThanOrEqual => UnsignedLessThanOrEqual,
133 _ => self,
134 }
135 }
136
137 pub fn to_static_str(self) -> &'static str {
139 use self::IntCC::*;
140 match self {
141 Equal => "eq",
142 NotEqual => "ne",
143 SignedGreaterThan => "sgt",
144 SignedGreaterThanOrEqual => "sge",
145 SignedLessThan => "slt",
146 SignedLessThanOrEqual => "sle",
147 UnsignedGreaterThan => "ugt",
148 UnsignedGreaterThanOrEqual => "uge",
149 UnsignedLessThan => "ult",
150 UnsignedLessThanOrEqual => "ule",
151 }
152 }
153}
154
155impl Display for IntCC {
156 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
157 f.write_str(self.to_static_str())
158 }
159}
160
161impl FromStr for IntCC {
162 type Err = ();
163
164 fn from_str(s: &str) -> Result<Self, Self::Err> {
165 use self::IntCC::*;
166 match s {
167 "eq" => Ok(Equal),
168 "ne" => Ok(NotEqual),
169 "sge" => Ok(SignedGreaterThanOrEqual),
170 "sgt" => Ok(SignedGreaterThan),
171 "sle" => Ok(SignedLessThanOrEqual),
172 "slt" => Ok(SignedLessThan),
173 "uge" => Ok(UnsignedGreaterThanOrEqual),
174 "ugt" => Ok(UnsignedGreaterThan),
175 "ule" => Ok(UnsignedLessThanOrEqual),
176 "ult" => Ok(UnsignedLessThan),
177 _ => Err(()),
178 }
179 }
180}
181
182#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
198#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
199pub enum FloatCC {
200 Ordered,
202 Unordered,
204
205 Equal,
207 NotEqual,
210 OrderedNotEqual,
212 UnorderedOrEqual,
214
215 LessThan,
217 LessThanOrEqual,
219 GreaterThan,
221 GreaterThanOrEqual,
223
224 UnorderedOrLessThan,
226 UnorderedOrLessThanOrEqual,
228 UnorderedOrGreaterThan,
230 UnorderedOrGreaterThanOrEqual,
232}
233
234impl FloatCC {
235 pub fn all() -> &'static [FloatCC] {
237 &[
238 FloatCC::Ordered,
239 FloatCC::Unordered,
240 FloatCC::Equal,
241 FloatCC::NotEqual,
242 FloatCC::OrderedNotEqual,
243 FloatCC::UnorderedOrEqual,
244 FloatCC::LessThan,
245 FloatCC::LessThanOrEqual,
246 FloatCC::GreaterThan,
247 FloatCC::GreaterThanOrEqual,
248 FloatCC::UnorderedOrLessThan,
249 FloatCC::UnorderedOrLessThanOrEqual,
250 FloatCC::UnorderedOrGreaterThan,
251 FloatCC::UnorderedOrGreaterThanOrEqual,
252 ]
253 }
254}
255
256impl CondCode for FloatCC {
257 fn complement(self) -> Self {
258 use self::FloatCC::*;
259 match self {
260 Ordered => Unordered,
261 Unordered => Ordered,
262 Equal => NotEqual,
263 NotEqual => Equal,
264 OrderedNotEqual => UnorderedOrEqual,
265 UnorderedOrEqual => OrderedNotEqual,
266 LessThan => UnorderedOrGreaterThanOrEqual,
267 LessThanOrEqual => UnorderedOrGreaterThan,
268 GreaterThan => UnorderedOrLessThanOrEqual,
269 GreaterThanOrEqual => UnorderedOrLessThan,
270 UnorderedOrLessThan => GreaterThanOrEqual,
271 UnorderedOrLessThanOrEqual => GreaterThan,
272 UnorderedOrGreaterThan => LessThanOrEqual,
273 UnorderedOrGreaterThanOrEqual => LessThan,
274 }
275 }
276 fn swap_args(self) -> Self {
277 use self::FloatCC::*;
278 match self {
279 Ordered => Ordered,
280 Unordered => Unordered,
281 Equal => Equal,
282 NotEqual => NotEqual,
283 OrderedNotEqual => OrderedNotEqual,
284 UnorderedOrEqual => UnorderedOrEqual,
285 LessThan => GreaterThan,
286 LessThanOrEqual => GreaterThanOrEqual,
287 GreaterThan => LessThan,
288 GreaterThanOrEqual => LessThanOrEqual,
289 UnorderedOrLessThan => UnorderedOrGreaterThan,
290 UnorderedOrLessThanOrEqual => UnorderedOrGreaterThanOrEqual,
291 UnorderedOrGreaterThan => UnorderedOrLessThan,
292 UnorderedOrGreaterThanOrEqual => UnorderedOrLessThanOrEqual,
293 }
294 }
295}
296
297impl Display for FloatCC {
298 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
299 use self::FloatCC::*;
300 f.write_str(match *self {
301 Ordered => "ord",
302 Unordered => "uno",
303 Equal => "eq",
304 NotEqual => "ne",
305 OrderedNotEqual => "one",
306 UnorderedOrEqual => "ueq",
307 LessThan => "lt",
308 LessThanOrEqual => "le",
309 GreaterThan => "gt",
310 GreaterThanOrEqual => "ge",
311 UnorderedOrLessThan => "ult",
312 UnorderedOrLessThanOrEqual => "ule",
313 UnorderedOrGreaterThan => "ugt",
314 UnorderedOrGreaterThanOrEqual => "uge",
315 })
316 }
317}
318
319impl FromStr for FloatCC {
320 type Err = ();
321
322 fn from_str(s: &str) -> Result<Self, Self::Err> {
323 use self::FloatCC::*;
324 match s {
325 "ord" => Ok(Ordered),
326 "uno" => Ok(Unordered),
327 "eq" => Ok(Equal),
328 "ne" => Ok(NotEqual),
329 "one" => Ok(OrderedNotEqual),
330 "ueq" => Ok(UnorderedOrEqual),
331 "lt" => Ok(LessThan),
332 "le" => Ok(LessThanOrEqual),
333 "gt" => Ok(GreaterThan),
334 "ge" => Ok(GreaterThanOrEqual),
335 "ult" => Ok(UnorderedOrLessThan),
336 "ule" => Ok(UnorderedOrLessThanOrEqual),
337 "ugt" => Ok(UnorderedOrGreaterThan),
338 "uge" => Ok(UnorderedOrGreaterThanOrEqual),
339 _ => Err(()),
340 }
341 }
342}
343
344#[cfg(test)]
345mod tests {
346 use super::*;
347 use std::string::ToString;
348
349 #[test]
350 fn int_complement() {
351 for r in IntCC::all() {
352 let cc = *r;
353 let inv = cc.complement();
354 assert!(cc != inv);
355 assert_eq!(inv.complement(), cc);
356 }
357 }
358
359 #[test]
360 fn int_swap_args() {
361 for r in IntCC::all() {
362 let cc = *r;
363 let rev = cc.swap_args();
364 assert_eq!(rev.swap_args(), cc);
365 }
366 }
367
368 #[test]
369 fn int_display() {
370 for r in IntCC::all() {
371 let cc = *r;
372 assert_eq!(cc.to_string().parse(), Ok(cc));
373 }
374 assert_eq!("bogus".parse::<IntCC>(), Err(()));
375 }
376
377 #[test]
378 fn float_complement() {
379 for r in FloatCC::all() {
380 let cc = *r;
381 let inv = cc.complement();
382 assert!(cc != inv);
383 assert_eq!(inv.complement(), cc);
384 }
385 }
386
387 #[test]
388 fn float_swap_args() {
389 for r in FloatCC::all() {
390 let cc = *r;
391 let rev = cc.swap_args();
392 assert_eq!(rev.swap_args(), cc);
393 }
394 }
395
396 #[test]
397 fn float_display() {
398 for r in FloatCC::all() {
399 let cc = *r;
400 assert_eq!(cc.to_string().parse(), Ok(cc));
401 }
402 assert_eq!("bogus".parse::<FloatCC>(), Err(()));
403 }
404}