extendr_api/wrapper/
macros.rs1macro_rules! gen_vector_wrapper_impl {
3 (
4 vector_type: $type : ident,
5 scalar_type: $scalar_type : ty,
6 primitive_type: $primitive_type : ty,
7 r_prefix: $r_prefix : ident,
8 SEXP: $sexp : ident,
9 doc_name: $doc_name : ident,
10 altrep_constructor: $altrep_constructor : ident,
11 ) => {
12
13 impl Attributes for $type {}
14
15 impl Default for $type {
16 fn default() -> Self {
17 $type::new(0)
18 }
19 }
20
21 impl From<Option<$type>> for Robj {
22 fn from(value: Option<$type>) -> Self {
23 match value {
24 None => nil_value(),
25 Some(value) => value.into(),
26 }
27 }
28 }
29
30 impl $type {
31 paste::paste!{
32 #[doc = "Create a new vector of " $type:lower "."]
33 #[doc = "```"]
34 #[doc = "use extendr_api::prelude::*;"]
35 #[doc = "test! {"]
36 #[doc = " let vec = " $type "::new(10);"]
37 #[doc = " assert_eq!(vec.is_" $r_prefix:lower "(), true);"]
38 #[doc = " assert_eq!(vec.len(), 10);"]
39 #[doc = "}"]
40 #[doc = "```"]
41 pub fn new(len: usize) -> $type {
43 let iter = (0..len).map(|_| <$primitive_type>::default());
45 <$type>::from_values(iter)
46 }
47
48 pub fn new_with_na(len: usize) -> $type {
50 let iter = (0..len).map(|_| <$primitive_type>::na());
51 <$type>::from_values(iter)
52 }
53 }
54 paste::paste!{
55 #[doc = "Wrapper for creating non-ALTREP " $doc_name " (" $sexp ") vectors from iterators."]
56 #[doc = "The iterator must be exact."]
57 #[doc = "If you want a more generalised constructor, use `iter.collect::<" $type ">()`."]
58 pub fn from_values<V>(values: V) -> Self
59 where
60 V: IntoIterator,
61 V::IntoIter: ExactSizeIterator,
62 V::Item: Into<$scalar_type>,
63 {
64 single_threaded(|| {
65 let values: V::IntoIter = values.into_iter();
66
67 let mut robj = Robj::alloc_vector($sexp, values.len());
68 let dest: &mut [$scalar_type] = robj.as_typed_slice_mut().unwrap();
69
70 for (d, v) in dest.iter_mut().zip(values) {
71 *d = v.into();
72 }
73 Self { robj }
74 })
75 }
76 }
77
78 paste::paste!{
79 #[doc = "Wrapper for creating ALTREP " $doc_name " (" $sexp ") vectors from iterators."]
80 #[doc = "The iterator must be exact, cloneable and implement Debug."]
81 #[doc = "If you want a more generalised constructor, use `iter.collect::<" $type ">()`."]
82 pub fn from_values_altrep<V>(values: V) -> Self
83 where
84 V: IntoIterator,
85 V::IntoIter: ExactSizeIterator + std::fmt::Debug + Clone + 'static + std::any::Any,
86 V::Item: Into<$scalar_type>,
87 {
88 single_threaded(|| {
89 let values: V::IntoIter = values.into_iter();
90
91 let robj =
92 Altrep::$altrep_constructor(values)
93 .try_into()
94 .unwrap();
95 Self { robj }
96 })
97 }
98 }
99
100 paste::paste! {
101 #[doc = "Get a single element from the vector."]
102 #[doc = "Note that this is very inefficient in a tight loop."]
103 #[doc = "```"]
104 #[doc = "use extendr_api::prelude::*;"]
105 #[doc = "test! {"]
106 #[doc = " let vec = " $type "::new(10);"]
107 #[doc = " assert_eq!(vec.elt(0), <"$scalar_type ">::default());"]
108 #[doc = " assert_eq!(vec.elt(9), <"$scalar_type ">::default());"]
109 #[doc = " assert!(vec.elt(10).is_na());"]
110 #[doc = "}"]
111 #[doc = "```"]
112 pub fn elt(&self, index: usize) -> $scalar_type {
113 use extendr_ffi::{R_xlen_t};
114 if(index >= self.len()) {
117 <$scalar_type>::na()
118 } else {
119 unsafe { extendr_ffi::[<$r_prefix _ELT>](self.get(), index as R_xlen_t).into() }
120 }
121 }
122 }
123
124 paste::paste!{
125 #[doc = "Return an iterator for a " $doc_name " object."]
126 #[doc = "Forces ALTREP objects to manifest."]
127 pub fn iter(&self) -> impl Iterator<Item = $scalar_type> {
128 self.as_robj().as_typed_slice().unwrap().iter().cloned()
129 }
130 }
131
132 paste::paste!{
133 #[doc = "Return a writable iterator for a " $doc_name " object."]
134 #[doc = "Forces ALTREP objects to manifest."]
135 pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut $scalar_type> {
136 self.as_robj_mut().as_typed_slice_mut().unwrap().iter_mut()
137 }
138 }
139 }
140
141 impl FromIterator<$scalar_type> for $type {
142 fn from_iter<T: IntoIterator<Item = $scalar_type>>(iter: T) -> Self {
145 let values: Vec<$scalar_type> = iter.into_iter().collect();
148
149 let mut robj = Robj::alloc_vector($sexp, values.len());
150 let dest: &mut [$scalar_type] = robj.as_typed_slice_mut().unwrap();
151
152 for (d, v) in dest.iter_mut().zip(values) {
153 *d = v;
154 }
155
156 $type { robj }
157 }
158 }
159 }
160}
161
162macro_rules! gen_from_iterator_impl {
163 (
164 vector_type: $type : ident,
165 collect_from_type: $collect_from_type : ty,
166 underlying_type: $underlying_type : ty,
167 SEXP: $sexp : ident,
168 assignment: $assignment : expr
169 ) => {
170 impl FromIterator<$collect_from_type> for $type {
171 fn from_iter<T: IntoIterator<Item = $collect_from_type>>(iter: T) -> Self {
174 let values: Vec<$collect_from_type> = iter.into_iter().collect();
177
178 let mut robj = Robj::alloc_vector($sexp, values.len());
179 let dest: &mut [$underlying_type] = robj.as_typed_slice_mut().unwrap();
180
181 for (d, v) in dest.iter_mut().zip(values) {
182 $assignment(d, v)
183 }
184
185 $type { robj }
186 }
187 }
188
189 impl<'a> FromIterator<&'a $collect_from_type> for $type {
190 fn from_iter<T: IntoIterator<Item = &'a $collect_from_type>>(iter: T) -> Self {
193 let values: Vec<&'a $collect_from_type> = iter.into_iter().collect();
196
197 let mut robj = Robj::alloc_vector($sexp, values.len());
198 let dest: &mut [$underlying_type] = robj.as_typed_slice_mut().unwrap();
199
200 for (d, v) in dest.iter_mut().zip(values) {
201 $assignment(d, *v)
202 }
203
204 $type { robj }
205 }
206 }
207 };
208}
209
210pub(in crate::wrapper) use gen_from_iterator_impl;
211pub(in crate::wrapper) use gen_vector_wrapper_impl;