Skip to main content

OwnedProtect

Struct OwnedProtect 

Source
pub struct OwnedProtect {
    sexp: SEXP,
    armed: bool,
    _nosend: PhantomData<Rc<()>>,
}
Expand description

A single-object RAII guard: PROTECT on create, UNPROTECT(1) on drop.

Use this for simple cases where you’re protecting a single value and don’t need the batching benefits of ProtectScope.

§Example

ⓘ
unsafe fn allocate_and_fill() -> SEXP {
    let guard = OwnedProtect::new(Rf_allocVector(REALSXP, 10));
    fill_vector(guard.get());
    // Return the SEXP - guard drops and unprotects on this line.
    // This is safe because no GC can occur between unprotect and return.
    guard.get()
}

§Warning: Stack Ordering

OwnedProtect uses UNPROTECT(1), which removes the top of the protection stack. If you have nested protections from other sources, the drop order matters!

For complex scenarios, prefer ProtectScope which unprotects all its values at once when dropped.

Fields§

§sexp: SEXP§armed: bool§_nosend: PhantomData<Rc<()>>

Implementations§

Source§

impl OwnedProtect

Source

pub unsafe fn new(x: SEXP) -> Self

Create a new protection guard for x.

Calls Rf_protect(x) immediately.

§Safety
  • Must be called from the R main thread
  • x must be a valid SEXP
Source

pub fn get(&self) -> SEXP

Get the protected SEXP.

Source

pub unsafe fn forget(self)

Escape hatch: do not UNPROTECT(1) on drop.

§Safety

Leaks one protection entry unless unprotected elsewhere.

Methods from Deref<Target = SEXP>§

Source

pub fn is_null_ptr(self) -> bool

Is this SEXP a C null pointer (address 0x0)?

This answers a pointer question, not an R question. An SEXP that R hands you (a .Call() argument, a list element, an attribute) is never a C null pointer: R’s NULL is the R_NilValue singleton, a real object at a non-zero address. A C null pointer only shows up where C code uses address zero for “nothing here”: an uninitialised static or field (SEXP::null()), an ALTREP data1/data2 slot that was never set, or an FFI function that returns NULL on failure.

To ask “is this R’s NULL?”, use SEXP::is_nil().

use miniextendr_api::SEXP;

let unset = SEXP::null();
assert!(unset.is_null_ptr());

There is no SEXP::is_null(): the name read like a test for R’s NULL, so it is gone on purpose.

ⓘ
use miniextendr_api::SEXP;

let unset = SEXP::null();
assert!(unset.is_null());

See also: SEXP::is_nil(), SEXP::is_null_or_nil(), SEXP::null()

Source

pub fn is_nil(self) -> bool

Is this SEXP R’s NULL (R_NilValue)?

This is the check for an R value: an optional argument that defaults to NULL, an absent attribute, an empty list slot. It compares the address against the R_NilValue singleton and never dereferences self, so it is safe on a stale SEXP. A C null pointer is not R’s NULL; for that, use SEXP::is_null_ptr().

use miniextendr_api::SEXP;

// `x` is an argument whose R default is `NULL`: `f()` and `f(NULL)`
// both arrive as `R_NilValue`.
fn given(x: SEXP) -> bool {
    !x.is_nil()
}

See also: SEXP::nil(), SEXP::is_null_ptr(), SEXP::is_null_or_nil()

Source

pub fn is_null_or_nil(self) -> bool

Is this SEXP either a C null pointer or R’s NULL?

For a slot that can hold either kind of “nothing”: unset (address zero) or set to R_NilValue, such as an external pointer’s protected value. For an R value alone, SEXP::is_nil() is the right check.

use miniextendr_api::SEXP;

// A slot that was never set counts as empty.
assert!(SEXP::null().is_null_or_nil());

See also: SEXP::is_nil(), SEXP::is_null_ptr()

Source

pub fn as_ptr(self) -> *mut SEXPREC

Get the raw pointer.

Source

pub unsafe fn altrep_data1_raw(self) -> SEXP

Get the raw SEXP in the ALTREP data1 slot.

§Safety
  • self must be a valid ALTREP SEXP
  • Must be called from the R main thread
Source

pub unsafe fn altrep_data1_raw_unchecked(self) -> SEXP

Get the raw SEXP in the ALTREP data1 slot (unchecked — no thread routing).

§Safety
  • self must be a valid ALTREP SEXP
  • Must be called from the R main thread
Source

pub unsafe fn set_altrep_data1(self, v: SEXP)

Set the ALTREP data1 slot.

§Safety
  • self must be a valid ALTREP SEXP
  • Must be called from the R main thread
Source

pub unsafe fn altrep_data2_raw(self) -> SEXP

Get the raw SEXP in the ALTREP data2 slot.

§Safety
  • self must be a valid ALTREP SEXP
  • Must be called from the R main thread
Source

pub unsafe fn altrep_data2_raw_unchecked(self) -> SEXP

Get the raw SEXP in the ALTREP data2 slot (unchecked — no thread routing).

§Safety
  • self must be a valid ALTREP SEXP
  • Must be called from the R main thread
Source

pub unsafe fn set_altrep_data2(self, v: SEXP)

Set the ALTREP data2 slot.

§Safety
  • self must be a valid ALTREP SEXP
  • Must be called from the R main thread
Source

pub unsafe fn set_altrep_data2_unchecked(self, v: SEXP)

Set the ALTREP data2 slot (unchecked — no thread routing).

§Safety
  • self must be a valid ALTREP SEXP
  • Must be called from the R main thread

Trait Implementations§

Source§

impl Deref for OwnedProtect

Source§

type Target = SEXP

The resulting type after dereferencing.
Source§

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

Dereferences the value.
Source§

impl Drop for OwnedProtect

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more

Auto Trait Implementations§

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> SizeHint for T
where T: ?Sized,

Source§

default fn lower_bound(&self) -> usize

🔬This is a nightly-only experimental API. (core_io_internals)
Returns a lower bound on the number of elements this container-like item contains. For example, an array [u8; 12] could return any value between 0 and 12 inclusively as a correct implementation. Read more
Source§

default fn upper_bound(&self) -> Option<usize>

🔬This is a nightly-only experimental API. (core_io_internals)
Returns an upper bound on the number of elements this container-like item contains if it can be determined, otherwise None. Read more
Source§

final fn size_hint(&self) -> (usize, Option<usize>)

🔬This is a nightly-only experimental API. (core_io_internals)
Returns an estimate for the number of elements this container like type contains. Read more
Source§

impl<T> SizedTypeProperties for T

Source§

#[doc(hidden)]
const SIZE: usize = _

🔬This is a nightly-only experimental API. (sized_type_properties)
Source§

#[doc(hidden)]
const ALIGN: usize = _

🔬This is a nightly-only experimental API. (sized_type_properties)
Source§

#[doc(hidden)]
const ALIGNMENT: Alignment = _

🔬This is a nightly-only experimental API. (ptr_alignment_type)
Source§

#[doc(hidden)]
const IS_ZST: bool = _

🔬This is a nightly-only experimental API. (sized_type_properties)
true if this type requires no storage. false if its size is greater than zero. Read more
Source§

#[doc(hidden)]
const LAYOUT: Layout = _

🔬This is a nightly-only experimental API. (sized_type_properties)
Source§

#[doc(hidden)]
const MAX_SLICE_LEN: usize = _

🔬This is a nightly-only experimental API. (sized_type_properties)
The largest safe length for a [Self]. Read more
Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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.

Layout§

Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...) attributes. Please see the Rust Reference's “Type Layout” chapter for details on type layout guarantees.

Size: 16 bytes