1use std::borrow::Cow;
13use std::ops::Range;
14
15use crate::{IsNA, RLogical, Rcomplex, SEXP};
16
17use super::{
18 AltComplexData, AltIntegerData, AltLogicalData, AltRawData, AltRealData, AltStringData,
19 AltrepDataptr, AltrepLen, AltrepSerialize, Logical, Sortedness,
20};
21
22macro_rules! impl_len_vec {
26 ($elem:ty) => {
27 impl AltrepLen for Vec<$elem> {
28 fn altrep_len(&self) -> usize {
29 Vec::len(self)
30 }
31 }
32 };
33}
34
35macro_rules! impl_len_boxed {
37 ($elem:ty) => {
38 impl AltrepLen for Box<[$elem]> {
39 fn altrep_len(&self) -> usize {
40 <[$elem]>::len(self)
41 }
42 }
43 };
44}
45
46macro_rules! impl_len_array {
48 ($elem:ty) => {
49 impl<const N: usize> AltrepLen for [$elem; N] {
50 fn altrep_len(&self) -> usize {
51 N
52 }
53 }
54 };
55}
56
57macro_rules! impl_len_slice {
59 ($elem:ty) => {
60 impl AltrepLen for &[$elem] {
61 fn altrep_len(&self) -> usize {
62 <[$elem]>::len(self)
63 }
64 }
65 };
66}
67
68macro_rules! impl_dataptr_vec {
70 ($elem:ty) => {
71 impl_dataptr_vec!($elem => $elem);
72 };
73 ($elem:ty => $storage:ty) => {
75 impl AltrepDataptr<$storage> for Vec<$elem> {
76 fn dataptr(&mut self, _writable: bool) -> Option<*mut $storage> {
77 Some(self.as_mut_ptr().cast())
78 }
79
80 fn dataptr_or_null(&self) -> Option<*const $storage> {
81 Some(self.as_ptr().cast())
82 }
83 }
84 };
85}
86
87macro_rules! impl_dataptr_boxed {
89 ($elem:ty) => {
90 impl_dataptr_boxed!($elem => $elem);
91 };
92 ($elem:ty => $storage:ty) => {
94 impl AltrepDataptr<$storage> for Box<[$elem]> {
95 fn dataptr(&mut self, _writable: bool) -> Option<*mut $storage> {
96 Some(self.as_mut_ptr().cast())
97 }
98
99 fn dataptr_or_null(&self) -> Option<*const $storage> {
100 Some(self.as_ptr().cast())
101 }
102 }
103 };
104}
105
106macro_rules! impl_serialize {
111 ($ty:ty) => {
112 impl_serialize!($ty, $ty, std::convert::identity);
113 };
114 ($ty:ty, $owned:ty, $wrap:expr) => {
115 impl AltrepSerialize for $ty {
116 fn serialized_state(&self) -> SEXP {
117 use crate::into_r::IntoR;
118 self.clone().into_sexp()
119 }
120
121 fn unserialize(state: SEXP) -> Option<Self> {
122 use crate::from_r::TryFromSexp;
123 <$owned>::try_from_sexp(state).ok().map($wrap)
124 }
125 }
126 };
127}
128macro_rules! impl_altinteger_slice {
151 ($ty:ty) => {
152 impl AltIntegerData for $ty {
153 fn elt(&self, i: usize) -> i32 {
154 self[i]
155 }
156
157 fn as_slice(&self) -> Option<&[i32]> {
158 let s: &[i32] = self;
159 Some(s)
160 }
161
162 fn get_region(&self, start: usize, len: usize, buf: &mut [i32]) -> usize {
163 let s: &[i32] = self;
164 let end = (start + len).min(s.len());
165 let actual_len = end.saturating_sub(start);
166 if actual_len > 0 {
167 buf[..actual_len].copy_from_slice(&s[start..end]);
168 }
169 actual_len
170 }
171
172 fn no_na(&self) -> Option<bool> {
173 let s: &[i32] = self;
174 Some(!s.iter().any(IsNA::is_na))
175 }
176
177 fn sum(&self, na_rm: bool) -> Option<i64> {
178 let s: &[i32] = self;
179 let mut sum: i64 = 0;
180 for &x in s.iter() {
181 if x.is_na() {
182 if !na_rm {
183 return None; }
185 } else {
186 sum += x as i64;
187 }
188 }
189 Some(sum)
190 }
191
192 fn min(&self, na_rm: bool) -> Option<i32> {
193 let s: &[i32] = self;
194 let mut min = i32::MAX;
195 let mut found = false;
196 for &x in s.iter() {
197 if x.is_na() {
198 if !na_rm {
199 return None;
200 }
201 } else {
202 found = true;
203 min = min.min(x);
204 }
205 }
206 if found { Some(min) } else { None }
207 }
208
209 fn max(&self, na_rm: bool) -> Option<i32> {
210 let s: &[i32] = self;
211 let mut max = i32::MIN + 1; let mut found = false;
213 for &x in s.iter() {
214 if x.is_na() {
215 if !na_rm {
216 return None;
217 }
218 } else {
219 found = true;
220 max = max.max(x);
221 }
222 }
223 if found { Some(max) } else { None }
224 }
225 }
226 };
227}
228
229fn real_slice_no_na(s: &[f64]) -> bool {
238 !s.iter().any(|x| x.is_nan())
239}
240
241fn real_slice_sum(s: &[f64], na_rm: bool) -> f64 {
249 let mut sum = 0.0;
250 let mut nan = false;
251 for &x in s {
252 if x.is_nan() {
253 if na_rm {
254 continue;
255 }
256 if x.is_na() {
257 return x;
258 }
259 nan = true;
260 } else {
261 sum += x;
262 }
263 }
264 if nan { f64::NAN } else { sum }
265}
266
267fn real_slice_extreme(s: &[f64], na_rm: bool, pick: fn(f64, f64) -> f64) -> Option<f64> {
275 let mut best: Option<f64> = None;
276 let mut nan = false;
277 for &x in s {
278 if x.is_nan() {
279 if na_rm {
280 continue;
281 }
282 if x.is_na() {
283 return Some(x);
284 }
285 nan = true;
286 } else {
287 best = Some(best.map_or(x, |b| pick(b, x)));
288 }
289 }
290 if nan { Some(f64::NAN) } else { best }
291}
292
293macro_rules! impl_altreal_slice {
301 ($ty:ty) => {
302 impl AltRealData for $ty {
303 fn elt(&self, i: usize) -> f64 {
304 self[i]
305 }
306
307 fn as_slice(&self) -> Option<&[f64]> {
308 let s: &[f64] = self;
309 Some(s)
310 }
311
312 fn get_region(&self, start: usize, len: usize, buf: &mut [f64]) -> usize {
313 let s: &[f64] = self;
314 let end = (start + len).min(s.len());
315 let actual_len = end.saturating_sub(start);
316 if actual_len > 0 {
317 buf[..actual_len].copy_from_slice(&s[start..end]);
318 }
319 actual_len
320 }
321
322 fn no_na(&self) -> Option<bool> {
323 Some(real_slice_no_na(self))
324 }
325
326 fn sum(&self, na_rm: bool) -> Option<f64> {
327 Some(real_slice_sum(self, na_rm))
328 }
329
330 fn min(&self, na_rm: bool) -> Option<f64> {
331 real_slice_extreme(self, na_rm, f64::min)
332 }
333
334 fn max(&self, na_rm: bool) -> Option<f64> {
335 real_slice_extreme(self, na_rm, f64::max)
336 }
337 }
338 };
339}
340
341macro_rules! impl_altraw_slice {
343 ($ty:ty) => {
344 impl AltRawData for $ty {
345 fn elt(&self, i: usize) -> u8 {
346 self[i]
347 }
348
349 fn as_slice(&self) -> Option<&[u8]> {
350 let s: &[u8] = self;
351 Some(s)
352 }
353
354 fn get_region(&self, start: usize, len: usize, buf: &mut [u8]) -> usize {
355 let s: &[u8] = self;
356 let end = (start + len).min(s.len());
357 let actual_len = end.saturating_sub(start);
358 if actual_len > 0 {
359 buf[..actual_len].copy_from_slice(&s[start..end]);
360 }
361 actual_len
362 }
363 }
364 };
365}
366
367macro_rules! impl_altcomplex_slice {
369 ($ty:ty) => {
370 impl AltComplexData for $ty {
371 fn elt(&self, i: usize) -> Rcomplex {
372 self[i]
373 }
374
375 fn as_slice(&self) -> Option<&[Rcomplex]> {
376 let s: &[Rcomplex] = self;
377 Some(s)
378 }
379
380 fn get_region(&self, start: usize, len: usize, buf: &mut [Rcomplex]) -> usize {
381 let s: &[Rcomplex] = self;
382 let end = (start + len).min(s.len());
383 let actual_len = end.saturating_sub(start);
384 if actual_len > 0 {
385 buf[..actual_len].copy_from_slice(&s[start..end]);
386 }
387 actual_len
388 }
389 }
390 };
391}
392
393macro_rules! impl_altlogical_slice {
395 ($ty:ty) => {
396 impl AltLogicalData for $ty {
397 fn elt(&self, i: usize) -> Logical {
398 self[i].into()
399 }
400
401 fn no_na(&self) -> Option<bool> {
402 Some(true) }
404
405 fn sum(&self, _na_rm: bool) -> Option<i64> {
406 let s: &[bool] = self;
407 Some(s.iter().filter(|&&x| x).count() as i64)
408 }
409 }
410 };
411}
412macro_rules! impl_altlogical_native_slice {
414 ($ty:ty) => {
415 impl AltLogicalData for $ty {
416 fn elt(&self, i: usize) -> Logical {
417 self[i].into()
418 }
419
420 fn as_r_slice(&self) -> Option<&[i32]> {
421 let values: &[RLogical] = self;
422 Some(unsafe { std::slice::from_raw_parts(values.as_ptr().cast(), values.len()) })
424 }
425
426 fn get_region(&self, start: usize, len: usize, out: &mut [i32]) -> usize {
427 let values: &[RLogical] = self;
428 super::fill_region(start, len, values.len(), out, |i| values[i].to_i32())
429 }
430
431 fn no_na(&self) -> Option<bool> {
432 let values: &[RLogical] = self;
433 Some(!values.iter().any(IsNA::is_na))
434 }
435 }
436 };
437}
438impl AltrepSerialize for Vec<i32> {
fn serialized_state(&self) -> SEXP {
use crate::into_r::IntoR;
self.clone().into_sexp()
}
fn unserialize(state: SEXP) -> Option<Self> {
use crate::from_r::TryFromSexp;
<Vec<i32>>::try_from_sexp(state).ok().map(std::convert::identity)
}
}impl_serialize!(Vec<i32>);
443impl AltrepSerialize for Vec<f64> {
fn serialized_state(&self) -> SEXP {
use crate::into_r::IntoR;
self.clone().into_sexp()
}
fn unserialize(state: SEXP) -> Option<Self> {
use crate::from_r::TryFromSexp;
<Vec<f64>>::try_from_sexp(state).ok().map(std::convert::identity)
}
}impl_serialize!(Vec<f64>);
444impl AltrepSerialize for Vec<u8> {
fn serialized_state(&self) -> SEXP {
use crate::into_r::IntoR;
self.clone().into_sexp()
}
fn unserialize(state: SEXP) -> Option<Self> {
use crate::from_r::TryFromSexp;
<Vec<u8>>::try_from_sexp(state).ok().map(std::convert::identity)
}
}impl_serialize!(Vec<u8>);
445impl AltrepSerialize for Vec<bool> {
fn serialized_state(&self) -> SEXP {
use crate::into_r::IntoR;
self.clone().into_sexp()
}
fn unserialize(state: SEXP) -> Option<Self> {
use crate::from_r::TryFromSexp;
<Vec<bool>>::try_from_sexp(state).ok().map(std::convert::identity)
}
}impl_serialize!(Vec<bool>);
446impl AltrepSerialize for Vec<RLogical> {
fn serialized_state(&self) -> SEXP {
use crate::into_r::IntoR;
self.clone().into_sexp()
}
fn unserialize(state: SEXP) -> Option<Self> {
use crate::from_r::TryFromSexp;
<Vec<RLogical>>::try_from_sexp(state).ok().map(std::convert::identity)
}
}impl_serialize!(Vec<RLogical>);
447impl AltrepSerialize for Vec<String> {
fn serialized_state(&self) -> SEXP {
use crate::into_r::IntoR;
self.clone().into_sexp()
}
fn unserialize(state: SEXP) -> Option<Self> {
use crate::from_r::TryFromSexp;
<Vec<String>>::try_from_sexp(state).ok().map(std::convert::identity)
}
}impl_serialize!(Vec<String>);
448impl AltrepSerialize for Vec<Option<String>> {
fn serialized_state(&self) -> SEXP {
use crate::into_r::IntoR;
self.clone().into_sexp()
}
fn unserialize(state: SEXP) -> Option<Self> {
use crate::from_r::TryFromSexp;
<Vec<Option<String>>>::try_from_sexp(state).ok().map(std::convert::identity)
}
}impl_serialize!(Vec<Option<String>>);
449impl AltrepSerialize for Vec<Rcomplex> {
fn serialized_state(&self) -> SEXP {
use crate::into_r::IntoR;
self.clone().into_sexp()
}
fn unserialize(state: SEXP) -> Option<Self> {
use crate::from_r::TryFromSexp;
<Vec<Rcomplex>>::try_from_sexp(state).ok().map(std::convert::identity)
}
}impl_serialize!(Vec<Rcomplex>);
450impl AltrepSerialize for Vec<Cow<'static, str>> {
fn serialized_state(&self) -> SEXP {
use crate::into_r::IntoR;
self.clone().into_sexp()
}
fn unserialize(state: SEXP) -> Option<Self> {
use crate::from_r::TryFromSexp;
<Vec<String>>::try_from_sexp(state).ok().map(|values|
{ values.into_iter().map(Cow::Owned).collect() })
}
}impl_serialize!(Vec<Cow<'static, str>>, Vec<String>, |values| {
453 values.into_iter().map(Cow::Owned).collect()
454});
455impl AltrepSerialize for Vec<Option<Cow<'static, str>>> {
fn serialized_state(&self) -> SEXP {
use crate::into_r::IntoR;
self.clone().into_sexp()
}
fn unserialize(state: SEXP) -> Option<Self> {
use crate::from_r::TryFromSexp;
<Vec<Option<String>>>::try_from_sexp(state).ok().map(|values|
values.into_iter().map(|value|
value.map(Cow::Owned)).collect())
}
}impl_serialize!(
456 Vec<Option<Cow<'static, str>>>,
457 Vec<Option<String>>,
458 |values| values
459 .into_iter()
460 .map(|value| value.map(Cow::Owned))
461 .collect()
462);
463impl AltrepSerialize for Box<[i32]> {
fn serialized_state(&self) -> SEXP {
use crate::into_r::IntoR;
self.clone().into_sexp()
}
fn unserialize(state: SEXP) -> Option<Self> {
use crate::from_r::TryFromSexp;
<Box<[i32]>>::try_from_sexp(state).ok().map(std::convert::identity)
}
}impl_serialize!(Box<[i32]>);
469impl AltrepSerialize for Box<[f64]> {
fn serialized_state(&self) -> SEXP {
use crate::into_r::IntoR;
self.clone().into_sexp()
}
fn unserialize(state: SEXP) -> Option<Self> {
use crate::from_r::TryFromSexp;
<Box<[f64]>>::try_from_sexp(state).ok().map(std::convert::identity)
}
}impl_serialize!(Box<[f64]>);
470impl AltrepSerialize for Box<[u8]> {
fn serialized_state(&self) -> SEXP {
use crate::into_r::IntoR;
self.clone().into_sexp()
}
fn unserialize(state: SEXP) -> Option<Self> {
use crate::from_r::TryFromSexp;
<Box<[u8]>>::try_from_sexp(state).ok().map(std::convert::identity)
}
}impl_serialize!(Box<[u8]>);
471impl AltrepSerialize for Box<[bool]> {
fn serialized_state(&self) -> SEXP {
use crate::into_r::IntoR;
self.clone().into_sexp()
}
fn unserialize(state: SEXP) -> Option<Self> {
use crate::from_r::TryFromSexp;
<Box<[bool]>>::try_from_sexp(state).ok().map(std::convert::identity)
}
}impl_serialize!(Box<[bool]>);
472impl AltrepSerialize for Box<[RLogical]> {
fn serialized_state(&self) -> SEXP {
use crate::into_r::IntoR;
self.clone().into_sexp()
}
fn unserialize(state: SEXP) -> Option<Self> {
use crate::from_r::TryFromSexp;
<Box<[RLogical]>>::try_from_sexp(state).ok().map(std::convert::identity)
}
}impl_serialize!(Box<[RLogical]>);
473impl AltrepSerialize for Box<[String]> {
fn serialized_state(&self) -> SEXP {
use crate::into_r::IntoR;
self.clone().into_sexp()
}
fn unserialize(state: SEXP) -> Option<Self> {
use crate::from_r::TryFromSexp;
<Box<[String]>>::try_from_sexp(state).ok().map(std::convert::identity)
}
}impl_serialize!(Box<[String]>);
474impl AltrepSerialize for Box<[Rcomplex]> {
fn serialized_state(&self) -> SEXP {
use crate::into_r::IntoR;
self.clone().into_sexp()
}
fn unserialize(state: SEXP) -> Option<Self> {
use crate::from_r::TryFromSexp;
<Box<[Rcomplex]>>::try_from_sexp(state).ok().map(std::convert::identity)
}
}impl_serialize!(Box<[Rcomplex]>);
475impl AltrepLen for Vec<i32> {
fn altrep_len(&self) -> usize { Vec::len(self) }
}impl_len_vec!(i32);
480impl AltIntegerData for Vec<i32> {
fn elt(&self, i: usize) -> i32 { self[i] }
fn as_slice(&self) -> Option<&[i32]> { let s: &[i32] = self; Some(s) }
fn get_region(&self, start: usize, len: usize, buf: &mut [i32]) -> usize {
let s: &[i32] = self;
let end = (start + len).min(s.len());
let actual_len = end.saturating_sub(start);
if actual_len > 0 {
buf[..actual_len].copy_from_slice(&s[start..end]);
}
actual_len
}
fn no_na(&self) -> Option<bool> {
let s: &[i32] = self;
Some(!s.iter().any(IsNA::is_na))
}
fn sum(&self, na_rm: bool) -> Option<i64> {
let s: &[i32] = self;
let mut sum: i64 = 0;
for &x in s.iter() {
if x.is_na() {
if !na_rm { return None; }
} else { sum += x as i64; }
}
Some(sum)
}
fn min(&self, na_rm: bool) -> Option<i32> {
let s: &[i32] = self;
let mut min = i32::MAX;
let mut found = false;
for &x in s.iter() {
if x.is_na() {
if !na_rm { return None; }
} else { found = true; min = min.min(x); }
}
if found { Some(min) } else { None }
}
fn max(&self, na_rm: bool) -> Option<i32> {
let s: &[i32] = self;
let mut max = i32::MIN + 1;
let mut found = false;
for &x in s.iter() {
if x.is_na() {
if !na_rm { return None; }
} else { found = true; max = max.max(x); }
}
if found { Some(max) } else { None }
}
}impl_altinteger_slice!(Vec<i32>);
481impl AltrepDataptr<i32> for Vec<i32> {
fn dataptr(&mut self, _writable: bool) -> Option<*mut i32> {
Some(self.as_mut_ptr().cast())
}
fn dataptr_or_null(&self) -> Option<*const i32> {
Some(self.as_ptr().cast())
}
}impl_dataptr_vec!(i32);
482
483impl AltrepLen for Vec<f64> {
fn altrep_len(&self) -> usize { Vec::len(self) }
}impl_len_vec!(f64);
484impl AltRealData for Vec<f64> {
fn elt(&self, i: usize) -> f64 { self[i] }
fn as_slice(&self) -> Option<&[f64]> { let s: &[f64] = self; Some(s) }
fn get_region(&self, start: usize, len: usize, buf: &mut [f64]) -> usize {
let s: &[f64] = self;
let end = (start + len).min(s.len());
let actual_len = end.saturating_sub(start);
if actual_len > 0 {
buf[..actual_len].copy_from_slice(&s[start..end]);
}
actual_len
}
fn no_na(&self) -> Option<bool> { Some(real_slice_no_na(self)) }
fn sum(&self, na_rm: bool) -> Option<f64> {
Some(real_slice_sum(self, na_rm))
}
fn min(&self, na_rm: bool) -> Option<f64> {
real_slice_extreme(self, na_rm, f64::min)
}
fn max(&self, na_rm: bool) -> Option<f64> {
real_slice_extreme(self, na_rm, f64::max)
}
}impl_altreal_slice!(Vec<f64>);
485impl AltrepDataptr<f64> for Vec<f64> {
fn dataptr(&mut self, _writable: bool) -> Option<*mut f64> {
Some(self.as_mut_ptr().cast())
}
fn dataptr_or_null(&self) -> Option<*const f64> {
Some(self.as_ptr().cast())
}
}impl_dataptr_vec!(f64);
486
487impl AltrepLen for Vec<u8> {
fn altrep_len(&self) -> usize { Vec::len(self) }
}impl_len_vec!(u8);
488impl AltRawData for Vec<u8> {
fn elt(&self, i: usize) -> u8 { self[i] }
fn as_slice(&self) -> Option<&[u8]> { let s: &[u8] = self; Some(s) }
fn get_region(&self, start: usize, len: usize, buf: &mut [u8]) -> usize {
let s: &[u8] = self;
let end = (start + len).min(s.len());
let actual_len = end.saturating_sub(start);
if actual_len > 0 {
buf[..actual_len].copy_from_slice(&s[start..end]);
}
actual_len
}
}impl_altraw_slice!(Vec<u8>);
489impl AltrepDataptr<u8> for Vec<u8> {
fn dataptr(&mut self, _writable: bool) -> Option<*mut u8> {
Some(self.as_mut_ptr().cast())
}
fn dataptr_or_null(&self) -> Option<*const u8> {
Some(self.as_ptr().cast())
}
}impl_dataptr_vec!(u8);
490
491impl AltrepLen for Vec<String> {
fn altrep_len(&self) -> usize { Vec::len(self) }
}impl_len_vec!(String);
492
493impl AltStringData for Vec<String> {
494 fn elt(&self, i: usize) -> Option<&str> {
495 Some(self[i].as_str())
496 }
497
498 fn no_na(&self) -> Option<bool> {
499 Some(true) }
501}
502
503impl AltrepLen for Vec<Option<String>> {
fn altrep_len(&self) -> usize { Vec::len(self) }
}impl_len_vec!(Option<String>);
504
505impl AltStringData for Vec<Option<String>> {
506 fn elt(&self, i: usize) -> Option<&str> {
507 self[i].as_deref()
508 }
509
510 fn no_na(&self) -> Option<bool> {
511 Some(!self.iter().any(|x| x.is_none()))
512 }
513}
514
515impl AltrepLen for Vec<std::borrow::Cow<'static, str>> {
516 fn altrep_len(&self) -> usize {
517 self.len()
518 }
519}
520
521impl AltStringData for Vec<std::borrow::Cow<'static, str>> {
522 fn elt(&self, i: usize) -> Option<&str> {
523 Some(self[i].as_ref())
524 }
525
526 fn no_na(&self) -> Option<bool> {
527 Some(true) }
529}
530
531impl AltrepLen for Vec<Option<std::borrow::Cow<'static, str>>> {
532 fn altrep_len(&self) -> usize {
533 self.len()
534 }
535}
536
537impl AltStringData for Vec<Option<std::borrow::Cow<'static, str>>> {
538 fn elt(&self, i: usize) -> Option<&str> {
539 self[i].as_deref()
540 }
541
542 fn no_na(&self) -> Option<bool> {
543 Some(!self.iter().any(|x| x.is_none()))
544 }
545}
546
547impl AltrepLen for Vec<bool> {
fn altrep_len(&self) -> usize { Vec::len(self) }
}impl_len_vec!(bool);
548impl AltLogicalData for Vec<bool> {
fn elt(&self, i: usize) -> Logical { self[i].into() }
fn no_na(&self) -> Option<bool> { Some(true) }
fn sum(&self, _na_rm: bool) -> Option<i64> {
let s: &[bool] = self;
Some(s.iter().filter(|&&x| x).count() as i64)
}
}impl_altlogical_slice!(Vec<bool>);
549
550impl AltrepLen for Vec<RLogical> {
fn altrep_len(&self) -> usize { Vec::len(self) }
}impl_len_vec!(RLogical);
551impl AltLogicalData for Vec<RLogical> {
fn elt(&self, i: usize) -> Logical { self[i].into() }
fn as_r_slice(&self) -> Option<&[i32]> {
let values: &[RLogical] = self;
Some(unsafe {
std::slice::from_raw_parts(values.as_ptr().cast(),
values.len())
})
}
fn get_region(&self, start: usize, len: usize, out: &mut [i32]) -> usize {
let values: &[RLogical] = self;
super::fill_region(start, len, values.len(), out,
|i| values[i].to_i32())
}
fn no_na(&self) -> Option<bool> {
let values: &[RLogical] = self;
Some(!values.iter().any(IsNA::is_na))
}
}impl_altlogical_native_slice!(Vec<RLogical>);
552impl AltrepDataptr<i32> for Vec<RLogical> {
fn dataptr(&mut self, _writable: bool) -> Option<*mut i32> {
Some(self.as_mut_ptr().cast())
}
fn dataptr_or_null(&self) -> Option<*const i32> {
Some(self.as_ptr().cast())
}
}impl_dataptr_vec!(RLogical => i32);
553impl AltrepLen for Box<[i32]> {
fn altrep_len(&self) -> usize { <[i32]>::len(self) }
}impl_len_boxed!(i32);
569impl AltIntegerData for Box<[i32]> {
fn elt(&self, i: usize) -> i32 { self[i] }
fn as_slice(&self) -> Option<&[i32]> { let s: &[i32] = self; Some(s) }
fn get_region(&self, start: usize, len: usize, buf: &mut [i32]) -> usize {
let s: &[i32] = self;
let end = (start + len).min(s.len());
let actual_len = end.saturating_sub(start);
if actual_len > 0 {
buf[..actual_len].copy_from_slice(&s[start..end]);
}
actual_len
}
fn no_na(&self) -> Option<bool> {
let s: &[i32] = self;
Some(!s.iter().any(IsNA::is_na))
}
fn sum(&self, na_rm: bool) -> Option<i64> {
let s: &[i32] = self;
let mut sum: i64 = 0;
for &x in s.iter() {
if x.is_na() {
if !na_rm { return None; }
} else { sum += x as i64; }
}
Some(sum)
}
fn min(&self, na_rm: bool) -> Option<i32> {
let s: &[i32] = self;
let mut min = i32::MAX;
let mut found = false;
for &x in s.iter() {
if x.is_na() {
if !na_rm { return None; }
} else { found = true; min = min.min(x); }
}
if found { Some(min) } else { None }
}
fn max(&self, na_rm: bool) -> Option<i32> {
let s: &[i32] = self;
let mut max = i32::MIN + 1;
let mut found = false;
for &x in s.iter() {
if x.is_na() {
if !na_rm { return None; }
} else { found = true; max = max.max(x); }
}
if found { Some(max) } else { None }
}
}impl_altinteger_slice!(Box<[i32]>);
570impl AltrepDataptr<i32> for Box<[i32]> {
fn dataptr(&mut self, _writable: bool) -> Option<*mut i32> {
Some(self.as_mut_ptr().cast())
}
fn dataptr_or_null(&self) -> Option<*const i32> {
Some(self.as_ptr().cast())
}
}impl_dataptr_boxed!(i32);
571
572impl AltrepLen for Box<[f64]> {
fn altrep_len(&self) -> usize { <[f64]>::len(self) }
}impl_len_boxed!(f64);
573impl AltRealData for Box<[f64]> {
fn elt(&self, i: usize) -> f64 { self[i] }
fn as_slice(&self) -> Option<&[f64]> { let s: &[f64] = self; Some(s) }
fn get_region(&self, start: usize, len: usize, buf: &mut [f64]) -> usize {
let s: &[f64] = self;
let end = (start + len).min(s.len());
let actual_len = end.saturating_sub(start);
if actual_len > 0 {
buf[..actual_len].copy_from_slice(&s[start..end]);
}
actual_len
}
fn no_na(&self) -> Option<bool> { Some(real_slice_no_na(self)) }
fn sum(&self, na_rm: bool) -> Option<f64> {
Some(real_slice_sum(self, na_rm))
}
fn min(&self, na_rm: bool) -> Option<f64> {
real_slice_extreme(self, na_rm, f64::min)
}
fn max(&self, na_rm: bool) -> Option<f64> {
real_slice_extreme(self, na_rm, f64::max)
}
}impl_altreal_slice!(Box<[f64]>);
574impl AltrepDataptr<f64> for Box<[f64]> {
fn dataptr(&mut self, _writable: bool) -> Option<*mut f64> {
Some(self.as_mut_ptr().cast())
}
fn dataptr_or_null(&self) -> Option<*const f64> {
Some(self.as_ptr().cast())
}
}impl_dataptr_boxed!(f64);
575
576impl AltrepLen for Box<[u8]> {
fn altrep_len(&self) -> usize { <[u8]>::len(self) }
}impl_len_boxed!(u8);
577impl AltRawData for Box<[u8]> {
fn elt(&self, i: usize) -> u8 { self[i] }
fn as_slice(&self) -> Option<&[u8]> { let s: &[u8] = self; Some(s) }
fn get_region(&self, start: usize, len: usize, buf: &mut [u8]) -> usize {
let s: &[u8] = self;
let end = (start + len).min(s.len());
let actual_len = end.saturating_sub(start);
if actual_len > 0 {
buf[..actual_len].copy_from_slice(&s[start..end]);
}
actual_len
}
}impl_altraw_slice!(Box<[u8]>);
578impl AltrepDataptr<u8> for Box<[u8]> {
fn dataptr(&mut self, _writable: bool) -> Option<*mut u8> {
Some(self.as_mut_ptr().cast())
}
fn dataptr_or_null(&self) -> Option<*const u8> {
Some(self.as_ptr().cast())
}
}impl_dataptr_boxed!(u8);
579
580impl AltrepLen for Box<[bool]> {
fn altrep_len(&self) -> usize { <[bool]>::len(self) }
}impl_len_boxed!(bool);
581impl AltLogicalData for Box<[bool]> {
fn elt(&self, i: usize) -> Logical { self[i].into() }
fn no_na(&self) -> Option<bool> { Some(true) }
fn sum(&self, _na_rm: bool) -> Option<i64> {
let s: &[bool] = self;
Some(s.iter().filter(|&&x| x).count() as i64)
}
}impl_altlogical_slice!(Box<[bool]>);
582
583impl AltrepLen for Box<[RLogical]> {
fn altrep_len(&self) -> usize { <[RLogical]>::len(self) }
}impl_len_boxed!(RLogical);
584impl AltLogicalData for Box<[RLogical]> {
fn elt(&self, i: usize) -> Logical { self[i].into() }
fn as_r_slice(&self) -> Option<&[i32]> {
let values: &[RLogical] = self;
Some(unsafe {
std::slice::from_raw_parts(values.as_ptr().cast(),
values.len())
})
}
fn get_region(&self, start: usize, len: usize, out: &mut [i32]) -> usize {
let values: &[RLogical] = self;
super::fill_region(start, len, values.len(), out,
|i| values[i].to_i32())
}
fn no_na(&self) -> Option<bool> {
let values: &[RLogical] = self;
Some(!values.iter().any(IsNA::is_na))
}
}impl_altlogical_native_slice!(Box<[RLogical]>);
585impl AltrepDataptr<i32> for Box<[RLogical]> {
fn dataptr(&mut self, _writable: bool) -> Option<*mut i32> {
Some(self.as_mut_ptr().cast())
}
fn dataptr_or_null(&self) -> Option<*const i32> {
Some(self.as_ptr().cast())
}
}impl_dataptr_boxed!(RLogical => i32);
586
587impl AltrepLen for Box<[String]> {
fn altrep_len(&self) -> usize { <[String]>::len(self) }
}impl_len_boxed!(String);
588
589impl AltStringData for Box<[String]> {
590 fn elt(&self, i: usize) -> Option<&str> {
591 Some(self[i].as_str())
592 }
593
594 fn no_na(&self) -> Option<bool> {
595 Some(true) }
597}
598impl AltrepSerialize for Range<i32> {
604 fn serialized_state(&self) -> SEXP {
605 use crate::into_r::IntoR;
606 ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[self.start, self.end]))vec![self.start, self.end].into_sexp()
607 }
608
609 fn unserialize(state: SEXP) -> Option<Self> {
610 use crate::from_r::TryFromSexp;
611 let v = Vec::<i32>::try_from_sexp(state).ok()?;
612 if v.len() == 2 { Some(v[0]..v[1]) } else { None }
613 }
614}
615
616impl AltrepSerialize for Range<i64> {
617 fn serialized_state(&self) -> SEXP {
618 use crate::into_r::IntoR;
619 ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[f64::from_bits(self.start as u64), f64::from_bits(self.end as u64)]))vec![
622 f64::from_bits(self.start as u64),
623 f64::from_bits(self.end as u64),
624 ]
625 .into_sexp()
626 }
627
628 fn unserialize(state: SEXP) -> Option<Self> {
629 use crate::from_r::TryFromSexp;
630 let v = Vec::<f64>::try_from_sexp(state).ok()?;
631 if v.len() == 2 {
632 Some((v[0].to_bits() as i64)..(v[1].to_bits() as i64))
633 } else {
634 None
635 }
636 }
637}
638
639impl AltrepSerialize for Range<f64> {
640 fn serialized_state(&self) -> SEXP {
641 use crate::into_r::IntoR;
642 ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[self.start, self.end]))vec![self.start, self.end].into_sexp()
643 }
644
645 fn unserialize(state: SEXP) -> Option<Self> {
646 use crate::from_r::TryFromSexp;
647 let v = Vec::<f64>::try_from_sexp(state).ok()?;
648 if v.len() == 2 { Some(v[0]..v[1]) } else { None }
649 }
650}
651impl AltrepLen for Range<i32> {
656 fn altrep_len(&self) -> usize {
657 if self.end > self.start {
658 (self.end - self.start) as usize
659 } else {
660 0
661 }
662 }
663}
664
665impl AltIntegerData for Range<i32> {
666 fn elt(&self, i: usize) -> i32 {
667 self.start + i as i32
668 }
669
670 fn is_sorted(&self) -> Option<Sortedness> {
671 Some(Sortedness::Increasing)
672 }
673
674 fn no_na(&self) -> Option<bool> {
675 let contains_na = self.start.is_na() && self.end > i32::MIN;
679 Some(!contains_na)
680 }
681
682 fn sum(&self, na_rm: bool) -> Option<i64> {
683 let n = AltrepLen::altrep_len(self) as i64;
684 if n == 0 {
685 return Some(0);
686 }
687
688 let contains_na = self.start.is_na() && self.end > i32::MIN;
690 if contains_na && !na_rm {
691 return None; }
693
694 if contains_na {
697 let n_valid = n - 1;
699 if n_valid == 0 {
700 return Some(0);
701 }
702 let first = (self.start + 1) as i64;
703 let last = (self.end - 1) as i64;
704 Some(n_valid * (first + last) / 2)
705 } else {
706 let first = self.start as i64;
707 let last = (self.end - 1) as i64;
708 Some(n * (first + last) / 2)
709 }
710 }
711
712 fn min(&self, na_rm: bool) -> Option<i32> {
713 if AltrepLen::altrep_len(self) == 0 {
714 return None;
715 }
716
717 if self.start.is_na() {
719 if na_rm {
720 if self.end > self.start + 1 {
722 Some(self.start + 1)
723 } else {
724 None }
726 } else {
727 None }
729 } else {
730 Some(self.start)
731 }
732 }
733
734 fn max(&self, na_rm: bool) -> Option<i32> {
735 if AltrepLen::altrep_len(self) == 0 {
736 return None;
737 }
738
739 let contains_na = self.start.is_na() && self.end > i32::MIN;
742 if contains_na && !na_rm {
743 return None; }
745
746 Some(self.end - 1)
749 }
750}
751
752impl AltrepLen for Range<i64> {
753 fn altrep_len(&self) -> usize {
754 if self.end > self.start {
755 (self.end - self.start) as usize
756 } else {
757 0
758 }
759 }
760}
761
762impl AltIntegerData for Range<i64> {
763 fn elt(&self, i: usize) -> i32 {
764 let val = self.start.saturating_add(i as i64);
765 if val > i32::MAX as i64 || val <= i32::MIN as i64 {
768 crate::altrep_traits::NA_INTEGER
769 } else {
770 val as i32
771 }
772 }
773
774 fn is_sorted(&self) -> Option<Sortedness> {
775 Some(Sortedness::Increasing)
776 }
777
778 fn no_na(&self) -> Option<bool> {
779 let na_sentinel = i32::MIN as i64;
789 let i32_max = i32::MAX as i64;
790
791 let contains_na_sentinel = self.start <= na_sentinel && self.end > na_sentinel;
793
794 let has_underflow = self.start < na_sentinel;
797 let has_overflow = (self.end - 1) > i32_max;
798
799 Some(!contains_na_sentinel && !has_underflow && !has_overflow)
800 }
801
802 fn sum(&self, na_rm: bool) -> Option<i64> {
803 let n = AltrepLen::altrep_len(self) as i64;
804 if n == 0 {
805 return Some(0);
806 }
807
808 let na_sentinel = i32::MIN as i64;
810 let i32_max = i32::MAX as i64;
811 let contains_na_sentinel = self.start <= na_sentinel && self.end > na_sentinel;
812 let has_underflow = self.start < na_sentinel;
813 let has_overflow = (self.end - 1) > i32_max;
814 let has_na = contains_na_sentinel || has_underflow || has_overflow;
815
816 if has_na && !na_rm {
817 return None; }
819
820 if has_na {
821 return None;
824 }
825
826 let first = self.start;
827 let last = self.end - 1;
828
829 let sum_endpoints = first.checked_add(last)?;
832 let product = n.checked_mul(sum_endpoints)?;
833 Some(product / 2)
834 }
835
836 fn min(&self, na_rm: bool) -> Option<i32> {
837 if AltrepLen::altrep_len(self) == 0 {
838 return None;
839 }
840
841 let na_sentinel = i32::MIN as i64;
842 let i32_max = i32::MAX as i64;
843
844 let contains_na_sentinel = self.start <= na_sentinel && self.end > na_sentinel;
846 let has_underflow = self.start < na_sentinel;
847 let has_overflow = (self.end - 1) > i32_max;
848 let has_na = contains_na_sentinel || has_underflow || has_overflow;
849
850 if has_na && !na_rm {
851 return None; }
853
854 if has_na {
855 return None;
858 }
859
860 Some(self.start as i32)
862 }
863
864 fn max(&self, na_rm: bool) -> Option<i32> {
865 if AltrepLen::altrep_len(self) == 0 {
866 return None;
867 }
868
869 let na_sentinel = i32::MIN as i64;
870 let i32_max = i32::MAX as i64;
871
872 let contains_na_sentinel = self.start <= na_sentinel && self.end > na_sentinel;
874 let has_underflow = self.start < na_sentinel;
875 let has_overflow = (self.end - 1) > i32_max;
876 let has_na = contains_na_sentinel || has_underflow || has_overflow;
877
878 if has_na && !na_rm {
879 return None; }
881
882 if has_na {
883 return None;
886 }
887
888 Some((self.end - 1) as i32)
890 }
891}
892
893impl AltrepLen for Range<f64> {
894 fn altrep_len(&self) -> usize {
895 if self.end > self.start {
897 (self.end - self.start).ceil() as usize
898 } else {
899 0
900 }
901 }
902}
903
904impl AltRealData for Range<f64> {
905 fn elt(&self, i: usize) -> f64 {
906 self.start + i as f64
907 }
908
909 fn is_sorted(&self) -> Option<Sortedness> {
910 Some(Sortedness::Increasing)
911 }
912
913 fn no_na(&self) -> Option<bool> {
914 Some(true)
915 }
916
917 fn sum(&self, _na_rm: bool) -> Option<f64> {
918 let n = AltrepLen::altrep_len(self) as f64;
919 if n == 0.0 {
920 return Some(0.0);
921 }
922 let first = self.start;
923 let last = self.start + (n - 1.0);
924 Some(n * (first + last) / 2.0)
925 }
926
927 fn min(&self, _na_rm: bool) -> Option<f64> {
928 if AltrepLen::altrep_len(self) > 0 {
929 Some(self.start)
930 } else {
931 None
932 }
933 }
934
935 fn max(&self, _na_rm: bool) -> Option<f64> {
936 if AltrepLen::altrep_len(self) > 0 {
937 Some(self.start + (AltrepLen::altrep_len(self) - 1) as f64)
938 } else {
939 None
940 }
941 }
942}
943impl AltrepLen for &[i32] {
fn altrep_len(&self) -> usize { <[i32]>::len(self) }
}impl_len_slice!(i32);
948impl AltIntegerData for &[i32] {
fn elt(&self, i: usize) -> i32 { self[i] }
fn as_slice(&self) -> Option<&[i32]> { let s: &[i32] = self; Some(s) }
fn get_region(&self, start: usize, len: usize, buf: &mut [i32]) -> usize {
let s: &[i32] = self;
let end = (start + len).min(s.len());
let actual_len = end.saturating_sub(start);
if actual_len > 0 {
buf[..actual_len].copy_from_slice(&s[start..end]);
}
actual_len
}
fn no_na(&self) -> Option<bool> {
let s: &[i32] = self;
Some(!s.iter().any(IsNA::is_na))
}
fn sum(&self, na_rm: bool) -> Option<i64> {
let s: &[i32] = self;
let mut sum: i64 = 0;
for &x in s.iter() {
if x.is_na() {
if !na_rm { return None; }
} else { sum += x as i64; }
}
Some(sum)
}
fn min(&self, na_rm: bool) -> Option<i32> {
let s: &[i32] = self;
let mut min = i32::MAX;
let mut found = false;
for &x in s.iter() {
if x.is_na() {
if !na_rm { return None; }
} else { found = true; min = min.min(x); }
}
if found { Some(min) } else { None }
}
fn max(&self, na_rm: bool) -> Option<i32> {
let s: &[i32] = self;
let mut max = i32::MIN + 1;
let mut found = false;
for &x in s.iter() {
if x.is_na() {
if !na_rm { return None; }
} else { found = true; max = max.max(x); }
}
if found { Some(max) } else { None }
}
}impl_altinteger_slice!(&[i32]);
949
950impl AltrepLen for &[f64] {
fn altrep_len(&self) -> usize { <[f64]>::len(self) }
}impl_len_slice!(f64);
951impl AltRealData for &[f64] {
fn elt(&self, i: usize) -> f64 { self[i] }
fn as_slice(&self) -> Option<&[f64]> { let s: &[f64] = self; Some(s) }
fn get_region(&self, start: usize, len: usize, buf: &mut [f64]) -> usize {
let s: &[f64] = self;
let end = (start + len).min(s.len());
let actual_len = end.saturating_sub(start);
if actual_len > 0 {
buf[..actual_len].copy_from_slice(&s[start..end]);
}
actual_len
}
fn no_na(&self) -> Option<bool> { Some(real_slice_no_na(self)) }
fn sum(&self, na_rm: bool) -> Option<f64> {
Some(real_slice_sum(self, na_rm))
}
fn min(&self, na_rm: bool) -> Option<f64> {
real_slice_extreme(self, na_rm, f64::min)
}
fn max(&self, na_rm: bool) -> Option<f64> {
real_slice_extreme(self, na_rm, f64::max)
}
}impl_altreal_slice!(&[f64]);
952
953impl AltrepLen for &[u8] {
fn altrep_len(&self) -> usize { <[u8]>::len(self) }
}impl_len_slice!(u8);
954impl AltRawData for &[u8] {
fn elt(&self, i: usize) -> u8 { self[i] }
fn as_slice(&self) -> Option<&[u8]> { let s: &[u8] = self; Some(s) }
fn get_region(&self, start: usize, len: usize, buf: &mut [u8]) -> usize {
let s: &[u8] = self;
let end = (start + len).min(s.len());
let actual_len = end.saturating_sub(start);
if actual_len > 0 {
buf[..actual_len].copy_from_slice(&s[start..end]);
}
actual_len
}
}impl_altraw_slice!(&[u8]);
955
956impl AltrepLen for &[bool] {
fn altrep_len(&self) -> usize { <[bool]>::len(self) }
}impl_len_slice!(bool);
957impl AltLogicalData for &[bool] {
fn elt(&self, i: usize) -> Logical { self[i].into() }
fn no_na(&self) -> Option<bool> { Some(true) }
fn sum(&self, _na_rm: bool) -> Option<i64> {
let s: &[bool] = self;
Some(s.iter().filter(|&&x| x).count() as i64)
}
}impl_altlogical_slice!(&[bool]);
958
959impl AltrepLen for &[String] {
fn altrep_len(&self) -> usize { <[String]>::len(self) }
}impl_len_slice!(String);
960
961impl AltStringData for &[String] {
962 fn elt(&self, i: usize) -> Option<&str> {
963 Some(self[i].as_str())
964 }
965}
966
967impl AltrepLen for &[&str] {
fn altrep_len(&self) -> usize { <[&str]>::len(self) }
}impl_len_slice!(&str);
968
969impl AltStringData for &[&str] {
970 fn elt(&self, i: usize) -> Option<&str> {
971 Some(self[i])
972 }
973}
974macro_rules! impl_dataptr_array {
995 ($elem:ty => $storage:ty) => {
996 impl<const N: usize> AltrepDataptr<$storage> for [$elem; N] {
997 fn dataptr(&mut self, _writable: bool) -> Option<*mut $storage> {
998 Some(self.as_mut_ptr().cast())
999 }
1000
1001 fn dataptr_or_null(&self) -> Option<*const $storage> {
1002 Some(self.as_ptr().cast())
1003 }
1004 }
1005 };
1006}
1007
1008impl<const N : usize> AltrepDataptr<i32> for [i32; N] {
fn dataptr(&mut self, _writable: bool) -> Option<*mut i32> {
Some(self.as_mut_ptr().cast())
}
fn dataptr_or_null(&self) -> Option<*const i32> {
Some(self.as_ptr().cast())
}
}impl_dataptr_array!(i32 => i32);
1009impl<const N : usize> AltrepDataptr<f64> for [f64; N] {
fn dataptr(&mut self, _writable: bool) -> Option<*mut f64> {
Some(self.as_mut_ptr().cast())
}
fn dataptr_or_null(&self) -> Option<*const f64> {
Some(self.as_ptr().cast())
}
}impl_dataptr_array!(f64 => f64);
1010impl<const N : usize> AltrepDataptr<u8> for [u8; N] {
fn dataptr(&mut self, _writable: bool) -> Option<*mut u8> {
Some(self.as_mut_ptr().cast())
}
fn dataptr_or_null(&self) -> Option<*const u8> {
Some(self.as_ptr().cast())
}
}impl_dataptr_array!(u8 => u8);
1011impl<const N : usize> AltrepDataptr<Rcomplex> for [Rcomplex; N] {
fn dataptr(&mut self, _writable: bool) -> Option<*mut Rcomplex> {
Some(self.as_mut_ptr().cast())
}
fn dataptr_or_null(&self) -> Option<*const Rcomplex> {
Some(self.as_ptr().cast())
}
}impl_dataptr_array!(Rcomplex => Rcomplex);
1012impl<const N : usize> AltrepDataptr<i32> for [RLogical; N] {
fn dataptr(&mut self, _writable: bool) -> Option<*mut i32> {
Some(self.as_mut_ptr().cast())
}
fn dataptr_or_null(&self) -> Option<*const i32> {
Some(self.as_ptr().cast())
}
}impl_dataptr_array!(RLogical => i32);
1013
1014impl<const N : usize> AltrepLen for [RLogical; N] {
fn altrep_len(&self) -> usize { N }
}impl_len_array!(RLogical);
1015
1016impl<const N: usize> AltLogicalData for [RLogical; N] {
1017 fn elt(&self, i: usize) -> Logical {
1018 self[i].into()
1019 }
1020
1021 fn as_r_slice(&self) -> Option<&[i32]> {
1022 Some(unsafe { std::slice::from_raw_parts(self.as_ptr().cast(), N) })
1024 }
1025
1026 fn get_region(&self, start: usize, len: usize, out: &mut [i32]) -> usize {
1027 super::fill_region(start, len, N, out, |i| self[i].to_i32())
1028 }
1029
1030 fn no_na(&self) -> Option<bool> {
1031 Some(!self.contains(&RLogical::NA))
1032 }
1033}
1034
1035impl<const N : usize> AltrepLen for [i32; N] {
fn altrep_len(&self) -> usize { N }
}impl_len_array!(i32);
1036
1037impl<const N: usize> AltIntegerData for [i32; N] {
1038 fn elt(&self, i: usize) -> i32 {
1039 self[i]
1040 }
1041
1042 fn as_slice(&self) -> Option<&[i32]> {
1043 Some(self.as_slice())
1044 }
1045
1046 fn get_region(&self, start: usize, len: usize, buf: &mut [i32]) -> usize {
1047 super::fill_region(start, len, N, buf, |i| self[i])
1048 }
1049
1050 fn no_na(&self) -> Option<bool> {
1051 Some(!self.iter().any(IsNA::is_na))
1052 }
1053}
1054
1055impl<const N : usize> AltrepLen for [f64; N] {
fn altrep_len(&self) -> usize { N }
}impl_len_array!(f64);
1056
1057impl<const N: usize> AltRealData for [f64; N] {
1058 fn elt(&self, i: usize) -> f64 {
1059 self[i]
1060 }
1061
1062 fn as_slice(&self) -> Option<&[f64]> {
1063 Some(self.as_slice())
1064 }
1065
1066 fn get_region(&self, start: usize, len: usize, buf: &mut [f64]) -> usize {
1067 super::fill_region(start, len, N, buf, |i| self[i])
1068 }
1069
1070 fn no_na(&self) -> Option<bool> {
1071 Some(real_slice_no_na(self))
1072 }
1073}
1074
1075impl<const N : usize> AltrepLen for [bool; N] {
fn altrep_len(&self) -> usize { N }
}impl_len_array!(bool);
1076
1077impl<const N: usize> AltLogicalData for [bool; N] {
1078 fn elt(&self, i: usize) -> Logical {
1079 Logical::from_bool(self[i])
1080 }
1081
1082 fn no_na(&self) -> Option<bool> {
1083 Some(true) }
1085}
1086
1087impl<const N : usize> AltrepLen for [u8; N] {
fn altrep_len(&self) -> usize { N }
}impl_len_array!(u8);
1088
1089impl<const N: usize> AltRawData for [u8; N] {
1090 fn elt(&self, i: usize) -> u8 {
1091 self[i]
1092 }
1093
1094 fn as_slice(&self) -> Option<&[u8]> {
1095 Some(self.as_slice())
1096 }
1097
1098 fn get_region(&self, start: usize, len: usize, buf: &mut [u8]) -> usize {
1099 super::fill_region(start, len, N, buf, |i| self[i])
1100 }
1101}
1102
1103impl<const N : usize> AltrepLen for [String; N] {
fn altrep_len(&self) -> usize { N }
}impl_len_array!(String);
1104
1105impl<const N: usize> AltStringData for [String; N] {
1106 fn elt(&self, i: usize) -> Option<&str> {
1107 Some(self[i].as_str())
1108 }
1109}
1110impl AltrepLen for Vec<Rcomplex> {
fn altrep_len(&self) -> usize { Vec::len(self) }
}impl_len_vec!(Rcomplex);
1115impl AltComplexData for Vec<Rcomplex> {
fn elt(&self, i: usize) -> Rcomplex { self[i] }
fn as_slice(&self) -> Option<&[Rcomplex]> {
let s: &[Rcomplex] = self;
Some(s)
}
fn get_region(&self, start: usize, len: usize, buf: &mut [Rcomplex])
-> usize {
let s: &[Rcomplex] = self;
let end = (start + len).min(s.len());
let actual_len = end.saturating_sub(start);
if actual_len > 0 {
buf[..actual_len].copy_from_slice(&s[start..end]);
}
actual_len
}
}impl_altcomplex_slice!(Vec<Rcomplex>);
1116impl AltrepDataptr<Rcomplex> for Vec<Rcomplex> {
fn dataptr(&mut self, _writable: bool) -> Option<*mut Rcomplex> {
Some(self.as_mut_ptr().cast())
}
fn dataptr_or_null(&self) -> Option<*const Rcomplex> {
Some(self.as_ptr().cast())
}
}impl_dataptr_vec!(Rcomplex);
1117impl AltrepLen for Box<[Rcomplex]> {
fn altrep_len(&self) -> usize { <[Rcomplex]>::len(self) }
}impl_len_boxed!(Rcomplex);
1122impl AltComplexData for Box<[Rcomplex]> {
fn elt(&self, i: usize) -> Rcomplex { self[i] }
fn as_slice(&self) -> Option<&[Rcomplex]> {
let s: &[Rcomplex] = self;
Some(s)
}
fn get_region(&self, start: usize, len: usize, buf: &mut [Rcomplex])
-> usize {
let s: &[Rcomplex] = self;
let end = (start + len).min(s.len());
let actual_len = end.saturating_sub(start);
if actual_len > 0 {
buf[..actual_len].copy_from_slice(&s[start..end]);
}
actual_len
}
}impl_altcomplex_slice!(Box<[Rcomplex]>);
1123impl AltrepDataptr<Rcomplex> for Box<[Rcomplex]> {
fn dataptr(&mut self, _writable: bool) -> Option<*mut Rcomplex> {
Some(self.as_mut_ptr().cast())
}
fn dataptr_or_null(&self) -> Option<*const Rcomplex> {
Some(self.as_ptr().cast())
}
}impl_dataptr_boxed!(Rcomplex);
1124impl<const N : usize> AltrepLen for [Rcomplex; N] {
fn altrep_len(&self) -> usize { N }
}impl_len_array!(Rcomplex);
1129
1130impl<const N: usize> AltComplexData for [Rcomplex; N] {
1131 fn elt(&self, i: usize) -> Rcomplex {
1132 self[i]
1133 }
1134
1135 fn as_slice(&self) -> Option<&[Rcomplex]> {
1136 Some(self.as_slice())
1137 }
1138
1139 fn get_region(&self, start: usize, len: usize, buf: &mut [Rcomplex]) -> usize {
1140 super::fill_region(start, len, N, buf, |i| self[i])
1141 }
1142}
1143macro_rules! impl_owned_str_altrep_data {
1148 ($owner:ident) => {
1149 impl_len_vec!($owner<str>);
1150 impl_len_vec!(Option<$owner<str>>);
1151 impl AltStringData for Vec<$owner<str>> {
1152 fn elt(&self, i: usize) -> Option<&str> {
1153 Some(self[i].as_ref())
1154 }
1155 fn no_na(&self) -> Option<bool> {
1156 Some(true)
1157 }
1158 }
1159 impl AltStringData for Vec<Option<$owner<str>>> {
1160 fn elt(&self, i: usize) -> Option<&str> {
1161 self[i].as_deref()
1162 }
1163 fn no_na(&self) -> Option<bool> {
1164 Some(self.iter().all(Option::is_some))
1165 }
1166 }
1167 impl_serialize!(Vec<$owner<str>>);
1168 impl_serialize!(Vec<Option<$owner<str>>>);
1169 };
1170}
1171impl AltrepLen for Vec<Option<Box<str>>> {
fn altrep_len(&self) -> usize { Vec::len(self) }
}
impl AltStringData for Vec<Box<str>> {
fn elt(&self, i: usize) -> Option<&str> { Some(self[i].as_ref()) }
fn no_na(&self) -> Option<bool> { Some(true) }
}
impl AltStringData for Vec<Option<Box<str>>> {
fn elt(&self, i: usize) -> Option<&str> { self[i].as_deref() }
fn no_na(&self) -> Option<bool> { Some(self.iter().all(Option::is_some)) }
}
impl AltrepSerialize for Vec<Box<str>> {
fn serialized_state(&self) -> SEXP {
use crate::into_r::IntoR;
self.clone().into_sexp()
}
fn unserialize(state: SEXP) -> Option<Self> {
use crate::from_r::TryFromSexp;
<Vec<Box<str>>>::try_from_sexp(state).ok().map(std::convert::identity)
}
}
impl AltrepSerialize for Vec<Option<Box<str>>> {
fn serialized_state(&self) -> SEXP {
use crate::into_r::IntoR;
self.clone().into_sexp()
}
fn unserialize(state: SEXP) -> Option<Self> {
use crate::from_r::TryFromSexp;
<Vec<Option<Box<str>>>>::try_from_sexp(state).ok().map(std::convert::identity)
}
}impl_owned_str_altrep_data!(Box);
1172impl AltrepLen for Vec<Option<Rc<str>>> {
fn altrep_len(&self) -> usize { Vec::len(self) }
}
impl AltStringData for Vec<Rc<str>> {
fn elt(&self, i: usize) -> Option<&str> { Some(self[i].as_ref()) }
fn no_na(&self) -> Option<bool> { Some(true) }
}
impl AltStringData for Vec<Option<Rc<str>>> {
fn elt(&self, i: usize) -> Option<&str> { self[i].as_deref() }
fn no_na(&self) -> Option<bool> { Some(self.iter().all(Option::is_some)) }
}
impl AltrepSerialize for Vec<Rc<str>> {
fn serialized_state(&self) -> SEXP {
use crate::into_r::IntoR;
self.clone().into_sexp()
}
fn unserialize(state: SEXP) -> Option<Self> {
use crate::from_r::TryFromSexp;
<Vec<Rc<str>>>::try_from_sexp(state).ok().map(std::convert::identity)
}
}
impl AltrepSerialize for Vec<Option<Rc<str>>> {
fn serialized_state(&self) -> SEXP {
use crate::into_r::IntoR;
self.clone().into_sexp()
}
fn unserialize(state: SEXP) -> Option<Self> {
use crate::from_r::TryFromSexp;
<Vec<Option<Rc<str>>>>::try_from_sexp(state).ok().map(std::convert::identity)
}
}impl_owned_str_altrep_data!(Rc);
1173impl AltrepLen for Vec<Option<Arc<str>>> {
fn altrep_len(&self) -> usize { Vec::len(self) }
}
impl AltStringData for Vec<Arc<str>> {
fn elt(&self, i: usize) -> Option<&str> { Some(self[i].as_ref()) }
fn no_na(&self) -> Option<bool> { Some(true) }
}
impl AltStringData for Vec<Option<Arc<str>>> {
fn elt(&self, i: usize) -> Option<&str> { self[i].as_deref() }
fn no_na(&self) -> Option<bool> { Some(self.iter().all(Option::is_some)) }
}
impl AltrepSerialize for Vec<Arc<str>> {
fn serialized_state(&self) -> SEXP {
use crate::into_r::IntoR;
self.clone().into_sexp()
}
fn unserialize(state: SEXP) -> Option<Self> {
use crate::from_r::TryFromSexp;
<Vec<Arc<str>>>::try_from_sexp(state).ok().map(std::convert::identity)
}
}
impl AltrepSerialize for Vec<Option<Arc<str>>> {
fn serialized_state(&self) -> SEXP {
use crate::into_r::IntoR;
self.clone().into_sexp()
}
fn unserialize(state: SEXP) -> Option<Self> {
use crate::from_r::TryFromSexp;
<Vec<Option<Arc<str>>>>::try_from_sexp(state).ok().map(std::convert::identity)
}
}impl_owned_str_altrep_data!(Arc);
1174macro_rules! impl_shared_slice_data {
1182 ($owner:ident) => {
1183 impl<T> AltrepLen for $owner<[T]> {
1184 fn altrep_len(&self) -> usize {
1185 <[T]>::len(self)
1186 }
1187 }
1188 impl_altinteger_slice!($owner<[i32]>);
1189 impl_altreal_slice!($owner<[f64]>);
1190 impl_altraw_slice!($owner<[u8]>);
1191 impl_altcomplex_slice!($owner<[Rcomplex]>);
1192 impl_altlogical_native_slice!($owner<[RLogical]>);
1193 impl_altlogical_slice!($owner<[bool]>);
1194 impl AltStringData for $owner<[String]> {
1195 fn elt(&self, i: usize) -> Option<&str> {
1196 Some(&self[i])
1197 }
1198 fn no_na(&self) -> Option<bool> {
1199 Some(true)
1200 }
1201 }
1202 };
1203}
1204macro_rules! impl_shared_slice_dataptr {
1205 ($owner:ident, $elem:ty, $storage:ty) => {
1206 impl AltrepDataptr<$storage> for $owner<[$elem]> {
1207 fn dataptr(&mut self, _writable: bool) -> Option<*mut $storage> {
1208 Some($owner::make_mut(self).as_mut_ptr().cast())
1211 }
1212 fn dataptr_or_null(&self) -> Option<*const $storage> {
1213 ($owner::strong_count(self) == 1 && $owner::weak_count(self) == 0)
1214 .then(|| self.as_ptr().cast())
1215 }
1216 }
1217 };
1218}
1219use std::rc::Rc;
1220use std::sync::Arc;
1221impl<T> AltrepLen for Rc<[T]> {
fn altrep_len(&self) -> usize { <[T]>::len(self) }
}
impl AltIntegerData for Rc<[i32]> {
fn elt(&self, i: usize) -> i32 { self[i] }
fn as_slice(&self) -> Option<&[i32]> { let s: &[i32] = self; Some(s) }
fn get_region(&self, start: usize, len: usize, buf: &mut [i32]) -> usize {
let s: &[i32] = self;
let end = (start + len).min(s.len());
let actual_len = end.saturating_sub(start);
if actual_len > 0 {
buf[..actual_len].copy_from_slice(&s[start..end]);
}
actual_len
}
fn no_na(&self) -> Option<bool> {
let s: &[i32] = self;
Some(!s.iter().any(IsNA::is_na))
}
fn sum(&self, na_rm: bool) -> Option<i64> {
let s: &[i32] = self;
let mut sum: i64 = 0;
for &x in s.iter() {
if x.is_na() {
if !na_rm { return None; }
} else { sum += x as i64; }
}
Some(sum)
}
fn min(&self, na_rm: bool) -> Option<i32> {
let s: &[i32] = self;
let mut min = i32::MAX;
let mut found = false;
for &x in s.iter() {
if x.is_na() {
if !na_rm { return None; }
} else { found = true; min = min.min(x); }
}
if found { Some(min) } else { None }
}
fn max(&self, na_rm: bool) -> Option<i32> {
let s: &[i32] = self;
let mut max = i32::MIN + 1;
let mut found = false;
for &x in s.iter() {
if x.is_na() {
if !na_rm { return None; }
} else { found = true; max = max.max(x); }
}
if found { Some(max) } else { None }
}
}
impl AltRealData for Rc<[f64]> {
fn elt(&self, i: usize) -> f64 { self[i] }
fn as_slice(&self) -> Option<&[f64]> { let s: &[f64] = self; Some(s) }
fn get_region(&self, start: usize, len: usize, buf: &mut [f64]) -> usize {
let s: &[f64] = self;
let end = (start + len).min(s.len());
let actual_len = end.saturating_sub(start);
if actual_len > 0 {
buf[..actual_len].copy_from_slice(&s[start..end]);
}
actual_len
}
fn no_na(&self) -> Option<bool> { Some(real_slice_no_na(self)) }
fn sum(&self, na_rm: bool) -> Option<f64> {
Some(real_slice_sum(self, na_rm))
}
fn min(&self, na_rm: bool) -> Option<f64> {
real_slice_extreme(self, na_rm, f64::min)
}
fn max(&self, na_rm: bool) -> Option<f64> {
real_slice_extreme(self, na_rm, f64::max)
}
}
impl AltRawData for Rc<[u8]> {
fn elt(&self, i: usize) -> u8 { self[i] }
fn as_slice(&self) -> Option<&[u8]> { let s: &[u8] = self; Some(s) }
fn get_region(&self, start: usize, len: usize, buf: &mut [u8]) -> usize {
let s: &[u8] = self;
let end = (start + len).min(s.len());
let actual_len = end.saturating_sub(start);
if actual_len > 0 {
buf[..actual_len].copy_from_slice(&s[start..end]);
}
actual_len
}
}
impl AltComplexData for Rc<[Rcomplex]> {
fn elt(&self, i: usize) -> Rcomplex { self[i] }
fn as_slice(&self) -> Option<&[Rcomplex]> {
let s: &[Rcomplex] = self;
Some(s)
}
fn get_region(&self, start: usize, len: usize, buf: &mut [Rcomplex])
-> usize {
let s: &[Rcomplex] = self;
let end = (start + len).min(s.len());
let actual_len = end.saturating_sub(start);
if actual_len > 0 {
buf[..actual_len].copy_from_slice(&s[start..end]);
}
actual_len
}
}
impl AltLogicalData for Rc<[RLogical]> {
fn elt(&self, i: usize) -> Logical { self[i].into() }
fn as_r_slice(&self) -> Option<&[i32]> {
let values: &[RLogical] = self;
Some(unsafe {
std::slice::from_raw_parts(values.as_ptr().cast(),
values.len())
})
}
fn get_region(&self, start: usize, len: usize, out: &mut [i32]) -> usize {
let values: &[RLogical] = self;
super::fill_region(start, len, values.len(), out,
|i| values[i].to_i32())
}
fn no_na(&self) -> Option<bool> {
let values: &[RLogical] = self;
Some(!values.iter().any(IsNA::is_na))
}
}
impl AltLogicalData for Rc<[bool]> {
fn elt(&self, i: usize) -> Logical { self[i].into() }
fn no_na(&self) -> Option<bool> { Some(true) }
fn sum(&self, _na_rm: bool) -> Option<i64> {
let s: &[bool] = self;
Some(s.iter().filter(|&&x| x).count() as i64)
}
}
impl AltStringData for Rc<[String]> {
fn elt(&self, i: usize) -> Option<&str> { Some(&self[i]) }
fn no_na(&self) -> Option<bool> { Some(true) }
}impl_shared_slice_data!(Rc);
1222impl<T> AltrepLen for Arc<[T]> {
fn altrep_len(&self) -> usize { <[T]>::len(self) }
}
impl AltIntegerData for Arc<[i32]> {
fn elt(&self, i: usize) -> i32 { self[i] }
fn as_slice(&self) -> Option<&[i32]> { let s: &[i32] = self; Some(s) }
fn get_region(&self, start: usize, len: usize, buf: &mut [i32]) -> usize {
let s: &[i32] = self;
let end = (start + len).min(s.len());
let actual_len = end.saturating_sub(start);
if actual_len > 0 {
buf[..actual_len].copy_from_slice(&s[start..end]);
}
actual_len
}
fn no_na(&self) -> Option<bool> {
let s: &[i32] = self;
Some(!s.iter().any(IsNA::is_na))
}
fn sum(&self, na_rm: bool) -> Option<i64> {
let s: &[i32] = self;
let mut sum: i64 = 0;
for &x in s.iter() {
if x.is_na() {
if !na_rm { return None; }
} else { sum += x as i64; }
}
Some(sum)
}
fn min(&self, na_rm: bool) -> Option<i32> {
let s: &[i32] = self;
let mut min = i32::MAX;
let mut found = false;
for &x in s.iter() {
if x.is_na() {
if !na_rm { return None; }
} else { found = true; min = min.min(x); }
}
if found { Some(min) } else { None }
}
fn max(&self, na_rm: bool) -> Option<i32> {
let s: &[i32] = self;
let mut max = i32::MIN + 1;
let mut found = false;
for &x in s.iter() {
if x.is_na() {
if !na_rm { return None; }
} else { found = true; max = max.max(x); }
}
if found { Some(max) } else { None }
}
}
impl AltRealData for Arc<[f64]> {
fn elt(&self, i: usize) -> f64 { self[i] }
fn as_slice(&self) -> Option<&[f64]> { let s: &[f64] = self; Some(s) }
fn get_region(&self, start: usize, len: usize, buf: &mut [f64]) -> usize {
let s: &[f64] = self;
let end = (start + len).min(s.len());
let actual_len = end.saturating_sub(start);
if actual_len > 0 {
buf[..actual_len].copy_from_slice(&s[start..end]);
}
actual_len
}
fn no_na(&self) -> Option<bool> { Some(real_slice_no_na(self)) }
fn sum(&self, na_rm: bool) -> Option<f64> {
Some(real_slice_sum(self, na_rm))
}
fn min(&self, na_rm: bool) -> Option<f64> {
real_slice_extreme(self, na_rm, f64::min)
}
fn max(&self, na_rm: bool) -> Option<f64> {
real_slice_extreme(self, na_rm, f64::max)
}
}
impl AltRawData for Arc<[u8]> {
fn elt(&self, i: usize) -> u8 { self[i] }
fn as_slice(&self) -> Option<&[u8]> { let s: &[u8] = self; Some(s) }
fn get_region(&self, start: usize, len: usize, buf: &mut [u8]) -> usize {
let s: &[u8] = self;
let end = (start + len).min(s.len());
let actual_len = end.saturating_sub(start);
if actual_len > 0 {
buf[..actual_len].copy_from_slice(&s[start..end]);
}
actual_len
}
}
impl AltComplexData for Arc<[Rcomplex]> {
fn elt(&self, i: usize) -> Rcomplex { self[i] }
fn as_slice(&self) -> Option<&[Rcomplex]> {
let s: &[Rcomplex] = self;
Some(s)
}
fn get_region(&self, start: usize, len: usize, buf: &mut [Rcomplex])
-> usize {
let s: &[Rcomplex] = self;
let end = (start + len).min(s.len());
let actual_len = end.saturating_sub(start);
if actual_len > 0 {
buf[..actual_len].copy_from_slice(&s[start..end]);
}
actual_len
}
}
impl AltLogicalData for Arc<[RLogical]> {
fn elt(&self, i: usize) -> Logical { self[i].into() }
fn as_r_slice(&self) -> Option<&[i32]> {
let values: &[RLogical] = self;
Some(unsafe {
std::slice::from_raw_parts(values.as_ptr().cast(),
values.len())
})
}
fn get_region(&self, start: usize, len: usize, out: &mut [i32]) -> usize {
let values: &[RLogical] = self;
super::fill_region(start, len, values.len(), out,
|i| values[i].to_i32())
}
fn no_na(&self) -> Option<bool> {
let values: &[RLogical] = self;
Some(!values.iter().any(IsNA::is_na))
}
}
impl AltLogicalData for Arc<[bool]> {
fn elt(&self, i: usize) -> Logical { self[i].into() }
fn no_na(&self) -> Option<bool> { Some(true) }
fn sum(&self, _na_rm: bool) -> Option<i64> {
let s: &[bool] = self;
Some(s.iter().filter(|&&x| x).count() as i64)
}
}
impl AltStringData for Arc<[String]> {
fn elt(&self, i: usize) -> Option<&str> { Some(&self[i]) }
fn no_na(&self) -> Option<bool> { Some(true) }
}impl_shared_slice_data!(Arc);
1223impl AltrepDataptr<i32> for Rc<[i32]> {
fn dataptr(&mut self, _writable: bool) -> Option<*mut i32> {
Some(Rc::make_mut(self).as_mut_ptr().cast())
}
fn dataptr_or_null(&self) -> Option<*const i32> {
(Rc::strong_count(self) == 1 &&
Rc::weak_count(self) == 0).then(|| self.as_ptr().cast())
}
}impl_shared_slice_dataptr!(Rc, i32, i32);
1224impl AltrepDataptr<f64> for Rc<[f64]> {
fn dataptr(&mut self, _writable: bool) -> Option<*mut f64> {
Some(Rc::make_mut(self).as_mut_ptr().cast())
}
fn dataptr_or_null(&self) -> Option<*const f64> {
(Rc::strong_count(self) == 1 &&
Rc::weak_count(self) == 0).then(|| self.as_ptr().cast())
}
}impl_shared_slice_dataptr!(Rc, f64, f64);
1225impl AltrepDataptr<u8> for Rc<[u8]> {
fn dataptr(&mut self, _writable: bool) -> Option<*mut u8> {
Some(Rc::make_mut(self).as_mut_ptr().cast())
}
fn dataptr_or_null(&self) -> Option<*const u8> {
(Rc::strong_count(self) == 1 &&
Rc::weak_count(self) == 0).then(|| self.as_ptr().cast())
}
}impl_shared_slice_dataptr!(Rc, u8, u8);
1226impl AltrepDataptr<Rcomplex> for Rc<[Rcomplex]> {
fn dataptr(&mut self, _writable: bool) -> Option<*mut Rcomplex> {
Some(Rc::make_mut(self).as_mut_ptr().cast())
}
fn dataptr_or_null(&self) -> Option<*const Rcomplex> {
(Rc::strong_count(self) == 1 &&
Rc::weak_count(self) == 0).then(|| self.as_ptr().cast())
}
}impl_shared_slice_dataptr!(Rc, Rcomplex, Rcomplex);
1227impl AltrepDataptr<i32> for Rc<[RLogical]> {
fn dataptr(&mut self, _writable: bool) -> Option<*mut i32> {
Some(Rc::make_mut(self).as_mut_ptr().cast())
}
fn dataptr_or_null(&self) -> Option<*const i32> {
(Rc::strong_count(self) == 1 &&
Rc::weak_count(self) == 0).then(|| self.as_ptr().cast())
}
}impl_shared_slice_dataptr!(Rc, RLogical, i32);
1228impl AltrepDataptr<i32> for Arc<[i32]> {
fn dataptr(&mut self, _writable: bool) -> Option<*mut i32> {
Some(Arc::make_mut(self).as_mut_ptr().cast())
}
fn dataptr_or_null(&self) -> Option<*const i32> {
(Arc::strong_count(self) == 1 &&
Arc::weak_count(self) == 0).then(|| self.as_ptr().cast())
}
}impl_shared_slice_dataptr!(Arc, i32, i32);
1229impl AltrepDataptr<f64> for Arc<[f64]> {
fn dataptr(&mut self, _writable: bool) -> Option<*mut f64> {
Some(Arc::make_mut(self).as_mut_ptr().cast())
}
fn dataptr_or_null(&self) -> Option<*const f64> {
(Arc::strong_count(self) == 1 &&
Arc::weak_count(self) == 0).then(|| self.as_ptr().cast())
}
}impl_shared_slice_dataptr!(Arc, f64, f64);
1230impl AltrepDataptr<u8> for Arc<[u8]> {
fn dataptr(&mut self, _writable: bool) -> Option<*mut u8> {
Some(Arc::make_mut(self).as_mut_ptr().cast())
}
fn dataptr_or_null(&self) -> Option<*const u8> {
(Arc::strong_count(self) == 1 &&
Arc::weak_count(self) == 0).then(|| self.as_ptr().cast())
}
}impl_shared_slice_dataptr!(Arc, u8, u8);
1231impl AltrepDataptr<Rcomplex> for Arc<[Rcomplex]> {
fn dataptr(&mut self, _writable: bool) -> Option<*mut Rcomplex> {
Some(Arc::make_mut(self).as_mut_ptr().cast())
}
fn dataptr_or_null(&self) -> Option<*const Rcomplex> {
(Arc::strong_count(self) == 1 &&
Arc::weak_count(self) == 0).then(|| self.as_ptr().cast())
}
}impl_shared_slice_dataptr!(Arc, Rcomplex, Rcomplex);
1232impl AltrepDataptr<i32> for Arc<[RLogical]> {
fn dataptr(&mut self, _writable: bool) -> Option<*mut i32> {
Some(Arc::make_mut(self).as_mut_ptr().cast())
}
fn dataptr_or_null(&self) -> Option<*const i32> {
(Arc::strong_count(self) == 1 &&
Arc::weak_count(self) == 0).then(|| self.as_ptr().cast())
}
}impl_shared_slice_dataptr!(Arc, RLogical, i32);
1233macro_rules! impl_len_cow {
1243 ($elem:ty) => {
1244 impl AltrepLen for Cow<'static, [$elem]> {
1245 fn altrep_len(&self) -> usize {
1246 <[$elem]>::len(self)
1247 }
1248 }
1249 };
1250}
1251
1252macro_rules! impl_dataptr_cow {
1253 ($elem:ty) => {
1254 impl_dataptr_cow!($elem => $elem);
1255 };
1256 ($elem:ty => $storage:ty) => {
1258 impl AltrepDataptr<$storage> for Cow<'static, [$elem]> {
1259 fn dataptr(&mut self, writable: bool) -> Option<*mut $storage> {
1260 if writable {
1261 Some(self.to_mut().as_mut_ptr().cast())
1264 } else {
1265 Some(self.as_ptr().cast_mut().cast())
1268 }
1269 }
1270
1271 fn dataptr_or_null(&self) -> Option<*const $storage> {
1272 Some(self.as_ptr().cast())
1273 }
1274 }
1275 };
1276}
1277
1278impl AltrepLen for Cow<'static, [RLogical]> {
fn altrep_len(&self) -> usize { <[RLogical]>::len(self) }
}impl_len_cow!(RLogical);
1281impl AltLogicalData for Cow<'static, [RLogical]> {
fn elt(&self, i: usize) -> Logical { self[i].into() }
fn as_r_slice(&self) -> Option<&[i32]> {
let values: &[RLogical] = self;
Some(unsafe {
std::slice::from_raw_parts(values.as_ptr().cast(),
values.len())
})
}
fn get_region(&self, start: usize, len: usize, out: &mut [i32]) -> usize {
let values: &[RLogical] = self;
super::fill_region(start, len, values.len(), out,
|i| values[i].to_i32())
}
fn no_na(&self) -> Option<bool> {
let values: &[RLogical] = self;
Some(!values.iter().any(IsNA::is_na))
}
}impl_altlogical_native_slice!(Cow<'static, [RLogical]>);
1282impl AltrepDataptr<i32> for Cow<'static, [RLogical]> {
fn dataptr(&mut self, writable: bool) -> Option<*mut i32> {
if writable {
Some(self.to_mut().as_mut_ptr().cast())
} else { Some(self.as_ptr().cast_mut().cast()) }
}
fn dataptr_or_null(&self) -> Option<*const i32> {
Some(self.as_ptr().cast())
}
}impl_dataptr_cow!(RLogical => i32);
1283impl AltrepSerialize for Cow<'static, [RLogical]> {
fn serialized_state(&self) -> SEXP {
use crate::into_r::IntoR;
self.clone().into_sexp()
}
fn unserialize(state: SEXP) -> Option<Self> {
use crate::from_r::TryFromSexp;
<Vec<RLogical>>::try_from_sexp(state).ok().map(Cow::Owned)
}
}impl_serialize!(Cow<'static, [RLogical]>, Vec<RLogical>, Cow::Owned);
1284
1285impl AltrepLen for Cow<'static, [i32]> {
fn altrep_len(&self) -> usize { <[i32]>::len(self) }
}impl_len_cow!(i32);
1286impl AltIntegerData for Cow<'static, [i32]> {
fn elt(&self, i: usize) -> i32 { self[i] }
fn as_slice(&self) -> Option<&[i32]> { let s: &[i32] = self; Some(s) }
fn get_region(&self, start: usize, len: usize, buf: &mut [i32]) -> usize {
let s: &[i32] = self;
let end = (start + len).min(s.len());
let actual_len = end.saturating_sub(start);
if actual_len > 0 {
buf[..actual_len].copy_from_slice(&s[start..end]);
}
actual_len
}
fn no_na(&self) -> Option<bool> {
let s: &[i32] = self;
Some(!s.iter().any(IsNA::is_na))
}
fn sum(&self, na_rm: bool) -> Option<i64> {
let s: &[i32] = self;
let mut sum: i64 = 0;
for &x in s.iter() {
if x.is_na() {
if !na_rm { return None; }
} else { sum += x as i64; }
}
Some(sum)
}
fn min(&self, na_rm: bool) -> Option<i32> {
let s: &[i32] = self;
let mut min = i32::MAX;
let mut found = false;
for &x in s.iter() {
if x.is_na() {
if !na_rm { return None; }
} else { found = true; min = min.min(x); }
}
if found { Some(min) } else { None }
}
fn max(&self, na_rm: bool) -> Option<i32> {
let s: &[i32] = self;
let mut max = i32::MIN + 1;
let mut found = false;
for &x in s.iter() {
if x.is_na() {
if !na_rm { return None; }
} else { found = true; max = max.max(x); }
}
if found { Some(max) } else { None }
}
}impl_altinteger_slice!(Cow<'static, [i32]>);
1287impl AltrepDataptr<i32> for Cow<'static, [i32]> {
fn dataptr(&mut self, writable: bool) -> Option<*mut i32> {
if writable {
Some(self.to_mut().as_mut_ptr().cast())
} else { Some(self.as_ptr().cast_mut().cast()) }
}
fn dataptr_or_null(&self) -> Option<*const i32> {
Some(self.as_ptr().cast())
}
}impl_dataptr_cow!(i32);
1288impl AltrepSerialize for Cow<'static, [i32]> {
fn serialized_state(&self) -> SEXP {
use crate::into_r::IntoR;
self.clone().into_sexp()
}
fn unserialize(state: SEXP) -> Option<Self> {
use crate::from_r::TryFromSexp;
<Vec<i32>>::try_from_sexp(state).ok().map(Cow::Owned)
}
}impl_serialize!(Cow<'static, [i32]>, Vec<i32>, Cow::Owned);
1289
1290impl AltrepLen for Cow<'static, [f64]> {
fn altrep_len(&self) -> usize { <[f64]>::len(self) }
}impl_len_cow!(f64);
1291impl AltRealData for Cow<'static, [f64]> {
fn elt(&self, i: usize) -> f64 { self[i] }
fn as_slice(&self) -> Option<&[f64]> { let s: &[f64] = self; Some(s) }
fn get_region(&self, start: usize, len: usize, buf: &mut [f64]) -> usize {
let s: &[f64] = self;
let end = (start + len).min(s.len());
let actual_len = end.saturating_sub(start);
if actual_len > 0 {
buf[..actual_len].copy_from_slice(&s[start..end]);
}
actual_len
}
fn no_na(&self) -> Option<bool> { Some(real_slice_no_na(self)) }
fn sum(&self, na_rm: bool) -> Option<f64> {
Some(real_slice_sum(self, na_rm))
}
fn min(&self, na_rm: bool) -> Option<f64> {
real_slice_extreme(self, na_rm, f64::min)
}
fn max(&self, na_rm: bool) -> Option<f64> {
real_slice_extreme(self, na_rm, f64::max)
}
}impl_altreal_slice!(Cow<'static, [f64]>);
1292impl AltrepDataptr<f64> for Cow<'static, [f64]> {
fn dataptr(&mut self, writable: bool) -> Option<*mut f64> {
if writable {
Some(self.to_mut().as_mut_ptr().cast())
} else { Some(self.as_ptr().cast_mut().cast()) }
}
fn dataptr_or_null(&self) -> Option<*const f64> {
Some(self.as_ptr().cast())
}
}impl_dataptr_cow!(f64);
1293impl AltrepSerialize for Cow<'static, [f64]> {
fn serialized_state(&self) -> SEXP {
use crate::into_r::IntoR;
self.clone().into_sexp()
}
fn unserialize(state: SEXP) -> Option<Self> {
use crate::from_r::TryFromSexp;
<Vec<f64>>::try_from_sexp(state).ok().map(Cow::Owned)
}
}impl_serialize!(Cow<'static, [f64]>, Vec<f64>, Cow::Owned);
1294
1295impl AltrepLen for Cow<'static, [u8]> {
fn altrep_len(&self) -> usize { <[u8]>::len(self) }
}impl_len_cow!(u8);
1296impl AltRawData for Cow<'static, [u8]> {
fn elt(&self, i: usize) -> u8 { self[i] }
fn as_slice(&self) -> Option<&[u8]> { let s: &[u8] = self; Some(s) }
fn get_region(&self, start: usize, len: usize, buf: &mut [u8]) -> usize {
let s: &[u8] = self;
let end = (start + len).min(s.len());
let actual_len = end.saturating_sub(start);
if actual_len > 0 {
buf[..actual_len].copy_from_slice(&s[start..end]);
}
actual_len
}
}impl_altraw_slice!(Cow<'static, [u8]>);
1297impl AltrepDataptr<u8> for Cow<'static, [u8]> {
fn dataptr(&mut self, writable: bool) -> Option<*mut u8> {
if writable {
Some(self.to_mut().as_mut_ptr().cast())
} else { Some(self.as_ptr().cast_mut().cast()) }
}
fn dataptr_or_null(&self) -> Option<*const u8> {
Some(self.as_ptr().cast())
}
}impl_dataptr_cow!(u8);
1298impl AltrepSerialize for Cow<'static, [u8]> {
fn serialized_state(&self) -> SEXP {
use crate::into_r::IntoR;
self.clone().into_sexp()
}
fn unserialize(state: SEXP) -> Option<Self> {
use crate::from_r::TryFromSexp;
<Vec<u8>>::try_from_sexp(state).ok().map(Cow::Owned)
}
}impl_serialize!(Cow<'static, [u8]>, Vec<u8>, Cow::Owned);
1299
1300impl AltrepLen for Cow<'static, [Rcomplex]> {
fn altrep_len(&self) -> usize { <[Rcomplex]>::len(self) }
}impl_len_cow!(Rcomplex);
1301impl AltComplexData for Cow<'static, [Rcomplex]> {
fn elt(&self, i: usize) -> Rcomplex { self[i] }
fn as_slice(&self) -> Option<&[Rcomplex]> {
let s: &[Rcomplex] = self;
Some(s)
}
fn get_region(&self, start: usize, len: usize, buf: &mut [Rcomplex])
-> usize {
let s: &[Rcomplex] = self;
let end = (start + len).min(s.len());
let actual_len = end.saturating_sub(start);
if actual_len > 0 {
buf[..actual_len].copy_from_slice(&s[start..end]);
}
actual_len
}
}impl_altcomplex_slice!(Cow<'static, [Rcomplex]>);
1302impl AltrepDataptr<Rcomplex> for Cow<'static, [Rcomplex]> {
fn dataptr(&mut self, writable: bool) -> Option<*mut Rcomplex> {
if writable {
Some(self.to_mut().as_mut_ptr().cast())
} else { Some(self.as_ptr().cast_mut().cast()) }
}
fn dataptr_or_null(&self) -> Option<*const Rcomplex> {
Some(self.as_ptr().cast())
}
}impl_dataptr_cow!(Rcomplex);
1303impl AltrepSerialize for Cow<'static, [Rcomplex]> {
fn serialized_state(&self) -> SEXP {
use crate::into_r::IntoR;
self.clone().into_sexp()
}
fn unserialize(state: SEXP) -> Option<Self> {
use crate::from_r::TryFromSexp;
<Vec<Rcomplex>>::try_from_sexp(state).ok().map(Cow::Owned)
}
}impl_serialize!(Cow<'static, [Rcomplex]>, Vec<Rcomplex>, Cow::Owned);
1304#[cfg(test)]
1320mod tests {
1321 use super::*;
1322 use crate::altrep_data::AltRealData;
1323 use crate::altrep_traits::NA_REAL;
1324
1325 const COMPUTED_NA: f64 = f64::from_bits(0x7FF8_0000_0000_07A2);
1328
1329 #[test]
1333 fn na_real_bit_pattern() {
1334 assert_eq!(NA_REAL.to_bits(), 0x7FF0_0000_0000_07A2);
1335 }
1336
1337 #[test]
1339 fn nan_is_not_na_real() {
1340 let nan = f64::NAN;
1341 assert!(nan.is_nan());
1342 assert_ne!(nan.to_bits(), NA_REAL.to_bits());
1343 }
1344
1345 #[test]
1352 fn vec_f64_no_na_with_regular_nan_is_false() {
1353 let v: Vec<f64> = vec![1.0, f64::NAN, 3.0];
1354 assert_eq!(AltRealData::no_na(&v), Some(false));
1355 }
1356
1357 #[test]
1359 fn vec_f64_no_na_with_computed_na_is_false() {
1360 let v: Vec<f64> = vec![1.0, COMPUTED_NA, 3.0];
1361 assert_eq!(AltRealData::no_na(&v), Some(false));
1362 }
1363
1364 #[test]
1366 fn vec_f64_no_na_with_na_real_is_false() {
1367 let v: Vec<f64> = vec![1.0, NA_REAL, 3.0];
1368 assert_eq!(AltRealData::no_na(&v), Some(false));
1369 }
1370
1371 #[test]
1373 fn vec_f64_no_na_all_finite_is_true() {
1374 let v: Vec<f64> = vec![1.0, 2.0, 3.0];
1375 assert_eq!(AltRealData::no_na(&v), Some(true));
1376 }
1377
1378 #[test]
1384 fn vec_f64_sum_na_propagates() {
1385 let v: Vec<f64> = vec![1.0, NA_REAL, 3.0];
1386 let result = AltRealData::sum(&v, false);
1387 assert!(result.is_some());
1388 let bits = result.unwrap().to_bits();
1389 assert_eq!(
1390 bits,
1391 NA_REAL.to_bits(),
1392 "sum with NA should return NA_real_"
1393 );
1394 }
1395
1396 #[test]
1398 fn vec_f64_sum_na_rm_skips_na() {
1399 let v: Vec<f64> = vec![1.0, NA_REAL, 3.0];
1400 let result = AltRealData::sum(&v, true);
1401 assert_eq!(result, Some(4.0));
1402 }
1403
1404 #[test]
1406 fn vec_f64_sum_nan_propagates_as_nan_not_na() {
1407 let v: Vec<f64> = vec![1.0, f64::NAN, 3.0];
1408 let result = AltRealData::sum(&v, false);
1409 assert!(result.is_some());
1410 let val = result.unwrap();
1411 assert!(val.is_nan(), "sum with NaN (not NA) should return NaN");
1412 assert_ne!(
1413 val.to_bits(),
1414 NA_REAL.to_bits(),
1415 "sum with regular NaN should NOT return NA_real_"
1416 );
1417 }
1418
1419 #[test]
1421 fn vec_f64_sum_nan_rm_skips_nan() {
1422 let v: Vec<f64> = vec![1.0, f64::NAN, 3.0];
1423 let result = AltRealData::sum(&v, true);
1424 assert_eq!(result, Some(4.0));
1425 }
1426
1427 #[test]
1429 fn vec_f64_sum_computed_na() {
1430 let v: Vec<f64> = vec![1.0, COMPUTED_NA, 3.0];
1431 let na = AltRealData::sum(&v, false).expect("sum is always computed");
1432 assert!(na.is_na(), "{:#x}", na.to_bits());
1433 assert_eq!(AltRealData::sum(&v, true), Some(4.0));
1434 }
1435
1436 #[test]
1438 fn vec_f64_min_max_na_trumps_nan() {
1439 for v in [
1440 vec![f64::NAN, 1.0, COMPUTED_NA],
1441 vec![COMPUTED_NA, f64::NAN, 1.0],
1442 vec![1.0, f64::NAN, NA_REAL],
1443 ] {
1444 for extreme in [
1445 AltRealData::min(&v, false),
1446 AltRealData::max(&v, false),
1447 AltRealData::sum(&v, false),
1448 ] {
1449 let value = extreme.expect("missing values give a result");
1450 assert!(value.is_na(), "{v:?} gave {:#x}", value.to_bits());
1451 }
1452 assert_eq!(AltRealData::min(&v, true), Some(1.0));
1453 assert_eq!(AltRealData::max(&v, true), Some(1.0));
1454 }
1455 let nan_only = vec![3.0, f64::NAN, 1.0];
1456 let min = AltRealData::min(&nan_only, false).expect("NaN gives a result");
1457 assert!(min.is_nan() && !min.is_na());
1458 assert_eq!(AltRealData::min(&nan_only, true), Some(1.0));
1459 assert_eq!(AltRealData::max(&nan_only, true), Some(3.0));
1460 let all_missing = vec![NA_REAL, f64::NAN];
1461 assert_eq!(AltRealData::min(&all_missing, true), None);
1462 }
1463
1464 #[test]
1469 fn box_f64_no_na_with_regular_nan_is_false() {
1470 let v: Box<[f64]> = vec![1.0, f64::NAN, 3.0].into_boxed_slice();
1471 assert_eq!(AltRealData::no_na(&v), Some(false));
1472 }
1473
1474 #[test]
1475 fn box_f64_no_na_with_na_real_is_false() {
1476 let v: Box<[f64]> = vec![1.0, NA_REAL, 3.0].into_boxed_slice();
1477 assert_eq!(AltRealData::no_na(&v), Some(false));
1478 }
1479
1480 #[test]
1485 fn slice_f64_no_na_with_regular_nan_is_false() {
1486 let data: &[f64] = &[1.0, f64::NAN, 3.0];
1487 assert_eq!(AltRealData::no_na(&data), Some(false));
1488 }
1489
1490 #[test]
1491 fn slice_f64_no_na_with_na_real_is_false() {
1492 let data: &[f64] = &[1.0, NA_REAL, 3.0];
1493 assert_eq!(AltRealData::no_na(&data), Some(false));
1494 }
1495
1496 #[test]
1501 fn array_f64_no_na_with_regular_nan_is_false() {
1502 let arr: [f64; 3] = [1.0, f64::NAN, 3.0];
1503 assert_eq!(AltRealData::no_na(&arr), Some(false));
1504 }
1505
1506 #[test]
1507 fn array_f64_no_na_with_na_real_is_false() {
1508 let arr: [f64; 3] = [1.0, NA_REAL, 3.0];
1509 assert_eq!(AltRealData::no_na(&arr), Some(false));
1510 }
1511
1512 #[test]
1517 fn cow_f64_no_na_with_regular_nan_is_false() {
1518 let v: Cow<'static, [f64]> = Cow::Owned(vec![1.0, f64::NAN, 3.0]);
1519 assert_eq!(AltRealData::no_na(&v), Some(false));
1520 }
1521
1522 #[test]
1523 fn cow_f64_no_na_with_na_real_is_false() {
1524 let v: Cow<'static, [f64]> = Cow::Owned(vec![1.0, NA_REAL, 3.0]);
1525 assert_eq!(AltRealData::no_na(&v), Some(false));
1526 }
1527
1528 }