1use std::{
2 any::TypeId,
3 cmp::Ordering,
4 fmt,
5 hash::{Hash, Hasher},
6 ops::{Deref, DerefMut},
7 slice,
8 sync::Arc,
9};
10
11use bitflags::bitflags;
12use ecow::{EcoString, EcoVec};
13use rayon::prelude::*;
14use serde::{de::DeserializeOwned, *};
15
16use crate::{
17 algorithm::{
18 map::{MapKeys, EMPTY_NAN, TOMBSTONE_NAN},
19 ArrayCmpSlice,
20 },
21 cowslice::{cowslice, CowSlice},
22 fill::{Fill, FillValue},
23 grid_fmt::GridFmt,
24 Boxed, Complex, ExactDoubleIterator, FfiType, HandleKind, Shape, Value, WILDCARD_CHAR,
25 WILDCARD_NAN,
26};
27
28#[derive(Clone, Serialize, Deserialize)]
30#[serde(
31 from = "ArrayRep<T>",
32 into = "ArrayRep<T>",
33 bound(
34 serialize = "T: ArrayValueSer + Serialize",
35 deserialize = "T: ArrayValueSer + Deserialize<'de>"
36 )
37)]
38#[repr(C)]
39pub struct Array<T> {
40 pub shape: Shape,
42 pub(crate) data: CowSlice<T>,
43 pub meta: ArrayMeta,
45}
46
47#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
49#[repr(C)]
50#[non_exhaustive]
51pub struct ArrayMetaInner {
52 #[serde(default, skip_serializing_if = "Option::is_none")]
54 pub label: Option<EcoString>,
55 #[serde(default, skip_serializing_if = "ArrayFlags::is_empty")]
57 pub flags: ArrayFlags,
58 #[serde(default, skip_serializing_if = "Option::is_none")]
60 pub map_keys: Option<MapKeys>,
61 #[serde(skip)]
63 pub pointer: Option<MetaPtr>,
64 #[serde(skip)]
66 pub handle_kind: Option<HandleKind>,
67}
68
69static DEFAULT_META_INNER: ArrayMetaInner = ArrayMetaInner {
71 label: None,
72 flags: ArrayFlags::NONE,
73 map_keys: None,
74 pointer: None,
75 handle_kind: None,
76};
77
78#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
85#[serde(transparent)]
86#[repr(C)]
87pub struct ArrayMeta(Option<Arc<ArrayMetaInner>>);
88
89impl Deref for ArrayMeta {
90 type Target = ArrayMetaInner;
91 fn deref(&self) -> &Self::Target {
92 self.0.as_deref().unwrap_or(&DEFAULT_META_INNER)
93 }
94}
95
96impl DerefMut for ArrayMeta {
97 fn deref_mut(&mut self) -> &mut Self::Target {
98 Arc::make_mut(self.0.get_or_insert_with(Default::default))
99 }
100}
101
102impl ArrayMeta {
103 fn get_inner_mut(&mut self) -> Option<&mut ArrayMetaInner> {
104 self.0.as_mut().map(Arc::make_mut)
105 }
106 pub fn get_mut(&mut self) -> Option<&mut Self> {
108 self.0.is_some().then_some(self)
109 }
110 pub fn map_keys_mut(&mut self) -> Option<&mut MapKeys> {
112 self.get_inner_mut()?.map_keys.as_mut()
113 }
114 pub fn is_default(&self) -> bool {
116 self.label.is_none()
117 && self.map_keys.is_none()
118 && self.handle_kind.is_none()
119 && self.pointer.is_none()
120 && self.flags.is_empty()
121 }
122 pub fn is_sorted_up(&self) -> bool {
124 self.flags.contains(ArrayFlags::SORTED_UP)
125 }
126 pub fn is_sorted_down(&self) -> bool {
128 self.flags.contains(ArrayFlags::SORTED_DOWN)
129 }
130 pub fn take_per_meta(&mut self) -> PersistentMeta {
132 self.get_inner_mut()
133 .map(|inner| {
134 let label = inner.label.take();
135 let map_keys = inner.map_keys.take();
136 PersistentMeta { label, map_keys }
137 })
138 .unwrap_or_default()
139 }
140 pub fn take_label(&mut self) -> Option<EcoString> {
142 let inner = self.get_inner_mut()?;
143 if inner.label.is_some() {
144 inner.label.take()
145 } else {
146 None
147 }
148 }
149 pub fn take_map_keys(&mut self) -> Option<MapKeys> {
151 self.get_inner_mut()?.map_keys.take()
152 }
153 pub fn take_sorted_flags(&mut self) -> ArrayFlags {
155 let flags = self.flags & ArrayFlags::SORTEDNESS;
156 self.flags &= !flags;
157 flags
158 }
159 pub fn take_value_flags(&mut self) -> ArrayFlags {
161 let flags = self.flags & ArrayFlags::VALUE;
162 self.flags &= !ArrayFlags::VALUE;
163 flags
164 }
165 pub fn set_label(&mut self, label: Option<EcoString>) {
167 if label.is_none() && self.label.is_none() {
168 return;
169 }
170 self.label = label;
171 }
172 pub fn set_per_meta(&mut self, per_meta: PersistentMeta) {
174 if self.map_keys.is_some() != per_meta.map_keys.is_some() {
175 self.map_keys = per_meta.map_keys;
176 }
177 if self.label.is_some() != per_meta.label.is_some() {
178 self.label = per_meta.label;
179 }
180 }
181 pub fn or_sorted_flags(&mut self, mut flags: ArrayFlags) {
183 flags &= ArrayFlags::SORTEDNESS;
184 if flags == ArrayFlags::NONE {
185 return;
186 }
187 self.flags |= flags;
188 }
189 pub(crate) fn mark_sorted_up(&mut self, sorted: bool) {
193 if sorted {
194 self.flags.insert(ArrayFlags::SORTED_UP);
195 } else if let Some(inner) = self.get_inner_mut() {
196 inner.flags.remove(ArrayFlags::SORTED_UP);
197 }
198 }
199 pub(crate) fn mark_sorted_down(&mut self, sorted: bool) {
203 if sorted {
204 self.flags.insert(ArrayFlags::SORTED_DOWN);
205 } else if let Some(inner) = self.get_inner_mut() {
206 inner.flags.remove(ArrayFlags::SORTED_DOWN);
207 }
208 }
209 pub fn combine(&mut self, other: &Self) {
211 if let Some(other) = other.0.as_deref() {
212 self.flags &= other.flags;
213 self.map_keys = None;
214 if self.handle_kind != other.handle_kind {
215 self.handle_kind = None;
216 }
217 } else if let Some(inner) = self.get_inner_mut() {
218 inner.flags &= !ArrayFlags::VALUE;
219 }
220 }
221 pub fn reset_flags(&mut self) {
223 self.flags.reset();
224 }
225}
226
227#[derive(Debug, Clone)]
229pub struct MetaPtr {
230 pub ptr: usize,
232 pub ty: FfiType,
234}
235
236impl MetaPtr {
237 pub const fn null() -> Self {
239 Self {
240 ptr: 0,
241 ty: FfiType::Void,
242 }
243 }
244 pub fn new(ptr: usize, ffi_type: FfiType) -> Self {
246 Self { ptr, ty: ffi_type }
247 }
248 pub fn get(&self) -> *const u8 {
250 self.ptr as *const _
251 }
252 pub fn get_mut(&self) -> *mut u8 {
254 self.ptr as *mut _
255 }
256}
257
258impl PartialEq for MetaPtr {
259 fn eq(&self, other: &Self) -> bool {
260 self.ptr == other.ptr
261 }
262}
263
264impl Eq for MetaPtr {}
265
266bitflags! {
267 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize, Deserialize)]
269 pub struct ArrayFlags: u8 {
270 const NONE = 0;
272 const BOOLEAN = 1;
274 const BOOLEAN_LITERAL = 2;
276 const SORTED_UP = 4;
278 const SORTED_DOWN = 8;
280 const VALUE = Self::BOOLEAN.bits() | Self::BOOLEAN_LITERAL.bits();
282 const SORTEDNESS = Self::SORTED_UP.bits() | Self::SORTED_DOWN.bits();
284 }
285}
286
287impl ArrayFlags {
288 pub fn is_boolean(self) -> bool {
290 self.contains(Self::BOOLEAN)
291 }
292 pub fn reset(&mut self) {
294 *self = Self::NONE;
295 }
296 pub fn reverse_sorted(&mut self) {
298 let sorted_up = self.contains(Self::SORTED_UP);
299 let sorted_down = self.contains(Self::SORTED_DOWN);
300 self.set(Self::SORTED_UP, sorted_down);
301 self.set(Self::SORTED_DOWN, sorted_up);
302 }
303}
304
305#[derive(Clone, Default)]
307pub struct PersistentMeta {
308 pub(crate) label: Option<EcoString>,
309 pub(crate) map_keys: Option<MapKeys>,
310}
311
312impl PersistentMeta {
313 pub fn xor(self, other: Self) -> Self {
315 Self {
316 label: self.label.xor(other.label),
317 map_keys: self.map_keys.xor(other.map_keys),
318 }
319 }
320 pub fn xor_all(metas: impl IntoIterator<Item = Self>) -> Self {
322 let mut label = None;
323 let mut map_keys = None;
324 let mut set_label = false;
325 let mut set_map_keys = false;
326 for meta in metas {
327 if let Some(l) = meta.label {
328 if set_label {
329 label = None;
330 } else {
331 label = Some(l);
332 set_label = true;
333 }
334 }
335 if let Some(keys) = meta.map_keys {
336 if set_map_keys {
337 map_keys = None;
338 } else {
339 map_keys = Some(keys);
340 set_map_keys = true;
341 }
342 }
343 }
344 Self { label, map_keys }
345 }
346}
347
348impl<T: ArrayValue> Default for Array<T> {
349 fn default() -> Self {
350 Self {
351 shape: 0.into(),
352 data: CowSlice::new(),
353 meta: ArrayMeta::default(),
354 }
355 }
356}
357
358impl<T: ArrayValue> fmt::Debug for Array<T>
359where
360 Array<T>: GridFmt,
361{
362 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
363 write!(f, "{}", self.grid_string(true))
364 }
365}
366
367impl<T: ArrayValue> fmt::Display for Array<T>
368where
369 Array<T>: GridFmt,
370{
371 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
372 match self.rank() {
373 0 => write!(f, "{}", self.data[0]),
374 1 => {
375 let (start, end) = T::format_delims();
376 write!(f, "{start}")?;
377 for (i, x) in self.data.iter().enumerate() {
378 if i > 0 {
379 write!(f, "{}", T::format_sep())?;
380 }
381 write!(f, "{x}")?;
382 }
383 write!(f, "{end}")
384 }
385 _ => {
386 write!(f, "\n{}", self.grid_string(false))
387 }
388 }
389 }
390}
391
392#[track_caller]
393#[inline(always)]
394pub(crate) fn validate_shape(_shape: &[usize], _len: usize) {
395 #[cfg(debug_assertions)]
396 {
397 let elems = if _shape.contains(&0) {
398 0
399 } else {
400 _shape.iter().product()
401 };
402 assert_eq!(
403 elems, _len,
404 "shape {_shape:?} does not match data length {_len}"
405 )
406 }
407}
408
409impl<T> Array<T> {
410 pub const EMPTY_LIST: Self = Array {
412 shape: Shape::EMPTY_LIST,
413 data: CowSlice::new(),
414 meta: ArrayMeta(None),
415 };
416 #[track_caller]
417 pub fn new(shape: impl Into<Shape>, data: impl Into<CowSlice<T>>) -> Self {
422 let shape = shape.into();
423 let data = data.into();
424 validate_shape(&shape, data.len());
425 Self {
426 shape,
427 data,
428 meta: ArrayMeta::default(),
429 }
430 }
431 #[inline(always)]
433 pub fn row_count(&self) -> usize {
434 self.shape.row_count()
435 }
436 pub fn element_count(&self) -> usize {
438 self.data.len()
439 }
440 #[inline(always)]
442 pub fn row_len(&self) -> usize {
443 self.shape.row_len()
444 }
445 #[inline(always)]
447 pub fn rank(&self) -> usize {
448 self.shape.len()
449 }
450 pub fn elements(&self) -> impl ExactDoubleIterator<Item = &T> {
452 self.data.iter()
453 }
454 pub fn row_slices(
456 &self,
457 ) -> impl ExactSizeIterator<Item = &[T]> + DoubleEndedIterator + Clone + Send + Sync
458 where
459 T: Send + Sync,
460 {
461 let row_len = self.row_len();
462 let data = self.data.as_slice();
463 (0..self.row_count())
465 .map(move |i| unsafe { slice::from_raw_parts(data.as_ptr().add(i * row_len), row_len) })
466 }
467 #[track_caller]
469 pub fn row_slice(&self, row: usize) -> &[T] {
470 let row_len = self.row_len();
471 &self.data[row * row_len..(row + 1) * row_len]
472 }
473}
474
475impl<T: Clone> Array<T> {
476 pub fn row_slices_mut(
478 &mut self,
479 ) -> impl ExactSizeIterator<Item = &mut [T]> + DoubleEndedIterator + Send + Sync
480 where
481 T: Send + Sync,
482 {
483 let row_count = self.row_count();
484 let row_len = self.row_len();
485 let data = self.data.as_mut_slice();
486 (0..row_count).map(move |i| unsafe {
488 slice::from_raw_parts_mut(data.as_mut_ptr().add(i * row_len), row_len)
489 })
490 }
491 #[track_caller]
493 pub fn row(&self, row: usize) -> Self {
494 if self.rank() == 0 {
495 let mut row = self.clone();
496 row.meta.take_map_keys();
497 row.meta.take_label();
498 return row;
499 }
500 let row_count = self.row_count();
501 if row >= row_count {
502 panic!("row index out of bounds: {row} >= {row_count}");
503 }
504 let row_len = self.row_len();
505 let start = row * row_len;
506 let end = start + row_len;
507 let mut row = Self::new(&self.shape[1..], self.data.slice(start..end));
508 let value_flags = self.meta.flags & ArrayFlags::VALUE;
509 if value_flags != ArrayFlags::NONE {
510 row.meta.flags = value_flags;
511 }
512 row
513 }
514}
515
516impl<T: ArrayValue> Array<T> {
517 pub fn scalar(data: T) -> Self {
519 Self::new(Shape::SCALAR, cowslice![data])
520 }
521 pub fn into_scalar(self) -> Result<T, Self> {
523 if self.shape.is_empty() {
524 Ok(self.data.into_iter().next().unwrap())
525 } else {
526 Err(self)
527 }
528 }
529 pub fn as_scalar(&self) -> Option<&T> {
531 if self.shape.is_empty() {
532 Some(&self.data[0])
533 } else {
534 None
535 }
536 }
537 pub fn as_scalar_mut(&mut self) -> Option<&mut T> {
539 if self.shape.is_empty() {
540 Some(&mut self.data.as_mut_slice()[0])
541 } else {
542 None
543 }
544 }
545 pub fn rows(&self) -> impl ExactDoubleIterator<Item = Self> + '_ {
547 let value_flags = self.meta.flags & ArrayFlags::VALUE;
548 let set_value_flags = value_flags != ArrayFlags::NONE;
549 let row_len = self.row_len();
550 (0..self.row_count()).map(move |row| {
551 if self.rank() == 0 {
552 let mut row = self.clone();
553 row.meta.take_map_keys();
554 row.meta.take_label();
555 return row;
556 }
557 let start = row * row_len;
558 let end = start + row_len;
559 let mut row = Array::<T>::new(&self.shape[1..], self.data.slice(start..end));
560 if set_value_flags {
561 row.meta.flags = value_flags;
562 }
563 row
564 })
565 }
566 pub(crate) fn row_shaped_slice(&self, index: usize, row_shape: Shape) -> Self {
567 let row_len = row_shape.elements();
568 let start = index * row_len;
569 let end = start + row_len;
570 Self::new(row_shape, self.data.slice(start..end))
571 }
572 pub fn row_shaped_slices(
574 &self,
575 row_shape: Shape,
576 ) -> impl ExactDoubleIterator<Item = Self> + '_ {
577 let row_len = row_shape.elements();
578 let row_count = self.element_count() / row_len;
579 (0..row_count).map(move |i| {
580 let start = i * row_len;
581 let end = start + row_len;
582 Self::new(row_shape.clone(), self.data.slice(start..end))
583 })
584 }
585 pub fn into_row_shaped_slices(self, row_shape: Shape) -> impl DoubleEndedIterator<Item = Self> {
587 let row_len = row_shape.elements();
588 let zero_count = if row_len == 0 { self.row_count() } else { 0 };
589 let row_sh = row_shape.clone();
590 let nonzero = self
591 .data
592 .into_slices(row_len)
593 .map(move |data| Self::new(row_sh.clone(), data));
594 let zero = (0..zero_count).map(move |_| Self::new(row_shape.clone(), CowSlice::new()));
595 nonzero.chain(zero)
596 }
597 #[track_caller]
598 pub(crate) fn depth_row(&self, depth: usize, row: usize) -> Self {
599 if self.rank() <= depth {
600 let mut row = self.clone();
601 row.meta.take_map_keys();
602 row.meta.take_label();
603 return row;
604 }
605 let row_count: usize = self.shape[..depth + 1].iter().product();
606 if row >= row_count {
607 panic!("row index out of bounds: {row} >= {row_count}");
608 }
609 let row_len: usize = self.shape[depth + 1..].iter().product();
610 let start = row * row_len;
611 let end = start + row_len;
612 Self::new(&self.shape[depth + 1..], self.data.slice(start..end))
613 }
614 #[track_caller]
615 pub(crate) fn depth_rows(&self, depth: usize) -> impl ExactDoubleIterator<Item = Self> + '_ {
616 let row_count: usize = self.shape[..depth].iter().product();
617 let row_len: usize = self.shape[depth..].iter().product();
618 (0..row_count).map(move |row| {
619 let start = row * row_len;
620 let end = start + row_len;
621 Self::new(&self.shape[depth..], self.data.slice(start..end))
622 })
623 }
624 #[track_caller]
625 pub fn slice_rows(&self, start: usize, end: usize) -> Self {
633 assert!(start <= end);
634 assert!(start < self.row_count());
635 assert!(end <= self.row_count());
636 let row_len = self.row_len();
637 let mut shape = self.shape.clone();
638 shape[0] = end - start;
639 let start = start * row_len;
640 let end = end * row_len;
641 Self::new(shape, self.data.slice(start..end))
642 }
643 pub fn into_rows(self) -> impl ExactDoubleIterator<Item = Self> {
645 (0..self.row_count()).map(move |i| self.row(i))
646 }
647 pub(crate) fn first_dim_zero(&self) -> Self {
648 if self.rank() == 0 {
649 return self.clone();
650 }
651 let mut shape = self.shape.clone();
652 shape[0] = 0;
653 Array::new(shape, CowSlice::new())
654 }
655 pub fn show(&self) -> String {
659 self.grid_string(true)
660 }
661 pub(crate) fn pop_row(&mut self) -> Option<Self> {
662 if self.row_count() == 0 {
663 return None;
664 }
665 let data = self.data.split_off(self.data.len() - self.row_len());
666 self.shape[0] -= 1;
667 let shape: Shape = self.shape[1..].into();
668 self.validate();
669 Some(Self::new(shape, data))
670 }
671 #[track_caller]
673 pub fn row_slice_mut(&mut self, row: usize) -> &mut [T] {
674 let row_len = self.row_len();
675 &mut self.data.as_mut_slice()[row * row_len..(row + 1) * row_len]
676 }
677 pub fn derive_sortedness(&mut self) {
679 if !self.data.iter().all(|x| x.is_sortable()) {
680 return;
681 }
682 let mut sorted_up = true;
683 let mut sorted_down = true;
684 let mut rows = self.row_slices().map(ArrayCmpSlice);
685 if let Some(mut prev) = rows.next() {
686 for row in rows {
687 match prev.cmp(&row) {
688 Ordering::Equal => {}
689 Ordering::Less => {
690 sorted_down = false;
691 if !sorted_up {
692 break;
693 }
694 }
695 Ordering::Greater => {
696 sorted_up = false;
697 if !sorted_down {
698 break;
699 }
700 }
701 }
702 prev = row;
703 }
704 } else {
705 drop(rows);
706 }
707 self.meta.mark_sorted_up(sorted_up);
708 self.meta.mark_sorted_down(sorted_down);
709 }
710 #[track_caller]
711 #[inline(always)]
712 pub(crate) fn validate(&self) {
714 #[cfg(debug_assertions)]
715 {
716 validate_shape(&self.shape, self.data.len());
717 let is_sorted_up = self.meta.is_sorted_up();
718 let is_sorted_down = self.meta.is_sorted_down();
719 if is_sorted_up || is_sorted_down {
720 let mut rows = (0..self.row_count()).map(|i| self.row_slice(i));
721 if let Some(prev) = rows.next() {
722 let mut prev = ArrayCmpSlice(prev);
723 for row in rows {
724 let row = ArrayCmpSlice(row);
725 assert!(
726 !is_sorted_up || prev <= row,
727 "{} array marked as sorted up is not. {:?} > {:?}.",
728 T::NAME,
729 prev.0,
730 row.0
731 );
732 assert!(
733 !is_sorted_down || prev >= row,
734 "{} array marked as sorted down is not. {:?} < {:?}.",
735 T::NAME,
736 prev.0,
737 row.0
738 );
739 prev = row;
740 }
741 }
742 }
743 T::dbg_validate(self);
744 }
745 }
746}
747
748impl<T: Clone> Array<T> {
749 #[inline(always)]
751 pub fn convert<U>(self) -> Array<U>
752 where
753 T: Into<U> + 'static,
754 U: Clone + 'static,
755 {
756 if TypeId::of::<T>() == TypeId::of::<U>() {
757 unsafe { std::mem::transmute::<Array<T>, Array<U>>(self) }
758 } else {
759 self.convert_with(Into::into)
760 }
761 }
762 pub fn convert_with<U: Clone>(self, f: impl FnMut(T) -> U) -> Array<U> {
764 Array {
765 shape: self.shape,
766 data: self.data.into_iter().map(f).collect(),
767 meta: self.meta,
768 }
769 }
770 pub fn try_convert_with<U: Clone, E>(
772 self,
773 f: impl FnMut(T) -> Result<U, E>,
774 ) -> Result<Array<U>, E> {
775 Ok(Array {
776 shape: self.shape,
777 data: self.data.into_iter().map(f).collect::<Result<_, _>>()?,
778 meta: self.meta,
779 })
780 }
781 pub fn convert_ref<U>(&self) -> Array<U>
783 where
784 T: Into<U>,
785 U: Clone,
786 {
787 self.convert_ref_with(Into::into)
788 }
789 pub fn convert_ref_with<U: Clone>(&self, f: impl FnMut(T) -> U) -> Array<U> {
791 Array {
792 shape: self.shape.clone(),
793 data: self.data.iter().cloned().map(f).collect(),
794 meta: self.meta.clone(),
795 }
796 }
797 #[track_caller]
798 #[allow(dead_code)]
799 pub(crate) fn depth_slices(&self, depth: usize) -> impl ExactDoubleIterator<Item = &[T]> {
800 let row_len: usize = self.shape[depth..].iter().product();
801 self.data.chunks_exact(row_len)
802 }
803 #[track_caller]
804 #[allow(dead_code)]
805 pub(crate) fn depth_slices_mut(
806 &mut self,
807 depth: usize,
808 ) -> impl ExactDoubleIterator<Item = &mut [T]> {
809 let row_len: usize = self.shape[depth..].iter().product();
810 self.data.as_mut_slice().chunks_exact_mut(row_len)
811 }
812}
813
814impl Array<u8> {
815 pub(crate) fn json_bool(b: bool) -> Self {
816 let mut arr = Self::from(b);
817 arr.meta.flags |= ArrayFlags::BOOLEAN_LITERAL;
818 arr
819 }
820}
821
822impl Array<Boxed> {
823 pub fn into_unboxed(self) -> Result<Value, Self> {
825 match self.into_scalar() {
826 Ok(v) => Ok(v.0),
827 Err(a) => Err(a),
828 }
829 }
830 pub fn as_unboxed(&self) -> Option<&Value> {
832 self.as_scalar().map(|v| &v.0)
833 }
834 pub fn as_unboxed_mut(&mut self) -> Option<&mut Value> {
836 self.as_scalar_mut().map(|v| &mut v.0)
837 }
838}
839
840impl<T: ArrayValue + ArrayCmp<U>, U: ArrayValue> PartialEq<Array<U>> for Array<T> {
841 fn eq(&self, other: &Array<U>) -> bool {
842 if self.shape != other.shape {
843 return false;
844 }
845 if self.meta.map_keys != other.meta.map_keys {
846 return false;
847 }
848 self.data
849 .iter()
850 .zip(&other.data)
851 .all(|(a, b)| a.array_eq(b))
852 }
853}
854
855impl<T: ArrayValue> Eq for Array<T> {}
856
857impl<T: ArrayValue + ArrayCmp<U>, U: ArrayValue> PartialOrd<Array<U>> for Array<T> {
858 fn partial_cmp(&self, other: &Array<U>) -> Option<Ordering> {
859 let rank_cmp = self.rank().cmp(&other.rank());
860 if rank_cmp != Ordering::Equal {
861 return Some(rank_cmp);
862 }
863 let cmp = self
864 .data
865 .iter()
866 .zip(&other.data)
867 .map(|(a, b)| a.array_cmp(b))
868 .find(|o| o != &Ordering::Equal)
869 .unwrap_or_else(|| self.shape.cmp(&other.shape));
870 Some(cmp)
871 }
872}
873
874impl<T: ArrayValue> Ord for Array<T> {
875 fn cmp(&self, other: &Self) -> Ordering {
876 self.partial_cmp(other).unwrap()
877 }
878}
879
880impl<T: ArrayValue> Hash for Array<T> {
881 fn hash<H: Hasher>(&self, hasher: &mut H) {
882 if let Some(keys) = &self.meta.map_keys {
883 keys.hash(hasher);
884 }
885 T::TYPE_ID.hash(hasher);
886 if let Some(scalar) = self.as_scalar() {
887 if let Some(value) = scalar.nested_value() {
888 value.hash(hasher);
889 return;
890 }
891 }
892 self.shape.hash(hasher);
893 self.data.iter().for_each(|x| x.array_hash(hasher));
894 }
895}
896
897impl<T: ArrayValue> From<T> for Array<T> {
898 fn from(data: T) -> Self {
899 Self::scalar(data)
900 }
901}
902
903impl<T: ArrayValue> From<EcoVec<T>> for Array<T> {
904 fn from(data: EcoVec<T>) -> Self {
905 Self::new(data.len(), data)
906 }
907}
908
909impl<T: ArrayValue> From<CowSlice<T>> for Array<T> {
910 fn from(data: CowSlice<T>) -> Self {
911 Self::new(data.len(), data)
912 }
913}
914
915impl<'a, T: ArrayValue> From<&'a [T]> for Array<T> {
916 fn from(data: &'a [T]) -> Self {
917 Self::new(data.len(), data)
918 }
919}
920
921impl<T: ArrayValue> FromIterator<T> for Array<T> {
922 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
923 Self::from(iter.into_iter().collect::<CowSlice<T>>())
924 }
925}
926
927impl From<String> for Array<char> {
928 fn from(s: String) -> Self {
929 s.chars().collect()
930 }
931}
932
933impl From<&str> for Array<char> {
934 fn from(s: &str) -> Self {
935 s.chars().collect()
936 }
937}
938
939impl From<Vec<bool>> for Array<u8> {
940 fn from(data: Vec<bool>) -> Self {
941 Self::new(
942 data.len(),
943 data.into_iter().map(u8::from).collect::<CowSlice<_>>(),
944 )
945 }
946}
947
948impl From<bool> for Array<u8> {
949 fn from(data: bool) -> Self {
950 let mut arr = Self::new(Shape::SCALAR, cowslice![u8::from(data)]);
951 arr.meta.flags |= ArrayFlags::BOOLEAN;
952 arr
953 }
954}
955
956impl From<Vec<usize>> for Array<f64> {
957 fn from(data: Vec<usize>) -> Self {
958 Self::new(
959 data.len(),
960 data.into_iter().map(|u| u as f64).collect::<CowSlice<_>>(),
961 )
962 }
963}
964
965impl FromIterator<String> for Array<Boxed> {
966 fn from_iter<I: IntoIterator<Item = String>>(iter: I) -> Self {
967 Array::from(
968 iter.into_iter()
969 .map(Value::from)
970 .map(Boxed)
971 .collect::<CowSlice<_>>(),
972 )
973 }
974}
975
976impl<'a> FromIterator<&'a str> for Array<Boxed> {
977 fn from_iter<I: IntoIterator<Item = &'a str>>(iter: I) -> Self {
978 Array::from(
979 iter.into_iter()
980 .map(Value::from)
981 .map(Boxed)
982 .collect::<CowSlice<_>>(),
983 )
984 }
985}
986
987#[allow(unused_variables)]
989pub trait ArrayValue:
990 Default + Clone + fmt::Debug + fmt::Display + GridFmt + ArrayCmp + Send + Sync + 'static
991{
992 const NAME: &'static str;
994 const SYMBOL: char;
996 const TYPE_ID: u8;
998 fn get_scalar_fill(fill: &Fill) -> Result<FillValue<Self>, &'static str>;
1000 fn get_array_fill(fill: &Fill) -> Result<FillValue<Array<Self>>, &'static str>;
1002 fn array_hash<H: Hasher>(&self, hasher: &mut H);
1004 fn proxy() -> Self;
1006 fn nested_value(&self) -> Option<&Value> {
1008 None
1009 }
1010 fn has_wildcard(&self) -> bool {
1012 false
1013 }
1014 fn sort_list(list: &mut [Self], up: bool) {
1016 default_sort_list(list, up)
1017 }
1018 fn is_sortable(&self) -> bool {
1020 true
1021 }
1022 fn dbg_validate(arr: &Array<Self>) {}
1024}
1025
1026fn default_sort_list<T: ArrayCmp + Send>(list: &mut [T], up: bool) {
1027 if up {
1028 list.par_sort_unstable_by(T::array_cmp);
1029 } else {
1030 list.par_sort_unstable_by(|a, b| b.array_cmp(a));
1031 }
1032}
1033
1034impl ArrayValue for f64 {
1035 const NAME: &'static str = "number";
1036 const SYMBOL: char = 'ℝ';
1037 const TYPE_ID: u8 = 0;
1038 fn get_scalar_fill(fill: &Fill) -> Result<FillValue<Self>, &'static str> {
1039 fill.num_scalar()
1040 }
1041 fn get_array_fill(fill: &Fill) -> Result<FillValue<Array<Self>>, &'static str> {
1042 fill.num_array()
1043 }
1044 fn array_hash<H: Hasher>(&self, hasher: &mut H) {
1045 let v = if self.to_bits() == EMPTY_NAN.to_bits() {
1046 EMPTY_NAN
1047 } else if self.to_bits() == TOMBSTONE_NAN.to_bits() {
1048 TOMBSTONE_NAN
1049 } else if self.to_bits() == WILDCARD_NAN.to_bits() {
1050 WILDCARD_NAN
1051 } else if self.is_nan() {
1052 f64::NAN
1053 } else if *self == 0.0 && self.is_sign_negative() {
1054 0.0
1055 } else {
1056 *self
1057 };
1058 v.to_bits().hash(hasher)
1059 }
1060 fn proxy() -> Self {
1061 0.0
1062 }
1063 fn has_wildcard(&self) -> bool {
1064 self.to_bits() == WILDCARD_NAN.to_bits()
1065 }
1066 fn is_sortable(&self) -> bool {
1067 !self.is_nan()
1068 }
1069}
1070
1071#[cfg(test)]
1072#[test]
1073fn f64_summarize() {
1074 assert_eq!(f64::summarize(&[2.0, 6.0, 1.0]), "1-6 μ3");
1075}
1076
1077impl ArrayValue for u8 {
1078 const NAME: &'static str = "number";
1079 const SYMBOL: char = 'ℝ';
1080 const TYPE_ID: u8 = 0;
1081 fn get_scalar_fill(fill: &Fill) -> Result<FillValue<Self>, &'static str> {
1082 fill.byte_scalar()
1083 }
1084 fn get_array_fill(fill: &Fill) -> Result<FillValue<Array<Self>>, &'static str> {
1085 fill.byte_array()
1086 }
1087 fn array_hash<H: Hasher>(&self, hasher: &mut H) {
1088 (*self as f64).to_bits().hash(hasher)
1089 }
1090 fn proxy() -> Self {
1091 0
1092 }
1093 fn sort_list(list: &mut [Self], up: bool) {
1094 let mut counts: [usize; 256] = [0; 256];
1095 for x in &mut *list {
1096 counts[*x as usize] += 1;
1097 }
1098 let mut i = 0;
1099 if up {
1100 for (j, &count) in counts.iter().enumerate() {
1101 let n = j as u8;
1102 for _ in 0..count {
1103 list[i] = n;
1104 i += 1;
1105 }
1106 }
1107 } else {
1108 let offset = list.len().saturating_sub(1);
1109 for (j, &count) in counts.iter().enumerate() {
1110 let n = j as u8;
1111 for _ in 0..count {
1112 list[offset - i] = n;
1113 i += 1;
1114 }
1115 }
1116 }
1117 }
1118 #[track_caller]
1119 fn dbg_validate(arr: &Array<Self>) {
1120 if arr.meta.flags.is_boolean() {
1121 if let Some(b) = arr.data.iter().find(|&b| *b > 1) {
1122 panic!("Array marked as boolean contains {b}")
1123 }
1124 }
1125 }
1126}
1127
1128impl ArrayValue for char {
1129 const NAME: &'static str = "character";
1130 const SYMBOL: char = '@';
1131 const TYPE_ID: u8 = 1;
1132 fn get_scalar_fill(fill: &Fill) -> Result<FillValue<Self>, &'static str> {
1133 fill.char_scalar()
1134 }
1135 fn get_array_fill(fill: &Fill) -> Result<FillValue<Array<Self>>, &'static str> {
1136 fill.char_array()
1137 }
1138 fn array_hash<H: Hasher>(&self, hasher: &mut H) {
1139 self.hash(hasher)
1140 }
1141 fn proxy() -> Self {
1142 ' '
1143 }
1144 fn has_wildcard(&self) -> bool {
1145 *self == WILDCARD_CHAR
1146 }
1147}
1148
1149impl ArrayValue for Boxed {
1150 const NAME: &'static str = "box";
1151 const SYMBOL: char = '□';
1152 const TYPE_ID: u8 = 2;
1153 fn get_scalar_fill(fill: &Fill) -> Result<FillValue<Self>, &'static str> {
1154 fill.box_scalar()
1155 }
1156 fn get_array_fill(fill: &Fill) -> Result<FillValue<Array<Self>>, &'static str> {
1157 fill.box_array()
1158 }
1159 fn array_hash<H: Hasher>(&self, hasher: &mut H) {
1160 self.0.hash(hasher);
1161 }
1162 fn proxy() -> Self {
1163 Boxed(Array::<f64>::new(0, []).into())
1164 }
1165 fn nested_value(&self) -> Option<&Value> {
1166 Some(&self.0)
1167 }
1168 fn has_wildcard(&self) -> bool {
1169 self.0.has_wildcard()
1170 }
1171}
1172
1173impl ArrayValue for Complex {
1174 const NAME: &'static str = "complex";
1175 const SYMBOL: char = 'ℂ';
1176 const TYPE_ID: u8 = 3;
1177 fn get_scalar_fill(fill: &Fill) -> Result<FillValue<Self>, &'static str> {
1178 fill.complex_scalar()
1179 }
1180 fn get_array_fill(fill: &Fill) -> Result<FillValue<Array<Self>>, &'static str> {
1181 fill.complex_array()
1182 }
1183 fn array_hash<H: Hasher>(&self, hasher: &mut H) {
1184 for n in [self.re, self.im] {
1185 n.array_hash(hasher);
1186 }
1187 }
1188 fn proxy() -> Self {
1189 Complex::new(0.0, 0.0)
1190 }
1191}
1192
1193pub trait RealArrayValue: ArrayValue + Copy {
1195 fn is_int(&self) -> bool;
1197 fn to_f64(&self) -> f64;
1199}
1200
1201impl RealArrayValue for f64 {
1202 fn is_int(&self) -> bool {
1203 self.fract().abs() < f64::EPSILON
1204 }
1205 fn to_f64(&self) -> f64 {
1206 *self
1207 }
1208}
1209
1210impl RealArrayValue for u8 {
1211 fn is_int(&self) -> bool {
1212 true
1213 }
1214 fn to_f64(&self) -> f64 {
1215 *self as f64
1216 }
1217}
1218
1219pub trait ArrayCmp<U = Self> {
1221 fn array_cmp(&self, other: &U) -> Ordering;
1223 fn array_eq(&self, other: &U) -> bool {
1225 self.array_cmp(other) == Ordering::Equal
1226 }
1227}
1228
1229impl ArrayCmp for f64 {
1230 fn array_cmp(&self, other: &Self) -> Ordering {
1231 self.partial_cmp(other).unwrap_or_else(|| {
1232 if self.to_bits() == WILDCARD_NAN.to_bits() || other.to_bits() == WILDCARD_NAN.to_bits()
1233 {
1234 Ordering::Equal
1235 } else {
1236 self.is_nan().cmp(&other.is_nan())
1237 }
1238 })
1239 }
1240}
1241
1242impl ArrayCmp for u8 {
1243 fn array_cmp(&self, other: &Self) -> Ordering {
1244 self.cmp(other)
1245 }
1246}
1247
1248impl ArrayCmp for Complex {
1249 fn array_cmp(&self, other: &Self) -> Ordering {
1250 self.partial_cmp(other).unwrap_or_else(|| {
1251 (self.re.is_nan(), self.im.is_nan()).cmp(&(other.re.is_nan(), other.im.is_nan()))
1252 })
1253 }
1254}
1255
1256impl ArrayCmp for char {
1257 fn array_eq(&self, other: &Self) -> bool {
1258 *self == *other || *self == WILDCARD_CHAR || *other == WILDCARD_CHAR
1259 }
1260 fn array_cmp(&self, other: &Self) -> Ordering {
1261 if *self == WILDCARD_CHAR || *other == WILDCARD_CHAR {
1262 Ordering::Equal
1263 } else {
1264 self.cmp(other)
1265 }
1266 }
1267}
1268
1269impl ArrayCmp for Boxed {
1270 fn array_cmp(&self, other: &Self) -> Ordering {
1271 self.cmp(other)
1272 }
1273}
1274
1275impl ArrayCmp<f64> for u8 {
1276 fn array_cmp(&self, other: &f64) -> Ordering {
1277 (*self as f64).array_cmp(other)
1278 }
1279}
1280
1281impl ArrayCmp<u8> for f64 {
1282 fn array_cmp(&self, other: &u8) -> Ordering {
1283 self.array_cmp(&(*other as f64))
1284 }
1285}
1286
1287#[derive(Clone, Copy, PartialEq, Eq)]
1289pub struct FormatShape<'a, T = usize>(pub &'a [T]);
1290
1291impl<T: fmt::Display> fmt::Debug for FormatShape<'_, T> {
1292 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1293 write!(f, "{self}")
1294 }
1295}
1296
1297impl<T: fmt::Display> fmt::Display for FormatShape<'_, T> {
1298 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1299 write!(f, "[")?;
1300 for (i, dim) in self.0.iter().enumerate() {
1301 if i > 0 {
1302 write!(f, " × ")?;
1303 }
1304 write!(f, "{dim}")?;
1305 }
1306 write!(f, "]")
1307 }
1308}
1309
1310#[derive(Debug, Clone, Serialize, Deserialize)]
1311#[serde(untagged)]
1312#[serde(bound(
1313 serialize = "T: ArrayValueSer + Serialize",
1314 deserialize = "T: ArrayValueSer + Deserialize<'de>"
1315))]
1316enum ArrayRep<T: ArrayValueSer> {
1317 List(T::Collection),
1318 Scalar(T::Scalar),
1319 Map(Shape, Value, T::Collection),
1320 Metaless(Shape, T::Collection),
1321 Full(Shape, T::Collection, ArrayMeta),
1322}
1323
1324impl<T: ArrayValueSer> From<ArrayRep<T>> for Array<T> {
1325 fn from(rep: ArrayRep<T>) -> Self {
1326 let mut arr = match rep {
1327 ArrayRep::Scalar(data) => Self::new([], [data.into()]),
1328 ArrayRep::List(data) => {
1329 let data = T::make_data(data);
1330 Self::new(data.len(), data)
1331 }
1332 ArrayRep::Map(shape, keys, data) => {
1333 let data = T::make_data(data);
1334 let mut arr = Self::new(shape, data);
1335 _ = arr.map(keys, &());
1336 arr
1337 }
1338 ArrayRep::Metaless(shape, data) => {
1339 let data = T::make_data(data);
1340 Self::new(shape, data)
1341 }
1342 ArrayRep::Full(shape, data, meta) => {
1343 let data = T::make_data(data);
1344 Self { shape, data, meta }
1345 }
1346 };
1347
1348 let mut is_sorted_up = true;
1350 let mut is_sorted_down = true;
1351 {
1352 let mut rows = arr.row_slices();
1353 if let Some(mut curr) = rows.next() {
1354 for row in rows {
1355 if !is_sorted_up && !is_sorted_down {
1356 break;
1357 }
1358 match ArrayCmpSlice(curr).cmp(&ArrayCmpSlice(row)) {
1359 Ordering::Equal => {}
1360 Ordering::Less => is_sorted_down = false,
1361 Ordering::Greater => is_sorted_up = false,
1362 }
1363 curr = row;
1364 }
1365 }
1366 }
1367 arr.meta.mark_sorted_up(is_sorted_up);
1368 arr.meta.mark_sorted_down(is_sorted_down);
1369 arr
1370 }
1371}
1372
1373impl<T: ArrayValueSer> From<Array<T>> for ArrayRep<T> {
1374 fn from(mut arr: Array<T>) -> Self {
1375 if let Some(inner) = (arr.meta.0.take()).filter(|meta| **meta != DEFAULT_META_INNER) {
1376 let mut inner = Arc::unwrap_or_clone(inner);
1377 let map_keys = inner.map_keys.take();
1378 if inner == DEFAULT_META_INNER {
1379 if let Some(map_keys) = map_keys {
1380 let keys = map_keys.normalized();
1381 return ArrayRep::Map(arr.shape, keys, T::make_collection(arr.data));
1382 }
1383 } else {
1384 inner.map_keys = map_keys;
1385 }
1386 inner.flags = ArrayFlags::empty();
1387 if inner != DEFAULT_META_INNER {
1388 return ArrayRep::Full(
1389 arr.shape,
1390 T::make_collection(arr.data),
1391 ArrayMeta(Some(inner.into())),
1392 );
1393 }
1394 }
1395 match arr.rank() {
1396 0 if !T::no_scalar() => ArrayRep::Scalar(arr.data[0].clone().into()),
1397 1 => ArrayRep::List(T::make_collection(arr.data)),
1398 _ => ArrayRep::Metaless(arr.shape, T::make_collection(arr.data)),
1399 }
1400 }
1401}
1402
1403trait ArrayValueSer: ArrayValue + fmt::Debug {
1404 type Scalar: Serialize + DeserializeOwned + fmt::Debug + From<Self> + Into<Self>;
1405 type Collection: Serialize + DeserializeOwned + fmt::Debug;
1406 fn make_collection(data: CowSlice<Self>) -> Self::Collection;
1407 fn make_data(collection: Self::Collection) -> CowSlice<Self>;
1408 fn no_scalar() -> bool {
1410 false
1411 }
1412}
1413
1414impl ArrayValueSer for u8 {
1415 type Scalar = u8;
1416 type Collection = CowSlice<u8>;
1417 fn make_collection(data: CowSlice<Self>) -> Self::Collection {
1418 data
1419 }
1420 fn make_data(collection: Self::Collection) -> CowSlice<Self> {
1421 collection
1422 }
1423}
1424
1425#[derive(Debug, Clone, Serialize, Deserialize)]
1426enum BoxCollection {
1427 #[serde(rename = "empty_boxes")]
1428 Empty([Boxed; 0]),
1429 #[serde(untagged)]
1430 List(CowSlice<Boxed>),
1431}
1432
1433impl ArrayValueSer for Boxed {
1434 type Scalar = Boxed;
1435 type Collection = BoxCollection;
1436 fn make_collection(data: CowSlice<Self>) -> Self::Collection {
1437 if data.is_empty() {
1438 BoxCollection::Empty([])
1439 } else {
1440 BoxCollection::List(data)
1441 }
1442 }
1443 fn make_data(collection: Self::Collection) -> CowSlice<Self> {
1444 match collection {
1445 BoxCollection::Empty(_) => CowSlice::new(),
1446 BoxCollection::List(data) => data,
1447 }
1448 }
1449}
1450
1451#[derive(Debug, Clone, Serialize, Deserialize)]
1452enum ComplexCollection {
1453 #[serde(rename = "empty_complex")]
1454 Empty([Complex; 0]),
1455 #[serde(untagged)]
1456 List(CowSlice<Complex>),
1457}
1458
1459impl ArrayValueSer for Complex {
1460 type Scalar = Complex;
1461 type Collection = ComplexCollection;
1462 fn make_collection(data: CowSlice<Self>) -> Self::Collection {
1463 if data.is_empty() {
1464 ComplexCollection::Empty([])
1465 } else {
1466 ComplexCollection::List(data)
1467 }
1468 }
1469 fn make_data(collection: Self::Collection) -> CowSlice<Self> {
1470 match collection {
1471 ComplexCollection::Empty(_) => CowSlice::new(),
1472 ComplexCollection::List(data) => data,
1473 }
1474 }
1475 fn no_scalar() -> bool {
1476 true
1477 }
1478}
1479
1480impl ArrayValueSer for f64 {
1481 type Scalar = F64Rep;
1482 type Collection = Vec<F64Rep>;
1483 fn make_collection(data: CowSlice<Self>) -> Self::Collection {
1484 data.iter().map(|&n| n.into()).collect()
1485 }
1486 fn make_data(collection: Self::Collection) -> CowSlice<Self> {
1487 collection.into_iter().map(f64::from).collect()
1488 }
1489}
1490
1491impl ArrayValueSer for char {
1492 type Scalar = char;
1493 type Collection = String;
1494 fn make_collection(data: CowSlice<Self>) -> Self::Collection {
1495 data.iter().collect()
1496 }
1497 fn make_data(collection: Self::Collection) -> CowSlice<Self> {
1498 collection.chars().collect()
1499 }
1500 fn no_scalar() -> bool {
1501 true
1502 }
1503}
1504
1505#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
1506enum F64Rep {
1507 #[serde(rename = "NaN")]
1508 NaN,
1509 #[serde(rename = "empty")]
1510 MapEmpty,
1511 #[serde(rename = "tomb")]
1512 MapTombstone,
1513 #[serde(rename = "∞")]
1514 Infinity,
1515 #[serde(rename = "-∞")]
1516 NegInfinity,
1517 #[serde(untagged)]
1518 Num(f64),
1519}
1520
1521impl From<f64> for F64Rep {
1522 fn from(n: f64) -> Self {
1523 if n.is_nan() {
1524 if n.to_bits() == EMPTY_NAN.to_bits() {
1525 Self::MapEmpty
1526 } else if n.to_bits() == TOMBSTONE_NAN.to_bits() {
1527 Self::MapTombstone
1528 } else {
1529 Self::NaN
1530 }
1531 } else if n.is_infinite() {
1532 if n.is_sign_positive() {
1533 Self::Infinity
1534 } else {
1535 Self::NegInfinity
1536 }
1537 } else {
1538 Self::Num(n)
1539 }
1540 }
1541}
1542
1543impl From<F64Rep> for f64 {
1544 fn from(rep: F64Rep) -> Self {
1545 match rep {
1546 F64Rep::NaN => f64::NAN,
1547 F64Rep::MapEmpty => EMPTY_NAN,
1548 F64Rep::MapTombstone => TOMBSTONE_NAN,
1549 F64Rep::Infinity => f64::INFINITY,
1550 F64Rep::NegInfinity => f64::NEG_INFINITY,
1551 F64Rep::Num(n) => n,
1552 }
1553 }
1554}