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}