#[path = "base.s.r-type.lib-r.rs"]
pub mod lib_r;
use super::Sexp;
#[cfg(doc)]
use super::{Owned, Protected, SExt};
use core::ffi::{c_char, c_int, c_void};
use lib_r::*;
pub use lib_r::{SEXP, SEXPTYPE}; pub mod macros {
pub macro trait_def($(#[$m:meta])*; {$($vis:tt)*} $trait:tt $qual:tt $blk:tt for $macros:tt {$($extra:tt)*} $($t:tt)*){
$(#[$m])*
$($vis)* trait $trait : $qual
$blk
$macros!{$trait with {$($extra)*} for $($t)*}
}
pub macro RTypeMatrix($trait:tt with {$SEXPTYPE:tt $alias:tt $define:tt $self:tt} for $($ty:ty $(: $tyalias:literal)?, $Rty:tt, $RCode:tt $(=$RCodeVal:tt)? {$($extraTrait:tt)*});*$(;)?) {
$(
#[allow(non_camel_case_types)]
#[doc=core::concat!("Data type that an R [`SEXP`] with [`stype`](SEXPext::stype)` == `[`",stringify! ($RCode),"`] "$(,"(",$RCodeVal,")")?," contains.")]
#[doc=""]
#[doc=core::concat!("Such [`SEXP`] has R type [`",core::stringify!($Rty), "`] and is defined into Rust [`",core::stringify!($ty) ,"`]",$($tyalias,)?" type")]
pub type $Rty = $ty;
crate::macros::cond_eval!{($($RCodeVal)?) use $self::$define::$RCode;}
impl $trait for $Rty { #[doc=core::concat!("[`SEXP`] type of R [`",core::stringify!($Rty), "`] type is ",stringify!($RCode))] const $SEXPTYPE:$SEXPTYPE=$RCode; }
$(impl $extraTrait for $Rty {})*
)*
pub mod $define {
#[cfg(doc)]
use $self::$alias::*;
$($(
#[doc=core::concat!(" R [`",core::stringify!($Rty),"`] type")] pub const $RCode: $self::$SEXPTYPE = $RCodeVal;
)?)*
}
pub mod $alias {
$(
#[doc(inline)] pub use $self::$Rty;
)*
}
}
}
use macros::{trait_def, RTypeMatrix};
trait_def!(
;
{ pub }
RType
Copy
{
const SEXPTYPE:SEXPTYPE;
type Data:Copy=Self; unsafe fn new(len: usize) -> SEXP where Self : RDefault {
unsafe {<Self as RDefault>::new(len as R_xlen_t)}
}
#[inline(always)]
unsafe fn from(s:impl core::convert::AsRef<[<Self as RType>::Data]>) -> SEXP where Self:RTypeFrom {
unsafe {<Self as RTypeFrom>::from(s)}
}
#[inline(always)]
fn is_type(s:SEXP) -> bool {
unsafe { TYPEOF(s) == Self::SEXPTYPE }
}
#[inline(always)]
unsafe fn data(s:SEXP) -> *const Self::Data {
unsafe { DATAPTR_RO(s) as *const Self::Data }
}
#[inline(always)]
unsafe fn data_mut(s:SEXP) -> *mut Self::Data where Self:RTypeMut {
unsafe { DATAPTR(s) as *mut Self::Data }
}
}
for RTypeMatrix { SEXPTYPE alias define self }
():"(unit)", NULL, NILSXP=0 { };
u8, Rchar, CHARSXP=9 { };
u32, logical, LGLSXP =10 {RDefault RTypeMut};
i32, integer, INTSXP =13 {RDefault RTypeMut};
f64, numeric, REALSXP=14 {RDefault RTypeMut};
SEXP, list, VECSXP=19 {RDefault RTypeMut};
*mut c_void, externalptr, EXTPTRSXP=22 { };
Sexp<numeric>:"(Sexp)", numeric_list, VECSXP {RDefault RTypeMut};
Sexp<integer>:"(Sexp)", integer_list, VECSXP {RDefault RTypeMut};
Sexp<logical>:"(Sexp)", logical_list, VECSXP {RDefault RTypeMut};
Sexp<Rchar>, character, STRSXP=16 {RDefault RTypeMut};
);
pub trait RDefault: RType {
unsafe fn new(len: R_xlen_t) -> SEXP {
unsafe { Rf_allocVector(<Self as RType>::SEXPTYPE, len) }
}
}
impl RDefault for NULL {
unsafe fn new(_len: R_xlen_t) -> SEXP {
R_NilValue
}
}
pub trait RTypeMut: RType {}
pub trait RTypeFrom: RType {
unsafe fn from(data: impl core::convert::AsRef<[<Self as RType>::Data]>) -> SEXP;
}
impl<T: RDefault + RTypeMut> RTypeFrom for T {
#[inline(always)]
unsafe fn from(data: impl core::convert::AsRef<[<Self as RType>::Data]>) -> SEXP {
let data = data.as_ref();
let (src, len) = (data.as_ptr(), data.len());
unsafe {
let sexp = <T as RType>::new(data.len());
let dst = <T as RType>::data_mut(sexp);
core::intrinsics::copy_nonoverlapping(src, dst, len);
sexp
}
}
}
impl RTypeFrom for Rchar {
#[inline(always)]
unsafe fn from(data: impl core::convert::AsRef<[<Self as RType>::Data]>) -> SEXP {
let data = data.as_ref();
unsafe {
Rf_mkCharLenCE(
data.as_ptr() as *const c_char,
data.len() as c_int,
cetype_t_CE_UTF8,
)
}
}
}
pub trait SEXPext: Copy {
unsafe fn protect(self) -> Self;
unsafe fn unprotect(self);
unsafe fn stype(self) -> SEXPTYPE;
unsafe fn len(self) -> R_xlen_t;
unsafe fn missing(self) -> c_int;
unsafe fn get_attr(self, attr: SEXP) -> SEXP;
unsafe fn set_attr(self, attr: SEXP, val: SEXP) -> SEXP;
}
impl SEXPext for SEXP {
#[inline(always)]
unsafe fn protect(self) -> Self {
unsafe { Rf_protect(self) }
}
#[inline(always)]
unsafe fn unprotect(self) {
unsafe { Rf_unprotect_ptr(self) }
}
#[inline(always)]
unsafe fn stype(self) -> SEXPTYPE {
unsafe { TYPEOF(self) }
}
#[inline(always)]
unsafe fn len(self) -> R_xlen_t {
unsafe { Rf_xlength(self) }
}
#[inline(always)]
unsafe fn missing(self) -> c_int {
unsafe { MISSING(self) }
}
#[inline(always)]
unsafe fn get_attr(self, slot: SEXP) -> SEXP {
unsafe { Rf_getAttrib(self, slot) }
}
#[inline(always)]
unsafe fn set_attr(self, slot: SEXP, val: SEXP) -> SEXP {
unsafe { Rf_setAttrib(self, slot, val) }
}
}
pub unsafe fn error(message: *const Rchar) -> ! {
unsafe { Rf_errorcall(lib_r::R_CurrentExpression, FMT, message as *const c_char) }
}
pub unsafe fn print(message: *const Rchar) {
unsafe { Rprintf(FMT, message as *const c_char) }
}
pub unsafe fn eprint(message: *const Rchar) {
unsafe { REprintf(FMT, message as *const c_char) }
}
pub const FMT: *const c_char = c"%s".as_ptr();