rustr/protect/
indexp.rs

1use ::rdll::*;
2use ::traits::*;
3
4/// Armor
5///
6/// save index in Armor
7
8pub struct Armor {
9    data: SEXP,
10    index: PROTECT_INDEX,
11}
12
13impl Armor {
14    /// return R_NilValue 
15    pub fn empty() -> Armor {
16        unsafe {
17            Armor {
18                data: R_NilValue,
19                index: -1,
20            }
21        }
22    }
23
24    /// create from a SEXP
25    pub fn new<T: ToSEXP>(x: T) -> Armor {
26        let mut res = Armor::empty();
27        unsafe {
28            res.init(x.s());
29        }
30
31        res
32    }
33
34    /// protect with index in new, and will be asigned later
35    pub unsafe fn init(&mut self, x: SEXP) {
36        let index: *mut PROTECT_INDEX = &mut (self.index);
37        R_ProtectWithIndex(x, index);
38    }
39
40    pub fn reassign<T: ToSEXP>(&mut self, x: T) -> &SEXP {
41        unsafe {
42            self.data = x.s();
43            R_Reprotect(self.data, self.index);
44            &(self.data)
45        }
46    }
47}
48
49impl Drop for Armor {
50    fn drop(&mut self) {
51        unsafe {
52            if self.index >= 0 {
53                Rf_unprotect(1);
54            }
55        }
56    }
57}
58
59impl Moves for Armor {
60    fn moves(mut other: Armor) -> Armor {
61        let res = Armor {
62            data: other.data,
63            index: other.index,
64        };
65        other.index = -1;
66        unsafe {
67            other.data = R_NilValue;
68        }
69
70        res
71    }
72}
73
74impl ToSEXP for Armor {
75    unsafe fn s(&self) -> SEXP {
76        self.data
77    }
78}