1use crate::SEXP;
10use crate::altrep_traits::NA_REAL;
11use crate::sys::{
12 COMPLEX, COMPLEX_ELT, INTEGER, INTEGER_ELT, LOGICAL, LOGICAL_ELT, RAW, RAW_ELT, REAL, REAL_ELT,
13 Rf_type2char, Rf_xlength,
14};
15
16#[allow(non_camel_case_types)]
17pub type R_xlen_t = isize;
19pub type Rbyte = ::std::os::raw::c_uchar;
21
22#[repr(C)]
24#[derive(Debug, Copy, Clone, PartialEq)]
25pub struct Rcomplex {
26 pub r: f64,
28 pub i: f64,
30}
31
32#[repr(u32)]
34#[non_exhaustive]
35#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
36pub enum SEXPTYPE {
37 #[doc = " nil = NULL"]
38 NILSXP = 0,
39 #[doc = " symbols"]
40 SYMSXP = 1,
41 #[doc = " lists of dotted pairs"]
42 LISTSXP = 2,
43 #[doc = " closures"]
44 CLOSXP = 3,
45 #[doc = " environments"]
46 ENVSXP = 4,
47 #[doc = r" promises: \[un\]evaluated closure arguments"]
48 PROMSXP = 5,
49 #[doc = " language constructs (special lists)"]
50 LANGSXP = 6,
51 #[doc = " special forms"]
52 SPECIALSXP = 7,
53 #[doc = " builtin non-special forms"]
54 BUILTINSXP = 8,
55 #[doc = " \"scalar\" string type (internal only)"]
56 CHARSXP = 9,
57 #[doc = " logical vectors"]
58 LGLSXP = 10,
59 #[doc = " integer vectors"]
60 INTSXP = 13,
61 #[doc = " real variables"]
62 REALSXP = 14,
63 #[doc = " complex variables"]
64 CPLXSXP = 15,
65 #[doc = " string vectors"]
66 STRSXP = 16,
67 #[doc = " dot-dot-dot object"]
68 DOTSXP = 17,
69 #[doc = " make \"any\" args work"]
70 ANYSXP = 18,
71 #[doc = " generic vectors"]
72 VECSXP = 19,
73 #[doc = " expressions vectors"]
74 EXPRSXP = 20,
75 #[doc = " byte code"]
76 BCODESXP = 21,
77 #[doc = " external pointer"]
78 EXTPTRSXP = 22,
79 #[doc = " weak reference"]
80 WEAKREFSXP = 23,
81 #[doc = " raw bytes"]
82 RAWSXP = 24,
83 #[doc = " S4 non-vector"]
84 S4SXP = 25,
85 #[doc = " fresh node created in new page"]
86 NEWSXP = 30,
87 #[doc = " node released by GC"]
88 FREESXP = 31,
89 #[doc = " Closure or Builtin"]
90 FUNSXP = 99,
91}
92
93impl SEXPTYPE {
94 pub const OBJSXP: SEXPTYPE = SEXPTYPE::S4SXP;
99
100 #[inline]
104 pub fn type_name(self) -> &'static str {
105 let cstr = unsafe { Rf_type2char(self) };
106 unsafe { std::ffi::CStr::from_ptr(cstr) }
108 .to_str()
109 .unwrap_or("unknown")
110 }
111}
112
113pub trait RNativeType: Sized + Copy + 'static {
117 const SEXP_TYPE: SEXPTYPE;
119
120 const R_NA: Self;
130
131 unsafe fn dataptr_mut(sexp: SEXP) -> *mut Self;
142
143 fn elt(sexp: SEXP, i: isize) -> Self;
147}
148
149#[repr(transparent)]
162#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
163pub struct RLogical(i32);
164
165impl RLogical {
166 pub const FALSE: Self = Self(0);
168 pub const TRUE: Self = Self(1);
170 pub const NA: Self = Self(i32::MIN);
172
173 #[inline]
175 pub const fn from_i32(raw: i32) -> Self {
176 Self(raw)
177 }
178
179 #[inline]
181 pub const fn to_i32(self) -> i32 {
182 self.0
183 }
184
185 #[inline]
187 pub const fn is_na(self) -> bool {
188 self.0 == i32::MIN
189 }
190
191 #[inline]
193 pub const fn to_option_bool(self) -> Option<bool> {
194 match self.0 {
195 0 => Some(false),
196 i32::MIN => None,
197 _ => Some(true),
198 }
199 }
200}
201
202impl From<bool> for RLogical {
203 #[inline]
204 fn from(value: bool) -> Self {
205 if value { Self::TRUE } else { Self::FALSE }
206 }
207}
208
209impl RNativeType for i32 {
210 const SEXP_TYPE: SEXPTYPE = SEXPTYPE::INTSXP;
211 const R_NA: Self = i32::MIN; #[inline]
214 unsafe fn dataptr_mut(sexp: SEXP) -> *mut Self {
215 unsafe {
216 if Rf_xlength(sexp) == 0 {
217 std::ptr::NonNull::<Self>::dangling().as_ptr()
218 } else {
219 INTEGER(sexp)
220 }
221 }
222 }
223
224 #[inline]
225 fn elt(sexp: SEXP, i: isize) -> Self {
226 unsafe { INTEGER_ELT(sexp, i) }
227 }
228}
229
230impl RNativeType for f64 {
231 const SEXP_TYPE: SEXPTYPE = SEXPTYPE::REALSXP;
232 const R_NA: Self = NA_REAL; #[inline]
235 unsafe fn dataptr_mut(sexp: SEXP) -> *mut Self {
236 unsafe {
237 if Rf_xlength(sexp) == 0 {
238 std::ptr::NonNull::<Self>::dangling().as_ptr()
239 } else {
240 REAL(sexp)
241 }
242 }
243 }
244
245 #[inline]
246 fn elt(sexp: SEXP, i: isize) -> Self {
247 unsafe { REAL_ELT(sexp, i) }
248 }
249}
250
251impl RNativeType for u8 {
252 const SEXP_TYPE: SEXPTYPE = SEXPTYPE::RAWSXP;
253 const R_NA: Self = 0;
255
256 #[inline]
257 unsafe fn dataptr_mut(sexp: SEXP) -> *mut Self {
258 unsafe {
259 if Rf_xlength(sexp) == 0 {
260 std::ptr::NonNull::<Self>::dangling().as_ptr()
261 } else {
262 RAW(sexp)
263 }
264 }
265 }
266
267 #[inline]
268 fn elt(sexp: SEXP, i: isize) -> Self {
269 unsafe { RAW_ELT(sexp, i) }
270 }
271}
272
273impl RNativeType for RLogical {
274 const SEXP_TYPE: SEXPTYPE = SEXPTYPE::LGLSXP;
275 const R_NA: Self = RLogical::NA; #[inline]
278 unsafe fn dataptr_mut(sexp: SEXP) -> *mut Self {
279 unsafe {
281 if Rf_xlength(sexp) == 0 {
282 std::ptr::NonNull::<Self>::dangling().as_ptr()
283 } else {
284 LOGICAL(sexp).cast()
285 }
286 }
287 }
288
289 #[inline]
290 fn elt(sexp: SEXP, i: isize) -> Self {
291 RLogical(unsafe { LOGICAL_ELT(sexp, i) })
292 }
293}
294
295impl RNativeType for Rcomplex {
296 const SEXP_TYPE: SEXPTYPE = SEXPTYPE::CPLXSXP;
297 const R_NA: Self = Rcomplex {
298 r: NA_REAL,
299 i: NA_REAL,
300 };
301
302 #[inline]
303 unsafe fn dataptr_mut(sexp: SEXP) -> *mut Self {
304 unsafe {
305 if Rf_xlength(sexp) == 0 {
306 std::ptr::NonNull::<Self>::dangling().as_ptr()
307 } else {
308 COMPLEX(sexp)
309 }
310 }
311 }
312
313 #[inline]
314 fn elt(sexp: SEXP, i: isize) -> Self {
315 unsafe { COMPLEX_ELT(sexp, i) }
316 }
317}
318
319#[repr(i32)]
320#[non_exhaustive]
321#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
322pub enum Rboolean {
324 FALSE = 0,
326 TRUE = 1,
328}
329
330impl From<bool> for Rboolean {
331 fn from(value: bool) -> Self {
332 match value {
333 true => Rboolean::TRUE,
334 false => Rboolean::FALSE,
335 }
336 }
337}
338
339impl From<Rboolean> for bool {
340 fn from(value: Rboolean) -> Self {
341 match value {
342 Rboolean::FALSE => false,
343 Rboolean::TRUE => true,
344 }
345 }
346}
347
348#[allow(non_camel_case_types)]
349pub type R_CFinalizer_t = ::std::option::Option<unsafe extern "C-unwind" fn(s: SEXP)>;
351
352#[repr(C)]
353#[derive(Copy, Clone)]
354#[allow(non_camel_case_types)]
355pub enum cetype_t {
357 CE_NATIVE = 0,
359 CE_UTF8 = 1,
361 CE_LATIN1 = 2,
363 CE_BYTES = 3,
365 CE_SYMBOL = 5,
367 CE_ANY = 99,
369}
370pub use cetype_t::CE_UTF8;