rustr/
storage.rs

1//! Preserve and Unprotect SEXP struct
2//!
3
4use ::rdll::*;
5use ::protect::*;
6use ::traits::*;
7use ::util::*;
8use ::error::*;
9use ::error::REKind::*;
10
11// pub enum RType{
12// 	CHAR(Preserve),
13// 	LGL(Preserve),
14// 	INT(Preserve),
15// 	REAL(Preserve),
16// 	CPLX(Preserve),
17// 	STR(Preserve),
18// 	VEC(Preserve),
19// 	S4(Preserve),
20// 	RAW(Preserve),
21// 	EXPR(Preserve),
22// }
23
24pub type Pre = Preserve;
25pub type Nop = NoProtect;
26
27#[derive(PartialEq, Eq, Debug)]
28pub struct Preserve {
29    data: SEXP,
30}
31
32pub trait SEXPbucket :Drop+ToSEXP {
33    fn init() -> Self;
34    fn new(x: SEXP) -> Self;
35    fn invalidate(&mut self) -> SEXP;
36    fn inherits(&self, class_: &str) -> RResult<bool>;
37    fn set(&mut self, x: SEXP);
38    fn copy<'a, 'b>(&'a mut self, other: &'b Self) -> &'a Self;
39}
40
41impl SEXPbucket for Preserve {
42    fn init() -> Preserve {
43        unsafe { Preserve { data: R_NilValue } }
44
45    }
46
47    fn new(x: SEXP) -> Preserve {
48        unsafe {
49            rustr_preserve_object(x);
50        }
51
52        Preserve { data: x }
53    }
54
55    fn invalidate(&mut self) -> SEXP {
56        let out = self.data;
57        unsafe {
58            self.data = R_NilValue;
59        }
60        out
61    }
62
63    fn inherits(&self, class_: &str) -> RResult<bool> {
64        let class = match cstring_user(class_) {
65            Ok(x) => x,
66            Err(y) => return rerror(Other(y.into())),
67        };
68
69        unsafe { Ok(Rf_inherits(self.data, class.as_ptr()) == Rboolean::TRUE) }
70    }
71
72
73    fn set(&mut self, x: SEXP) {
74
75        unsafe {
76            self.data = rustr_replace_object(self.data, x);
77        }
78        // calls the update method of CLASS
79        // this is where to react to changes in the underlying SEXP
80
81        // todo
82        // static_cast<CLASS&>(*this).update(data) ; 调用父类方法
83        //
84    }
85
86    // template <typename T>
87    //
88    // life time example result have the same life time as self
89    fn copy<'a, 'b>(&'a mut self, other: &'b Preserve) -> &'a Preserve {
90        if self != other {
91            self.set(unsafe { other.s() });
92        }
93        self
94    }
95}
96
97impl Drop for Preserve {
98    fn drop(&mut self) {
99        unsafe {
100            rustr_release_object(self.data);
101            self.data = R_NilValue;
102        }
103    }
104}
105
106impl ToSEXP for Preserve {
107    unsafe fn s(&self) -> SEXP {
108        self.data
109    }
110}
111
112impl From<SEXP> for Preserve {
113    fn from(x: SEXP) -> Preserve {
114        Preserve::new(x)
115    }
116}
117
118/// ///////////////// noprotect
119#[derive(PartialEq, Eq, Debug)]
120pub struct NoProtect {
121    data: SEXP,
122}
123
124pub type RInput = NoProtect;
125
126impl SEXPbucket for NoProtect {
127    fn init() -> NoProtect {
128        unsafe { NoProtect { data: R_NilValue } }
129
130    }
131
132    fn new(x: SEXP) -> NoProtect {
133        NoProtect { data: x }
134    }
135
136    fn invalidate(&mut self) -> SEXP {
137        let out = self.data;
138        unsafe {
139            self.data = R_NilValue;
140        }
141        out
142    }
143    fn inherits(&self, class_: &str) -> RResult<bool> {
144        let class = match cstring_user(class_) {
145            Ok(x) => x,
146            Err(y) => return rerror(Other(y.into())), // nul string error
147        };
148
149        unsafe { Ok(Rf_inherits(self.data, class.as_ptr()) == Rboolean::TRUE) }
150    }
151
152
153    fn set(&mut self, x: SEXP) {
154
155        self.data = x;
156
157        // calls the update method of CLASS
158        // this is where to react to changes in the underlying SEXP
159
160        // todo
161        // static_cast<CLASS&>(*this).update(data) ; 调用父类方法
162        //
163    }
164
165    // template <typename T>
166    //
167    // life time example result have the same life time as self
168    fn copy<'a, 'b>(&'a mut self, other: &'b NoProtect) -> &'a NoProtect {
169        if self != other {
170            self.set(unsafe { other.s() });
171        }
172        self
173    }
174}
175
176impl Drop for NoProtect {
177    fn drop(&mut self) {
178
179        unsafe {
180            self.data = R_NilValue;
181        }
182
183    }
184}
185
186impl ToSEXP for NoProtect {
187    unsafe fn s(&self) -> SEXP {
188        self.data
189    }
190}
191
192impl From<SEXP> for NoProtect {
193    fn from(x: SEXP) -> NoProtect {
194        NoProtect::new(x)
195    }
196}