Skip to content

Commit

Permalink
Merge pull request #173 from anna-hope/master
Browse files Browse the repository at this point in the history
Add Gc::as_ptr
  • Loading branch information
Manishearth authored Oct 3, 2023
2 parents 7357c28 + e02c562 commit 9ce4e3c
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 0 deletions.
18 changes: 18 additions & 0 deletions gc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,24 @@ impl<T: ?Sized> Gc<T> {
pub fn ptr_eq(this: &Gc<T>, other: &Gc<T>) -> 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<T>) -> *const T {
let ptr = this.inner_ptr();
GcBox::value_ptr(ptr)
}
}

/// Returns the given pointer with its root bit cleared.
Expand Down
28 changes: 28 additions & 0 deletions gc/tests/gc_semantics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<A>);

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);
}

0 comments on commit 9ce4e3c

Please sign in to comment.