rustr/vectorx/
list.rs

1use ::rdll::*;
2use ::storage::*;
3use ::traits::*;
4use ::rtype::*;
5use ::protect::stackp::*;
6use error::*;
7use error::REKind::NotCompatible;
8use std::ops::Range;
9use util::*;
10use super::CharVec;
11use vector::IntVec;
12
13pub type RList = RListM<Preserve>;
14
15
16impl<T: SEXPbucket> RListM<T> {
17    pub fn new(x: SEXP) -> RResult<RListM<T>> {
18
19        if RTYPEOF(x) != VECSXP {
20            return rerror(NotCompatible("expecting a list".into()));
21        }
22
23        Ok(RListM { data: T::new(x) })
24    }
25    pub fn alloc(x: usize) -> RListM<T> {
26        RListM { data: T::new(unsafe { Rf_allocVector(VECSXP, x as R_xlen_t) }) }
27    }
28    pub fn alloc_matrix(x: usize, y: usize) -> RListM<T> {
29        RListM {
30            data: T::new(unsafe {
31                Rf_allocMatrix(VECSXP,
32                               x as ::std::os::raw::c_int,
33                               y as ::std::os::raw::c_int)
34            }),
35        }
36    }
37    pub fn at(&self, ind: usize) -> Option<SEXP> {
38        unsafe {
39            if Rf_xlength(self.s()) <= ind as R_xlen_t {
40                return None;
41            }
42            Some(VECTOR_ELT(self.s(), ind as R_xlen_t))
43        }
44    }
45    pub unsafe fn uat(&self, ind: usize) -> SEXP {
46        VECTOR_ELT(self.s(), ind as R_xlen_t)
47    }
48    pub unsafe fn uset<TT: ToSEXP>(&mut self, ind: usize, value: TT) {
49        SET_VECTOR_ELT(self.s(), ind as R_xlen_t, value.s());
50    }
51    pub fn set<TT: ToSEXP>(&mut self, ind: usize, value: TT) -> RResult<()> {
52        unsafe {
53            if Rf_xlength(self.s()) <= ind as R_xlen_t {
54                return rraise("index out of bound");
55            }
56            SET_VECTOR_ELT(self.s(), ind as R_xlen_t, value.s());
57            Ok(())
58        }
59    }
60    pub fn range(&self, ind: Range<usize>) -> Option<Vec<SEXP>> {
61        unsafe {
62            if Rf_xlength(self.s()) <= ind.end as R_xlen_t {
63                return None;
64            }
65            let mut vecs = Vec::with_capacity((ind.end - ind.start) as usize);
66            for ii in ind {
67                vecs.push(VECTOR_ELT(self.s(), ii as R_xlen_t));
68            }
69            Some(vecs)
70        }
71    }
72    pub fn is_duplicated(&self, from_last: bool) -> R_xlen_t {
73        let last = if from_last {
74            Rboolean::TRUE
75        } else {
76            Rboolean::FALSE
77        };
78        unsafe { Rf_any_duplicated(self.s(), last) }
79    }
80    pub fn as_data_frame(&mut self)->RResult<()>{
81    	if self.rsize() == 0{
82    		unsafe{
83            Rf_setAttrib(self.s(), R_NamesSymbol, Rf_allocVector(STRSXP, 0));
84            Rf_setAttrib(self.s(), R_RowNamesSymbol, Rf_allocVector(INTSXP, 0));
85            Rf_setAttrib(self.s(), R_ClassSymbol, Rf_mkString(c_str("data.frame").as_ptr()));
86    		}
87            return Ok(());
88    	}
89    	unsafe{
90    		if self.namesexp() == R_NilValue{
91    			let mut colname = CharVec::alloc(self.rsize() as usize);
92    			for ii in 0..(self.rsize() as usize){
93    				colname.uset(ii, &format!("col{}", ii+1));
94    			}
95    			self.uset_name(&colname);
96    		}
97 			let colsize : usize = Rf_xlength(self.uat(0)) as usize ;
98 			for ii in 0..(self.rsize() as usize){
99    			if colsize  != Rf_xlength(self.uat(ii)) as usize {
100    				return rraise("not all colunm are the same length.");
101    			}
102			}
103 			let mut rowname = IntVec::alloc(colsize as usize);
104			for ii in 0..(self.rsize() as usize){
105    				rowname.uset(ii, (ii as ::std::os::raw::c_int)+1);
106			}
107            Rf_setAttrib(self.s(), R_RowNamesSymbol, rowname.s());
108			Rf_setAttrib(self.s(), R_ClassSymbol, Rf_mkString(c_str("data.frame").as_ptr()));
109    		Ok(())
110    	}
111    }
112}
113
114#[cfg_attr(feature = "dev",allow(explicit_counter_loop))]
115impl<T: SEXPbucket, E: UIntoR + Clone> From<Vec<E>> for RListM<T> {
116    fn from(x: Vec<E>) -> RListM<T> {
117        let size_x = x.len();
118        unsafe {
119            let rvec = Shield::new(Rf_allocVector(VECSXP, size_x as R_xlen_t));
120            let mut xs = 0;
121            for ii in x {
122                SET_VECTOR_ELT(rvec.s(), xs, Shield::new(ii.uintor()).s());
123                xs += 1;
124            }
125            RListM { data: T::new(rvec.s()) }
126        }
127    }
128}
129
130// impl<T: SEXPbucket,D:URNew> From<RListM<T>> for Vec<D> {
131//    fn from(x: RListM<T>) -> Vec<D> {
132//        unsafe {
133//            let lens = Rf_xlength(x.s());
134//            let mut vecs = Vec::with_capacity(lens as usize);
135//            for ii in 0..lens {
136//                vecs.push(D::urnew(VECTOR_ELT(x.s(), ii)));
137//            }
138//            vecs
139//        }
140//    }
141// }
142
143
144impl<T: SEXPbucket> URNew for RListM<T> {
145    unsafe fn urnew(x: SEXP) -> Self {
146        RListM { data: T::new(x) }
147    }
148}
149
150impl<T: SEXPbucket> RNew for RListM<T> {
151    fn rnew(x: SEXP) -> RResult<Self> {
152        Self::new(x)
153    }
154}
155
156impl<T: SEXPbucket> RSize for RListM<T> {
157    fn rsize(&self) -> R_xlen_t {
158        unsafe { Rf_xlength(self.s()) }
159    }
160}
161
162gen_traits_sexp!(RListM);
163
164
165impl<T: SEXPbucket> RName for RListM<T> {}
166impl<T: SEXPbucket> RDim for RListM<T> {
167    type Output = SEXP;
168}
169
170#[derive(Debug)]
171pub struct RListIter<T: SEXPbucket> {
172    size: R_xlen_t,
173    next: R_xlen_t,
174    ty: RListM<T>,
175}
176
177impl<T: SEXPbucket> Iterator for RListIter<T> {
178    // we will be counting with usize
179    type Item = SEXP;
180
181    // next() is the only required method
182    fn next(&mut self) -> Option<SEXP> {
183        // increment our count. This is why we started at zero.
184        // check to see if we've finished counting or not.
185        if self.next < self.size {
186            self.next += 1;
187            unsafe { Some(VECTOR_ELT(self.ty.s(), self.next - 1)) }
188        } else {
189            None
190        }
191
192    }
193}
194
195impl<T: SEXPbucket> IntoIterator for RListM<T> {
196    type Item = SEXP;
197    type IntoIter = RListIter<T>;
198
199    fn into_iter(self) -> Self::IntoIter {
200        RListIter {
201            size: self.rsize(),
202            next: 0,
203            ty: self,
204        }
205    }
206}
207
208impl<T: SEXPbucket> ExactSizeIterator for RListIter<T> {
209    // We already have the number of iterations, so we can use it directly.
210    fn len(&self) -> usize {
211        self.size as usize
212    }
213}
214
215/// Helper for the number of arguments 
216///
217#[macro_export]
218macro_rules! replace_expr {
219    ($_t:expr, $sub:expr) => {$sub};
220}
221
222/// Create a RList
223///
224#[macro_export]
225macro_rules! rlist {
226    ($($tts:expr),*) => {
227      // count macro parameter learn from rust macro book	
228      {let size = <[()]>::len(&[$(replace_expr!($tts, ())),*]);
229      	
230      // init 
231      let mut res = RList::alloc(size as usize);
232	  unsafe{
233      let mut x = 0;
234      $(
235			// skip a warning message 
236			x += 1;
237      		res.uset(x-1, $tts.intor()?);
238      		
239      )*      
240	}
241      res
242      }
243    };
244    
245    ($($id:ident ~ $tts:expr),*) => {
246      // count macro parameter learn from rust macro book	
247      {let size = <[()]>::len(&[$(replace_expr!($tts, ())),*]);
248      	
249      // init 
250      let mut res = RList::alloc(size as usize);
251	  let mut name = CharVec::alloc(size as usize);
252	  unsafe{
253      let mut x = 0;
254      $(
255			// skip a warning message 
256			x += 1;
257      		res.uset(x-1, $tts.intor()?);
258      		name.uset(x-1, stringify!($id));
259      )*
260	}
261	  unsafe{Rf_setAttrib(res.s(), R_NamesSymbol,name.s());}
262      res
263      }
264    }
265}
266
267/// Create a rlist with unsafe code
268/// 
269
270#[macro_export]
271macro_rules! urlist {
272    ($($tts:expr),*) => {
273      // count macro parameter learn from rust macro book	
274      {let size = <[()]>::len(&[$(replace_expr!($tts, ())),*]);
275      	
276      // init 
277      let mut res = RList::alloc(size as usize);
278      let mut x = 0;
279      $(
280			// skip a warning message 
281			x += 1;
282      		res.uset(x-1, $tts.uintor());
283      		
284      )*      
285      res
286      }
287    };
288        ($($id:ident ~ $tts:expr),*) => {
289      // count macro parameter learn from rust macro book	
290      {let size = <[()]>::len(&[$(replace_expr!($tts, ())),*]);
291      	
292      // init 
293      let mut res = RList::alloc(size as usize);
294	  let mut name = CharVec::alloc(size as usize);
295
296      let mut x = 0;
297      $(
298			// skip a warning message 
299			x += 1;
300      		res.uset(x-1, $tts.uintor());
301      		name.uset(x-1, stringify!($id));
302      )*
303	
304	  Rf_setAttrib(res.s(), R_NamesSymbol,name.s());
305      res
306      }
307    }
308}