rmin 0.2.0

A minimal Rust lib for writting R extensions
Documentation
//! # rmin - A minimal Rust lib for writting R extensions
//!
//! This is a very early version, only support vector type, and thus its overhead is minimized.
//!
//! Compare to the well-knowned `rextendr`, This crate although with some limitations but could provide a faster implementation, a smaller code size, and a faster compile time
//! ( could generate a release build in 0.45s with `#![no_std], but may cause memory leak).
//!
//! Since it is small enough, you could vendor this crate easily into your CRAN package.
//!
//! # Usage
//!
//! Version 0.1.0 provides a fastest (but ugly) way to achieve about 2x speedup on with functions. They are discarded in 0.2.* since they are really unsafe and may cause memory leak.
//!
//! I cannot ensure whether the api will change again in the future, but currently v0.2.0 seems usable.
//!
//! ## 0.2.0, rewrite to prevent memory leak
//!
//! Several changes have been made since v0.1.0:
//!
//! 1. Add a panic_handler with default `std` feature, it is because currently, Rust cannot call all drop function before a longjmp is executed, which will cause memory leak, thus `catch_unwind` must be used and thus `std` crate is needed. I have not check whether `#![no_std]` works now, but it is better not to use it.
//! 2. Move `SEXP` to `libR::SEXP`, and exporting `SEXP<T>`, `Owned<T>` (and `Protected<T>` generated by `Owned<T>::protect` which cannot be used directly, since return `Protected<T>` to R will break the protect balance)
//! 3. Currently, you could directly indexing a sexp object, but convert them firstly into slices is more preferred.
//!
//! ### grammar
//! ```rust
//! use rmin::prelude::*;
//! /// Return a+b to R.
//! #[no_mangle]
//! pub extern "C-unwind" fn add_protect(a:SEXP<f64>,b:SEXP<f64>) -> Owned<f64> {
//!     handle_panic(||{
//!         let mut c=Owned::new(1).protect();
//!         c[0]=a[0]+b[0];
//!         c.into()
//!     })
//! }
//! #[no_mangle]
//! pub extern "C-unwind" fn add_noprotect(a:SEXP<f64>,b:SEXP<f64>) -> Owned<f64> {
//!     handle_panic(||{
//!         let mut c=Owned::new(1);
//!         c[0]=a[0]+b[0];
//!         c
//!     })
//! }
//!
//! /// raise panic.
//! #[no_mangle]
//! pub extern "C-unwind" fn panic() -> Owned<f64> {
//!     handle_panic(||{
//!         panic!("error occurs")
//!     })
//! }
//! ```
//!
//! The program above could be tested with test command
//! ```bash
//! export LOAD="dyn.load('target/release/examples/libcompare_rmin.so');addnp=getNativeSymbolInfo('add_noprotect');addp=getNativeSymbolInfo('add_protect');panic=getNativeSymbolInfo('panic')" ; LC_ALL=C r -e "$LOAD;system.time(sapply(1:100000,function(x)tryCatch(.Call(wrap__panic),error=I)))" 2>/dev/null ; LC_ALL=C r -e "$LOAD;system.time(sapply(1:1000000,function(x).Call(addnp,1.,2.)));system.time(sapply(1:1000000,function(x).Call(addnp,1.,2.)))"
//! ```
#![feature(rustdoc_missing_doc_code_examples)]
#![warn(missing_docs, rustdoc::missing_crate_level_docs, rustdoc::missing_doc_code_examples)]
#![allow(unused_imports)]
#![cfg_attr(not(feature = "std"), no_std)]
#![allow(internal_features)]
#![feature(lang_items, panic_info_message, c_unwind, associated_type_defaults, impl_trait_in_assoc_type)]
#[cfg_attr(feature = "std", allow(unused))]
#[macro_use]
mod macros;
#[allow(non_snake_case)]
mod RType;
#[allow(non_snake_case)]
mod libR;
mod handle_panic;


#[cfg(not(feature = "std"))]
pub type String = crate::String;
#[cfg(not(feature = "std"))]
pub use crate::Vec;
pub use crate::{handle_panic::handle_panic, libR::S::{SEXP,Owned,SExt}};

/// It makes no difference to choose either write `use rmin::prelude::*` or `use rmin::*`.
///
/// Choose your favorite one:)
///
/// # Example
/// ## 1. use prelude
/// ```
/// use rmin::prelude::*;
/// ```
/// ## 2. use a shorter version
/// ```
/// use rmin::*;
/// ```
pub mod prelude {
    pub use crate::*;
}