From 340e0cec99a73759a5704f726c2fa3eed8fc3af6 Mon Sep 17 00:00:00 2001 From: Finn Bear Date: Thu, 22 Sep 2022 19:34:03 -0700 Subject: [PATCH] HistoryBuffer::{clone, eq}. --- src/histbuf.rs | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/src/histbuf.rs b/src/histbuf.rs index 2bd52ec0..5ada3b4b 100644 --- a/src/histbuf.rs +++ b/src/histbuf.rs @@ -238,6 +238,17 @@ where } } +impl Clone for HistoryBuffer +where + T: Clone, +{ + fn clone(&self) -> Self { + let mut ret = Self::new(); + ret.extend(self.iter().cloned()); + ret + } +} + impl Drop for HistoryBuffer { fn drop(&mut self) { unsafe { @@ -279,6 +290,15 @@ impl Default for HistoryBuffer { } } +impl PartialEq for HistoryBuffer +where + T: PartialEq, +{ + fn eq(&self, other: &Self) -> bool { + self.oldest_ordered().eq(other.oldest_ordered()) + } +} + /// An iterator on the underlying buffer ordered from oldest data to newest #[derive(Clone)] pub struct OldestOrdered<'a, T, const N: usize> { @@ -311,6 +331,7 @@ impl<'a, T, const N: usize> Iterator for OldestOrdered<'a, T, N> { mod tests { use crate::HistoryBuffer; use core::fmt::Debug; + use core::sync::atomic::{AtomicUsize, Ordering}; #[test] fn new() { @@ -350,6 +371,47 @@ mod tests { assert_eq!(x.as_slice(), [1; 4]); } + #[test] + fn clone() { + let mut x: HistoryBuffer = HistoryBuffer::new(); + for i in 0..10 { + assert_eq!(x.as_slice(), x.clone().as_slice()); + x.write(i); + } + + // Records number of clones locally and globally. + static GLOBAL: AtomicUsize = AtomicUsize::new(0); + #[derive(Default, PartialEq, Debug)] + struct InstrumentedClone(usize); + + impl Clone for InstrumentedClone { + fn clone(&self) -> Self { + GLOBAL.fetch_add(1, Ordering::Relaxed); + Self(self.0 + 1) + } + } + + let mut y: HistoryBuffer = HistoryBuffer::new(); + let _ = y.clone(); + assert_eq!(GLOBAL.load(Ordering::Relaxed), 0); + y.write(InstrumentedClone(0)); + assert_eq!(GLOBAL.load(Ordering::Relaxed), 0); + assert_eq!(y.clone().as_slice(), [InstrumentedClone(1)]); + assert_eq!(GLOBAL.load(Ordering::Relaxed), 1); + y.write(InstrumentedClone(0)); + assert_eq!(GLOBAL.load(Ordering::Relaxed), 1); + assert_eq!( + y.clone().as_slice(), + [InstrumentedClone(1), InstrumentedClone(1)] + ); + assert_eq!(GLOBAL.load(Ordering::Relaxed), 3); + assert_eq!( + y.clone().clone().clone().as_slice(), + [InstrumentedClone(3), InstrumentedClone(3)] + ); + assert_eq!(GLOBAL.load(Ordering::Relaxed), 9); + } + #[test] fn recent() { let mut x: HistoryBuffer = HistoryBuffer::new(); @@ -430,4 +492,30 @@ mod tests { } } } + + #[test] + fn partial_eq() { + let mut x: HistoryBuffer = HistoryBuffer::new(); + let mut y: HistoryBuffer = HistoryBuffer::new(); + assert_eq!(x, y); + x.write(1); + assert_ne!(x, y); + y.write(1); + assert_eq!(x, y); + for _ in 0..4 { + x.write(2); + assert_ne!(x, y); + for i in 0..5 { + x.write(i); + y.write(i); + } + assert_eq!( + x, + y, + "{:?} {:?}", + x.iter().collect::>(), + y.iter().collect::>() + ); + } + } }