Skip to main content

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}