1use ::rdll::*;
2use ::storage::*;
3use ::traits::*;
4use ::rtype::*;
5use ::protect::stackp::*;
6use error::*;
7use error::REKind::NotCompatible;
8use std::ops::Range;
9use std::os::raw::c_int;
10pub type BoolVec = BoolVecM<Preserve>;
11
12impl<T: SEXPbucket> BoolVecM<T> {
13 pub fn new(x: SEXP) -> RResult<BoolVecM<T>> {
14 if RTYPEOF(x) != LGLSXP {
15 return rerror(NotCompatible("expecting a numeric vector".into()));
16 }
17 Ok(BoolVecM { data: T::new(x) })
18 }
19 pub fn alloc(x: usize) -> BoolVecM<T> {
20 BoolVecM { data: T::new(unsafe { Rf_allocVector(LGLSXP, x as R_xlen_t) }) }
21 }
22 pub fn alloc_matrix(x: usize, y: usize) -> BoolVecM<T> {
23 BoolVecM {
24 data: T::new(unsafe {
25 Rf_allocMatrix(LGLSXP,
26 x as ::std::os::raw::c_int,
27 y as ::std::os::raw::c_int)
28 }),
29 }
30 }
31 pub fn at(&self, ind: usize) -> Option<bool> {
32 unsafe {
33 if Rf_xlength(self.s()) <= ind as R_xlen_t {
34 return None;
35 }
36 let ptr = LOGICAL(self.s());
37
38 Some(*ptr.offset(ind as isize) == 1)
39 }
40 }
41 pub unsafe fn uat(&self, ind: usize) -> bool {
42 let ptr = LOGICAL(self.s());
43 *ptr.offset(ind as isize) == 1
44 }
45 pub unsafe fn uset(&mut self, ind: usize, value: bool) {
46 let ptr = LOGICAL(self.s());
47 *ptr.offset(ind as isize) = value as c_int;
48 }
49 pub fn set(&mut self, ind: usize, value: bool) -> RResult<()> {
50 unsafe {
51 if Rf_xlength(self.s()) < ind as R_xlen_t {
52 return rraise("index out of bound");
53 }
54 let ptr = LOGICAL(self.s());
55 *ptr.offset(ind as isize) = value as c_int;
56 Ok(())
57 }
58 }
59 pub fn range(&self, ind: Range<usize>) -> Option<Vec<bool>> {
60 unsafe {
61 if Rf_xlength(self.s()) <= ind.end as R_xlen_t {
62 return None;
63 }
64 let mut vecs = Vec::with_capacity(ind.len() as usize);
65 let ptr = LOGICAL(self.s());
66 for ii in ind {
67 vecs.push(*ptr.offset(ii as isize) == 1);
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}
81
82
83
84impl<T: SEXPbucket, E: Into<bool> + Clone> From<Vec<E>> for BoolVecM<T> {
85 fn from(x: Vec<E>) -> BoolVecM<T> {
86 let size_x = x.len();
87 unsafe {
88 let rvec = Shield::new(Rf_allocVector(LGLSXP, size_x as R_xlen_t));
89 let rptr = LOGICAL(rvec.s());
90 for ii in 0..size_x {
91 *rptr.offset(ii as isize) =
92 (*x.get_unchecked(ii as usize)).clone().into() as ::std::os::raw::c_int;
93 }
94 BoolVecM { data: T::new(rvec.s()) }
95 }
96 }
97}
98
99impl<T: SEXPbucket> From<BoolVecM<T>> for Vec<bool> {
100 fn from(x: BoolVecM<T>) -> Vec<bool> {
101 unsafe {
102 let lens = Rf_xlength(x.s());
103 let mut vecs = Vec::with_capacity(lens as usize);
104 let rptr = LOGICAL(x.s());
105 for ii in 0..lens {
106 vecs.push(*rptr.offset(ii as isize) == 1);
107 }
108 vecs
109 }
110 }
111}
112
113impl<T: SEXPbucket> URNew for BoolVecM<T> {
114 unsafe fn urnew(x: SEXP) -> Self {
115 BoolVecM { data: T::new(x) }
116 }
117}
118
119impl<T: SEXPbucket> RNew for BoolVecM<T> {
120 fn rnew(x: SEXP) -> RResult<Self> {
121 Self::new(x)
122 }
123}
124
125impl<T: SEXPbucket> RSize for BoolVecM<T> {
126 fn rsize(&self) -> R_xlen_t {
127 unsafe { Rf_xlength(self.s()) }
128 }
129}
130
131gen_traits_sexp!(BoolVecM);
132
133
134impl<T: SEXPbucket> RName for BoolVecM<T> {}
135impl<T: SEXPbucket> RDim for BoolVecM<T> {
136 type Output = bool;
137}
138
139#[derive(Debug)]
140pub struct BoolVecIter<T: SEXPbucket> {
141 data: *mut ::std::os::raw::c_int,
142 size: R_xlen_t,
143 next: R_xlen_t,
144 ty: BoolVecM<T>,
145}
146
147impl<T: SEXPbucket> Iterator for BoolVecIter<T> {
148 type Item = bool;
150
151 fn next(&mut self) -> Option<bool> {
153 if self.next < self.size {
156 self.next += 1;
157 unsafe { Some(*self.data.offset((self.next - 1) as isize) == 1) }
158 } else {
159 None
160 }
161
162 }
163}
164
165impl<T: SEXPbucket> IntoIterator for BoolVecM<T> {
166 type Item = bool;
167 type IntoIter = BoolVecIter<T>;
168
169 fn into_iter(self) -> Self::IntoIter {
170 unsafe {
171 BoolVecIter {
172 data: LOGICAL(self.s()),
173 size: self.rsize(),
174 next: 0,
175 ty: self,
176 }
177 }
178 }
179}
180
181impl<T: SEXPbucket> ExactSizeIterator for BoolVecIter<T> {
182 fn len(&self) -> usize {
184 self.size as usize
185 }
186}
187
188
189
190#[macro_export]
193macro_rules! boolvec {
194 ($($tts:expr),*) => {
195 {let size = <[()]>::len(&[$(replace_expr!($tts, ())),*]);
197
198 let mut res = BoolVec::alloc(size as usize);
200 unsafe{
201 let mut x = 0;
202 $(
203 x += 1;
205 res.uset(x-1 as usize, $tts);
206
207 )*
208 }
209 res
210 }
211 };
212
213 ($($id:ident ~ $tts:expr),*) => {
214 {let size = <[()]>::len(&[$(replace_expr!($tts, ())),*]);
216
217 let mut res = BoolVec::alloc(size as usize);
219 let mut name = CharVec::alloc(size as usize);
220 unsafe{
221 let mut x = 0;
222 $(
223 x += 1;
225 res.uset(x-1 as usize , $tts);
226 name.uset(x-1, stringify!($id));
227 )*
228 }
229 unsafe{Rf_setAttrib(res.s(), R_NamesSymbol,name.s());}
230 res
231 }
232 }
233}