use std::cell::Cell; use std::cmp::Ordering::{self, *}; use std::ptr; // Minimal type with an `Ord` implementation violating transitivity. #[derive(Debug)] pub enum Cyclic3 { A, B, C, } use Cyclic3::*; impl PartialOrd for Cyclic3 { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } impl Ord for Cyclic3 { fn cmp(&self, other: &Self) -> Ordering { match (self, other) { (A, A) | (B, B) | (C, C) => Equal, (A, B) | (B, C) | (C, A) => Less, (A, C) | (B, A) | (C, B) => Greater, } } } impl PartialEq for Cyclic3 { fn eq(&self, other: &Self) -> bool { self.cmp(&other) == Equal } } impl Eq for Cyclic3 {} // Controls the ordering of values wrapped by `Governed`. #[derive(Debug)] pub struct Governor { flipped: Cell, } impl Governor { pub fn new() -> Self { Governor { flipped: Cell::new(false) } } pub fn flip(&self) { self.flipped.set(!self.flipped.get()); } } // Type with an `Ord` implementation that forms a total order at any moment // (assuming that `T` respects total order), but can suddenly be made to invert // that total order. #[derive(Debug)] pub struct Governed<'a, T>(pub T, pub &'a Governor); impl PartialOrd for Governed<'_, T> { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } impl Ord for Governed<'_, T> { fn cmp(&self, other: &Self) -> Ordering { assert!(ptr::eq(self.1, other.1)); let ord = self.0.cmp(&other.0); if self.1.flipped.get() { ord.reverse() } else { ord } } } impl PartialEq for Governed<'_, T> { fn eq(&self, other: &Self) -> bool { assert!(ptr::eq(self.1, other.1)); self.0.eq(&other.0) } } impl Eq for Governed<'_, T> {}