savvy/sexp/integer.rs
1use std::ops::{Index, IndexMut};
2
3use savvy_ffi::{INTEGER, INTSXP, SEXP};
4
5use super::utils::assert_len;
6use super::{impl_common_sexp_ops, impl_common_sexp_ops_owned, Sexp};
7use crate::protect::{self, local_protect};
8use crate::NotAvailableValue; // for na()
9
10/// An external SEXP of an integer vector.
11pub struct IntegerSexp(pub SEXP);
12
13/// A newly-created SEXP of an integer vector.
14pub struct OwnedIntegerSexp {
15 inner: SEXP,
16 token: SEXP,
17 len: usize,
18 raw: *mut i32,
19}
20
21// implement inner(), len(), empty(), and name()
22impl_common_sexp_ops!(IntegerSexp);
23impl_common_sexp_ops_owned!(OwnedIntegerSexp);
24
25impl IntegerSexp {
26 /// Extracts a slice containing the underlying data of the SEXP.
27 ///
28 /// # Examples
29 ///
30 /// ```
31 /// # let int_sexp = savvy::OwnedIntegerSexp::try_from_slice([1, 2, 3])?.as_read_only();
32 /// // `int_sexp` is c(1L, 2L, 3L)
33 /// assert_eq!(int_sexp.as_slice(), &[1, 2, 3]);
34 /// ```
35 pub fn as_slice(&self) -> &[i32] {
36 if self.is_empty() {
37 return &[];
38 }
39 unsafe { std::slice::from_raw_parts(INTEGER(self.inner()) as _, self.len()) }
40 }
41
42 /// Returns an iterator over the underlying data of the SEXP.
43 ///
44 /// # Examples
45 ///
46 /// ```
47 /// # let int_sexp = savvy::OwnedIntegerSexp::try_from_slice([1, 2, 3])?.as_read_only();
48 /// // `int_sexp` is c(1L, 2L, 3L)
49 /// let mut iter = int_sexp.iter();
50 /// assert_eq!(iter.next(), Some(&1));
51 /// assert_eq!(iter.as_slice(), &[2, 3]);
52 /// ```
53 ///
54 /// # Technical Note
55 ///
56 /// If the input is an ALTREP, this materialize it first, so it might not be
57 /// most efficient. However, it seems Rust's slice implementation is very
58 /// fast, so probably being efficient for ALTREP is not worth giving up the
59 /// benefit.
60 pub fn iter<'a>(&'a self) -> std::slice::Iter<'a, i32> {
61 self.as_slice().iter()
62 }
63
64 /// Copies the underlying data of the SEXP into a new `Vec`.
65 ///
66 /// # Examples
67 ///
68 /// ```
69 /// # let int_sexp = savvy::OwnedIntegerSexp::try_from_slice([1, 2, 3])?.as_read_only();
70 /// // `int_sexp` is c(1L, 2L, 3L)
71 /// assert_eq!(int_sexp.to_vec(), vec![1, 2, 3]);
72 /// ```
73 pub fn to_vec(&self) -> Vec<i32> {
74 self.as_slice().to_vec()
75 }
76}
77
78impl OwnedIntegerSexp {
79 /// Returns the read-only version of the wrapper. This is mainly for testing
80 /// purposes.
81 pub fn as_read_only(&self) -> IntegerSexp {
82 IntegerSexp(self.inner)
83 }
84
85 /// Extracts a slice containing the underlying data of the SEXP.
86 ///
87 /// # Examples
88 ///
89 /// ```
90 /// use savvy::OwnedIntegerSexp;
91 ///
92 /// let int_sexp = OwnedIntegerSexp::try_from_slice([1, 2, 3])?;
93 /// assert_eq!(int_sexp.as_slice(), &[1, 2, 3]);
94 /// ```
95 pub fn as_slice(&self) -> &[i32] {
96 if self.len == 0 {
97 return &[];
98 }
99 unsafe { std::slice::from_raw_parts(self.raw, self.len) }
100 }
101
102 /// Extracts a mutable slice containing the underlying data of the SEXP.
103 ///
104 /// # Examples
105 ///
106 /// ```
107 /// use savvy::OwnedIntegerSexp;
108 ///
109 /// let mut int_sexp = OwnedIntegerSexp::new(3)?;
110 /// let s = int_sexp.as_mut_slice();
111 /// s[2] = 10;
112 /// assert_eq!(int_sexp.as_slice(), &[0, 0, 10]);
113 /// ```
114 pub fn as_mut_slice(&mut self) -> &mut [i32] {
115 if self.len == 0 {
116 return &mut [];
117 }
118 unsafe { std::slice::from_raw_parts_mut(self.raw, self.len) }
119 }
120
121 /// Returns an iterator over the underlying data of the SEXP.
122 pub fn iter<'a>(&'a self) -> std::slice::Iter<'a, i32> {
123 self.as_slice().iter()
124 }
125
126 /// Returns a mutable iterator over the underlying data of the SEXP.
127 ///
128 /// # Examples
129 ///
130 /// ```
131 /// use savvy::OwnedIntegerSexp;
132 ///
133 /// let mut int_sexp = OwnedIntegerSexp::try_from_slice([1, 2, 3])?;
134 /// int_sexp.iter_mut().for_each(|x| *x = *x * 2);
135 /// assert_eq!(int_sexp.as_slice(), &[2, 4, 6]);
136 /// ```
137 pub fn iter_mut<'a>(&'a mut self) -> std::slice::IterMut<'a, i32> {
138 self.as_mut_slice().iter_mut()
139 }
140
141 /// Copies the underlying data of the SEXP into a new `Vec`.
142 pub fn to_vec(&self) -> Vec<i32> {
143 self.as_slice().to_vec()
144 }
145
146 /// Set the value of the `i`-th element. `i` starts from `0`.
147 ///
148 /// # Examples
149 ///
150 /// ```
151 /// use savvy::OwnedIntegerSexp;
152 ///
153 /// let mut int_sexp = OwnedIntegerSexp::new(3)?;
154 /// int_sexp.set_elt(2, 10)?;
155 /// assert_eq!(int_sexp.as_slice(), &[0, 0, 10]);
156 /// ```
157 pub fn set_elt(&mut self, i: usize, v: i32) -> crate::error::Result<()> {
158 super::utils::assert_len(self.len, i)?;
159
160 unsafe { self.set_elt_unchecked(i, v) };
161
162 Ok(())
163 }
164
165 #[inline]
166 unsafe fn set_elt_unchecked(&mut self, i: usize, v: i32) {
167 unsafe { *(self.raw.add(i)) = v };
168 }
169
170 /// Set the `i`-th element to NA. `i` starts from `0`.
171 ///
172 /// # Examples
173 ///
174 /// ```
175 /// use savvy::OwnedIntegerSexp;
176 /// use savvy::NotAvailableValue;
177 ///
178 /// let mut int_sexp = OwnedIntegerSexp::new(3)?;
179 /// int_sexp.set_na(2)?;
180 /// assert_eq!(int_sexp.as_slice(), &[0, 0, <i32>::na()]);
181 /// ```
182 pub fn set_na(&mut self, i: usize) -> crate::error::Result<()> {
183 super::utils::assert_len(self.len, i)?;
184
185 unsafe { self.set_elt_unchecked(i, i32::na()) };
186
187 Ok(())
188 }
189
190 fn new_inner(len: usize, init: bool) -> crate::error::Result<Self> {
191 let inner = crate::alloc_vector(INTSXP, len as _)?;
192
193 // Fill the vector with default values
194 if len > 0 && init {
195 unsafe {
196 std::ptr::write_bytes(INTEGER(inner), 0, len);
197 }
198 }
199
200 Self::new_from_raw_sexp(inner, len)
201 }
202
203 /// Constructs a new, initialized integer vector.
204 ///
205 /// ```
206 /// let x = savvy::OwnedIntegerSexp::new(3)?;
207 /// assert_eq!(x.as_slice(), &[0, 0, 0]);
208 /// ```
209 pub fn new(len: usize) -> crate::error::Result<Self> {
210 Self::new_inner(len, true)
211 }
212
213 /// Constructs a new, **uninitialized** integer vector.
214 ///
215 /// This is an expert-only version of `new()`, which can be found useful
216 /// when you want to skip initialization and you are confident that the
217 /// vector will be filled with values later.
218 ///
219 /// For example, you can use this in `TryFrom` implementation.
220 ///
221 /// ```
222 /// use savvy::OwnedIntegerSexp;
223 ///
224 /// struct Pair {
225 /// x: i32,
226 /// y: i32
227 /// }
228 ///
229 /// impl TryFrom<Pair> for OwnedIntegerSexp {
230 /// type Error = savvy::Error;
231 ///
232 /// fn try_from(value: Pair) -> savvy::Result<Self> {
233 /// let mut out = unsafe { OwnedIntegerSexp::new_without_init(2)? };
234 /// out[0] = value.x;
235 /// out[1] = value.y;
236 ///
237 /// Ok(out)
238 /// }
239 /// }
240 ///
241 /// let pair = Pair { x: 1, y: 2 };
242 /// let int_sexp = <OwnedIntegerSexp>::try_from(pair)?;
243 /// assert_eq!(int_sexp.as_slice(), &[1, 2]);
244 /// ```
245 ///
246 /// # Safety
247 ///
248 /// As the memory is uninitialized, all elements must be filled values
249 /// before return.
250 pub unsafe fn new_without_init(len: usize) -> crate::error::Result<Self> {
251 Self::new_inner(len, false)
252 }
253
254 fn new_from_raw_sexp(inner: SEXP, len: usize) -> crate::error::Result<Self> {
255 let token = protect::insert_to_preserved_list(inner);
256 let raw = unsafe { INTEGER(inner) };
257
258 Ok(Self {
259 inner,
260 token,
261 len,
262 raw,
263 })
264 }
265
266 /// Constructs a new complex vector from an iterator.
267 ///
268 /// Note that, if you already have a slice or vec, [`try_from_slice()`][1]
269 /// is what you want. `try_from_slice` is more performant than
270 /// `try_from_iter` because it copies the underlying memory directly.
271 ///
272 /// [1]: `Self::try_from_slice()`
273 ///
274 /// # Examples
275 ///
276 /// ```
277 /// use savvy::OwnedIntegerSexp;
278 ///
279 /// let iter = (0..10).filter(|x| x % 2 == 0);
280 /// let int_sexp = OwnedIntegerSexp::try_from_iter(iter)?;
281 /// assert_eq!(int_sexp.as_slice(), &[0, 2, 4, 6, 8]);
282 /// ```
283 pub fn try_from_iter<I>(iter: I) -> crate::error::Result<Self>
284 where
285 I: IntoIterator<Item = i32>,
286 {
287 let iter = iter.into_iter();
288
289 match iter.size_hint() {
290 (_, Some(upper)) => {
291 // If the maximum length is known, use it at frist. But, the
292 // iterator's length might be shorter than the reported one
293 // (e.g. `(0..10).filter(|x| x % 2 == 0)`), so it needs to be
294 // truncated to the actual length at last.
295
296 let inner = crate::alloc_vector(INTSXP, upper as _)?;
297 let _inner_guard = local_protect(inner);
298 let raw = unsafe { INTEGER(inner) };
299
300 let mut last_index = 0;
301 for (i, v) in iter.enumerate() {
302 // The upper bound of size_hint() is just for optimization
303 // and what we should not trust.
304 assert_len(upper, i)?;
305 unsafe { *(raw.add(i)) = v };
306
307 last_index = i;
308 }
309
310 let new_len = last_index + 1;
311 if new_len == upper {
312 // If the length is the same as expected, use it as it is.
313 Self::new_from_raw_sexp(inner, upper)
314 } else {
315 // If the length is shorter than expected, re-allocate a new
316 // SEXP and copy the values into it.
317 let out = unsafe { Self::new_without_init(new_len)? };
318 let dst = unsafe { std::slice::from_raw_parts_mut(out.raw, new_len) };
319 // `raw` is longer than new_len, but the elements over new_len are ignored
320 let src = unsafe { std::slice::from_raw_parts(raw, new_len) };
321 dst.copy_from_slice(src);
322
323 Ok(out)
324 }
325 }
326 (_, None) => {
327 // When the length is not known at all, collect() it first.
328
329 let v: Vec<I::Item> = iter.collect();
330 v.try_into()
331 }
332 }
333 }
334
335 /// Constructs a new integer vector from a slice or vec.
336 ///
337 /// # Examples
338 ///
339 /// ```
340 /// use savvy::OwnedIntegerSexp;
341 ///
342 /// let int_sexp = OwnedIntegerSexp::try_from_slice([1, 2, 3])?;
343 /// assert_eq!(int_sexp.as_slice(), &[1, 2, 3]);
344 /// ```
345 pub fn try_from_slice<S>(x: S) -> crate::error::Result<Self>
346 where
347 S: AsRef<[i32]>,
348 {
349 let x_slice = x.as_ref();
350 let mut out = unsafe { Self::new_without_init(x_slice.len())? };
351 out.as_mut_slice().copy_from_slice(x_slice);
352 Ok(out)
353 }
354
355 /// Constructs a new integer vector from a scalar value.
356 ///
357 /// # Examples
358 ///
359 /// ```
360 /// use savvy::OwnedIntegerSexp;
361 ///
362 /// let int_sexp = OwnedIntegerSexp::try_from_scalar(1)?;
363 /// assert_eq!(int_sexp.as_slice(), &[1]);
364 /// ```
365 pub fn try_from_scalar(value: i32) -> crate::error::Result<Self> {
366 let sexp = unsafe { crate::unwind_protect(|| savvy_ffi::Rf_ScalarInteger(value))? };
367 Self::new_from_raw_sexp(sexp, 1)
368 }
369}
370
371impl Drop for OwnedIntegerSexp {
372 fn drop(&mut self) {
373 protect::release_from_preserved_list(self.token);
374 }
375}
376
377// conversions from/to IntegerSexp ***************
378
379impl TryFrom<Sexp> for IntegerSexp {
380 type Error = crate::error::Error;
381
382 fn try_from(value: Sexp) -> crate::error::Result<Self> {
383 value.assert_integer()?;
384 Ok(Self(value.0))
385 }
386}
387
388impl From<IntegerSexp> for Sexp {
389 fn from(value: IntegerSexp) -> Self {
390 Self(value.inner())
391 }
392}
393
394impl From<IntegerSexp> for crate::error::Result<Sexp> {
395 fn from(value: IntegerSexp) -> Self {
396 Ok(<Sexp>::from(value))
397 }
398}
399
400// conversions from/to OwnedIntegerSexp ***************
401
402impl TryFrom<&[i32]> for OwnedIntegerSexp {
403 type Error = crate::error::Error;
404
405 fn try_from(value: &[i32]) -> crate::error::Result<Self> {
406 Self::try_from_slice(value)
407 }
408}
409
410impl TryFrom<Vec<i32>> for OwnedIntegerSexp {
411 type Error = crate::error::Error;
412
413 fn try_from(value: Vec<i32>) -> crate::error::Result<Self> {
414 Self::try_from_slice(value)
415 }
416}
417
418impl TryFrom<i32> for OwnedIntegerSexp {
419 type Error = crate::error::Error;
420
421 fn try_from(value: i32) -> crate::error::Result<Self> {
422 Self::try_from_scalar(value)
423 }
424}
425
426impl From<OwnedIntegerSexp> for Sexp {
427 fn from(value: OwnedIntegerSexp) -> Self {
428 Self(value.inner())
429 }
430}
431
432impl From<OwnedIntegerSexp> for crate::error::Result<Sexp> {
433 fn from(value: OwnedIntegerSexp) -> Self {
434 Ok(<Sexp>::from(value))
435 }
436}
437
438macro_rules! impl_try_from_rust_integers {
439 ($ty: ty) => {
440 impl TryFrom<$ty> for Sexp {
441 type Error = crate::error::Error;
442
443 fn try_from(value: $ty) -> crate::error::Result<Self> {
444 <OwnedIntegerSexp>::try_from(value).map(|x| x.into())
445 }
446 }
447 };
448}
449
450impl_try_from_rust_integers!(&[i32]);
451impl_try_from_rust_integers!(Vec<i32>);
452impl_try_from_rust_integers!(i32);
453
454// Index for OwnedIntegerSexp ***************
455
456impl Index<usize> for OwnedIntegerSexp {
457 type Output = i32;
458
459 fn index(&self, index: usize) -> &Self::Output {
460 assert_len(self.len, index).unwrap();
461 unsafe { &*(self.raw.add(index)) }
462 }
463}
464
465impl IndexMut<usize> for OwnedIntegerSexp {
466 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
467 assert_len(self.len, index).unwrap();
468 unsafe { &mut *(self.raw.add(index)) }
469 }
470}
471
472#[cfg(feature = "savvy-test")]
473mod test {
474 use super::OwnedIntegerSexp;
475 use crate::NotAvailableValue;
476
477 #[test]
478 fn test_integer() -> crate::Result<()> {
479 let mut x = OwnedIntegerSexp::new(3)?;
480 assert_eq!(x.as_slice(), &[0, 0, 0]);
481
482 // set_elt()
483 x.set_elt(0, 1)?;
484 assert_eq!(x.as_slice(), &[1, 0, 0]);
485
486 // IndexMut
487 x[1] = 2;
488 assert_eq!(x.as_slice(), &[1, 2, 0]);
489
490 // set_na
491 x.set_na(2)?;
492 assert!(x[2].is_na());
493
494 Ok(())
495 }
496}