[][src]Struct abi_stable::sabi_types::StaticRef

#[repr(transparent)]pub struct StaticRef<T> { /* fields omitted */ }

A wrapper type for vtable static references, and other constants that have non-'static generic parameters but are safe to reference for the lifetime of T.

Purpose

This type is necessary because Rust doesn't understand that vtables live for 'static, even though they have non-'static type parameters.

Example

This defines a non-extensible vtable,using a StaticRef as the pointer to the vtable.

use abi_stable::{
    marker_type::ErasedObject,
    prefix_type::{PrefixTypeTrait,WithMetadata},
    sabi_types::StaticRef,
    utils::transmute_mut_reference,
    StableAbi,
    sabi_extern_fn,
    staticref,
};

use std::{
    marker::PhantomData,
    ops::Deref,
};

fn main(){
    let boxed = BoxLike::new("foo".to_string());
    assert_eq!(boxed.as_str(), "foo");
}

/// An ffi-safe `Box<T>`
#[repr(C)]
#[derive(StableAbi)]
pub struct BoxLike<T> {
    data: *mut T,
    
    vtable: StaticRef<VTable<T>>,

    _marker: PhantomData<T>,
}

impl<T> BoxLike<T> {
    pub fn new(value: T) -> Self {
        Self{
            data: Box::into_raw(Box::new(value)),
            vtable: VTable::<T>::VTABLE,
            _marker: PhantomData,
        }
    }
}

impl<T> Drop for BoxLike<T> {
    fn drop(&mut self){
        unsafe{
            (self.vtable.drop_)(self.data);
        }
    }
}

impl<T> Deref for BoxLike<T> {
    type Target = T;

    fn deref(&self) -> &T {
        unsafe{
            &*self.data
        }
    }
}

#[repr(C)]
#[derive(StableAbi)]
pub struct VTable<T>{
    drop_:unsafe extern "C" fn(*mut T),
}

impl<T> VTable<T> {
    // The `staticref` macro declares a `StaticRef<VTable<T>>` constant.
    staticref!(const VTABLE: Self = Self{
        drop_: drop_box::<T>,
    });
}


#[sabi_extern_fn]
unsafe fn drop_box<T>(object: *mut T){
    drop(Box::from_raw(object));
}

Implementations

impl<T, P> StaticRef<WithMetadata_<T, P>>[src]

pub const fn as_prefix(self) -> PrefixRef<P>[src]

Constructs a PrefixRef<P> from self.

This is most useful when you have a generic type that isn't 'static for type system reasons, but lives for the entire program.

Example

use abi_stable::{
    for_examples::{Module, Module_Ref},
    prefix_type::{PrefixRef, PrefixTypeTrait, WithMetadata},
    std_types::{RNone, RStr},
    staticref,
};
 
// The `staticref` invocation here declares a `StaticRef<WithMetadata<Module>>` constant.
const WITH_META: &WithMetadata<Module> = &WithMetadata::new(
    PrefixTypeTrait::METADATA,
    Module {
        first: RNone,
        second: RStr::from_str("hello"),
        third: 100,
    },
);
 
const MOD: Module_Ref = Module_Ref(WITH_META.static_as_prefix());
 
assert_eq!(MOD.first(), RNone);
assert_eq!(MOD.second().as_str(), "hello");
 

impl<T> StaticRef<T>[src]

pub const unsafe fn from_raw(ref_: *const T) -> Self[src]

Constructs this StaticRef from a raw pointer.

Safety

You must ensure that the raw pointer is valid for the entire program's lifetime.

Example

use abi_stable::sabi_types::StaticRef;

struct GetPtr<T>(T);

impl<T> GetPtr<T>{
    const PTR:*const Option<T>=&None;

    const STATIC:StaticRef<Option<T>>=unsafe{
        StaticRef::from_raw(Self::PTR)
    };
}

