]> git.lizzy.rs Git - rust.git/blob - library/alloc/src/testing/ord_chaos.rs
Rollup merge of #106859 - tialaramex:master, r=Nilstrieb
[rust.git] / library / alloc / src / testing / ord_chaos.rs
1 use std::cell::Cell;
2 use std::cmp::Ordering::{self, *};
3 use std::ptr;
4
5 // Minimal type with an `Ord` implementation violating transitivity.
6 #[derive(Debug)]
7 pub enum Cyclic3 {
8     A,
9     B,
10     C,
11 }
12 use Cyclic3::*;
13
14 impl PartialOrd for Cyclic3 {
15     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
16         Some(self.cmp(other))
17     }
18 }
19
20 impl Ord for Cyclic3 {
21     fn cmp(&self, other: &Self) -> Ordering {
22         match (self, other) {
23             (A, A) | (B, B) | (C, C) => Equal,
24             (A, B) | (B, C) | (C, A) => Less,
25             (A, C) | (B, A) | (C, B) => Greater,
26         }
27     }
28 }
29
30 impl PartialEq for Cyclic3 {
31     fn eq(&self, other: &Self) -> bool {
32         self.cmp(&other) == Equal
33     }
34 }
35
36 impl Eq for Cyclic3 {}
37
38 // Controls the ordering of values wrapped by `Governed`.
39 #[derive(Debug)]
40 pub struct Governor {
41     flipped: Cell<bool>,
42 }
43
44 impl Governor {
45     pub fn new() -> Self {
46         Governor { flipped: Cell::new(false) }
47     }
48
49     pub fn flip(&self) {
50         self.flipped.set(!self.flipped.get());
51     }
52 }
53
54 // Type with an `Ord` implementation that forms a total order at any moment
55 // (assuming that `T` respects total order), but can suddenly be made to invert
56 // that total order.
57 #[derive(Debug)]
58 pub struct Governed<'a, T>(pub T, pub &'a Governor);
59
60 impl<T: Ord> PartialOrd for Governed<'_, T> {
61     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
62         Some(self.cmp(other))
63     }
64 }
65
66 impl<T: Ord> Ord for Governed<'_, T> {
67     fn cmp(&self, other: &Self) -> Ordering {
68         assert!(ptr::eq(self.1, other.1));
69         let ord = self.0.cmp(&other.0);
70         if self.1.flipped.get() { ord.reverse() } else { ord }
71     }
72 }
73
74 impl<T: PartialEq> PartialEq for Governed<'_, T> {
75     fn eq(&self, other: &Self) -> bool {
76         assert!(ptr::eq(self.1, other.1));
77         self.0.eq(&other.0)
78     }
79 }
80
81 impl<T: Eq> Eq for Governed<'_, T> {}