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§
Methods from Deref<Target = SEXP>§
Sourcepub fn is_null_ptr(self) -> bool
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()
Sourcepub fn is_nil(self) -> bool
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()
Sourcepub fn is_null_or_nil(self) -> bool
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()
Sourcepub unsafe fn altrep_data1_raw(self) -> SEXP
pub unsafe fn altrep_data1_raw(self) -> SEXP
Get the raw SEXP in the ALTREP data1 slot.
§Safety
selfmust be a valid ALTREP SEXP- Must be called from the R main thread
Sourcepub unsafe fn altrep_data1_raw_unchecked(self) -> SEXP
pub unsafe fn altrep_data1_raw_unchecked(self) -> SEXP
Get the raw SEXP in the ALTREP data1 slot (unchecked — no thread routing).
§Safety
selfmust be a valid ALTREP SEXP- Must be called from the R main thread
Sourcepub unsafe fn set_altrep_data1(self, v: SEXP)
pub unsafe fn set_altrep_data1(self, v: SEXP)
Set the ALTREP data1 slot.
§Safety
selfmust be a valid ALTREP SEXP- Must be called from the R main thread
Sourcepub unsafe fn altrep_data2_raw(self) -> SEXP
pub unsafe fn altrep_data2_raw(self) -> SEXP
Get the raw SEXP in the ALTREP data2 slot.
§Safety
selfmust be a valid ALTREP SEXP- Must be called from the R main thread
Sourcepub unsafe fn altrep_data2_raw_unchecked(self) -> SEXP
pub unsafe fn altrep_data2_raw_unchecked(self) -> SEXP
Get the raw SEXP in the ALTREP data2 slot (unchecked — no thread routing).
§Safety
selfmust be a valid ALTREP SEXP- Must be called from the R main thread
Sourcepub unsafe fn set_altrep_data2(self, v: SEXP)
pub unsafe fn set_altrep_data2(self, v: SEXP)
Set the ALTREP data2 slot.
§Safety
selfmust be a valid ALTREP SEXP- Must be called from the R main thread
Sourcepub unsafe fn set_altrep_data2_unchecked(self, v: SEXP)
pub unsafe fn set_altrep_data2_unchecked(self, v: SEXP)
Set the ALTREP data2 slot (unchecked — no thread routing).
§Safety
selfmust be a valid ALTREP SEXP- Must be called from the R main thread
Trait Implementations§
Source§impl Deref for OwnedProtect
impl Deref for OwnedProtect
Source§impl Drop for OwnedProtect
impl Drop for OwnedProtect
Auto Trait Implementations§
impl !Send for OwnedProtect
impl !Sync for OwnedProtect
impl Freeze for OwnedProtect
impl RefUnwindSafe for OwnedProtect
impl Unpin for OwnedProtect
impl UnsafeUnpin for OwnedProtect
impl UnwindSafe for OwnedProtect
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> SizeHint for Twhere
T: ?Sized,
impl<T> SizeHint for Twhere
T: ?Sized,
Source§default fn lower_bound(&self) -> usize
default fn lower_bound(&self) -> usize
core_io_internals)[u8; 12] could return any value between 0 and
12 inclusively as a correct implementation. Read moreSource§impl<T> SizedTypeProperties for T
impl<T> SizedTypeProperties for T
Source§#[doc(hidden)]const SIZE: usize = _
#[doc(hidden)]const SIZE: usize = _
sized_type_properties)Source§#[doc(hidden)]const ALIGN: usize = _
#[doc(hidden)]const ALIGN: usize = _
sized_type_properties)Source§#[doc(hidden)]const ALIGNMENT: Alignment = _
#[doc(hidden)]const ALIGNMENT: Alignment = _
ptr_alignment_type)Source§#[doc(hidden)]const IS_ZST: bool = _
#[doc(hidden)]const IS_ZST: bool = _
sized_type_properties)Source§#[doc(hidden)]const LAYOUT: Layout = _
#[doc(hidden)]const LAYOUT: Layout = _
sized_type_properties)Source§#[doc(hidden)]const MAX_SLICE_LEN: usize = _
#[doc(hidden)]const MAX_SLICE_LEN: usize = _
sized_type_properties)[Self]. Read moreLayout§
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