pub const fn new(ref_: &'static T) -> Self[src]

Constructs this StaticRef from a static reference

This implicitly requires that T:'static.

Example

use abi_stable::sabi_types::StaticRef;

struct GetPtr<T>(T);

impl<T> GetPtr<T>
where
    T:'static
{
    const REF:&'static Option<T>=&None;

    const STATIC:StaticRef<Option<T>>=
        StaticRef::new(Self::REF);
}

pub fn leak_value(val: T) -> Self[src]

Creates a StaticRef by heap allocating and leaking val.

pub fn get<'a>(self) -> &'a T[src]

Gets access to the reference.

This returns &'a T instead of &'static T to support vtables of non-'static types.

Example

use abi_stable::sabi_types::StaticRef;

struct GetPtr<T>(T);

impl<T> GetPtr<T>{
    const PTR:*const Option<T>=&None;

    const STATIC:StaticRef<Option<T>>=unsafe{
        StaticRef::from_raw(Self::PTR)
    };
}

let reference:&'static Option<String>=
    GetPtr::<String>::STATIC.get();

pub const fn get_raw(self) -> *const T[src]

Gets access to the referenced value,as a raw pointer.

Example

use abi_stable::sabi_types::StaticRef;
use std::convert::Infallible;

struct GetPtr<T>(T);

impl<T> GetPtr<T>{
    const PTR:*const Option<T>=&None;

    const STATIC:StaticRef<Option<T>>=unsafe{
        StaticRef::from_raw(Self::PTR)
    };
}

let reference:*const Option<Infallible>=
    GetPtr::<Infallible>::STATIC.get_raw();

pub const unsafe fn transmute_ref<U>(self) -> StaticRef<U>[src]

Transmutes this StaticRef<T> to a StaticRef<U>.

Safety

StaticRef has the same rules that references have regarding transmuting from one type to another:

Example

use abi_stable::sabi_types::StaticRef;

struct GetPtr<T>(T);

impl<T> GetPtr<T>{
    const PTR:*const Option<T>=&None;

    const STATIC:StaticRef<Option<T>>=unsafe{
        StaticRef::from_raw(Self::PTR)
    };
}

let reference:StaticRef<Option<[();0xFFF_FFFF]>>=unsafe{
    GetPtr::<()>::STATIC
        .transmute_ref::<Option<[();0xFFF_FFFF]>>()
};

Trait Implementations

impl<T, U> CanTransmuteElement<U> for StaticRef<T>[src]

type TransmutedPtr = StaticRef<U>

The type of the pointer after it's element type has been changed.

impl<T> Clone for StaticRef<T>[src]

impl<T> Copy for StaticRef<T>[src]

impl<T> Debug for StaticRef<T> where
    T: Debug
[src]

impl<T> Deref for StaticRef<T>[src]

type Target = T

The resulting type after dereferencing.

impl<T> Display for StaticRef<T> where
    T: Display
[src]

impl<T> Eq for StaticRef<T> where
    T: Eq
[src]

impl<T> GetPointerKind for StaticRef<T>[src]

type Kind = PK_Reference

The kind of the pointer.

impl<T> GetStaticEquivalent_ for StaticRef<T> where
    T: __StableAbi
[src]

type StaticEquivalent = _static_StaticRef<__GetStaticEquivalent<T>>

impl<T> Hash for StaticRef<T> where
    T: Hash
[src]

impl<T> Ord for StaticRef<T> where
    T: Ord
[src]

impl<T> PartialEq<StaticRef<T>> for StaticRef<T> where
    T: PartialEq
[src]

impl<T> PartialOrd<StaticRef<T>> for StaticRef<T> where
    T: PartialOrd
[src]

impl<'a, T: 'a> Send for StaticRef<T> where
    &'a T: Send
[src]

impl<T> StableAbi for StaticRef<T> where
    T: __StableAbi
[src]

type IsNonZeroType = <NonNull<T> as __StableAbi>::IsNonZeroType

Whether this type has a single invalid bit-pattern. Read more

impl<'a, T: 'a> Sync for StaticRef<T> where
    &'a T: Sync
[src]

Auto Trait Implementations

impl<T> RefUnwindSafe for StaticRef<T> where
    T: RefUnwindSafe
[src]

impl<T> Unpin for StaticRef<T>[src]

impl<T> UnwindSafe for StaticRef<T> where
    T: RefUnwindSafe
[src]

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<'a, T> BorrowOwned<'a> for T where
    T: 'a + Clone
[src]

type ROwned = T

The owned type, stored in RCow::Owned

type RBorrowed = &'a T

The borrowed type, stored in RCow::Borrowed

impl<T> From<T> for T[src]

impl<T> GetWithMetadata for T[src]

type ForSelf = WithMetadata_<T, T>

This is always WithMetadata_<Self, Self>

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> SelfOps for T where
    T: ?Sized
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<This> TransmuteElement for This where
    This: ?Sized
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The error type returned when the conversion fails.

impl<T> TypeIdentity for T where
    T: ?Sized
[src]

type Type = T

The same type as Self. Read more

impl<This> ValidTag_Bounds for This where
    This: Debug + Clone + PartialEq<This>, 
[src]