Skip to main content

miniextendr_api/
altrep_ext.rs

1//! Extension trait for SEXP providing ALTREP-specific accessors.
2//!
3//! Using methods on SEXP (via `&self`) instead of free functions avoids
4//! `clippy::not_unsafe_ptr_arg_deref` in ALTREP trait implementations,
5//! mirroring the pattern established by [`SexpExt`](crate::ffi::SexpExt).
6
7use crate::externalptr::{ExternalPtr, TypedExternal};
8use crate::ffi::SEXP;
9
10/// ALTREP-specific extension methods for SEXP.
11///
12/// These methods wrap the free functions in `externalptr::altrep_helpers`
13/// and `ffi::altrep`, converting `func(x)` calls to `x.method()` calls.
14/// This avoids the `clippy::not_unsafe_ptr_arg_deref` lint in ALTREP trait
15/// method implementations that receive SEXP as a parameter.
16pub trait AltrepSexpExt {
17    /// Extract the ALTREP data1 slot as a typed `ExternalPtr<T>`.
18    ///
19    /// # Safety
20    ///
21    /// - `self` must be a valid ALTREP SEXP
22    /// - Must be called from the R main thread
23    unsafe fn altrep_data1<T: TypedExternal>(&self) -> Option<ExternalPtr<T>>;
24
25    /// Get a mutable reference to data in the ALTREP data1 slot.
26    ///
27    /// # Safety
28    ///
29    /// - `self` must be a valid ALTREP SEXP
30    /// - Must be called from the R main thread
31    /// - The caller must ensure no other references to the data exist
32    unsafe fn altrep_data1_mut_ref<T: TypedExternal>(&self) -> Option<&'static mut T>;
33
34    /// Get the ALTREP data2 slot.
35    ///
36    /// # Safety
37    ///
38    /// - `self` must be a valid ALTREP SEXP
39    /// - Must be called from the R main thread
40    unsafe fn altrep_data2(&self) -> SEXP;
41
42    /// Set the ALTREP data2 slot.
43    ///
44    /// # Safety
45    ///
46    /// - `self` must be a valid ALTREP SEXP
47    /// - Must be called from the R main thread
48    unsafe fn set_altrep_data2(&self, data2: SEXP);
49}
50
51impl AltrepSexpExt for SEXP {
52    #[inline]
53    unsafe fn altrep_data1<T: TypedExternal>(&self) -> Option<ExternalPtr<T>> {
54        unsafe { crate::altrep_data1_as::<T>(*self) }
55    }
56
57    #[inline]
58    unsafe fn altrep_data1_mut_ref<T: TypedExternal>(&self) -> Option<&'static mut T> {
59        unsafe { crate::altrep_data1_mut::<T>(*self) }
60    }
61
62    #[inline]
63    unsafe fn altrep_data2(&self) -> SEXP {
64        unsafe { crate::ffi::R_altrep_data2(*self) }
65    }
66
67    #[inline]
68    unsafe fn set_altrep_data2(&self, data2: SEXP) {
69        unsafe { crate::ffi::R_set_altrep_data2(*self, data2) }
70    }
71}