miniextendr_api/altrep_data/
builtins.rs1use std::ops::Range;
13
14use crate::ffi::Rcomplex;
15use crate::ffi::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 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 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 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 len(&self) -> usize {
62 <[$elem]>::len(self)
63 }
64 }
65 };
66}
67
68macro_rules! impl_dataptr_vec {
70 ($elem:ty) => {
71 impl AltrepDataptr<$elem> for Vec<$elem> {
72 fn dataptr(&mut self, _writable: bool) -> Option<*mut $elem> {
73 Some(self.as_mut_ptr())
74 }
75
76 fn dataptr_or_null(&self) -> Option<*const $elem> {
77 Some(self.as_ptr())
78 }
79 }
80 };
81}
82
83macro_rules! impl_dataptr_boxed {
85 ($elem:ty) => {
86 impl AltrepDataptr<$elem> for Box<[$elem]> {
87 fn dataptr(&mut self, _writable: bool) -> Option<*mut $elem> {
88 Some(self.as_mut_ptr())
89 }
90
91 fn dataptr_or_null(&self) -> Option<*const $elem> {
92 Some(self.as_ptr())
93 }
94 }
95 };
96}
97
98macro_rules! impl_serialize {
103 ($ty:ty) => {
104 impl AltrepSerialize for $ty {
105 fn serialized_state(&self) -> SEXP {
106 use crate::into_r::IntoR;
107 self.clone().into_sexp()
108 }
109
110 fn unserialize(state: SEXP) -> Option<Self> {
111 use crate::from_r::TryFromSexp;
112 <$ty>::try_from_sexp(state).ok()
113 }
114 }
115 };
116}
117impl_serialize!(Vec<i32>);
122impl_serialize!(Vec<f64>);
123impl_serialize!(Vec<u8>);
124impl_serialize!(Vec<bool>);
125impl_serialize!(Vec<String>);
126impl_serialize!(Vec<Option<String>>);
127impl_serialize!(Vec<Rcomplex>);
128impl_serialize!(Vec<std::borrow::Cow<'static, str>>);
131impl_serialize!(Vec<Option<std::borrow::Cow<'static, str>>>);
132impl AltrepSerialize for Box<[i32]> {
140 fn serialized_state(&self) -> SEXP {
141 use crate::into_r::IntoR;
142 self.to_vec().into_sexp()
143 }
144
145 fn unserialize(state: SEXP) -> Option<Self> {
146 use crate::from_r::TryFromSexp;
147 Vec::<i32>::try_from_sexp(state)
148 .ok()
149 .map(|v| v.into_boxed_slice())
150 }
151}
152
153impl AltrepSerialize for Box<[f64]> {
154 fn serialized_state(&self) -> SEXP {
155 use crate::into_r::IntoR;
156 self.to_vec().into_sexp()
157 }
158
159 fn unserialize(state: SEXP) -> Option<Self> {
160 use crate::from_r::TryFromSexp;
161 Vec::<f64>::try_from_sexp(state)
162 .ok()
163 .map(|v| v.into_boxed_slice())
164 }
165}
166
167impl AltrepSerialize for Box<[u8]> {
168 fn serialized_state(&self) -> SEXP {
169 use crate::into_r::IntoR;
170 self.to_vec().into_sexp()
171 }
172
173 fn unserialize(state: SEXP) -> Option<Self> {
174 use crate::from_r::TryFromSexp;
175 Vec::<u8>::try_from_sexp(state)
176 .ok()
177 .map(|v| v.into_boxed_slice())
178 }
179}
180
181impl AltrepSerialize for Box<[bool]> {
182 fn serialized_state(&self) -> SEXP {
183 use crate::into_r::IntoR;
184 self.to_vec().into_sexp()
185 }
186
187 fn unserialize(state: SEXP) -> Option<Self> {
188 use crate::from_r::TryFromSexp;
189 Vec::<bool>::try_from_sexp(state)
190 .ok()
191 .map(|v| v.into_boxed_slice())
192 }
193}
194
195impl AltrepSerialize for Box<[String]> {
196 fn serialized_state(&self) -> SEXP {
197 use crate::into_r::IntoR;
198 self.to_vec().into_sexp()
199 }
200
201 fn unserialize(state: SEXP) -> Option<Self> {
202 use crate::from_r::TryFromSexp;
203 Vec::<String>::try_from_sexp(state)
204 .ok()
205 .map(|v| v.into_boxed_slice())
206 }
207}
208
209impl AltrepSerialize for Box<[Rcomplex]> {
210 fn serialized_state(&self) -> SEXP {
211 use crate::into_r::IntoR;
212 self.to_vec().into_sexp()
213 }
214
215 fn unserialize(state: SEXP) -> Option<Self> {
216 use crate::from_r::TryFromSexp;
217 Vec::<Rcomplex>::try_from_sexp(state)
218 .ok()
219 .map(|v| v.into_boxed_slice())
220 }
221}
222impl_len_vec!(i32);
227
228impl AltIntegerData for Vec<i32> {
229 fn elt(&self, i: usize) -> i32 {
230 self[i]
231 }
232
233 fn as_slice(&self) -> Option<&[i32]> {
234 Some(self.as_slice())
235 }
236
237 fn get_region(&self, start: usize, len: usize, buf: &mut [i32]) -> usize {
238 let end = (start + len).min(self.len());
239 let actual_len = end.saturating_sub(start);
240 if actual_len > 0 {
241 buf[..actual_len].copy_from_slice(&self[start..end]);
242 }
243 actual_len
244 }
245
246 fn no_na(&self) -> Option<bool> {
247 Some(!self.contains(&i32::MIN))
248 }
249
250 fn sum(&self, na_rm: bool) -> Option<i64> {
251 let mut sum: i64 = 0;
252 for &x in self.iter() {
253 if x == i32::MIN {
254 if !na_rm {
255 return None; }
257 } else {
258 sum += x as i64;
259 }
260 }
261 Some(sum)
262 }
263
264 fn min(&self, na_rm: bool) -> Option<i32> {
265 let mut min = i32::MAX;
266 let mut found = false;
267 for &x in self.iter() {
268 if x == i32::MIN {
269 if !na_rm {
270 return None;
271 }
272 } else {
273 found = true;
274 min = min.min(x);
275 }
276 }
277 if found { Some(min) } else { None }
278 }
279
280 fn max(&self, na_rm: bool) -> Option<i32> {
281 let mut max = i32::MIN + 1; let mut found = false;
283 for &x in self.iter() {
284 if x == i32::MIN {
285 if !na_rm {
286 return None;
287 }
288 } else {
289 found = true;
290 max = max.max(x);
291 }
292 }
293 if found { Some(max) } else { None }
294 }
295}
296
297impl_dataptr_vec!(i32);
298
299impl_len_vec!(f64);
300
301impl AltRealData for Vec<f64> {
302 fn elt(&self, i: usize) -> f64 {
303 self[i]
304 }
305
306 fn as_slice(&self) -> Option<&[f64]> {
307 Some(self.as_slice())
308 }
309
310 fn get_region(&self, start: usize, len: usize, buf: &mut [f64]) -> usize {
311 let end = (start + len).min(self.len());
312 let actual_len = end.saturating_sub(start);
313 if actual_len > 0 {
314 buf[..actual_len].copy_from_slice(&self[start..end]);
315 }
316 actual_len
317 }
318
319 fn no_na(&self) -> Option<bool> {
320 Some(!self.iter().any(|x| x.is_nan()))
321 }
322
323 fn sum(&self, na_rm: bool) -> Option<f64> {
324 let mut sum = 0.0;
325 for &x in self.iter() {
326 if x.is_nan() {
327 if !na_rm {
328 return Some(f64::NAN);
329 }
330 } else {
331 sum += x;
332 }
333 }
334 Some(sum)
335 }
336
337 fn min(&self, na_rm: bool) -> Option<f64> {
338 let mut min = f64::INFINITY;
339 let mut found = false;
340 for &x in self.iter() {
341 if x.is_nan() {
342 if !na_rm {
343 return Some(f64::NAN);
344 }
345 } else {
346 found = true;
347 min = min.min(x);
348 }
349 }
350 if found { Some(min) } else { None }
351 }
352
353 fn max(&self, na_rm: bool) -> Option<f64> {
354 let mut max = f64::NEG_INFINITY;
355 let mut found = false;
356 for &x in self.iter() {
357 if x.is_nan() {
358 if !na_rm {
359 return Some(f64::NAN);
360 }
361 } else {
362 found = true;
363 max = max.max(x);
364 }
365 }
366 if found { Some(max) } else { None }
367 }
368}
369
370impl_dataptr_vec!(f64);
371
372impl_len_vec!(u8);
373
374impl AltRawData for Vec<u8> {
375 fn elt(&self, i: usize) -> u8 {
376 self[i]
377 }
378
379 fn as_slice(&self) -> Option<&[u8]> {
380 Some(self.as_slice())
381 }
382
383 fn get_region(&self, start: usize, len: usize, buf: &mut [u8]) -> usize {
384 let end = (start + len).min(self.len());
385 let actual_len = end.saturating_sub(start);
386 if actual_len > 0 {
387 buf[..actual_len].copy_from_slice(&self[start..end]);
388 }
389 actual_len
390 }
391}
392
393impl_dataptr_vec!(u8);
394
395impl_len_vec!(String);
396
397impl AltStringData for Vec<String> {
398 fn elt(&self, i: usize) -> Option<&str> {
399 Some(self[i].as_str())
400 }
401
402 fn no_na(&self) -> Option<bool> {
403 Some(true) }
405}
406
407impl_len_vec!(Option<String>);
408
409impl AltStringData for Vec<Option<String>> {
410 fn elt(&self, i: usize) -> Option<&str> {
411 self[i].as_deref()
412 }
413
414 fn no_na(&self) -> Option<bool> {
415 Some(!self.iter().any(|x| x.is_none()))
416 }
417}
418
419impl AltrepLen for Vec<std::borrow::Cow<'static, str>> {
420 fn len(&self) -> usize {
421 self.len()
422 }
423}
424
425impl AltStringData for Vec<std::borrow::Cow<'static, str>> {
426 fn elt(&self, i: usize) -> Option<&str> {
427 Some(self[i].as_ref())
428 }
429
430 fn no_na(&self) -> Option<bool> {
431 Some(true) }
433}
434
435impl AltrepLen for Vec<Option<std::borrow::Cow<'static, str>>> {
436 fn len(&self) -> usize {
437 self.len()
438 }
439}
440
441impl AltStringData for Vec<Option<std::borrow::Cow<'static, str>>> {
442 fn elt(&self, i: usize) -> Option<&str> {
443 self[i].as_deref()
444 }
445
446 fn no_na(&self) -> Option<bool> {
447 Some(!self.iter().any(|x| x.is_none()))
448 }
449}
450
451impl_len_vec!(bool);
452
453impl AltLogicalData for Vec<bool> {
454 fn elt(&self, i: usize) -> Logical {
455 if self[i] {
456 Logical::True
457 } else {
458 Logical::False
459 }
460 }
461
462 fn no_na(&self) -> Option<bool> {
463 Some(true) }
465
466 fn sum(&self, _na_rm: bool) -> Option<i64> {
467 Some(self.iter().filter(|&&x| x).count() as i64)
468 }
469}
470impl_len_boxed!(i32);
486
487impl AltIntegerData for Box<[i32]> {
488 fn elt(&self, i: usize) -> i32 {
489 self[i]
490 }
491
492 fn as_slice(&self) -> Option<&[i32]> {
493 Some(self)
494 }
495
496 fn get_region(&self, start: usize, len: usize, buf: &mut [i32]) -> usize {
497 let end = (start + len).min(<[i32]>::len(self));
498 let actual_len = end.saturating_sub(start);
499 if actual_len > 0 {
500 buf[..actual_len].copy_from_slice(&self[start..end]);
501 }
502 actual_len
503 }
504
505 fn no_na(&self) -> Option<bool> {
506 Some(!self.contains(&i32::MIN))
507 }
508
509 fn sum(&self, na_rm: bool) -> Option<i64> {
510 let mut sum: i64 = 0;
511 for &x in self.iter() {
512 if x == i32::MIN {
513 if !na_rm {
514 return None;
515 }
516 } else {
517 sum += x as i64;
518 }
519 }
520 Some(sum)
521 }
522
523 fn min(&self, na_rm: bool) -> Option<i32> {
524 let mut min = i32::MAX;
525 let mut found = false;
526 for &x in self.iter() {
527 if x == i32::MIN {
528 if !na_rm {
529 return None;
530 }
531 } else {
532 found = true;
533 min = min.min(x);
534 }
535 }
536 if found { Some(min) } else { None }
537 }
538
539 fn max(&self, na_rm: bool) -> Option<i32> {
540 let mut max = i32::MIN + 1; let mut found = false;
542 for &x in self.iter() {
543 if x == i32::MIN {
544 if !na_rm {
545 return None;
546 }
547 } else {
548 found = true;
549 max = max.max(x);
550 }
551 }
552 if found { Some(max) } else { None }
553 }
554}
555
556impl_dataptr_boxed!(i32);
557
558impl_len_boxed!(f64);
559
560impl AltRealData for Box<[f64]> {
561 fn elt(&self, i: usize) -> f64 {
562 self[i]
563 }
564
565 fn as_slice(&self) -> Option<&[f64]> {
566 Some(self)
567 }
568
569 fn get_region(&self, start: usize, len: usize, buf: &mut [f64]) -> usize {
570 let end = (start + len).min(<[f64]>::len(self));
571 let actual_len = end.saturating_sub(start);
572 if actual_len > 0 {
573 buf[..actual_len].copy_from_slice(&self[start..end]);
574 }
575 actual_len
576 }
577
578 fn no_na(&self) -> Option<bool> {
579 Some(!self.iter().any(|x| x.is_nan()))
580 }
581
582 fn sum(&self, na_rm: bool) -> Option<f64> {
583 let mut sum = 0.0;
584 for &x in self.iter() {
585 if x.is_nan() {
586 if !na_rm {
587 return Some(f64::NAN);
588 }
589 } else {
590 sum += x;
591 }
592 }
593 Some(sum)
594 }
595
596 fn min(&self, na_rm: bool) -> Option<f64> {
597 let mut min = f64::INFINITY;
598 let mut found = false;
599 for &x in self.iter() {
600 if x.is_nan() {
601 if !na_rm {
602 return Some(f64::NAN);
603 }
604 } else {
605 found = true;
606 min = min.min(x);
607 }
608 }
609 if found { Some(min) } else { None }
610 }
611
612 fn max(&self, na_rm: bool) -> Option<f64> {
613 let mut max = f64::NEG_INFINITY;
614 let mut found = false;
615 for &x in self.iter() {
616 if x.is_nan() {
617 if !na_rm {
618 return Some(f64::NAN);
619 }
620 } else {
621 found = true;
622 max = max.max(x);
623 }
624 }
625 if found { Some(max) } else { None }
626 }
627}
628
629impl_dataptr_boxed!(f64);
630
631impl_len_boxed!(u8);
632
633impl AltRawData for Box<[u8]> {
634 fn elt(&self, i: usize) -> u8 {
635 self[i]
636 }
637
638 fn as_slice(&self) -> Option<&[u8]> {
639 Some(self)
640 }
641
642 fn get_region(&self, start: usize, len: usize, buf: &mut [u8]) -> usize {
643 let end = (start + len).min(<[u8]>::len(self));
644 let actual_len = end.saturating_sub(start);
645 if actual_len > 0 {
646 buf[..actual_len].copy_from_slice(&self[start..end]);
647 }
648 actual_len
649 }
650}
651
652impl_dataptr_boxed!(u8);
653
654impl_len_boxed!(bool);
655
656impl AltLogicalData for Box<[bool]> {
657 fn elt(&self, i: usize) -> Logical {
658 if self[i] {
659 Logical::True
660 } else {
661 Logical::False
662 }
663 }
664
665 fn no_na(&self) -> Option<bool> {
666 Some(true) }
668
669 fn sum(&self, _na_rm: bool) -> Option<i64> {
670 Some(self.iter().filter(|&&x| x).count() as i64)
671 }
672}
673
674impl_len_boxed!(String);
675
676impl AltStringData for Box<[String]> {
677 fn elt(&self, i: usize) -> Option<&str> {
678 Some(self[i].as_str())
679 }
680
681 fn no_na(&self) -> Option<bool> {
682 Some(true) }
684}
685impl AltrepSerialize for Range<i32> {
691 fn serialized_state(&self) -> SEXP {
692 use crate::into_r::IntoR;
693 vec![self.start, self.end].into_sexp()
694 }
695
696 fn unserialize(state: SEXP) -> Option<Self> {
697 use crate::from_r::TryFromSexp;
698 let v = Vec::<i32>::try_from_sexp(state).ok()?;
699 if v.len() == 2 { Some(v[0]..v[1]) } else { None }
700 }
701}
702
703impl AltrepSerialize for Range<i64> {
704 fn serialized_state(&self) -> SEXP {
705 use crate::into_r::IntoR;
706 vec![
709 f64::from_bits(self.start as u64),
710 f64::from_bits(self.end as u64),
711 ]
712 .into_sexp()
713 }
714
715 fn unserialize(state: SEXP) -> Option<Self> {
716 use crate::from_r::TryFromSexp;
717 let v = Vec::<f64>::try_from_sexp(state).ok()?;
718 if v.len() == 2 {
719 Some((v[0].to_bits() as i64)..(v[1].to_bits() as i64))
720 } else {
721 None
722 }
723 }
724}
725
726impl AltrepSerialize for Range<f64> {
727 fn serialized_state(&self) -> SEXP {
728 use crate::into_r::IntoR;
729 vec![self.start, self.end].into_sexp()
730 }
731
732 fn unserialize(state: SEXP) -> Option<Self> {
733 use crate::from_r::TryFromSexp;
734 let v = Vec::<f64>::try_from_sexp(state).ok()?;
735 if v.len() == 2 { Some(v[0]..v[1]) } else { None }
736 }
737}
738impl AltrepLen for Range<i32> {
743 fn len(&self) -> usize {
744 if self.end > self.start {
745 (self.end - self.start) as usize
746 } else {
747 0
748 }
749 }
750}
751
752impl AltIntegerData for Range<i32> {
753 fn elt(&self, i: usize) -> i32 {
754 self.start + i as i32
755 }
756
757 fn is_sorted(&self) -> Option<Sortedness> {
758 Some(Sortedness::Increasing)
759 }
760
761 fn no_na(&self) -> Option<bool> {
762 let contains_na = self.start == i32::MIN && self.end > i32::MIN;
766 Some(!contains_na)
767 }
768
769 fn sum(&self, na_rm: bool) -> Option<i64> {
770 let n = AltrepLen::len(self) as i64;
771 if n == 0 {
772 return Some(0);
773 }
774
775 let contains_na = self.start == i32::MIN && self.end > i32::MIN;
777 if contains_na && !na_rm {
778 return None; }
780
781 if contains_na {
784 let n_valid = n - 1;
786 if n_valid == 0 {
787 return Some(0);
788 }
789 let first = (self.start + 1) as i64;
790 let last = (self.end - 1) as i64;
791 Some(n_valid * (first + last) / 2)
792 } else {
793 let first = self.start as i64;
794 let last = (self.end - 1) as i64;
795 Some(n * (first + last) / 2)
796 }
797 }
798
799 fn min(&self, na_rm: bool) -> Option<i32> {
800 if AltrepLen::len(self) == 0 {
801 return None;
802 }
803
804 if self.start == i32::MIN {
806 if na_rm {
807 if self.end > self.start + 1 {
809 Some(self.start + 1)
810 } else {
811 None }
813 } else {
814 None }
816 } else {
817 Some(self.start)
818 }
819 }
820
821 fn max(&self, na_rm: bool) -> Option<i32> {
822 if AltrepLen::len(self) == 0 {
823 return None;
824 }
825
826 let contains_na = self.start == i32::MIN && self.end > i32::MIN;
829 if contains_na && !na_rm {
830 return None; }
832
833 Some(self.end - 1)
836 }
837}
838
839impl AltrepLen for Range<i64> {
840 fn len(&self) -> usize {
841 if self.end > self.start {
842 (self.end - self.start) as usize
843 } else {
844 0
845 }
846 }
847}
848
849impl AltIntegerData for Range<i64> {
850 fn elt(&self, i: usize) -> i32 {
851 let val = self.start.saturating_add(i as i64);
852 if val > i32::MAX as i64 || val <= i32::MIN as i64 {
855 crate::altrep_traits::NA_INTEGER
856 } else {
857 val as i32
858 }
859 }
860
861 fn is_sorted(&self) -> Option<Sortedness> {
862 Some(Sortedness::Increasing)
863 }
864
865 fn no_na(&self) -> Option<bool> {
866 let na_sentinel = i32::MIN as i64;
876 let i32_max = i32::MAX as i64;
877
878 let contains_na_sentinel = self.start <= na_sentinel && self.end > na_sentinel;
880
881 let has_underflow = self.start < na_sentinel;
884 let has_overflow = (self.end - 1) > i32_max;
885
886 Some(!contains_na_sentinel && !has_underflow && !has_overflow)
887 }
888
889 fn sum(&self, na_rm: bool) -> Option<i64> {
890 let n = AltrepLen::len(self) as i64;
891 if n == 0 {
892 return Some(0);
893 }
894
895 let na_sentinel = i32::MIN as i64;
897 let i32_max = i32::MAX as i64;
898 let contains_na_sentinel = self.start <= na_sentinel && self.end > na_sentinel;
899 let has_underflow = self.start < na_sentinel;
900 let has_overflow = (self.end - 1) > i32_max;
901 let has_na = contains_na_sentinel || has_underflow || has_overflow;
902
903 if has_na && !na_rm {
904 return None; }
906
907 if has_na {
908 return None;
911 }
912
913 let first = self.start;
914 let last = self.end - 1;
915
916 let sum_endpoints = first.checked_add(last)?;
919 let product = n.checked_mul(sum_endpoints)?;
920 Some(product / 2)
921 }
922
923 fn min(&self, na_rm: bool) -> Option<i32> {
924 if AltrepLen::len(self) == 0 {
925 return None;
926 }
927
928 let na_sentinel = i32::MIN as i64;
929 let i32_max = i32::MAX as i64;
930
931 let contains_na_sentinel = self.start <= na_sentinel && self.end > na_sentinel;
933 let has_underflow = self.start < na_sentinel;
934 let has_overflow = (self.end - 1) > i32_max;
935 let has_na = contains_na_sentinel || has_underflow || has_overflow;
936
937 if has_na && !na_rm {
938 return None; }
940
941 if has_na {
942 return None;
945 }
946
947 Some(self.start as i32)
949 }
950
951 fn max(&self, na_rm: bool) -> Option<i32> {
952 if AltrepLen::len(self) == 0 {
953 return None;
954 }
955
956 let na_sentinel = i32::MIN as i64;
957 let i32_max = i32::MAX as i64;
958
959 let contains_na_sentinel = self.start <= na_sentinel && self.end > na_sentinel;
961 let has_underflow = self.start < na_sentinel;
962 let has_overflow = (self.end - 1) > i32_max;
963 let has_na = contains_na_sentinel || has_underflow || has_overflow;
964
965 if has_na && !na_rm {
966 return None; }
968
969 if has_na {
970 return None;
973 }
974
975 Some((self.end - 1) as i32)
977 }
978}
979
980impl AltrepLen for Range<f64> {
981 fn len(&self) -> usize {
982 if self.end > self.start {
984 (self.end - self.start).ceil() as usize
985 } else {
986 0
987 }
988 }
989}
990
991impl AltRealData for Range<f64> {
992 fn elt(&self, i: usize) -> f64 {
993 self.start + i as f64
994 }
995
996 fn is_sorted(&self) -> Option<Sortedness> {
997 Some(Sortedness::Increasing)
998 }
999
1000 fn no_na(&self) -> Option<bool> {
1001 Some(true)
1002 }
1003
1004 fn sum(&self, _na_rm: bool) -> Option<f64> {
1005 let n = AltrepLen::len(self) as f64;
1006 if n == 0.0 {
1007 return Some(0.0);
1008 }
1009 let first = self.start;
1010 let last = self.start + (n - 1.0);
1011 Some(n * (first + last) / 2.0)
1012 }
1013
1014 fn min(&self, _na_rm: bool) -> Option<f64> {
1015 if AltrepLen::len(self) > 0 {
1016 Some(self.start)
1017 } else {
1018 None
1019 }
1020 }
1021
1022 fn max(&self, _na_rm: bool) -> Option<f64> {
1023 if AltrepLen::len(self) > 0 {
1024 Some(self.start + (AltrepLen::len(self) - 1) as f64)
1025 } else {
1026 None
1027 }
1028 }
1029}
1030impl_len_slice!(i32);
1035
1036impl AltIntegerData for &[i32] {
1037 fn elt(&self, i: usize) -> i32 {
1038 self[i]
1039 }
1040
1041 fn as_slice(&self) -> Option<&[i32]> {
1042 Some(self)
1043 }
1044
1045 fn get_region(&self, start: usize, len: usize, buf: &mut [i32]) -> usize {
1046 let end = (start + len).min(<[i32]>::len(self));
1047 let actual_len = end.saturating_sub(start);
1048 if actual_len > 0 {
1049 buf[..actual_len].copy_from_slice(&self[start..end]);
1050 }
1051 actual_len
1052 }
1053
1054 fn no_na(&self) -> Option<bool> {
1055 Some(!self.contains(&i32::MIN))
1057 }
1058
1059 fn sum(&self, _na_rm: bool) -> Option<i64> {
1060 if self.contains(&i32::MIN) {
1062 if _na_rm {
1063 Some(
1064 self.iter()
1065 .filter(|&&x| x != i32::MIN)
1066 .map(|&x| x as i64)
1067 .sum(),
1068 )
1069 } else {
1070 None }
1072 } else {
1073 Some(self.iter().map(|&x| x as i64).sum())
1074 }
1075 }
1076
1077 fn min(&self, _na_rm: bool) -> Option<i32> {
1078 if self.is_empty() {
1079 return None;
1080 }
1081 if _na_rm {
1082 self.iter().filter(|&&x| x != i32::MIN).copied().min()
1083 } else if self.contains(&i32::MIN) {
1084 None } else {
1086 self.iter().copied().min()
1087 }
1088 }
1089
1090 fn max(&self, _na_rm: bool) -> Option<i32> {
1091 if self.is_empty() {
1092 return None;
1093 }
1094 if _na_rm {
1095 self.iter().filter(|&&x| x != i32::MIN).copied().max()
1096 } else if self.contains(&i32::MIN) {
1097 None } else {
1099 self.iter().copied().max()
1100 }
1101 }
1102}
1103
1104impl_len_slice!(f64);
1105
1106impl AltRealData for &[f64] {
1107 fn elt(&self, i: usize) -> f64 {
1108 self[i]
1109 }
1110
1111 fn as_slice(&self) -> Option<&[f64]> {
1112 Some(self)
1113 }
1114
1115 fn no_na(&self) -> Option<bool> {
1116 Some(!self.iter().any(|x| x.is_nan()))
1117 }
1118
1119 fn sum(&self, na_rm: bool) -> Option<f64> {
1120 if na_rm {
1121 Some(self.iter().filter(|x| !x.is_nan()).sum())
1122 } else if self.iter().any(|x| x.is_nan()) {
1123 None } else {
1125 Some(self.iter().sum())
1126 }
1127 }
1128
1129 fn min(&self, na_rm: bool) -> Option<f64> {
1130 if self.is_empty() {
1131 return None;
1132 }
1133 if na_rm {
1134 self.iter()
1135 .filter(|x| !x.is_nan())
1136 .copied()
1137 .min_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal))
1138 } else if self.iter().any(|x| x.is_nan()) {
1139 None
1140 } else {
1141 self.iter()
1142 .copied()
1143 .min_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal))
1144 }
1145 }
1146
1147 fn max(&self, na_rm: bool) -> Option<f64> {
1148 if self.is_empty() {
1149 return None;
1150 }
1151 if na_rm {
1152 self.iter()
1153 .filter(|x| !x.is_nan())
1154 .copied()
1155 .max_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal))
1156 } else if self.iter().any(|x| x.is_nan()) {
1157 None
1158 } else {
1159 self.iter()
1160 .copied()
1161 .max_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal))
1162 }
1163 }
1164}
1165
1166impl_len_slice!(u8);
1167
1168impl AltRawData for &[u8] {
1169 fn elt(&self, i: usize) -> u8 {
1170 self[i]
1171 }
1172
1173 fn as_slice(&self) -> Option<&[u8]> {
1174 Some(self)
1175 }
1176}
1177
1178impl_len_slice!(bool);
1179
1180impl AltLogicalData for &[bool] {
1181 fn elt(&self, i: usize) -> Logical {
1182 Logical::from_bool(self[i])
1183 }
1184
1185 fn no_na(&self) -> Option<bool> {
1186 Some(true) }
1188
1189 fn sum(&self, _na_rm: bool) -> Option<i64> {
1190 Some(self.iter().filter(|&&x| x).count() as i64)
1191 }
1192}
1193
1194impl_len_slice!(String);
1195
1196impl AltStringData for &[String] {
1197 fn elt(&self, i: usize) -> Option<&str> {
1198 Some(self[i].as_str())
1199 }
1200}
1201
1202impl_len_slice!(&str);
1203
1204impl AltStringData for &[&str] {
1205 fn elt(&self, i: usize) -> Option<&str> {
1206 Some(self[i])
1207 }
1208}
1209impl_len_array!(i32);
1229
1230impl<const N: usize> AltIntegerData for [i32; N] {
1231 fn elt(&self, i: usize) -> i32 {
1232 self[i]
1233 }
1234
1235 fn as_slice(&self) -> Option<&[i32]> {
1236 Some(self.as_slice())
1237 }
1238
1239 fn get_region(&self, start: usize, len: usize, buf: &mut [i32]) -> usize {
1240 let end = (start + len).min(N);
1241 let actual_len = end.saturating_sub(start);
1242 if actual_len > 0 {
1243 buf[..actual_len].copy_from_slice(&self[start..end]);
1244 }
1245 actual_len
1246 }
1247
1248 fn no_na(&self) -> Option<bool> {
1249 Some(!self.contains(&i32::MIN))
1250 }
1251}
1252
1253impl_len_array!(f64);
1254
1255impl<const N: usize> AltRealData for [f64; N] {
1256 fn elt(&self, i: usize) -> f64 {
1257 self[i]
1258 }
1259
1260 fn as_slice(&self) -> Option<&[f64]> {
1261 Some(self.as_slice())
1262 }
1263
1264 fn get_region(&self, start: usize, len: usize, buf: &mut [f64]) -> usize {
1265 let end = (start + len).min(N);
1266 let actual_len = end.saturating_sub(start);
1267 if actual_len > 0 {
1268 buf[..actual_len].copy_from_slice(&self[start..end]);
1269 }
1270 actual_len
1271 }
1272
1273 fn no_na(&self) -> Option<bool> {
1274 Some(!self.iter().any(|x| x.is_nan()))
1275 }
1276}
1277
1278impl_len_array!(bool);
1279
1280impl<const N: usize> AltLogicalData for [bool; N] {
1281 fn elt(&self, i: usize) -> Logical {
1282 Logical::from_bool(self[i])
1283 }
1284
1285 fn no_na(&self) -> Option<bool> {
1286 Some(true) }
1288}
1289
1290impl_len_array!(u8);
1291
1292impl<const N: usize> AltRawData for [u8; N] {
1293 fn elt(&self, i: usize) -> u8 {
1294 self[i]
1295 }
1296
1297 fn as_slice(&self) -> Option<&[u8]> {
1298 Some(self.as_slice())
1299 }
1300
1301 fn get_region(&self, start: usize, len: usize, buf: &mut [u8]) -> usize {
1302 let end = (start + len).min(N);
1303 let actual_len = end.saturating_sub(start);
1304 if actual_len > 0 {
1305 buf[..actual_len].copy_from_slice(&self[start..end]);
1306 }
1307 actual_len
1308 }
1309}
1310
1311impl_len_array!(String);
1312
1313impl<const N: usize> AltStringData for [String; N] {
1314 fn elt(&self, i: usize) -> Option<&str> {
1315 Some(self[i].as_str())
1316 }
1317}
1318impl_len_vec!(Rcomplex);
1323
1324impl AltComplexData for Vec<Rcomplex> {
1325 fn elt(&self, i: usize) -> Rcomplex {
1326 self[i]
1327 }
1328
1329 fn as_slice(&self) -> Option<&[Rcomplex]> {
1330 Some(self.as_slice())
1331 }
1332
1333 fn get_region(&self, start: usize, len: usize, buf: &mut [Rcomplex]) -> usize {
1334 let end = (start + len).min(self.len());
1335 let actual_len = end.saturating_sub(start);
1336 if actual_len > 0 {
1337 buf[..actual_len].copy_from_slice(&self[start..end]);
1338 }
1339 actual_len
1340 }
1341}
1342
1343impl_dataptr_vec!(Rcomplex);
1344impl_len_boxed!(Rcomplex);
1349
1350impl AltComplexData for Box<[Rcomplex]> {
1351 fn elt(&self, i: usize) -> Rcomplex {
1352 self[i]
1353 }
1354
1355 fn as_slice(&self) -> Option<&[Rcomplex]> {
1356 Some(self.as_ref())
1357 }
1358
1359 fn get_region(&self, start: usize, len: usize, buf: &mut [Rcomplex]) -> usize {
1360 let end = (start + len).min(self.len());
1361 let actual_len = end.saturating_sub(start);
1362 if actual_len > 0 {
1363 buf[..actual_len].copy_from_slice(&self[start..end]);
1364 }
1365 actual_len
1366 }
1367}
1368
1369impl_dataptr_boxed!(Rcomplex);
1370impl_len_array!(Rcomplex);
1375
1376impl<const N: usize> AltComplexData for [Rcomplex; N] {
1377 fn elt(&self, i: usize) -> Rcomplex {
1378 self[i]
1379 }
1380
1381 fn as_slice(&self) -> Option<&[Rcomplex]> {
1382 Some(self.as_slice())
1383 }
1384
1385 fn get_region(&self, start: usize, len: usize, buf: &mut [Rcomplex]) -> usize {
1386 let end = (start + len).min(N);
1387 let actual_len = end.saturating_sub(start);
1388 if actual_len > 0 {
1389 buf[..actual_len].copy_from_slice(&self[start..end]);
1390 }
1391 actual_len
1392 }
1393}
1394use std::borrow::Cow;
1404
1405macro_rules! impl_len_cow {
1406 ($elem:ty) => {
1407 impl AltrepLen for Cow<'static, [$elem]> {
1408 fn len(&self) -> usize {
1409 <[$elem]>::len(self)
1410 }
1411 }
1412 };
1413}
1414
1415macro_rules! impl_dataptr_cow {
1416 ($elem:ty) => {
1417 impl AltrepDataptr<$elem> for Cow<'static, [$elem]> {
1418 fn dataptr(&mut self, writable: bool) -> Option<*mut $elem> {
1419 if writable {
1420 Some(self.to_mut().as_mut_ptr())
1423 } else {
1424 Some(self.as_ptr().cast_mut())
1427 }
1428 }
1429
1430 fn dataptr_or_null(&self) -> Option<*const $elem> {
1431 Some(self.as_ptr())
1432 }
1433 }
1434 };
1435}
1436
1437macro_rules! impl_serialize_cow {
1438 ($elem:ty) => {
1439 impl AltrepSerialize for Cow<'static, [$elem]> {
1440 fn serialized_state(&self) -> SEXP {
1441 use crate::into_r::IntoR;
1442 self.clone().into_sexp()
1443 }
1444
1445 fn unserialize(state: SEXP) -> Option<Self> {
1446 use crate::from_r::TryFromSexp;
1447 Cow::<'static, [$elem]>::try_from_sexp(state).ok()
1448 }
1449 }
1450 };
1451}
1452
1453impl_len_cow!(i32);
1454
1455impl AltIntegerData for Cow<'static, [i32]> {
1456 fn elt(&self, i: usize) -> i32 {
1457 self[i]
1458 }
1459
1460 fn as_slice(&self) -> Option<&[i32]> {
1461 Some(self.as_ref())
1462 }
1463
1464 fn get_region(&self, start: usize, len: usize, buf: &mut [i32]) -> usize {
1465 let end = (start + len).min(<[i32]>::len(self));
1466 let actual_len = end.saturating_sub(start);
1467 if actual_len > 0 {
1468 buf[..actual_len].copy_from_slice(&self[start..end]);
1469 }
1470 actual_len
1471 }
1472
1473 fn no_na(&self) -> Option<bool> {
1474 Some(!self.contains(&i32::MIN))
1475 }
1476
1477 fn sum(&self, na_rm: bool) -> Option<i64> {
1478 let mut sum: i64 = 0;
1479 for &x in self.iter() {
1480 if x == i32::MIN {
1481 if !na_rm {
1482 return None;
1483 }
1484 } else {
1485 sum += x as i64;
1486 }
1487 }
1488 Some(sum)
1489 }
1490
1491 fn min(&self, na_rm: bool) -> Option<i32> {
1492 let mut min = i32::MAX;
1493 let mut found = false;
1494 for &x in self.iter() {
1495 if x == i32::MIN {
1496 if !na_rm {
1497 return None;
1498 }
1499 } else {
1500 found = true;
1501 min = min.min(x);
1502 }
1503 }
1504 if found { Some(min) } else { None }
1505 }
1506
1507 fn max(&self, na_rm: bool) -> Option<i32> {
1508 let mut max = i32::MIN + 1;
1509 let mut found = false;
1510 for &x in self.iter() {
1511 if x == i32::MIN {
1512 if !na_rm {
1513 return None;
1514 }
1515 } else {
1516 found = true;
1517 max = max.max(x);
1518 }
1519 }
1520 if found { Some(max) } else { None }
1521 }
1522}
1523
1524impl_dataptr_cow!(i32);
1525impl_serialize_cow!(i32);
1526
1527impl_len_cow!(f64);
1528
1529impl AltRealData for Cow<'static, [f64]> {
1530 fn elt(&self, i: usize) -> f64 {
1531 self[i]
1532 }
1533
1534 fn as_slice(&self) -> Option<&[f64]> {
1535 Some(self.as_ref())
1536 }
1537
1538 fn get_region(&self, start: usize, len: usize, buf: &mut [f64]) -> usize {
1539 let end = (start + len).min(<[f64]>::len(self));
1540 let actual_len = end.saturating_sub(start);
1541 if actual_len > 0 {
1542 buf[..actual_len].copy_from_slice(&self[start..end]);
1543 }
1544 actual_len
1545 }
1546
1547 fn no_na(&self) -> Option<bool> {
1548 Some(!self.iter().any(|x| x.is_nan()))
1549 }
1550
1551 fn sum(&self, na_rm: bool) -> Option<f64> {
1552 let mut sum = 0.0;
1553 for &x in self.iter() {
1554 if x.is_nan() {
1555 if !na_rm {
1556 return Some(f64::NAN);
1557 }
1558 } else {
1559 sum += x;
1560 }
1561 }
1562 Some(sum)
1563 }
1564
1565 fn min(&self, na_rm: bool) -> Option<f64> {
1566 let mut min = f64::INFINITY;
1567 let mut found = false;
1568 for &x in self.iter() {
1569 if x.is_nan() {
1570 if !na_rm {
1571 return Some(f64::NAN);
1572 }
1573 } else {
1574 found = true;
1575 min = min.min(x);
1576 }
1577 }
1578 if found { Some(min) } else { None }
1579 }
1580
1581 fn max(&self, na_rm: bool) -> Option<f64> {
1582 let mut max = f64::NEG_INFINITY;
1583 let mut found = false;
1584 for &x in self.iter() {
1585 if x.is_nan() {
1586 if !na_rm {
1587 return Some(f64::NAN);
1588 }
1589 } else {
1590 found = true;
1591 max = max.max(x);
1592 }
1593 }
1594 if found { Some(max) } else { None }
1595 }
1596}
1597
1598impl_dataptr_cow!(f64);
1599impl_serialize_cow!(f64);
1600
1601impl_len_cow!(u8);
1602
1603impl AltRawData for Cow<'static, [u8]> {
1604 fn elt(&self, i: usize) -> u8 {
1605 self[i]
1606 }
1607
1608 fn as_slice(&self) -> Option<&[u8]> {
1609 Some(self.as_ref())
1610 }
1611
1612 fn get_region(&self, start: usize, len: usize, buf: &mut [u8]) -> usize {
1613 let end = (start + len).min(<[u8]>::len(self));
1614 let actual_len = end.saturating_sub(start);
1615 if actual_len > 0 {
1616 buf[..actual_len].copy_from_slice(&self[start..end]);
1617 }
1618 actual_len
1619 }
1620}
1621
1622impl_dataptr_cow!(u8);
1623impl_serialize_cow!(u8);
1624
1625impl_len_cow!(Rcomplex);
1626
1627impl AltComplexData for Cow<'static, [Rcomplex]> {
1628 fn elt(&self, i: usize) -> Rcomplex {
1629 self[i]
1630 }
1631
1632 fn as_slice(&self) -> Option<&[Rcomplex]> {
1633 Some(self.as_ref())
1634 }
1635
1636 fn get_region(&self, start: usize, len: usize, buf: &mut [Rcomplex]) -> usize {
1637 let end = (start + len).min(<[Rcomplex]>::len(self));
1638 let actual_len = end.saturating_sub(start);
1639 if actual_len > 0 {
1640 buf[..actual_len].copy_from_slice(&self[start..end]);
1641 }
1642 actual_len
1643 }
1644}
1645
1646impl_dataptr_cow!(Rcomplex);
1647impl_serialize_cow!(Rcomplex);
1648