@@ -238,6 +238,21 @@ where
238238 }
239239}
240240
241+ impl < T , const N : usize > Clone for HistoryBuffer < T , N >
242+ where
243+ T : Clone ,
244+ {
245+ fn clone ( & self ) -> Self {
246+ let mut ret = Self :: new ( ) ;
247+ for ( new, old) in ret. data . iter_mut ( ) . zip ( self . as_slice ( ) ) {
248+ new. write ( old. clone ( ) ) ;
249+ }
250+ ret. filled = self . filled ;
251+ ret. write_at = self . write_at ;
252+ ret
253+ }
254+ }
255+
241256impl < T , const N : usize > Drop for HistoryBuffer < T , N > {
242257 fn drop ( & mut self ) {
243258 unsafe {
@@ -279,6 +294,15 @@ impl<T, const N: usize> Default for HistoryBuffer<T, N> {
279294 }
280295}
281296
297+ impl < T , const N : usize > PartialEq for HistoryBuffer < T , N >
298+ where
299+ T : PartialEq ,
300+ {
301+ fn eq ( & self , other : & Self ) -> bool {
302+ self . oldest_ordered ( ) . eq ( other. oldest_ordered ( ) )
303+ }
304+ }
305+
282306/// An iterator on the underlying buffer ordered from oldest data to newest
283307#[ derive( Clone ) ]
284308pub struct OldestOrdered < ' a , T , const N : usize > {
@@ -311,6 +335,7 @@ impl<'a, T, const N: usize> Iterator for OldestOrdered<'a, T, N> {
311335mod tests {
312336 use crate :: HistoryBuffer ;
313337 use core:: fmt:: Debug ;
338+ use core:: sync:: atomic:: { AtomicUsize , Ordering } ;
314339
315340 #[ test]
316341 fn new ( ) {
@@ -350,6 +375,47 @@ mod tests {
350375 assert_eq ! ( x. as_slice( ) , [ 1 ; 4 ] ) ;
351376 }
352377
378+ #[ test]
379+ fn clone ( ) {
380+ let mut x: HistoryBuffer < u8 , 3 > = HistoryBuffer :: new ( ) ;
381+ for i in 0 ..10 {
382+ assert_eq ! ( x. as_slice( ) , x. clone( ) . as_slice( ) ) ;
383+ x. write ( i) ;
384+ }
385+
386+ // Records number of clones locally and globally.
387+ static GLOBAL : AtomicUsize = AtomicUsize :: new ( 0 ) ;
388+ #[ derive( Default , PartialEq , Debug ) ]
389+ struct InstrumentedClone ( usize ) ;
390+
391+ impl Clone for InstrumentedClone {
392+ fn clone ( & self ) -> Self {
393+ GLOBAL . fetch_add ( 1 , Ordering :: Relaxed ) ;
394+ Self ( self . 0 + 1 )
395+ }
396+ }
397+
398+ let mut y: HistoryBuffer < InstrumentedClone , 2 > = HistoryBuffer :: new ( ) ;
399+ let _ = y. clone ( ) ;
400+ assert_eq ! ( GLOBAL . load( Ordering :: Relaxed ) , 0 ) ;
401+ y. write ( InstrumentedClone ( 0 ) ) ;
402+ assert_eq ! ( GLOBAL . load( Ordering :: Relaxed ) , 0 ) ;
403+ assert_eq ! ( y. clone( ) . as_slice( ) , [ InstrumentedClone ( 1 ) ] ) ;
404+ assert_eq ! ( GLOBAL . load( Ordering :: Relaxed ) , 1 ) ;
405+ y. write ( InstrumentedClone ( 0 ) ) ;
406+ assert_eq ! ( GLOBAL . load( Ordering :: Relaxed ) , 1 ) ;
407+ assert_eq ! (
408+ y. clone( ) . as_slice( ) ,
409+ [ InstrumentedClone ( 1 ) , InstrumentedClone ( 1 ) ]
410+ ) ;
411+ assert_eq ! ( GLOBAL . load( Ordering :: Relaxed ) , 3 ) ;
412+ assert_eq ! (
413+ y. clone( ) . clone( ) . clone( ) . as_slice( ) ,
414+ [ InstrumentedClone ( 3 ) , InstrumentedClone ( 3 ) ]
415+ ) ;
416+ assert_eq ! ( GLOBAL . load( Ordering :: Relaxed ) , 9 ) ;
417+ }
418+
353419 #[ test]
354420 fn recent ( ) {
355421 let mut x: HistoryBuffer < u8 , 4 > = HistoryBuffer :: new ( ) ;
@@ -430,4 +496,30 @@ mod tests {
430496 }
431497 }
432498 }
499+
500+ #[ test]
501+ fn partial_eq ( ) {
502+ let mut x: HistoryBuffer < u8 , 3 > = HistoryBuffer :: new ( ) ;
503+ let mut y: HistoryBuffer < u8 , 3 > = HistoryBuffer :: new ( ) ;
504+ assert_eq ! ( x, y) ;
505+ x. write ( 1 ) ;
506+ assert_ne ! ( x, y) ;
507+ y. write ( 1 ) ;
508+ assert_eq ! ( x, y) ;
509+ for _ in 0 ..4 {
510+ x. write ( 2 ) ;
511+ assert_ne ! ( x, y) ;
512+ for i in 0 ..5 {
513+ x. write ( i) ;
514+ y. write ( i) ;
515+ }
516+ assert_eq ! (
517+ x,
518+ y,
519+ "{:?} {:?}" ,
520+ x. iter( ) . collect:: <Vec <_>>( ) ,
521+ y. iter( ) . collect:: <Vec <_>>( )
522+ ) ;
523+ }
524+ }
433525}
0 commit comments