diff --git a/CHANGELOG.md b/CHANGELOG.md index e823923213..f4c4229928 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Added `SortedLinkedListView`, the `!Sized` version of `SortedLinkedList`. - Added implementation of `Borrow` and `BorrowMut` for `String` and `Vec`. - Added `Deque::{swap, swap_unchecked, swap_remove_front, swap_remove_back}`. +- Implemented `PartialEq` and `Eq` for `Deque`. ### Changed diff --git a/src/deque.rs b/src/deque.rs index 4c0bec81dc..470471a845 100644 --- a/src/deque.rs +++ b/src/deque.rs @@ -34,6 +34,7 @@ //! ``` use core::borrow::{Borrow, BorrowMut}; +use core::cmp::Ordering; use core::fmt; use core::iter::FusedIterator; use core::mem::MaybeUninit; @@ -950,6 +951,48 @@ where } } +impl PartialEq for Deque { + fn eq(&self, other: &Self) -> bool { + if self.len() != other.len() { + return false; + } + let (sa, sb) = self.as_slices(); + let (oa, ob) = other.as_slices(); + match sa.len().cmp(&oa.len()) { + Ordering::Equal => sa == oa && sb == ob, + Ordering::Less => { + // Always divisible in three sections, for example: + // self: [a b c|d e f] + // other: [0 1 2 3|4 5] + // front = 3, mid = 1, + // [a b c] == [0 1 2] && [d] == [3] && [e f] == [4 5] + let front = sa.len(); + let mid = oa.len() - front; + + let (oa_front, oa_mid) = oa.split_at(front); + let (sb_mid, sb_back) = sb.split_at(mid); + debug_assert_eq!(sa.len(), oa_front.len()); + debug_assert_eq!(sb_mid.len(), oa_mid.len()); + debug_assert_eq!(sb_back.len(), ob.len()); + sa == oa_front && sb_mid == oa_mid && sb_back == ob + } + Ordering::Greater => { + let front = oa.len(); + let mid = sa.len() - front; + + let (sa_front, sa_mid) = sa.split_at(front); + let (ob_mid, ob_back) = ob.split_at(mid); + debug_assert_eq!(sa_front.len(), oa.len()); + debug_assert_eq!(sa_mid.len(), ob_mid.len()); + debug_assert_eq!(sb.len(), ob_back.len()); + sa_front == oa && sa_mid == ob_mid && sb == ob_back + } + } + } +} + +impl Eq for Deque {} + #[cfg(test)] mod tests { use static_assertions::assert_not_impl_any; @@ -1440,4 +1483,60 @@ mod tests { q.pop_front().unwrap(); q.swap(0, 2); } + + #[test] + fn equality() { + let mut a: Deque = Deque::new(); + let mut b: Deque = Deque::new(); + + assert_eq!(a, b); + + a.push_back(1).unwrap(); + a.push_back(2).unwrap(); + a.push_back(3).unwrap(); + + assert_ne!(a, b); + + b.push_back(1).unwrap(); + b.push_back(2).unwrap(); + b.push_back(3).unwrap(); + + assert_eq!(a, b); + + a.push_back(1).unwrap(); + a.push_back(2).unwrap(); + a.push_back(3).unwrap(); + + assert_ne!(a, b); + + b.push_front(3).unwrap(); + b.push_front(2).unwrap(); + b.push_front(1).unwrap(); + + assert_eq!(a, b); + + a.push_back(4).unwrap(); + b.push_back(4).unwrap(); + + assert_eq!(a, b); + + a.clear(); + b.clear(); + + a.push_back(1).unwrap(); + a.push_back(2).unwrap(); + a.push_back(3).unwrap(); + a.push_front(3).unwrap(); + a.push_front(2).unwrap(); + a.push_front(1).unwrap(); + + b.push_back(2).unwrap(); + b.push_back(3).unwrap(); + b.push_back(1).unwrap(); + b.push_back(2).unwrap(); + b.push_back(3).unwrap(); + b.push_front(1).unwrap(); + + assert_eq!(a, b); + } }