pub trait GcPtrEq<Other> {
fn ptr_eq(x: &Self, y: &Other) -> bool;
}
pub trait GcMemberPtrNew<StrongPointer, MemberPointer> {
fn new_pointer(&self, p: StrongPointer) -> MemberPointer;
}
#[cfg(test)]
mod tests {
use crate::prelude::*;
#[cfg(feature = "multi_thread")]
use crate::sync::{GcMtMemberPtr, GcMtPtr};
use crate::{GcMemberPtr, GcPtr};
#[cfg(all(not(feature = "weak_pointer"), not(feature = "multi_thread")))]
trait AllGcPtrEq<T>
where
T: 'static + Send + Sync,
Self: GcPtrEq<GcPtr<T>>,
Self: GcPtrEq<GcMemberPtr<T>>,
{
}
#[cfg(all(feature = "multi_thread", not(feature = "weak_pointer")))]
trait AllGcPtrEq<T>
where
T: 'static + Send + Sync,
Self: GcPtrEq<GcPtr<T>>,
Self: GcPtrEq<GcMtPtr<T>>,
Self: GcPtrEq<GcMemberPtr<T>>,
Self: GcPtrEq<GcMtMemberPtr<T>>,
{
}
#[cfg(all(feature = "weak_pointer", not(feature = "multi_thread")))]
trait AllGcPtrEq<T>
where
T: 'static + Send + Sync,
Self: GcPtrEq<GcPtr<T>>,
Self: GcPtrEq<GcMemberPtr<T>>,
Self: GcPtrEq<crate::Weak<T>>,
{
}
#[cfg(all(feature = "weak_pointer", feature = "multi_thread"))]
trait AllGcPtrEq<T>
where
T: 'static + Send + Sync,
Self: GcPtrEq<GcPtr<T>>,
Self: GcPtrEq<GcMtPtr<T>>,
Self: GcPtrEq<GcMemberPtr<T>>,
Self: GcPtrEq<GcMtMemberPtr<T>>,
Self: GcPtrEq<crate::Weak<T>>,
Self: GcPtrEq<crate::sync::Weak<T>>,
{
}
impl<T> AllGcPtrEq<T> for GcPtr<T> where T: 'static + Send + Sync {}
#[cfg(feature = "multi_thread")]
impl<T> AllGcPtrEq<T> for GcMtPtr<T> where T: 'static + Send + Sync {}
impl<T> AllGcPtrEq<T> for GcMemberPtr<T> where T: 'static + Send + Sync {}
#[cfg(feature = "multi_thread")]
impl<T> AllGcPtrEq<T> for GcMtMemberPtr<T> where T: 'static + Send + Sync {}
#[cfg(feature = "weak_pointer")]
impl<T> AllGcPtrEq<T> for crate::Weak<T> where T: 'static + Send + Sync {}
#[cfg(all(feature = "multi_thread", feature = "weak_pointer"))]
impl<T> AllGcPtrEq<T> for crate::sync::Weak<T> where T: 'static + Send + Sync {}
struct TestData {}
struct MemberTestData {
member_ptr: GcMemberPtr<TestData>,
}
impl MemberTestData {
fn new(test_data: GcPtr<TestData>) -> GcPtr<MemberTestData> {
GcPtr::new(|metadata| MemberTestData {
member_ptr: metadata.new_pointer(test_data),
})
}
}
#[cfg(feature = "multi_thread")]
struct MtMemberTestData {
member_ptr: GcMtMemberPtr<TestData>,
}
#[cfg(feature = "multi_thread")]
impl MtMemberTestData {
fn new(test_data: GcMtPtr<TestData>) -> GcMtPtr<MtMemberTestData> {
GcMtPtr::new(|metadata| MtMemberTestData {
member_ptr: metadata.new_pointer(test_data),
})
}
}
struct TestPointers {
ptr: GcPtr<TestData>,
#[cfg(feature = "multi_thread")]
mt_ptr: GcMtPtr<TestData>,
mtd: GcPtr<MemberTestData>,
#[cfg(feature = "multi_thread")]
mt_mtd: GcMtPtr<MtMemberTestData>,
#[cfg(feature = "weak_pointer")]
weak: crate::Weak<TestData>,
#[cfg(all(feature = "multi_thread", feature = "weak_pointer"))]
mt_weak: crate::sync::Weak<TestData>,
}
impl Default for TestPointers {
#[cfg(not(feature = "multi_thread"))]
fn default() -> Self {
let main_ptr = GcPtr::new(|_| TestData {});
TestPointers {
ptr: main_ptr.clone(),
mtd: MemberTestData::new(main_ptr.clone()),
#[cfg(feature = "weak_pointer")]
weak: GcPtr::downgrade(&main_ptr),
}
}
#[cfg(feature = "multi_thread")]
fn default() -> Self {
let main_ptr = GcMtPtr::new(|_| TestData {});
TestPointers {
ptr: main_ptr.clone().into(),
mt_ptr: main_ptr.clone(),
mtd: MemberTestData::new(main_ptr.clone().into()),
mt_mtd: MtMemberTestData::new(main_ptr.clone()),
#[cfg(feature = "weak_pointer")]
weak: GcPtr::downgrade(&main_ptr.clone().into()),
#[cfg(feature = "weak_pointer")]
mt_weak: GcMtPtr::downgrade(&main_ptr),
}
}
}
fn assert_all_eq<Ptr>(ptr: &Ptr, tp: &TestPointers)
where
Ptr: AllGcPtrEq<TestData>,
{
assert!(Ptr::ptr_eq(&ptr, &tp.ptr));
#[cfg(feature = "multi_thread")]
assert!(Ptr::ptr_eq(&ptr, &tp.mt_ptr));
assert!(Ptr::ptr_eq(&ptr, &tp.mtd.member_ptr));
#[cfg(feature = "multi_thread")]
assert!(Ptr::ptr_eq(&ptr, &tp.mt_mtd.member_ptr));
#[cfg(feature = "weak_pointer")]
assert!(Ptr::ptr_eq(&ptr, &tp.weak));
#[cfg(all(feature = "multi_thread", feature = "weak_pointer"))]
assert!(Ptr::ptr_eq(&ptr, &tp.mt_weak));
}
fn assert_all_ne<Ptr>(ptr: &Ptr, tp: &TestPointers)
where
Ptr: AllGcPtrEq<TestData>,
{
assert!(!Ptr::ptr_eq(&ptr, &tp.ptr));
#[cfg(feature = "multi_thread")]
assert!(!Ptr::ptr_eq(&ptr, &tp.mt_ptr));
assert!(!Ptr::ptr_eq(&ptr, &tp.mtd.member_ptr));
#[cfg(feature = "multi_thread")]
assert!(!Ptr::ptr_eq(&ptr, &tp.mt_mtd.member_ptr));
#[cfg(feature = "weak_pointer")]
assert!(!Ptr::ptr_eq(&ptr, &tp.weak));
#[cfg(all(feature = "multi_thread", feature = "weak_pointer"))]
assert!(!Ptr::ptr_eq(&ptr, &tp.mt_weak));
}
#[test]
fn ptr_eq() {
let tp = TestPointers::default();
let other = TestPointers::default();
assert_all_eq(&tp.ptr.clone(), &tp);
assert_all_ne(&tp.ptr.clone(), &other);
#[cfg(feature = "multi_thread")]
assert_all_eq(&tp.mt_ptr.clone(), &tp);
#[cfg(feature = "multi_thread")]
assert_all_ne(&tp.mt_ptr.clone(), &other);
assert_all_eq(&tp.mtd.member_ptr, &tp);
assert_all_ne(&tp.mtd.member_ptr, &other);
#[cfg(feature = "multi_thread")]
assert_all_eq(&tp.mt_mtd.member_ptr, &tp);
#[cfg(feature = "multi_thread")]
assert_all_ne(&tp.mt_mtd.member_ptr, &other);
#[cfg(feature = "weak_pointer")]
assert_all_eq(&tp.weak.clone(), &tp);
#[cfg(feature = "weak_pointer")]
assert_all_ne(&tp.weak.clone(), &other);
#[cfg(all(feature = "multi_thread", feature = "weak_pointer"))]
assert_all_eq(&tp.mt_weak.clone(), &tp);
#[cfg(all(feature = "multi_thread", feature = "weak_pointer"))]
assert_all_ne(&tp.mt_weak.clone(), &other);
}
}