1use crate::CircularBuffer;
7use crate::FixedCircularBuffer;
8use core::cmp::Ordering;
9use core::convert::identity;
10use core::ops::Deref;
11
12#[cfg(feature = "alloc")]
13use crate::HeapCircularBuffer;
14
15#[cfg(all(not(feature = "std"), feature = "alloc"))]
16use alloc::boxed::Box;
17
18impl<T> Eq for CircularBuffer<T> where T: Eq {}
19
20impl<T, const N: usize> Eq for FixedCircularBuffer<T, N> where T: Eq {}
21
22#[cfg(feature = "alloc")]
23impl<T> Eq for HeapCircularBuffer<T> where T: Eq {}
24
25impl<T, U> PartialEq<CircularBuffer<U>> for CircularBuffer<T>
26where
27 T: PartialEq<U>,
28{
29 fn eq(&self, other: &CircularBuffer<U>) -> bool {
30 if self.len() != other.len() {
31 return false;
32 }
33
34 let (a_left, a_right) = self.as_slices();
35 let (b_left, b_right) = other.as_slices();
36
37 match a_left.len().cmp(&b_left.len()) {
38 Ordering::Less => {
39 let x = a_left.len();
40 let y = b_left.len() - x;
41 a_left[..] == b_left[..x]
42 && a_right[..y] == b_left[x..]
43 && a_right[y..] == b_right[..]
44 }
45 Ordering::Greater => {
46 let x = b_left.len();
47 let y = a_left.len() - x;
48 a_left[..x] == b_left[..]
49 && a_left[x..] == b_right[..y]
50 && a_right[..] == b_right[y..]
51 }
52 Ordering::Equal => {
53 debug_assert_eq!(a_left.len(), b_left.len());
54 debug_assert_eq!(a_right.len(), b_right.len());
55 a_left == b_left && a_right == b_right
56 }
57 }
58 }
59}
60
61impl<T, U> PartialEq<[U]> for CircularBuffer<T>
62where
63 T: PartialEq<U>,
64{
65 fn eq(&self, other: &[U]) -> bool {
66 if self.len() != other.len() {
67 return false;
68 }
69
70 let (a_left, a_right) = self.as_slices();
71 let (b_left, b_right) = other.split_at(a_left.len());
72
73 debug_assert_eq!(a_left.len(), b_left.len());
74 debug_assert_eq!(a_right.len(), b_right.len());
75 a_left == b_left && a_right == b_right
76 }
77}
78
79impl<T, U> PartialEq<CircularBuffer<U>> for [T]
80where
81 T: PartialEq<U>,
82{
83 #[inline]
84 fn eq(&self, other: &CircularBuffer<U>) -> bool {
85 if self.len() != other.len() {
86 return false;
87 }
88
89 let (a_left, a_right) = other.as_slices();
90 let (b_left, b_right) = self.split_at(a_left.len());
91
92 debug_assert_eq!(a_left.len(), b_left.len());
93 debug_assert_eq!(a_right.len(), b_right.len());
94 b_left == a_left && b_right == a_right
95 }
96}
97
98macro_rules! impl_partial_eq {
99 ( [ $( $generics:tt )* ] $lhs:ty [ $l_transform:path ] , $rhs:ty [ $r_transform:path ] ) => {
100 impl<T, U, $($generics)*> PartialEq<$rhs> for $lhs
101 where
102 T: PartialEq<U>,
103 {
104 #[inline]
105 fn eq(&self, other: &$rhs) -> bool {
106 $l_transform(self) == $r_transform(other)
107 }
108 }
109 };
110}
111
112macro_rules! impl_partial_eq_with_refs {
113 ( [ $( $generics:tt )* ] $lhs:ty [ $l_transform:path ] , $rhs:ty [ $r_transform:path ] ) => {
114 impl_partial_eq!([$($generics)*] $lhs [$l_transform], $rhs [$r_transform]);
115 impl_partial_eq!([$($generics)*] $lhs [$l_transform], &'_ $rhs [$r_transform]);
116 impl_partial_eq!([$($generics)*] $lhs [$l_transform], &'_ mut $rhs [$r_transform]);
117 impl_partial_eq!([$($generics)*] &'_ $lhs [$l_transform], $rhs [$r_transform]);
118 impl_partial_eq!([$($generics)*] &'_ mut $lhs [$l_transform], $rhs [$r_transform]);
119 };
120}
121
122impl_partial_eq!([] CircularBuffer<T> [identity], &'_ CircularBuffer<U> [Deref::deref]);
124impl_partial_eq!([] CircularBuffer<T> [identity], &'_ mut CircularBuffer<U> [Deref::deref]);
125impl_partial_eq!([] &'_ CircularBuffer<T> [Deref::deref], CircularBuffer<U> [identity]);
126impl_partial_eq!([] &'_ mut CircularBuffer<T> [Deref::deref], CircularBuffer<U> [identity]);
127
128impl_partial_eq!([] CircularBuffer<T> [identity], &'_ [U] [Deref::deref]);
130impl_partial_eq!([] CircularBuffer<T> [identity], &'_ mut [U] [Deref::deref]);
131impl_partial_eq!([] &'_ CircularBuffer<T> [Deref::deref], [U] [identity]);
132impl_partial_eq!([] &'_ mut CircularBuffer<T> [Deref::deref], [U] [identity]);
133
134impl_partial_eq_with_refs!([const M: usize] CircularBuffer<T> [identity], [U; M] [AsRef::as_ref]);
136
137impl_partial_eq_with_refs!([const M: usize] CircularBuffer<T> [identity], FixedCircularBuffer<U, M> [Deref::deref]);
139impl_partial_eq_with_refs!([const N: usize] FixedCircularBuffer<T, N> [Deref::deref], CircularBuffer<U> [identity]);
140
141#[cfg(feature = "alloc")]
143impl_partial_eq_with_refs!([] CircularBuffer<T> [identity], HeapCircularBuffer<U> [Deref::deref]);
144#[cfg(feature = "alloc")]
145impl_partial_eq_with_refs!([] HeapCircularBuffer<T> [Deref::deref], CircularBuffer<U> [identity]);
146
147impl_partial_eq_with_refs!([const N: usize, const M: usize] FixedCircularBuffer<T, N> [Deref::deref], FixedCircularBuffer<U, M> [Deref::deref]);
149impl_partial_eq_with_refs!([const N: usize] FixedCircularBuffer<T, N> [Deref::deref], [U] [identity]);
150impl_partial_eq_with_refs!([const N: usize, const M: usize] FixedCircularBuffer<T, N> [Deref::deref], [U; M] [AsRef::as_ref]);
151
152#[cfg(feature = "alloc")]
154impl_partial_eq_with_refs!([] HeapCircularBuffer<T> [Deref::deref], HeapCircularBuffer<U> [Deref::deref]);
155#[cfg(feature = "alloc")]
156impl_partial_eq_with_refs!([] HeapCircularBuffer<T> [Deref::deref], [U] [identity]);
157#[cfg(feature = "alloc")]
158impl_partial_eq_with_refs!([const M: usize] HeapCircularBuffer<T> [Deref::deref], [U; M] [AsRef::as_ref]);
159
160#[cfg(feature = "alloc")]
162impl_partial_eq_with_refs!([] Box<CircularBuffer<T>> [Deref::deref], [U] [identity]);
163#[cfg(feature = "alloc")]
164impl_partial_eq_with_refs!([const M: usize] Box<CircularBuffer<T>> [Deref::deref], [U; M] [AsRef::as_ref]);
165
166impl<T, U> PartialOrd<CircularBuffer<U>> for CircularBuffer<T>
167where
168 T: PartialOrd<U>,
169{
170 fn partial_cmp(&self, other: &CircularBuffer<U>) -> Option<Ordering> {
171 self.iter().partial_cmp(other.iter())
172 }
173}
174
175impl<T> Ord for CircularBuffer<T>
176where
177 T: Ord,
178{
179 fn cmp(&self, other: &Self) -> Ordering {
180 self.iter().cmp(other.iter())
181 }
182}
183
184impl<T, const N: usize, U, const M: usize> PartialOrd<FixedCircularBuffer<U, M>>
185 for FixedCircularBuffer<T, N>
186where
187 T: PartialOrd<U>,
188{
189 #[inline]
190 fn partial_cmp(&self, other: &FixedCircularBuffer<U, M>) -> Option<Ordering> {
191 self.deref().partial_cmp(other.deref())
192 }
193}
194
195impl<T, const N: usize> Ord for FixedCircularBuffer<T, N>
196where
197 T: Ord,
198{
199 #[inline]
200 fn cmp(&self, other: &Self) -> Ordering {
201 self.deref().cmp(other.deref())
202 }
203}
204
205#[cfg(feature = "alloc")]
206impl<T, U> PartialOrd<HeapCircularBuffer<U>> for HeapCircularBuffer<T>
207where
208 T: PartialOrd<U>,
209{
210 #[inline]
211 fn partial_cmp(&self, other: &HeapCircularBuffer<U>) -> Option<Ordering> {
212 self.deref().partial_cmp(other.deref())
213 }
214}
215
216#[cfg(feature = "alloc")]
217impl<T> Ord for HeapCircularBuffer<T>
218where
219 T: Ord,
220{
221 #[inline]
222 fn cmp(&self, other: &Self) -> Ordering {
223 self.deref().cmp(other.deref())
224 }
225}