1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
//! # 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.
//!
//! # Features
//!
//! Need at least one of these feature: `cfg-if`(for no_std environment) or `std`(for normal usage).
//!
//! `std`: Most of the rust crates are rely on `std::*`, if you want to use other crate, you should enable this feature. It takes ~1s compile the whole crate without `lto`, but if you enable `lto` for a faster executing speed, it might takes ~5s to finish compiling it.
//!
//! `public-all`: The most evil and dangerous feature. Better not to enable it. Most of the useful functions have a marker feature named `public-by-default-even-public-all-is-not-set`, that feature is a marker feature, do nothing but only tells you what function you could obtain from [`prelude`] module.
//!
//! `min-import`: For [`prelude`] module. Since all the [`RType`] aliases could be access from [`crate::prelude::R`], this feature disable import the aliases into [`prelude`] module.
//!
//! `panic-info-message`: enable rust feature `panic_info_message`, I suppose it does nothing since I have no idea how to send message in this way.
//!
//! `cfg-if`: enable by default since compile the exception handling functtion for `no_std` environment need `cfg-if`. If you are using `std` feature, this could be disabled.
//!
//! `public-by-default-even-public-all-is-not-set`: Dummy feature. Nothing happens if you disable it with `--no-default-feature`.
//!
//! # Note
//!
//! Please switch to [`prelude`] module page for a first glance, since I want to show all docs, most of the private things are documented with a `public-all` feature flag.
//! Please do not use them directly since most of them have a safe wrapper, and it is dangerous to use them directly.
//!
//! # 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.
//!
//! The currently 0.3.0 version is slightly different from 0.2.0, which rename `SEXP<T>` to [`Sexp<T>`], and (will) support things like [`Sexp`]<[`numeric_list`]>(R::numeric_list) or even an arbitrary list `Sexp<(T1,T2)>`.
//! Since renaming breaks the current symver, I'll delay the publishing of 0.3.0
//!
//! I cannot ensure whether the api will change again in the future, but the api seems to be stable.
//!
//! ## 0.3.0, bring `#[no_std]` back!
//!
//! In 0.3.0, feature `std` is optional again, which will give us a faster code generating speed.
//!
//! ### Changes:
//!
//! 1. \[ x \] currently, new method and from (rust type) method goes to SExt, you could still write [`Owned<T>`]`::`[`new`](crate::prelude::Owned::new)`()`, but a [`Protected<T>`](crate::base::s::Protected) yields.
//! 2. \[ x \] Add a [`catch_unwind`](crate::base::no_std::unwind::catch_unwind) for `no_std`.
//! 3. \[ x \] Move `SEXP<T>` to [`Sexp<T>`] thus SEXP and Sexp could be occur in the same situation
//! 4. \[ x \] Using macro 2.0 to hide most of the struct and method from user interface, but remains the doc for debug purpose.
//! 5. \[ \] Adding support for lists (partially done.)
//!
//! ### grammar
//! ```no_run
//! #![no_std]
//! use rmin::*;
//! /// Return a+b to R.
//! #[no_mangle]
//! pub extern "C" fn add_protect(a:Sexp<f64>,b:Sexp<f64>) -> Owned<f64> {
//! handle_panic(||{
//! let mut c=Owned::new(1);
//! c[0]=a[0]+b[0];
//! c.into()
//! })
//! }
//! #[no_mangle]
//! pub extern "C" 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.into()
//! })
//! }
//!
//! /// raise panic.
//! #[no_mangle]
//! pub extern "C" fn panic() -> Owned<f64> {
//! handle_panic(||{
//! panic!("error occurs")
//! })
//! }
//! fn main() {} // just makes compiler happy
//! ```
//!
//! 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(addp,1.,2.)));system.time(sapply(1:1000000,function(x).Call(addp,1.,2.)))"
//! ```
extern crate panic_unwind;
macro pm
pm!
/// Prelude, the only thing you could (and should) use
///
/// Originally, to prevent the misuse of things like putting [`Protected<T>`](crate::base::s::Protected) into a FFI interface, most of the structs are private and hided. And the crate is designed to function just with the visible prelude module.
///
/// Currently, a feature gate `public-all` is added, and thus users could see all of the docs, which helps debugging with this crate.
/// But, since the `public-all` feature gate is added to the base module, all the type are marked as **Available on crate feature `public-all` only**
///
/// To really checks what you could use directly, all the doc that prelude imports are inlined, and the prelude crate are marked as **Available on crate feature `always-avaliable-with-prelude-accesses` only.**
///
/// Here, `always-avaliable-with-prelude-accesses` is a dummy feature, it is enabled by default and does nothing (thus disable it makes nothing happens). The usage of that feature is that, when you see that feature,
/// you could use it without enable `public-all`.
///
/// Sometimes, you may obtain *private* things such as [`Protected<T>`](crate::base::s::Protected) (from a [`SExt`]`::<_>::`[`new`](SExt::new)`(_)`), that's OK, since the R ffi does not accept a [`Protected<T>`](crate::base::s::Protected),
/// and you cannot visit [`Protected<T>`](crate::base::s::Protected) directly without `public-all`, you could only keep that type until rust drop it automatically.
///
/// As for normal usage, it make no different to write `use rmin::*` or `use rmin::prelude::*`.
///
/// Choose your favorite one:)
///
/// # Example
/// ## 1. use prelude
/// ```
/// use rmin::prelude::*;
/// ```
/// ## 2. use a shorter version
/// ```
/// use rmin::*;
/// ```
pub use *;