1use rdll::{SEXP, R_NilValue, Rf_protect, Rf_unprotect};
2use traits::ToSEXP;
3use std::default::Default;
4
5pub struct Shelter {
9 nprotected: ::std::os::raw::c_int,
10}
11
12impl Default for Shelter {
13 fn default() -> Self {
14 Shelter { nprotected: 0 }
15 }
16}
17
18impl Shelter {
19 pub fn new() -> Shelter {
20 Self::default()
22 }
23
24 pub fn add<T: ToSEXP>(&mut self, a: T) -> SEXP {
25 let sexp = unsafe { a.s() };
26 unsafe {
27 if sexp != R_NilValue {
28 Rf_protect(sexp);
29 self.nprotected = self.nprotected + 1;
30 }
31 }
32
33 sexp
34 }
35}
36
37impl Drop for Shelter {
38 fn drop(&mut self) {
39 unsafe { Rf_unprotect(self.nprotected) }
40 }
41}