diff --git a/src/concurrency/chunked_ll.rs b/src/concurrency/chunked_ll.rs index 992640c..f4222ed 100644 --- a/src/concurrency/chunked_ll.rs +++ b/src/concurrency/chunked_ll.rs @@ -1,4 +1,3 @@ -use std::mem::{self, MaybeUninit}; use std::ptr; use std::sync::atomic::{AtomicPtr, AtomicUsize, Ordering}; use std::sync::Arc; @@ -236,14 +235,5 @@ impl ChunkedLinkedList { } fn initialize_values() -> [ArcSwapOption; CHUNK_SIZE] { - unsafe { - let mut data: [MaybeUninit>; CHUNK_SIZE] = - MaybeUninit::uninit().assume_init(); - - for elem in &mut data[..] { - ptr::write(elem.as_mut_ptr(), ArcSwapOption::new(None)); - } - - mem::transmute(data) - } + [(); CHUNK_SIZE].map(|_| ArcSwapOption::new(None)) } diff --git a/src/smart_ptr/deref_gc.rs b/src/smart_ptr/deref_gc.rs index df26a17..f1bbce9 100644 --- a/src/smart_ptr/deref_gc.rs +++ b/src/smart_ptr/deref_gc.rs @@ -7,10 +7,10 @@ use crate::{Finalize, Scan, Scanner, ToScan}; use std::any::{Any, TypeId}; use std::cmp::Ordering; -use std::fmt; use std::fmt::{Debug, Display, Formatter}; use std::hash::{Hash, Hasher}; use std::ops::Deref; +use std::{fmt, ptr}; /// A `Gc`, but with the ability to `Deref` to its contents! /// @@ -93,6 +93,14 @@ impl DerefGc { direct_ptr: ptr, } } + + /// `ptr_eq` lets you compare two `DerefGc`s for pointer equality. + /// + /// This has the same semantics as `ptr::eq` or `Arc::ptr_eq`. + #[must_use] + pub fn ptr_eq(&self, o: &Self) -> bool { + ptr::eq(self.direct_ptr, o.direct_ptr) + } } impl DerefGc { @@ -281,3 +289,25 @@ where (self.deref()).ge(other.deref()) } } + +#[cfg(test)] +mod test { + use crate::DerefGc; + + #[test] + #[allow(clippy::eq_op)] + fn test_eq() { + let a = DerefGc::new(1); + let b = DerefGc::new(1); + assert_eq!(a, a); + assert_eq!(b, b); + assert_eq!(a, b); + assert_eq!(b, a); + + assert!(a.ptr_eq(&a)); + assert!(b.ptr_eq(&b)); + assert!(!a.ptr_eq(&b)); + assert!(!b.ptr_eq(&a)); + assert!(a.ptr_eq(&a.clone())); + } +} diff --git a/src/smart_ptr/gc.rs b/src/smart_ptr/gc.rs index 66e3ccd..5e2dff3 100644 --- a/src/smart_ptr/gc.rs +++ b/src/smart_ptr/gc.rs @@ -5,10 +5,10 @@ use std::cmp::Ordering; use std::fmt::{self, Debug, Display, Formatter}; use std::hash::{Hash, Hasher}; use std::ops::Deref; -use std::sync; use std::sync::atomic; #[cfg(feature = "nightly-features")] use std::{marker::Unsize, ops::CoerceUnsized}; +use std::{ptr, sync}; use stable_deref_trait::StableDeref; @@ -218,6 +218,14 @@ impl Gc { } } + /// `ptr_eq` lets you compare two `Gc`s for pointer equality. + /// + /// This has the same semantics as `ptr::eq` or `Arc::ptr_eq`. + #[must_use] + pub fn ptr_eq(&self, o: &Self) -> bool { + ptr::eq(self.direct_ptr, o.direct_ptr) + } + pub(crate) fn assert_live(&self) { let ordering = atomic::Ordering::Relaxed; let is_deallocated = self.backing_handle.data().deallocated.load(ordering); @@ -623,4 +631,21 @@ mod test { let _: Gc>; let _: Gc>; } + + #[test] + #[allow(clippy::eq_op)] + fn test_eq() { + let a = Gc::new(1); + let b = Gc::new(1); + assert_eq!(a, a); + assert_eq!(b, b); + assert_eq!(a, b); + assert_eq!(b, a); + + assert!(a.ptr_eq(&a)); + assert!(b.ptr_eq(&b)); + assert!(!a.ptr_eq(&b)); + assert!(!b.ptr_eq(&a)); + assert!(a.ptr_eq(&a.clone())); + } }