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