#[path = "base.s.r-type.lib-r.rs"]
pub mod lib_r;
use lib_r::*;
pub use lib_r::{SEXP, SEXPTYPE};
use core::ffi::{c_int, c_char};
use super::Sexp;
#[cfg(doc)]
use super::{SExt, Owned, Protected}; 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::{RTypeMatrix, trait_def};
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};
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;
}
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) }
}
}
pub unsafe fn error(message:*const Rchar)->!{
unsafe { Rf_errorcall(lib_r::R_CurrentExpression, FMT, message as *const c_char) }
}
#[cfg_attr(doc,doc(cfg(not(have_std))))] #[cfg(not(have_std))]
pub unsafe fn print(message:*const Rchar){
unsafe { Rprintf(FMT, message as *const c_char) }
}
pub const FMT:*const c_char=b"%s\0" as *const u8 as *const c_char;