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::ffi::SEXP;
8
9/// ALTREP-specific extension methods for SEXP.
10///
11/// These methods wrap the free functions in `ffi::altrep`, converting
12/// `func(x)` calls to `x.method()` calls. This avoids the
13/// `clippy::not_unsafe_ptr_arg_deref` lint in ALTREP trait method
14/// implementations that receive SEXP as a parameter.
15///
16/// Only data2 (cache) accessors are exposed here; data1 (storage) is
17/// accessed via the `AltrepExtract` trait or the standalone free functions
18/// `altrep_data1_as` / `altrep_data1_as_unchecked` / `altrep_data1_mut` /
19/// `altrep_data1_mut_unchecked`.
20pub trait AltrepSexpExt {
21    /// Get the raw SEXP in the ALTREP data2 slot.
22    ///
23    /// # Safety
24    ///
25    /// - `self` must be a valid ALTREP SEXP
26    /// - Must be called from the R main thread
27    unsafe fn altrep_data2_raw(&self) -> SEXP;
28
29    /// Get the ALTREP data2 slot (unchecked — no thread routing).
30    ///
31    /// # Safety
32    ///
33    /// - `self` must be a valid ALTREP SEXP
34    /// - Must be called from the R main thread
35    unsafe fn altrep_data2_raw_unchecked(&self) -> SEXP;
36
37    /// Set the ALTREP data2 slot.
38    ///
39    /// # Safety
40    ///
41    /// - `self` must be a valid ALTREP SEXP
42    /// - Must be called from the R main thread
43    unsafe fn set_altrep_data2(&self, data2: SEXP);
44
45    /// Set the ALTREP data2 slot (unchecked — no thread routing).
46    ///
47    /// # Safety
48    ///
49    /// - `self` must be a valid ALTREP SEXP
50    /// - Must be called from the R main thread
51    unsafe fn set_altrep_data2_unchecked(&self, data2: SEXP);
52}
53
54impl AltrepSexpExt for SEXP {
55    #[inline]
56    unsafe fn altrep_data2_raw(&self) -> SEXP {
57        unsafe { SEXP::altrep_data2_raw(*self) }
58    }
59
60    #[inline]
61    unsafe fn altrep_data2_raw_unchecked(&self) -> SEXP {
62        unsafe { SEXP::altrep_data2_raw_unchecked(*self) }
63    }
64
65    #[inline]
66    unsafe fn set_altrep_data2(&self, data2: SEXP) {
67        unsafe { SEXP::set_altrep_data2(*self, data2) }
68    }
69
70    #[inline]
71    unsafe fn set_altrep_data2_unchecked(&self, data2: SEXP) {
72        unsafe { SEXP::set_altrep_data2_unchecked(*self, data2) }
73    }
74}