1use super::{tuple_deref, tuple_deref_mut};
2use std::hash::{Hash, Hasher};
3
4impl<T: ?Sized> OrdExt for T {}
5
6pub trait OrdExt {
7 #[inline]
8 fn eq_ord(self) -> EqOrdWrapper<Self>
9 where
10 Self: Sized,
11 {
12 EqOrdWrapper(self)
13 }
14
15 #[inline]
16 fn neq_ord(self) -> NeqOrdWrapper<Self>
17 where
18 Self: Sized,
19 {
20 NeqOrdWrapper(self)
21 }
22}
23
24pub struct NeqOrdWrapper<T>(T);
25
26tuple_deref!(NeqOrdWrapper<T>);
27tuple_deref_mut!(NeqOrdWrapper<T>);
28
29impl<T> Eq for NeqOrdWrapper<T> {}
30
31impl<T> PartialEq<Self> for NeqOrdWrapper<T> {
32 #[inline]
33 fn eq(&self, _other: &Self) -> bool {
34 false
35 }
36}
37
38impl<T> PartialOrd<Self> for NeqOrdWrapper<T> {
39 #[allow(clippy::non_canonical_partial_ord_impl)]
40 fn partial_cmp(&self, _other: &Self) -> Option<std::cmp::Ordering> {
41 None
42 }
43}
44
45impl<T> Ord for NeqOrdWrapper<T> {
46 fn cmp(&self, _other: &Self) -> std::cmp::Ordering {
47 std::cmp::Ordering::Greater
48 }
49}
50
51pub struct EqOrdWrapper<T>(T);
52
53tuple_deref!(EqOrdWrapper<T>);
54tuple_deref_mut!(EqOrdWrapper<T>);
55
56impl<T> Eq for EqOrdWrapper<T> {}
57
58impl<T> PartialEq<Self> for EqOrdWrapper<T> {
59 #[inline]
60 fn eq(&self, _other: &Self) -> bool {
61 true
62 }
63}
64
65impl<T> PartialOrd<Self> for EqOrdWrapper<T> {
66 #[allow(clippy::non_canonical_partial_ord_impl)]
67 fn partial_cmp(&self, _other: &Self) -> Option<std::cmp::Ordering> {
68 Some(std::cmp::Ordering::Equal)
69 }
70}
71
72impl<T> Ord for EqOrdWrapper<T> {
73 fn cmp(&self, _other: &Self) -> std::cmp::Ordering {
74 std::cmp::Ordering::Equal
75 }
76}
77
78impl<T: ?Sized> HashExt for T {}
79
80pub trait HashExt {
81 #[inline]
82 fn hash_value(self, h: u64) -> HashWrapper<Self>
83 where
84 Self: Sized,
85 {
86 HashWrapper(self, h)
87 }
88
89 #[inline]
90 fn hash_empty(self) -> EmptyHashWrapper<Self>
91 where
92 Self: Sized,
93 {
94 EmptyHashWrapper(self)
95 }
96}
97
98pub struct HashWrapper<T>(T, u64);
99
100tuple_deref!(HashWrapper<T>);
101tuple_deref_mut!(HashWrapper<T>);
102
103impl<T> Hash for HashWrapper<T> {
104 fn hash<H: Hasher>(&self, state: &mut H) {
105 self.1.hash(state);
106 }
107}
108
109pub struct EmptyHashWrapper<T>(T);
110
111tuple_deref!(EmptyHashWrapper<T>);
112tuple_deref_mut!(EmptyHashWrapper<T>);
113
114impl<T> Hash for EmptyHashWrapper<T> {
115 fn hash<H: Hasher>(&self, _state: &mut H) {}
116}
117
118impl<T: ?Sized> OrdHashExt for T {}
119
120pub trait OrdHashExt {
121 #[inline]
122 fn neq_ord_hash(self, h: u64) -> NeqOrdHashWrapper<Self>
123 where
124 Self: Sized,
125 {
126 NeqOrdHashWrapper(self, h)
127 }
128
129 #[inline]
130 fn neq_ord_empty(self) -> NeqOrdEmptyHashWrapper<Self>
131 where
132 Self: Sized,
133 {
134 NeqOrdEmptyHashWrapper(self)
135 }
136}
137
138pub struct NeqOrdEmptyHashWrapper<T>(T);
139
140tuple_deref!(NeqOrdEmptyHashWrapper<T>);
141tuple_deref_mut!(NeqOrdEmptyHashWrapper<T>);
142
143impl<T> Eq for NeqOrdEmptyHashWrapper<T> {}
144
145impl<T> PartialEq<Self> for NeqOrdEmptyHashWrapper<T> {
146 #[inline]
147 fn eq(&self, _other: &Self) -> bool {
148 false
149 }
150}
151
152impl<T> PartialOrd<Self> for NeqOrdEmptyHashWrapper<T> {
153 #[allow(clippy::non_canonical_partial_ord_impl)]
154 fn partial_cmp(&self, _other: &Self) -> Option<std::cmp::Ordering> {
155 None
156 }
157}
158
159impl<T> Ord for NeqOrdEmptyHashWrapper<T> {
160 fn cmp(&self, _other: &Self) -> std::cmp::Ordering {
161 std::cmp::Ordering::Greater
162 }
163}
164
165impl<T> Hash for NeqOrdEmptyHashWrapper<T> {
166 fn hash<H: Hasher>(&self, _state: &mut H) {}
167}
168
169pub struct NeqOrdHashWrapper<T>(T, u64);
170
171tuple_deref!(NeqOrdHashWrapper<T>);
172tuple_deref_mut!(NeqOrdHashWrapper<T>);
173
174impl<T> Eq for NeqOrdHashWrapper<T> {}
175
176impl<T> PartialEq<Self> for NeqOrdHashWrapper<T> {
177 #[inline]
178 fn eq(&self, _other: &Self) -> bool {
179 false
180 }
181}
182
183impl<T> PartialOrd<Self> for NeqOrdHashWrapper<T> {
184 fn partial_cmp(&self, _other: &Self) -> Option<std::cmp::Ordering> {
185 None
186 }
187}
188
189impl<T> Hash for NeqOrdHashWrapper<T> {
190 fn hash<H: Hasher>(&self, state: &mut H) {
191 self.1.hash(state)
192 }
193}
194
195#[test]
196fn test_neq() {
197 let a1 = NeqOrdWrapper(1);
198 let a2 = NeqOrdWrapper(1);
199 assert!(a1.ne(&a2));
200}
201
202#[test]
203fn test_eq() {
204 let a1 = EqOrdWrapper(1);
205 let a2 = EqOrdWrapper(1);
206 assert!(a1.eq(&a2));
207}