#[cfg(feature = "multi_thread")]
use super::MTObject;
#[cfg(feature = "multi_thread")]
use super::MTObjectIntf;
use super::{Object, ObjectIntf};
use crate::util::NonNull;
use std::mem;
use std::ops::Deref;
use std::pin::Pin;
pub(crate) struct ObjectPtr<T>
where
T: 'static,
{
ptr: NonNull<Object<T>>,
}
#[cfg(feature = "multi_thread")]
pub(crate) struct MTObjectPtr<T>
where
T: 'static,
{
ptr: NonNull<MTObject<T>>,
}
pub(crate) struct DynObjectPtr {
ptr: NonNull<dyn ObjectIntf>,
}
#[cfg(feature = "multi_thread")]
pub(crate) struct DynMTObjectPtr {
ptr: NonNull<dyn Send + Sync + MTObjectIntf>,
}
#[cfg(feature = "multi_thread")]
unsafe impl<T> Send for MTObjectPtr<T>
where
MTObject<T>: Send + Sync,
T: 'static,
{
}
#[cfg(feature = "multi_thread")]
unsafe impl<T> Sync for MTObjectPtr<T>
where
MTObject<T>: Send + Sync,
T: 'static,
{
}
#[cfg(feature = "multi_thread")]
unsafe impl Send for DynMTObjectPtr {}
#[cfg(feature = "multi_thread")]
unsafe impl Sync for DynMTObjectPtr {}
impl<T> From<ObjectPtr<T>> for DynObjectPtr
where
T: 'static,
{
#[inline]
fn from(obj_ptr: ObjectPtr<T>) -> Self {
let obj_ptr = mem::ManuallyDrop::new(obj_ptr);
DynObjectPtr {
ptr: NonNull::from_ptr(obj_ptr.ptr.as_ptr()),
}
}
}
#[cfg(feature = "multi_thread")]
impl<T> From<MTObjectPtr<T>> for DynMTObjectPtr
where
T: 'static + Send + Sync,
{
#[inline]
fn from(obj_ptr: MTObjectPtr<T>) -> Self {
let obj_ptr = mem::ManuallyDrop::new(obj_ptr);
DynMTObjectPtr {
ptr: NonNull::from_ptr(obj_ptr.ptr.as_ptr()),
}
}
}
impl<T> From<Pin<ObjectPtr<T>>> for Pin<DynObjectPtr>
where
T: 'static,
{
#[inline]
fn from(obj_ptr: Pin<ObjectPtr<T>>) -> Self {
unsafe { Pin::new_unchecked(DynObjectPtr::from(Pin::into_inner_unchecked(obj_ptr))) }
}
}
#[cfg(feature = "multi_thread")]
impl<T> From<Pin<MTObjectPtr<T>>> for Pin<DynMTObjectPtr>
where
T: 'static + Send + Sync,
{
#[inline]
fn from(obj_ptr: Pin<MTObjectPtr<T>>) -> Self {
unsafe { Pin::new_unchecked(DynMTObjectPtr::from(Pin::into_inner_unchecked(obj_ptr))) }
}
}
impl<T> Drop for ObjectPtr<T>
where
T: 'static,
{
fn drop(&mut self) {
unsafe {
self.ptr.as_ref().refcount_dec(); }
}
}
#[cfg(feature = "multi_thread")]
impl<T> Drop for MTObjectPtr<T>
where
T: 'static,
{
fn drop(&mut self) {
unsafe {
self.ptr.as_ref().refcount_dec(); }
}
}
impl Drop for DynObjectPtr {
fn drop(&mut self) {
unsafe {
self.ptr.as_ref().refcount_dec(); }
}
}
#[cfg(feature = "multi_thread")]
impl Drop for DynMTObjectPtr {
fn drop(&mut self) {
unsafe {
self.ptr.as_ref().refcount_dec(); }
}
}
impl<T> Deref for ObjectPtr<T>
where
T: 'static,
{
type Target = Object<T>;
fn deref(&self) -> &Self::Target {
unsafe { self.ptr.as_ref() }
}
}
#[cfg(feature = "multi_thread")]
impl<T> Deref for MTObjectPtr<T>
where
T: 'static,
{
type Target = MTObject<T>;
fn deref(&self) -> &Self::Target {
unsafe { self.ptr.as_ref() }
}
}
impl Deref for DynObjectPtr {
type Target = dyn ObjectIntf;
fn deref(&self) -> &Self::Target {
unsafe { self.ptr.as_ref() }
}
}
#[cfg(feature = "multi_thread")]
impl Deref for DynMTObjectPtr {
type Target = dyn Send + Sync + MTObjectIntf;
fn deref(&self) -> &Self::Target {
unsafe { self.ptr.as_ref() }
}
}
impl<T> Clone for ObjectPtr<T>
where
T: 'static,
{
fn clone(&self) -> Self {
unsafe { self.ptr.as_ref().refcount_inc() };
ObjectPtr {
ptr: self.ptr.clone(),
}
}
}
#[cfg(feature = "multi_thread")]
impl<T> Clone for MTObjectPtr<T>
where
T: 'static,
{
fn clone(&self) -> Self {
unsafe { self.ptr.as_ref().refcount_inc() };
MTObjectPtr {
ptr: self.ptr.clone(),
}
}
}
impl Clone for DynObjectPtr {
fn clone(&self) -> Self {
unsafe { self.ptr.as_ref().refcount_inc() };
DynObjectPtr {
ptr: self.ptr.clone(),
}
}
}
#[cfg(feature = "multi_thread")]
impl Clone for DynMTObjectPtr {
fn clone(&self) -> Self {
unsafe { self.ptr.as_ref().refcount_inc() };
DynMTObjectPtr {
ptr: self.ptr.clone(),
}
}
}
impl<T> ObjectPtr<T>
where
T: 'static,
{
pub(super) fn new(obj_ref: Pin<&Object<T>>) -> Pin<Self> {
obj_ref.refcount_inc();
unsafe {
Pin::new_unchecked(ObjectPtr {
ptr: NonNull::from_ref(obj_ref.get_ref()),
})
}
}
}
#[cfg(feature = "multi_thread")]
impl<T> MTObjectPtr<T>
where
T: 'static + Send + Sync,
{
pub(super) fn new(obj_ref: Pin<&MTObject<T>>) -> Pin<Self> {
obj_ref.refcount_inc();
unsafe {
Pin::new_unchecked(MTObjectPtr {
ptr: NonNull::from_ref(obj_ref.get_ref()),
})
}
}
}