NonPersistent

Struct NonPersistent 

Source
pub struct NonPersistent<T: ?Sized>(/* private fields */);
Expand description

Smart pointer around a nonpersistent allocation of T.

Rustmex marks all heap allocations as persistent — for most allocations, we want to be the only owner of the data. We know how to free the memory of our types, and will do so when we’re done with it; we don’t need Matlab’s help.

But there are some circumstances where we can’t, and thus where a nonpersistent allocation is required: for instance with divergent MEX API functions. If you need to pass some data to such a function which is dynamic and must be behind a pointer, you can use this type.

It is specifically meant to work with those API functions; it is not a general usage smart pointer. To make it slightly less of a footcannon, it implements some guardrails (such as Drop in case the function is conditionally divergent, or if you forgot to pass it into one you wont leak memory) — but it remains a footgun nonentheless.

A footgun it is, as alluded to, because it fundamentally does not comply with the basic principles of safe Rust code, i.e. there can be only one owner of the data. With NonPersistent, you now share ownership with Matlab’s garbage collector — which, since it does not know about you, may pull the rug out from underneath you at any point (especially if you persist the object after MexFunction returns). Maybe not such a footgun, but more of a ticking time bomb. All constructor methods are therefore marked as unsafe; you must understand that memory safety is now up to you to uphold.

To make it somewhat ergonomic to work with, it implements a basic set of traits (PartialEq, Display, AsRef, etc) by forwarding those to the inner types. It’s basically a meager Box.

It is also Send and Sync if the inner types are. While this has can be used to hold on to the NonPersistent longer than the lifetime of the MexFunction, it is not per se memory unsafe.

In short: only use for good, and only when absolutely required.

Implementations§

Source§

impl<T> NonPersistent<T>

Source

pub unsafe fn new(t: T) -> Self

Create a new non-persistent memory allocation.

Source§

impl<T: Copy> NonPersistent<T>

Source

pub fn inner(np: NonPersistent<T>) -> T

Return the inner value, and free the allocation

Source§

impl NonPersistent<[u8]>

Source

pub unsafe fn from_stringish<B: AsRef<[u8]>>(b: B, append_null: bool) -> Self

Construct a NonPersistent byte buffer from stringish types, optionally with a nul byte terminator.

Some MEX API functions expect a C string, while most of rust works with string slices. Instead of copying to a CString first (to add the nul terminator), directly copy into a nonpersistent buffer, eliding one copy.

Note that this function provides fewer guarantees than CString does.

Source§

impl<T: ?Sized> NonPersistent<T>

Source

pub unsafe fn ptr(np: &NonPersistent<T>) -> *const T

Get the inner pointer for communication with the MEX api. Marked as unsafe since the pointer may be used to create an alias to the data, so the invariants assumed by Send and Sync no longer hold.

Source

pub unsafe fn mut_ptr(np: &mut NonPersistent<T>) -> *mut T

Get the inner pointer as mutable for communcation with the MEX api. Marked as unsafe since the pointer may be used to create an alias to the data, so the invariants assumed by Send and Sync no longer hold.

Source

pub fn persist(np: NonPersistent<T>) -> Box<T>

Persist the current allocation by turning it into a “normal” box.

This does not copy the allocation, since there is a function to mark an allocation as persistent (but not the other way around).

Trait Implementations§

Source§

impl<T: ?Sized> AsMut<T> for NonPersistent<T>

Source§

fn as_mut(&mut self) -> &mut T

Converts this type into a mutable reference of the (usually inferred) input type.
Source§

impl<T: ?Sized> AsRef<T> for NonPersistent<T>

Source§

fn as_ref(&self) -> &T

Converts this type into a shared reference of the (usually inferred) input type.
Source§

impl<T> Debug for NonPersistent<T>
where T: Debug + ?Sized,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T: ?Sized> Deref for NonPersistent<T>

Source§

type Target = T

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Self::Target

Dereferences the value.
Source§

impl<T: ?Sized> DerefMut for NonPersistent<T>

Source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
Source§

impl<T> Display for NonPersistent<T>
where T: Display + ?Sized,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T: ?Sized> Drop for NonPersistent<T>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl<T, Other> PartialEq<Other> for NonPersistent<T>
where T: PartialEq<Other> + ?Sized,

Source§

fn eq(&self, other: &Other) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<T> Eq for NonPersistent<T>
where T: Eq + PartialEq<NonPersistent<T>> + ?Sized,

Source§

impl<T> Send for NonPersistent<T>
where T: Send + ?Sized,

Source§

impl<T> Sync for NonPersistent<T>
where T: Sync + ?Sized,

Auto Trait Implementations§

§

impl<T> Freeze for NonPersistent<T>
where T: ?Sized,

§

impl<T> RefUnwindSafe for NonPersistent<T>
where T: RefUnwindSafe + ?Sized,

§

impl<T> Unpin for NonPersistent<T>
where T: ?Sized,

§

impl<T> UnwindSafe for NonPersistent<T>
where T: RefUnwindSafe + ?Sized,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

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

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.