From e02c562bb9133047cee348f3ea6bd43c3ecaa75d Mon Sep 17 00:00:00 2001 From: Anna Melnikov Date: Tue, 3 Oct 2023 16:19:57 -0500 Subject: [PATCH] Add Gc::as_ptr --- gc/src/lib.rs | 18 ++++++++++++++++++ gc/tests/gc_semantics.rs | 28 ++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/gc/src/lib.rs b/gc/src/lib.rs index 9bbcd31..17ef897 100644 --- a/gc/src/lib.rs +++ b/gc/src/lib.rs @@ -110,6 +110,24 @@ impl Gc { pub fn ptr_eq(this: &Gc, other: &Gc) -> bool { GcBox::ptr_eq(this.inner(), other.inner()) } + + /// Provides a raw pointer to the data. + /// + /// # Examples + /// + /// ``` + /// use gc::Gc; + /// + /// let x = Gc::new("hello".to_owned()); + /// let y = x.clone(); + /// let x_ptr = Gc::as_ptr(&x); + /// assert_eq!(x_ptr, Gc::as_ptr(&y)); + /// assert_eq!(unsafe { &*x_ptr }, "hello"); + /// ``` + pub fn as_ptr(this: &Gc) -> *const T { + let ptr = this.inner_ptr(); + GcBox::value_ptr(ptr) + } } /// Returns the given pointer with its root bit cleared. diff --git a/gc/tests/gc_semantics.rs b/gc/tests/gc_semantics.rs index ca6d50c..3934d38 100644 --- a/gc/tests/gc_semantics.rs +++ b/gc/tests/gc_semantics.rs @@ -289,3 +289,31 @@ fn ptr_eq() { assert!(!Gc::ptr_eq(&b.0, &b2.0)); assert!(!Gc::ptr_eq(&b.0, &a2)); } + +#[test] +fn as_ptr() { + #[derive(Finalize, Trace)] + struct A; + + #[derive(Finalize, Trace)] + struct B(Gc); + + let a = Gc::new(A); + let aa = a.clone(); + let a_ptr = Gc::as_ptr(&a); + assert_eq!(a_ptr, Gc::as_ptr(&aa)); + + let b = Gc::new(B(a.clone())); + assert_eq!(a_ptr, Gc::as_ptr(&b.0)); + let bb = Gc::new(B(a.clone())); + assert_eq!(a_ptr, Gc::as_ptr(&bb.0)); + + let a2 = Gc::new(A); + let a2_ptr = Gc::as_ptr(&a2); + assert_ne!(a_ptr, a2_ptr); + let b2 = Gc::new(B(a2.clone())); + assert_eq!(a2_ptr, Gc::as_ptr(&b2.0)); + assert_ne!(a_ptr, Gc::as_ptr(&b2.0)); + assert_ne!(Gc::as_ptr(&b.0), Gc::as_ptr(&b2.0)); + assert_ne!(Gc::as_ptr(&b.0), a2_ptr); +}