#[path = "base.s.r-type.rs"]
pub mod r_type;
use r_type::{
alias::*,
error,
lib_r::{
R_ClassSymbol, R_MakeExternalPtr, R_NilValue, Rf_setAttrib
},
RDefault, RType, RTypeFrom, RTypeMut, SEXPext, SEXP, SEXPTYPE,
};
#[cfg(doc)]
use r_type::define::*;
use r_type::{print, eprint}; pub mod macros {
pub macro impl_sext_index (SExt=$SExt:tt SEXP=$SEXP:tt RType=$RType:tt RTypeMut=$RTypeMut:tt Mutable=$Mutable:tt,$($tt:tt)*) {
use core::ops::{Index,IndexMut};
$(
impl<T: $RType> $SExt for $tt<T> {
type Data = T;
unsafe fn as_sexp(&self) -> $SEXP {
self.sexp
}
}
impl<T: $RType> Index<usize> for $tt<T> where $tt<T>:$SExt {
type Output = <<$tt<T> as $SExt>::Data as $RType>::Data;
fn index(&self, index: usize) -> &<<$tt<T> as $SExt>::Data as $RType>::Data {
self.data().index(index)
}
}
impl<T: $RTypeMut> IndexMut<usize> for $tt<T> where $tt<T>:$Mutable, <$tt<T> as $SExt>::Data:$RTypeMut {
fn index_mut(&mut self, index: usize) -> &mut <<$tt<T> as $SExt>::Data as $RType>::Data {
self.data_mut().index_mut(index)
}
}
)*
}
}
use core::{ffi::c_void, marker::PhantomData};
use macros::impl_sext_index;
#[derive(Copy, Clone)]
#[repr(transparent)]
pub struct Sexp<T: RType> {
sexp: SEXP,
_marker: [PhantomData<T>; 0],
}
#[repr(transparent)]
#[derive(Clone, Copy)]
pub struct OptionSexp<T: RType> {
sexp: Sexp<T>
}
impl<T: RType> Sexp<T> {
#[deprecated = "Sexp<T> cannot missing (while the item is registered), using OptionSexp<T> instead."]
pub const unsafe fn missing(self)->bool {
false
}
}
impl<T: RType> OptionSexp<T> {
#[inline(always)]
pub unsafe fn into_option(self)->Option<Sexp<T>> {
if unsafe {self.missing()} {
None
} else {
Some(self.sexp)
}
}
#[inline(always)]
pub unsafe fn missing(&self) -> bool {
self.missingness() != 0
}
#[inline(always)]
pub unsafe fn missingness(&self) -> i32 {
unsafe { self.sexp.sexp.missing() as i32 }
}
}
#[repr(transparent)]
pub struct Owned<T: RType> {
sexp: SEXP,
_marker: [PhantomData<T>; 0],
}
impl<T: RType> Owned<T> {
pub fn protect(self) -> Protected<T> {
self.into()
}
}
pub trait R5: Sized + 'static {
#[cfg(feature = "const_type_name")]
const CLASS_NAME: &'static str = core::any::type_name::<Self>();
#[cfg(not(feature = "const_type_name"))]
const CLASS_NAME: &'static str;
fn new() -> Owned<externalptr> {
#[cfg(feature = "create_new_class_symbol")]
#[allow(non_snake_case)]
let R_ClassSymbol = unsafe {
Owned::raw_from_str("class")
.protect()
.as_sexp(Owned::raw_from_str(<Self as R5>::CLASS_NAME).protect())
};
let name = Owned::raw_from_str(<Self as R5>::CLASS_NAME).protect();
let ret = Owned::<externalptr> {
sexp: unsafe {
R_MakeExternalPtr(core::ptr::null_mut() as *mut c_void, R_NilValue, R_NilValue)
},
_marker: [],
}.protect();
unsafe { Rf_setAttrib(ret.sexp, R_ClassSymbol, name.sexp) };
ret.into()
}
}
#[repr(transparent)]
pub struct Protected<T: RType> {
sexp: SEXP,
_marker: [PhantomData<T>; 0],
}
pub trait SExt: Sized {
type Data: RType;
unsafe fn as_sexp(&self) -> SEXP;
fn stype(&self) -> SEXPTYPE {
unsafe { self.as_sexp().stype() }
}
fn new(len: usize) -> Protected<Self::Data>
where
Self::Data: RDefault,
{
Protected::<Self::Data> {
sexp: unsafe { <Self::Data as RType>::new(len).protect() },
_marker: [],
}
.into()
}
fn raw(len: usize) -> Owned<Self::Data>
where
Self::Data: RDefault,
{
Owned::<Self::Data> {
sexp: unsafe { <Self::Data as RType>::new(len) },
_marker: [],
}
}
fn from(data: impl AsRef<[<Self::Data as RType>::Data]>) -> Protected<Self::Data>
where
Self::Data: RTypeFrom,
{
Protected::<Self::Data> {
sexp: unsafe { <Self::Data as RType>::from(data) },
_marker: [],
}
.into()
}
fn raw_from(data: impl AsRef<[<Self::Data as RType>::Data]>) -> Owned<Self::Data>
where
Self::Data: RTypeFrom,
{
Owned::<Self::Data> {
sexp: unsafe { <Self::Data as RType>::from(data) },
_marker: [],
}
}
#[inline(always)]
fn is_correct_type(&self) -> bool {
self.stype() == Self::Data::SEXPTYPE
}
#[inline(always)]
fn len(&self) -> usize {
unsafe { self.as_sexp().len() as usize }
}
#[inline(always)]
unsafe fn data_unchecked(&self) -> &[<Self::Data as RType>::Data] {
unsafe { core::slice::from_raw_parts(Self::Data::data(self.as_sexp()), self.len()) }
}
#[inline(always)]
fn data(&self) -> &[<Self::Data as RType>::Data] {
if self.len() == 0 {
&[]
} else {
if self.is_correct_type() {
unsafe { self.data_unchecked() }
} else {
panic!(
"data has the type {}, but {}(={}) is required.",
self.stype(),
core::any::type_name::<<Self::Data as RType>::Data>(),
<Self::Data as RType>::SEXPTYPE,
)
}
}
}
#[inline(always)]
unsafe fn data_unchecked_mut(&self) -> &mut [<Self::Data as RType>::Data]
where
<Self as SExt>::Data: RTypeMut,
Self: Mutable,
{
unsafe { core::slice::from_raw_parts_mut(Self::Data::data_mut(self.as_sexp()), self.len()) }
}
#[inline(always)]
fn data_mut(&mut self) -> &mut [<Self::Data as RType>::Data]
where
<Self as SExt>::Data: RTypeMut,
Self: Mutable,
{
if self.len() == 0 {
&mut []
} else {
if self.is_correct_type() {
unsafe { self.data_unchecked_mut() }
} else {
panic!(
"data has the type {}, but {}(={}) is required.",
self.stype(),
core::any::type_name::<Self::Data>(),
<Self::Data as RType>::SEXPTYPE,
)
}
}
}
}
pub trait Mutable {}
impl<T: RTypeMut> Mutable for Owned<T> {}
impl<T: RTypeMut> Mutable for Protected<T> {}
impl<T: RType> From<Owned<T>> for Protected<T> {
#[inline(always)]
fn from(s: Owned<T>) -> Self {
Self {
sexp: unsafe { s.sexp.protect() },
_marker: [],
}
}
}
impl<T: RType> From<Protected<T>> for Owned<T> {
#[inline(always)]
fn from(s: Protected<T>) -> Self {
Self {
sexp: s.sexp,
_marker: [],
}
}
}
impl<T: RType> From<Protected<T>> for Sexp<T> {
#[inline(always)]
fn from(s: Protected<T>) -> Self {
Self {
sexp: s.sexp,
_marker: [],
}
}
}
impl<T: RType> From<Owned<T>> for Sexp<T> {
#[inline(always)]
fn from(s: Owned<T>) -> Self {
Self {
sexp: s.sexp,
_marker: [],
}
}
}
impl<T: RType> Drop for Protected<T> {
#[inline(always)]
fn drop(&mut self) {
unsafe { self.sexp.unprotect() }
}
}
unsafe impl Sync for Sexp<Rchar> {}
unsafe impl Send for Sexp<Rchar> {}
impl Sexp<Rchar> {
pub unsafe fn error(self) -> ! {
unsafe { error(Rchar::data(self.as_sexp())) }
}
pub fn print(self) {
unsafe { print(Rchar::data(self.as_sexp())) }
}
pub fn eprint(self) {
unsafe { eprint(Rchar::data(self.as_sexp())) }
}
}
impl Protected<character> {
fn raw_from_strs(a: impl ExactSizeIterator<Item:AsRef<[u8]>>) -> Self {
let mut ret = Owned{sexp: unsafe {<character as RType>::new(a.len())}, _marker:[]}.protect();
let item = ret.data_mut();
item.iter_mut().zip(a).for_each(|(i,a)|*i=Owned::raw_from(a).into());
ret
}
}
impl Owned<character> {
pub fn raw_from_strs(a: impl ExactSizeIterator<Item:AsRef<[u8]>>) -> Self {
Protected::<character>::raw_from_strs(a).into()
}
pub fn raw_from_str(a: impl AsRef<[u8]>) -> Self {
Self::raw_from([<Owned<Rchar> as Into<Sexp<Rchar>>>::into(Owned::raw_from(
a,
))])
}
#[deprecated(
since = "0.0.0",
note = "Please use `raw_from_str` to ensure you are generate a `raw Owned` rather than `normal protected` type."
)]
pub fn from_str(a: impl AsRef<[u8]>) -> Self {
Self::raw_from_str(a)
}
}
impl_sext_index! {SExt=SExt SEXP=SEXP RType=RType RTypeMut=RTypeMut Mutable=Mutable, Sexp Owned Protected}