use crate::generation::{Generation, GenerationPtr};
use crate::object::Object;
use crate::object::metadata::Metadata;
use crate::pointer::GcPtr;
use std::fmt;
#[cfg(feature = "weak_pointer")]
use crate::pointer::Weak;
#[derive(Clone)]
pub struct GenerationRef {
ptr: GenerationPtr,
}
impl GenerationRef {
#[inline]
pub(crate) const fn new_from_ptr(ptr: GenerationPtr) -> GenerationRef {
GenerationRef { ptr }
}
#[inline]
pub fn make<T, Factory>(&self, factory: Factory) -> GcPtr<T>
where
T: 'static,
Factory: FnOnce(Metadata) -> T,
{
unsafe { GcPtr::new_from_raw(Object::new_ptr(1, factory, Some(self.ptr.clone()))) }
}
#[cfg(feature = "weak_pointer")]
#[inline]
pub fn make_cyclic<T, Factory>(&self, factory: Factory) -> GcPtr<T>
where
T: 'static,
Factory: FnOnce(Metadata, Weak<T>) -> T,
{
unsafe { GcPtr::new_from_raw(Object::new_cyclic_ptr(1, factory, Some(self.ptr.clone()))) }
}
}
impl Default for GenerationRef {
#[allow(
clippy::missing_inline_in_public_items,
reason = "Always performs an allocation."
)]
fn default() -> Self {
Self::new_from_ptr(Generation::new())
}
}
impl PartialEq for GenerationRef {
#[inline]
fn eq(&self, other: &Self) -> bool {
GenerationPtr::ptr_eq(&self.ptr, &other.ptr)
}
}
impl Eq for GenerationRef {}
impl fmt::Debug for GenerationRef {
#[allow(
clippy::missing_inline_in_public_items,
reason = "Keeps the generation internals nicely hidden, and also if I messed up and we get into an infinite recursion, seeing this in the stack trace will be helpful."
)]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
fmt::Debug::fmt(&self.ptr, f)
}
}
#[cfg(feature = "multi_thread")]
pub(crate) mod sync {
use crate::generation::{MTGeneration, MTGenerationPtr};
use crate::object::MTObject;
use crate::object::metadata::sync::Metadata;
use crate::pointer::sync::GcMtPtr;
use std::fmt;
#[cfg(feature = "weak_pointer")]
use crate::pointer::sync::Weak;
#[derive(Clone)]
pub struct GenerationRef {
ptr: MTGenerationPtr,
}
impl GenerationRef {
#[inline]
pub(crate) const fn new_from_ptr(ptr: MTGenerationPtr) -> GenerationRef {
GenerationRef { ptr }
}
#[inline]
pub fn make<T, Factory>(&self, factory: Factory) -> GcMtPtr<T>
where
T: 'static + Send + Sync,
Factory: FnOnce(Metadata) -> T,
{
unsafe { GcMtPtr::new_from_raw(MTObject::new_ptr(1, factory, Some(self.ptr.clone()))) }
}
#[cfg(feature = "weak_pointer")]
#[inline]
pub fn make_cyclic<T, Factory>(&self, factory: Factory) -> GcMtPtr<T>
where
T: 'static + Send + Sync,
Factory: FnOnce(Metadata, Weak<T>) -> T,
{
unsafe {
GcMtPtr::new_from_raw(MTObject::new_cyclic_ptr(1, factory, Some(self.ptr.clone())))
}
}
}
impl Default for GenerationRef {
#[allow(
clippy::missing_inline_in_public_items,
reason = "Always performs an allocation."
)]
fn default() -> Self {
Self::new_from_ptr(MTGeneration::new())
}
}
impl PartialEq for GenerationRef {
#[inline]
fn eq(&self, other: &Self) -> bool {
MTGenerationPtr::ptr_eq(&self.ptr, &other.ptr)
}
}
impl Eq for GenerationRef {}
impl fmt::Debug for GenerationRef {
#[allow(
clippy::missing_inline_in_public_items,
reason = "Keeps the generation internals nicely hidden, and also if I messed up and we get into an infinite recursion, seeing this in the stack trace will be helpful."
)]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
fmt::Debug::fmt(&self.ptr, f)
}
}
}