1use std::borrow::Cow;
27use std::sync::atomic::{self, AtomicPtr, AtomicUsize, Ordering};
28use std::mem::{self, ManuallyDrop, MaybeUninit};
29use std::fmt::{self, Debug, LowerHex, UpperHex};
30use std::ops::{Bound, Range, RangeBounds};
31use std::alloc::{self, Layout};
32use std::ptr::{self, NonNull};
33use std::num::NonZero;
34use std::marker::PhantomData;
35use std::{slice, str};
36
37use crate::error::{Error, ErrorKind};
38use crate::value::DevEnum;
39use crate::dev::DevState;
40
41
42#[repr(C)]
49struct HeapHeader {
50 count: AtomicUsize,
52 cap: usize,
54 side: AtomicPtr<SideHeader>,
56}
57
58#[repr(C)]
62struct SideHeader {
63 next: *mut SideHeader,
65 size: usize,
67}
68
69const ALIGN: usize = 8;
72
73type AllocResult<T> = Result<T, Option<Layout>>;
76
77fn infallible<T>(res: AllocResult<T>) -> T {
80 match res {
81 Ok(value) => value,
82 Err(Some(layout)) => alloc::handle_alloc_error(layout),
83 Err(None) => panic!("capacity overflow"),
84 }
85}
86
87#[derive(Clone, Copy)]
90#[repr(transparent)]
91struct Heap(NonNull<HeapHeader>);
92
93#[repr(C, align(8))]
95struct EmptyHeapHeader(HeapHeader);
96
97static EMPTY_HEAP_HEADER: EmptyHeapHeader = EmptyHeapHeader(HeapHeader {
101 count: AtomicUsize::new(usize::MAX),
102 cap: 0,
103 side: AtomicPtr::new(ptr::null_mut()),
104});
105
106impl Heap {
107
108 const EMPTY: Self = Self(unsafe { NonNull::new_unchecked((&raw const EMPTY_HEAP_HEADER.0).cast_mut()) });
111
112 #[inline]
114 fn is_immortal(self) -> bool {
115 self.0 == Self::EMPTY.0
116 }
117
118 fn layout(cap: usize) -> Option<Layout> {
121 cap.checked_mul(ALIGN)
122 .and_then(|size| size.checked_add(mem::size_of::<HeapHeader>()))
123 .and_then(|size| Layout::from_size_align(size, ALIGN).ok())
124 }
125
126 fn alloc(len: usize) -> AllocResult<Self> {
131 let cap = len.div_ceil(ALIGN);
132 let layout = Self::layout(cap).ok_or(None)?;
133 let ptr = unsafe { alloc::alloc_zeroed(layout) };
135 let ptr = NonNull::new(ptr.cast::<HeapHeader>()).ok_or(Some(layout))?;
136 unsafe { ptr.write(HeapHeader { count: AtomicUsize::new(1), cap, side: AtomicPtr::new(ptr::null_mut()) }) };
138 Ok(Self(ptr))
139 }
140
141 #[inline]
143 fn data(self) -> *mut u8 {
144 unsafe { self.0.as_ptr().add(1).cast::<u8>() }
146 }
147
148 #[inline]
150 fn capacity(self) -> usize {
151 unsafe { (*self.0.as_ptr()).cap * ALIGN }
153 }
154
155 #[inline]
156 fn header(&self) -> &HeapHeader {
157 unsafe { self.0.as_ref() }
159 }
160
161 #[inline]
164 fn is_unique(self) -> bool {
165 self.header().count.load(Ordering::Acquire) == 1
166 }
167
168 #[inline]
170 fn acquire(self) {
171 if self.is_immortal() {
172 return;
173 }
174 let old = self.header().count.fetch_add(1, Ordering::Relaxed);
175 if old > isize::MAX as usize {
177 std::process::abort();
178 }
179 }
180
181 #[inline]
188 unsafe fn release(self) {
189 if self.is_immortal() || self.header().count.fetch_sub(1, Ordering::Release) != 1 {
190 return;
191 }
192 atomic::fence(Ordering::Acquire);
193 unsafe { self.free() }
195 }
196
197 #[cold]
198 unsafe fn free(self) {
199 let header = self.0.as_ptr();
200 unsafe {
202 self.free_sides();
203 alloc::dealloc(header.cast(), Self::layout((*header).cap).unwrap_unchecked());
204 }
205 }
206
207 fn side_layout(size: usize) -> Option<Layout> {
209 size.checked_add(mem::size_of::<SideHeader>())
210 .and_then(|size| Layout::from_size_align(size, ALIGN).ok())
211 }
212
213 fn push_side(self, side: DetachedSide) {
218 debug_assert!(!self.is_immortal(), "nothing is attached to the empty storage");
219 let side = ManuallyDrop::new(side).0;
220 let head = &self.header().side;
221 let mut next = head.load(Ordering::Relaxed);
222 loop {
223 unsafe { (*side.as_ptr()).next = next };
225 match head.compare_exchange_weak(next, side.as_ptr(), Ordering::Release, Ordering::Relaxed) {
226 Ok(_) => break,
227 Err(current) => next = current,
228 }
229 }
230 }
231
232 unsafe fn free_sides(self) {
239 let mut side = self.header().side.swap(ptr::null_mut(), Ordering::Relaxed);
240 while !side.is_null() {
241 unsafe {
244 let next = (*side).next;
245 alloc::dealloc(side.cast(), Self::side_layout((*side).size).unwrap_unchecked());
246 side = next;
247 }
248 }
249 }
250
251 #[cold]
261 unsafe fn grow(&mut self, capacity: usize) -> AllocResult<()> {
262 let old_cap = self.header().cap;
263 let cap = capacity.div_ceil(ALIGN).max(old_cap * 2);
264 let old_layout = unsafe { Self::layout(old_cap).unwrap_unchecked() };
266 let new_layout = Self::layout(cap).ok_or(None)?;
267 let ptr = unsafe { alloc::realloc(self.0.as_ptr().cast(), old_layout, new_layout.size()) };
269 self.0 = NonNull::new(ptr.cast::<HeapHeader>()).ok_or(Some(new_layout))?;
270 unsafe {
272 (*self.0.as_ptr()).cap = cap;
273 self.data().add(old_cap * ALIGN).write_bytes(0, (cap - old_cap) * ALIGN);
274 }
275 Ok(())
276 }
277
278}
279
280struct DetachedSide(NonNull<SideHeader>);
284
285impl DetachedSide {
286
287 fn new(size: usize) -> AllocResult<Self> {
290 let layout = Heap::side_layout(size).ok_or(None)?;
291 let side = NonNull::new(unsafe { alloc::alloc(layout) }.cast::<SideHeader>()).ok_or(Some(layout))?;
293 unsafe { side.write(SideHeader { next: ptr::null_mut(), size }) };
295 Ok(Self(side))
296 }
297
298 #[inline]
300 fn payload(&self) -> NonNull<u8> {
301 unsafe { self.0.add(1).cast::<u8>() }
303 }
304
305}
306
307impl Drop for DetachedSide {
308 fn drop(&mut self) {
309 unsafe { alloc::dealloc(self.0.as_ptr().cast(), Heap::side_layout((*self.0.as_ptr()).size).unwrap_unchecked()) }
312 }
313}
314
315struct HeapRef {
318 inner: Heap,
320 offset: usize,
322}
323
324impl HeapRef {
325
326 const EMPTY: Self = Self {
328 inner: Heap::EMPTY,
329 offset: 0,
330 };
331
332 fn copy(bytes: &[u8], capacity: usize) -> AllocResult<Self> {
334 let storage = Heap::alloc(bytes.len().max(capacity))?;
335 unsafe { ptr::copy_nonoverlapping(bytes.as_ptr(), storage.data(), bytes.len()) };
337 Ok(Self { inner: storage, offset: 0 })
338 }
339
340 #[inline]
342 fn ptr(&self) -> *mut u8 {
343 unsafe { self.inner.data().add(self.offset) }
345 }
346
347 #[inline]
349 fn clone_at(&self, count: usize) -> Self {
350 self.inner.acquire();
351 Self { inner: self.inner, offset: self.offset + count }
352 }
353
354 #[inline]
355 fn is_unique(&self) -> bool {
356 self.inner.is_unique()
357 }
358
359 #[inline]
363 fn is_writable(&self) -> bool {
364 self.inner.is_immortal() || self.inner.is_unique()
365 }
366
367}
368
369impl Clone for HeapRef {
370 #[inline]
371 fn clone(&self) -> Self {
372 self.clone_at(0)
373 }
374}
375
376impl Drop for HeapRef {
377 #[inline]
378 fn drop(&mut self) {
379 unsafe { self.inner.release() }
381 }
382}
383
384
385pub unsafe trait Spans: Copy + Send + Sync + 'static {
396
397 const EMPTY: Self;
399
400 unsafe fn span(self, index: usize) -> (usize, usize);
407
408 unsafe fn advance(self, count: usize) -> (usize, Self);
415
416}
417
418pub struct PackedSpans<T>(PhantomData<fn() -> T>);
421
422impl<T> PackedSpans<T> {
423 #[inline]
424 const fn new() -> Self {
425 Self(PhantomData)
426 }
427}
428
429impl<T> Clone for PackedSpans<T> {
430 #[inline]
431 fn clone(&self) -> Self {
432 *self
433 }
434}
435
436impl<T> Copy for PackedSpans<T> {}
437
438unsafe impl<T: 'static> Spans for PackedSpans<T> {
440
441 const EMPTY: Self = Self::new();
442
443 #[inline]
444 unsafe fn span(self, index: usize) -> (usize, usize) {
445 (index * mem::size_of::<T>(), mem::size_of::<T>())
446 }
447
448 #[inline]
449 unsafe fn advance(self, count: usize) -> (usize, Self) {
450 (count * mem::size_of::<T>(), self)
451 }
452
453}
454
455#[derive(Clone, Copy)]
464pub struct TableSpans(NonNull<Range<u32>>);
465
466unsafe impl Send for TableSpans {}
468unsafe impl Sync for TableSpans {}
469
470impl TableSpans {
471
472 #[inline]
475 fn single(len: usize) -> Self {
476 debug_assert!(len <= isize::MAX as usize);
477 Self(NonNull::without_provenance(unsafe { NonZero::new_unchecked(len << 1 | 1) }))
479 }
480
481 #[inline]
483 fn single_len(self) -> Option<usize> {
484 let addr = self.0.addr().get();
485 (addr & 1 != 0).then_some(addr >> 1)
486 }
487
488}
489
490unsafe impl Spans for TableSpans {
493
494 const EMPTY: Self = Self(NonNull::dangling());
495
496 #[inline]
497 unsafe fn span(self, index: usize) -> (usize, usize) {
498 if let Some(len) = self.single_len() {
499 return (0, len);
500 }
501 let Range { start, end } = unsafe { self.0.add(index).read() };
504 (start as usize, (end - start) as usize)
505 }
506
507 #[inline]
508 unsafe fn advance(self, count: usize) -> (usize, Self) {
509 if let Some(len) = self.single_len() {
510 return if count == 0 { (0, self) } else { (len, Self::EMPTY) };
512 }
513 (0, Self(unsafe { self.0.add(count) }))
515 }
516
517}
518
519
520pub unsafe trait Element: Send + Sync + 'static {
534
535 type Ref<'a>: Copy + Debug;
537
538 type Spans: Spans;
540
541 const INLINE_FIXED: bool;
544
545 fn validate(bytes: &[u8]) -> bool;
547
548 unsafe fn read<'a>(ptr: *const u8, len: usize) -> Self::Ref<'a>
555 where
556 Self: 'a;
557
558 fn fmt_row<'a, I>(values: I, f: &mut fmt::Formatter<'_>) -> fmt::Result
561 where
562 I: Iterator<Item = Self::Ref<'a>>,
563 Self: 'a,
564 {
565 for (index, value) in values.enumerate() {
566 if index != 0 {
567 f.write_str(", ")?;
568 }
569 Debug::fmt(&value, f)?;
570 }
571 Ok(())
572 }
573
574}
575
576pub unsafe trait PackedElement: Element<Spans = PackedSpans<Self>> + Copy {
586
587 fn validate_all(bytes: &[u8]) -> bool;
591
592}
593
594const fn inline_fixed<T>() -> bool {
596 assert!(mem::size_of::<T>() > 0, "a packed type is not zero-sized");
597 assert!(mem::size_of::<T>() <= mem::size_of::<Repr>(), "a packed type fits in place of a storage");
598 assert!(mem::align_of::<T>() <= ALIGN, "a packed type is aligned on at most 8 octets");
599 true
600}
601
602macro_rules! impl_packed_element {
605 ($($ty:ty $(where |$octet:ident| $valid:expr)? $(, debug $debug:path)?);* $(;)?) => { $(
606 unsafe impl Element for $ty {
608
609 type Ref<'a> = $ty;
610 type Spans = PackedSpans<$ty>;
611
612 const INLINE_FIXED: bool = inline_fixed::<$ty>();
613
614 #[inline]
615 fn validate(bytes: &[u8]) -> bool {
616 bytes.len() == mem::size_of::<$ty>() && Self::validate_all(bytes)
617 }
618
619 #[inline]
620 unsafe fn read<'a>(ptr: *const u8, _len: usize) -> $ty
621 where
622 $ty: 'a,
623 {
624 unsafe { ptr.cast::<$ty>().read() }
626 }
627
628 $(
629 #[inline]
630 fn fmt_row<'a, I>(values: I, f: &mut fmt::Formatter<'_>) -> fmt::Result
631 where
632 I: Iterator<Item = $ty>,
633 $ty: 'a,
634 {
635 $debug(values, f)
636 }
637 )?
638
639 }
640
641 unsafe impl PackedElement for $ty {
643 #[inline]
644 fn validate_all(_bytes: &[u8]) -> bool {
645 true $(&& _bytes.iter().all(|&$octet| $valid))?
646 }
647 }
648 )* };
649}
650
651impl_packed_element!(
652 u8, debug fmt_octets;
653 i8; u16; i16; u32; i32; u64; i64; f32; f64; DevEnum;
654 bool where |octet| octet <= 1;
655 DevState where |octet| octet <= DevState::Unknown as u8;
656);
657
658fn fmt_octets(octets: impl Iterator<Item = u8>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
661
662 let mut ascii = false;
663
664 for (index, byte) in octets.enumerate() {
665
666 if index != 0 && !ascii {
667 f.write_str(" ")?;
668 }
669
670 if byte.is_ascii_alphanumeric() || matches!(byte, b' ' | b':' | b'/' | b'.' | b'-' | b'_') {
671 if !ascii {
672 f.write_str("'")?;
673 ascii = true;
674 }
675 write!(f, "{}", byte as char)?;
676 } else {
677 if ascii {
678 f.write_str("' ")?;
679 ascii = false;
680 }
681 write!(f, "{byte:02X}")?;
682 }
683
684 }
685
686 if ascii {
687 f.write_str("'")?;
688 }
689
690 Ok(())
691
692}
693
694fn fmt_hex<T: PackedElement>(octets: &[u8], f: &mut fmt::Formatter<'_>, upper: bool) -> fmt::Result {
698 let size = mem::size_of::<T>();
699 for (index, &byte) in octets.iter().enumerate() {
700 if size > 1 && index != 0 && index % size == 0 {
701 f.write_str(" ")?;
702 }
703 if upper { write!(f, "{byte:02X}")? } else { write!(f, "{byte:02x}")? }
704 }
705 Ok(())
706}
707
708unsafe impl Element for str {
710
711 type Ref<'a> = &'a str;
712 type Spans = TableSpans;
713
714 const INLINE_FIXED: bool = false;
715
716 #[inline]
717 fn validate(bytes: &[u8]) -> bool {
718 str::from_utf8(bytes).is_ok()
719 }
720
721 #[inline]
722 unsafe fn read<'a>(ptr: *const u8, len: usize) -> &'a str
723 where
724 str: 'a,
725 {
726 unsafe { str::from_utf8_unchecked(slice::from_raw_parts(ptr, len)) }
728 }
729
730}
731
732
733#[repr(C)]
740union Repr {
741 raw: ManuallyDrop<HeapRef>,
742 inline: [MaybeUninit<u64>; mem::size_of::<HeapRef>() / 8],
743}
744
745pub struct Buf<T: Element + ?Sized, const DIM: usize> {
753 repr: Repr,
754 spans: T::Spans,
755 dim: [usize; DIM],
756 _t: PhantomData<*const T>,
757}
758
759unsafe impl<T: Element + ?Sized, const DIM: usize> Send for Buf<T, DIM> {}
762unsafe impl<T: Element + ?Sized, const DIM: usize> Sync for Buf<T, DIM> {}
763
764#[inline]
766fn checked_len(dim: &[usize]) -> Option<usize> {
767 dim.iter().try_fold(1usize, |len, &d| len.checked_mul(d))
768}
769
770#[track_caller]
772fn range_bounds<R: RangeBounds<usize>>(range: R, len: usize) -> Range<usize> {
773 let start = match range.start_bound() {
774 Bound::Included(&start) => start,
775 Bound::Excluded(&start) => start.checked_add(1).expect("range start overflow"),
776 Bound::Unbounded => 0,
777 };
778 let end = match range.end_bound() {
779 Bound::Included(&end) => end.checked_add(1).expect("range end overflow"),
780 Bound::Excluded(&end) => end,
781 Bound::Unbounded => len,
782 };
783 assert!(start <= end, "slice index starts at {start} but ends at {end}");
784 assert!(end <= len, "range end index {end} out of range for length {len}");
785 start..end
786}
787
788
789impl<T: Element + ?Sized, const DIM: usize> Buf<T, DIM> {
790
791 const INLINE: bool = DIM == 0 && T::INLINE_FIXED;
794
795 #[inline]
798 pub const fn new() -> Self {
799 const { assert!(DIM >= 1, "a scalar always holds one value") };
800 let raw = ManuallyDrop::new(HeapRef::EMPTY);
801 Self {
802 repr: Repr { raw },
803 spans: T::Spans::EMPTY,
804 dim: [0; DIM],
805 _t: PhantomData,
806 }
807 }
808
809 #[inline]
816 unsafe fn from_raw(raw: HeapRef, spans: T::Spans, dim: [usize; DIM]) -> Self {
817 debug_assert!(!Self::INLINE);
818 Self {
819 repr: Repr { raw: ManuallyDrop::new(raw) },
820 spans,
821 dim,
822 _t: PhantomData,
823 }
824 }
825
826 #[inline]
828 fn raw(&self) -> &HeapRef {
829 debug_assert!(!Self::INLINE);
830 unsafe { &self.repr.raw }
832 }
833
834 #[inline]
836 fn raw_mut(&mut self) -> &mut HeapRef {
837 debug_assert!(!Self::INLINE);
838 unsafe { &mut self.repr.raw }
840 }
841
842 #[inline]
845 fn into_raw(self) -> HeapRef {
846 let this = ManuallyDrop::new(self);
847 unsafe { ptr::read(this.raw()) }
849 }
850
851 #[inline]
853 fn base(&self) -> *const u8 {
854 if Self::INLINE {
855 ptr::addr_of!(self.repr).cast::<u8>()
856 } else {
857 self.raw().ptr()
858 }
859 }
860
861 #[inline]
864 fn base_mut(&mut self) -> *mut u8 {
865 if Self::INLINE {
866 ptr::addr_of_mut!(self.repr).cast::<u8>()
867 } else {
868 self.raw().ptr()
869 }
870 }
871
872 #[inline]
878 unsafe fn read(&self, index: usize) -> T::Ref<'_> {
879 unsafe {
881 let (offset, len) = self.spans.span(index);
882 T::read(self.base().add(offset), len)
883 }
884 }
885
886 #[inline]
888 pub fn dim(&self) -> [usize; DIM] {
889 self.dim
890 }
891
892 #[inline]
894 pub fn len(&self) -> usize {
895 self.dim.iter().product()
896 }
897
898 #[inline]
899 pub fn is_empty(&self) -> bool {
900 self.len() == 0
901 }
902
903 #[inline]
907 pub fn raw_index(&self, pos: [usize; DIM]) -> Option<usize> {
908 let mut index = 0;
909 let mut stride = 1;
910 for (&coord, &dim) in pos.iter().zip(&self.dim) {
911 if coord >= dim {
912 return None;
913 }
914 index += coord * stride;
915 stride *= dim;
916 }
917 Some(index)
918 }
919
920 #[inline]
924 pub fn get(&self, pos: [usize; DIM]) -> Option<T::Ref<'_>> {
925 let index = self.raw_index(pos)?;
926 Some(unsafe { self.read(index) })
928 }
929
930 pub fn get_scalar(&self, pos: [usize; DIM]) -> Option<Buf<T, 0>> {
934
935 let index = self.raw_index(pos)?;
936
937 if Buf::<T, 0>::INLINE {
938 let mut repr = Repr { inline: [MaybeUninit::uninit(); _] };
939 unsafe {
942 let (offset, len) = self.spans.span(index);
943 ptr::copy_nonoverlapping(self.base().add(offset), ptr::addr_of_mut!(repr).cast::<u8>(), len);
944 }
945 Some(Buf { repr, spans: self.spans, dim: [], _t: PhantomData })
946 } else {
947 unsafe {
951 let (octets, spans) = self.spans.advance(index);
952 Some(Buf::from_raw(self.raw().clone_at(octets), spans, []))
953 }
954 }
955
956 }
957
958 #[inline]
961 pub fn get_raw(&self, index: usize) -> Option<T::Ref<'_>> {
962 (index < self.len()).then(|| unsafe { self.read(index) })
964 }
965
966 #[inline]
968 pub fn iter(&self) -> impl ExactSizeIterator<Item = T::Ref<'_>> + '_ {
969 (0..self.len()).map(move |index| unsafe { self.read(index) })
971 }
972
973 #[track_caller]
981 pub fn slice<R: RangeBounds<usize>>(&self, range: R) -> Self {
982
983 const { assert!(DIM >= 1, "a scalar cannot be sliced") };
984 let Range { start, end } = range_bounds(range, self.dim[DIM - 1]);
985
986 let stride: usize = self.dim[..DIM - 1].iter().product();
987
988 let (octets, spans) = unsafe { self.spans.advance(start * stride) };
990 let mut dim = self.dim;
991 dim[DIM - 1] = end - start;
992
993 unsafe { Self::from_raw(self.raw().clone_at(octets), spans, dim) }
996
997 }
998
999 #[track_caller]
1008 pub fn split_to(&mut self, at: usize) -> Self {
1009 let front = self.slice(..at);
1010 *self = self.slice(at..);
1011 front
1012 }
1013
1014 #[track_caller]
1021 pub fn split_off(&mut self, at: usize) -> Self {
1022 let back = self.slice(at..);
1023 *self = self.slice(..at);
1024 back
1025 }
1026
1027 pub fn reshape<const D: usize>(self, dim: [usize; D]) -> Option<Buf<T, D>> {
1032 if checked_len(&dim)? != self.len() {
1033 return None;
1034 }
1035 let spans = self.spans;
1036 Some(match (Self::INLINE, Buf::<T, D>::INLINE) {
1038 (false, false) => unsafe { Buf::from_raw(self.into_raw(), spans, dim) },
1039 (true, true) => Buf { repr: Repr { inline: unsafe { self.repr.inline } }, spans, dim, _t: PhantomData },
1041 (true, false) => unsafe {
1042 let (offset, len) = spans.span(0);
1043 let bytes = slice::from_raw_parts(self.base().add(offset), len);
1044 Buf::from_raw(infallible(HeapRef::copy(bytes, len)), spans, dim)
1045 },
1046 (false, true) => {
1047 let raw = self.into_raw();
1048 let mut repr = Repr { inline: [MaybeUninit::uninit(); _] };
1049 unsafe {
1052 let (offset, len) = spans.span(0);
1053 ptr::copy_nonoverlapping(raw.ptr().add(offset), ptr::addr_of_mut!(repr).cast::<u8>(), len);
1054 }
1055 Buf { repr, spans, dim, _t: PhantomData }
1056 }
1057 })
1058 }
1059
1060 #[inline]
1063 pub fn into_scalar(self) -> Option<Buf<T, 0>> {
1064 self.reshape([])
1065 }
1066
1067 #[inline]
1070 pub fn is_unique(&self) -> bool {
1071 Self::INLINE || self.raw().is_unique()
1072 }
1073
1074 #[inline]
1076 fn is_writable(&self) -> bool {
1077 Self::INLINE || self.raw().is_writable()
1078 }
1079
1080}
1081
1082impl<T: Element + ?Sized> Buf<T, 1> {
1083
1084 #[inline]
1086 pub fn truncate(&mut self, len: usize) {
1087 self.dim[0] = self.dim[0].min(len);
1088 }
1089
1090}
1091
1092impl<T: Element + ?Sized> Buf<T, 0> {
1093
1094 #[inline]
1096 pub fn value(&self) -> T::Ref<'_> {
1097 unsafe { self.read(0) }
1099 }
1100
1101}
1102
1103impl<T: Element + ?Sized, const DIM: usize> Clone for Buf<T, DIM> {
1106 #[inline]
1107 fn clone(&self) -> Self {
1108 let repr = if Self::INLINE {
1109 Repr { inline: unsafe { self.repr.inline } }
1111 } else {
1112 Repr { raw: ManuallyDrop::new(self.raw().clone()) }
1113 };
1114 Self { repr, spans: self.spans, dim: self.dim, _t: PhantomData }
1115 }
1116}
1117
1118impl<T: Element + ?Sized, const DIM: usize> Drop for Buf<T, DIM> {
1119 #[inline]
1120 fn drop(&mut self) {
1121 if !Self::INLINE {
1122 unsafe { ManuallyDrop::drop(&mut self.repr.raw) }
1124 }
1125 }
1126}
1127
1128impl<T: Element + ?Sized, const DIM: usize> Default for Buf<T, DIM> {
1129 #[inline]
1131 fn default() -> Self {
1132 Self::new()
1133 }
1134}
1135
1136impl<T: Element + ?Sized, const DIM: usize> PartialEq for Buf<T, DIM>
1137where
1138 for<'a> T::Ref<'a>: PartialEq,
1139{
1140 fn eq(&self, other: &Self) -> bool {
1143 self.dim == other.dim && self.iter().eq(other.iter())
1144 }
1145}
1146
1147impl<T: Element + ?Sized, const DIM: usize> Eq for Buf<T, DIM>
1148where
1149 for<'a> T::Ref<'a>: Eq,
1150{}
1151
1152fn fmt_buf<'a, T, I>(f: &mut fmt::Formatter<'_>, name: &str, dim: &[usize], mut values: I) -> fmt::Result
1158where
1159 T: Element + ?Sized + 'a,
1160 I: Iterator<Item = T::Ref<'a>>,
1161{
1162 f.write_str(name)?;
1163 if dim.is_empty() {
1164 f.write_str("(")?;
1165 T::fmt_row(values, f)?;
1166 return f.write_str(")");
1167 }
1168 f.write_str("<")?;
1169 for (index, d) in dim.iter().enumerate() {
1170 if index != 0 {
1171 f.write_str(", ")?;
1172 }
1173 write!(f, "{d}")?;
1174 }
1175 f.write_str(">")?;
1176 fmt_level::<T, I>(f, dim, 0, &mut values)
1177}
1178
1179fn fmt_level<'a, T, I>(f: &mut fmt::Formatter<'_>, dim: &[usize], depth: usize, values: &mut I) -> fmt::Result
1181where
1182 T: Element + ?Sized + 'a,
1183 I: Iterator<Item = T::Ref<'a>>,
1184{
1185 const INDENT: usize = 4;
1186 let (&len, inner) = dim.split_last().expect("at least one dimension");
1187 f.write_str("[")?;
1188 if inner.is_empty() {
1189 T::fmt_row(values.by_ref().take(len), f)?;
1190 } else {
1191 let pretty = f.alternate();
1192 for index in 0..len {
1193 if pretty {
1194 write!(f, "\n{:1$}", "", (depth + 1) * INDENT)?;
1195 } else if index != 0 {
1196 f.write_str(", ")?;
1197 }
1198 fmt_level::<T, I>(f, inner, depth + 1, values)?;
1199 if pretty {
1200 f.write_str(",")?;
1201 }
1202 }
1203 if pretty && len != 0 {
1204 write!(f, "\n{:1$}", "", depth * INDENT)?;
1205 }
1206 }
1207 f.write_str("]")
1208}
1209
1210impl<T: Element + ?Sized, const DIM: usize> Debug for Buf<T, DIM> {
1211 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1213 fmt_buf::<T, _>(f, "Buf", &self.dim, self.iter())
1214 }
1215}
1216
1217impl<T: PackedElement> UpperHex for Buf<T, 1> {
1218 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1222 fmt_hex::<T>(self.as_bytes(), f, true)
1223 }
1224}
1225
1226impl<T: PackedElement> LowerHex for Buf<T, 1> {
1227 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1231 fmt_hex::<T>(self.as_bytes(), f, false)
1232 }
1233}
1234
1235impl<T: PackedElement, const DIM: usize> Buf<T, DIM> {
1238
1239 #[inline]
1243 fn check_packed(bytes: &[u8], dim: [usize; DIM]) -> Option<bool> {
1244 let size = checked_len(&dim)?.checked_mul(mem::size_of::<T>())?;
1245 if bytes.len() != size || !T::validate_all(bytes) {
1246 return None;
1247 }
1248 Some(!Self::INLINE && bytes.as_ptr().addr().is_multiple_of(mem::align_of::<T>()))
1249 }
1250
1251 unsafe fn copy_from_bytes(bytes: &[u8], dim: [usize; DIM]) -> Self {
1258 if Self::INLINE {
1259 let mut repr = Repr { inline: [MaybeUninit::uninit(); _] };
1260 unsafe { ptr::copy_nonoverlapping(bytes.as_ptr(), ptr::addr_of_mut!(repr).cast::<u8>(), bytes.len()) };
1262 Self { repr, spans: PackedSpans::new(), dim, _t: PhantomData }
1263 } else if bytes.is_empty() {
1264 unsafe { Self::from_raw(HeapRef::EMPTY, PackedSpans::new(), dim) }
1266 } else {
1267 unsafe { Self::from_raw(infallible(HeapRef::copy(bytes, bytes.len())), PackedSpans::new(), dim) }
1269 }
1270 }
1271
1272 pub fn from_slice(values: &[T], dim: [usize; DIM]) -> Option<Self> {
1276 if checked_len(&dim)? != values.len() {
1277 return None;
1278 }
1279 let bytes = unsafe { slice::from_raw_parts(values.as_ptr().cast::<u8>(), mem::size_of_val(values)) };
1281 Some(unsafe { Self::copy_from_bytes(bytes, dim) })
1283 }
1284
1285 #[inline]
1287 pub fn zeroed(dim: [usize; DIM]) -> Self {
1288 BufMut::zeroed(dim).freeze()
1289 }
1290
1291 #[inline]
1293 pub fn as_ptr(&self) -> *const T {
1294 self.base().cast::<T>()
1295 }
1296
1297 #[inline]
1299 pub fn as_slice(&self) -> &[T] {
1300 unsafe { slice::from_raw_parts(self.as_ptr(), self.len()) }
1302 }
1303
1304 #[inline]
1306 pub fn as_bytes(&self) -> &[u8] {
1307 unsafe { slice::from_raw_parts(self.base(), self.len() * mem::size_of::<T>()) }
1309 }
1310
1311 pub fn cast<U: PackedElement, const D: usize>(self, dim: [usize; D]) -> Result<Buf<U, D>, Self> {
1319
1320 let Some(share) = Buf::<U, D>::check_packed(self.as_bytes(), dim) else {
1321 return Err(self);
1322 };
1323
1324 Ok(unsafe {
1326 if share && !Self::INLINE {
1327 Buf::from_raw(self.into_raw(), PackedSpans::new(), dim)
1328 } else {
1329 Buf::copy_from_bytes(self.as_bytes(), dim)
1330 }
1331 })
1332
1333 }
1334
1335 pub fn into_bytes(self) -> Buf<u8, 1> {
1337 let len = self.as_bytes().len();
1338 match self.cast([len]) {
1339 Ok(bytes) => bytes,
1340 Err(_) => unreachable!("every octet is a valid one"),
1341 }
1342 }
1343
1344 #[inline]
1347 pub fn get_mut(&mut self) -> Option<&mut BufMut<T, DIM>> {
1348 self.is_writable().then(|| unsafe { &mut *(self as *mut Self).cast::<BufMut<T, DIM>>() })
1351 }
1352
1353 #[inline]
1357 pub fn make_mut(&mut self) -> &mut BufMut<T, DIM> {
1358 if !self.is_writable() {
1359 *self = unsafe { Self::copy_from_bytes(self.as_bytes(), self.dim) };
1361 }
1362 unsafe { &mut *(self as *mut Self).cast::<BufMut<T, DIM>>() }
1364 }
1365
1366 #[inline]
1369 pub fn try_into_mut(self) -> Result<BufMut<T, DIM>, Self> {
1370 if self.is_writable() {
1371 Ok(BufMut(self))
1372 } else {
1373 Err(self)
1374 }
1375 }
1376
1377 #[inline]
1381 pub fn into_mut(mut self) -> BufMut<T, DIM> {
1382 self.make_mut();
1383 BufMut(self)
1384 }
1385
1386 #[track_caller]
1395 pub fn slice_ref(&self, subset: &[T]) -> Self {
1396
1397 const { assert!(DIM >= 1, "a scalar cannot be sliced") };
1398
1399 let size = mem::size_of::<T>();
1400 let offset = subset.as_ptr().addr().wrapping_sub(self.base().addr());
1401 let (start, len) = (offset / size, self.len());
1402
1403 assert!(offset.is_multiple_of(size) && start <= len && subset.len() <= len - start,
1404 "the values at {:p} are not within the buffer at {:p}, of {len} values",
1405 subset.as_ptr(),
1406 self.base());
1407
1408 let stride: usize = self.dim[..DIM - 1].iter().product();
1409 if stride == 0 {
1410 return self.slice(..0);
1411 }
1412
1413 assert!(start.is_multiple_of(stride) && subset.len().is_multiple_of(stride),
1414 "the values {start}..{} are not whole rows of {stride} values",
1415 start + subset.len());
1416
1417 self.slice(start / stride..(start + subset.len()) / stride)
1418
1419 }
1420
1421}
1422
1423impl<T: PackedElement> From<T> for Buf<T, 0> {
1424 #[inline]
1426 fn from(value: T) -> Self {
1427 Self::from_slice(slice::from_ref(&value), []).expect("a scalar holds one value")
1428 }
1429}
1430
1431impl<T: PackedElement> From<&[T]> for Buf<T, 1> {
1432 #[inline]
1433 fn from(values: &[T]) -> Self {
1434 Self::from_slice(values, [values.len()]).expect("same length")
1435 }
1436}
1437
1438impl<T: PackedElement> From<Vec<T>> for Buf<T, 1> {
1439 #[inline]
1440 fn from(values: Vec<T>) -> Self {
1441 Self::from(values.as_slice())
1442 }
1443}
1444
1445impl<T: PackedElement> From<Box<[T]>> for Buf<T, 1> {
1446 #[inline]
1447 fn from(values: Box<[T]>) -> Self {
1448 Self::from(&*values)
1449 }
1450}
1451
1452impl<T: PackedElement, const N: usize> From<[T; N]> for Buf<T, 1> {
1453 #[inline]
1454 fn from(values: [T; N]) -> Self {
1455 Self::from(values.as_slice())
1456 }
1457}
1458
1459impl<T: PackedElement, const DIM: usize> From<BufMut<T, DIM>> for Buf<T, DIM> {
1460 #[inline]
1461 fn from(buf: BufMut<T, DIM>) -> Self {
1462 buf.freeze()
1463 }
1464}
1465
1466impl<T: Element<Spans = TableSpans> + ?Sized, const DIM: usize> Buf<T, DIM> {
1469
1470 fn with_spans<I, F>(bytes: Buf<u8, 1>, spans: I, dim: [usize; DIM], mut check: F) -> Result<Self, Buf<u8, 1>>
1476 where
1477 I: IntoIterator<Item = Range<u32>>,
1478 F: FnMut(&[u8], &Range<u32>) -> bool,
1479 {
1480
1481 let Some(len) = checked_len(&dim) else {
1482 return Err(bytes);
1483 };
1484
1485 let mut spans = spans.into_iter();
1486
1487 if len == 0 {
1489
1490 if spans.next().is_some() {
1491 return Err(bytes);
1492 }
1493
1494 return Ok(unsafe { Self::from_raw(bytes.into_raw(), TableSpans::EMPTY, dim) });
1496
1497 }
1498
1499 if len == 1 {
1502
1503 let Some(span) = spans.next().filter(|span| check(bytes.as_slice(), span)) else {
1504 return Err(bytes);
1505 };
1506
1507 if spans.next().is_some() {
1508 return Err(bytes);
1509 }
1510
1511 let mut raw = bytes.into_raw();
1512 raw.offset += span.start as usize;
1513 return Ok(unsafe { Self::from_raw(raw, TableSpans::single(span.len()), dim) });
1516
1517 }
1518
1519 let Some(size) = len.checked_mul(mem::size_of::<Range<u32>>()) else {
1520 return Err(bytes);
1521 };
1522
1523 let Ok(side) = DetachedSide::new(size) else {
1524 return Err(bytes);
1525 };
1526
1527 let table = side.payload().cast::<Range<u32>>();
1528 for index in 0..len {
1529 let Some(span) = spans.next().filter(|span| check(bytes.as_slice(), span)) else {
1530 return Err(bytes);
1531 };
1532 unsafe { table.add(index).write(span) };
1534 }
1535
1536 if spans.next().is_some() {
1537 return Err(bytes);
1538 }
1539
1540 let mut raw = bytes.into_raw();
1541 if raw.inner.is_immortal() {
1544 raw = HeapRef { inner: infallible(Heap::alloc(0)), offset: 0 };
1545 }
1546 raw.inner.push_side(side);
1547
1548 Ok(unsafe { Self::from_raw(raw, TableSpans(table), dim) })
1550
1551 }
1552
1553}
1554
1555impl<const DIM: usize> Buf<str, DIM> {
1556
1557 pub fn from_spans<I>(bytes: Buf<u8, 1>, spans: I, dim: [usize; DIM]) -> Result<Self, Buf<u8, 1>>
1564 where
1565 I: IntoIterator<Item = Range<u32>>,
1566 {
1567 Self::with_spans(bytes, spans, dim, |bytes, span| {
1568 bytes.get(span.start as usize..span.end as usize).is_some_and(str::validate)
1569 })
1570 }
1571
1572 #[inline]
1584 #[track_caller]
1585 pub unsafe fn from_spans_unchecked<I>(bytes: Buf<u8, 1>, spans: I, dim: [usize; DIM]) -> Self
1586 where
1587 I: IntoIterator<Item = Range<u32>>,
1588 {
1589 Self::with_spans(bytes, spans, dim, |_, _| true)
1590 .unwrap_or_else(|_| panic!("no table of as many spans as the dimensions {dim:?} say"))
1591 }
1592
1593}
1594
1595impl Buf<str, 1> {
1596
1597 pub fn from_strs<I>(values: I) -> Option<Self>
1603 where
1604 I: IntoIterator,
1605 I::Item: AsRef<str>,
1606 {
1607
1608 let mut values = values.into_iter();
1609
1610 let Some(first) = values.next() else {
1611 return Some(unsafe { Self::from_raw(HeapRef::EMPTY, TableSpans::EMPTY, [0]) });
1613 };
1614
1615 let Some(second) = values.next() else {
1616 let value = first.as_ref();
1617 let raw = if value.is_empty() { HeapRef::EMPTY } else { infallible(HeapRef::copy(value.as_bytes(), 0)) };
1618 return Some(unsafe { Self::from_raw(raw, TableSpans::single(value.len()), [1]) });
1620 };
1621
1622 let mut buf = BufMut::<u8, 1>::new();
1623 let mut spans = Vec::with_capacity(values.size_hint().0.saturating_add(2));
1626
1627 for value in [first, second].into_iter().chain(values) {
1628 let start = u32::try_from(buf.len()).ok()?;
1629 buf.extend_from_slice(value.as_ref().as_bytes());
1630 spans.push(start..u32::try_from(buf.len()).ok()?);
1631 }
1632
1633 let len = spans.len();
1634 Some(unsafe { Self::from_spans_unchecked(buf.freeze(), spans, [len]) })
1637
1638 }
1639
1640}
1641
1642impl From<&str> for Buf<str, 0> {
1643 #[inline]
1646 fn from(value: &str) -> Self {
1647 Buf::<str, 1>::from_strs([value])
1648 .and_then(Buf::into_scalar)
1649 .expect("a single string always makes a scalar")
1650 }
1651}
1652
1653impl From<Cow<'_, str>> for Buf<str, 0> {
1654 #[inline]
1656 fn from(value: Cow<'_, str>) -> Self {
1657 Self::from(&*value)
1658 }
1659}
1660
1661impl From<String> for Buf<str, 0> {
1662 #[inline]
1664 fn from(value: String) -> Self {
1665 Self::from(value.as_str())
1666 }
1667}
1668
1669impl<S: AsRef<str>> From<&[S]> for Buf<str, 1> {
1670 #[inline]
1671 fn from(values: &[S]) -> Self {
1672 Self::from_strs(values).expect("strings of more than 4 GiB")
1673 }
1674}
1675
1676
1677#[repr(transparent)]
1690pub struct BufMut<T: PackedElement, const DIM: usize>(Buf<T, DIM>);
1691
1692impl<T: PackedElement, const DIM: usize> BufMut<T, DIM> {
1693
1694 pub fn zeroed(dim: [usize; DIM]) -> Self {
1700
1701 let size = checked_len(&dim)
1702 .and_then(|len| len.checked_mul(mem::size_of::<T>()))
1703 .expect("capacity overflow");
1704
1705 if Buf::<T, DIM>::INLINE || size == 0 {
1706 return Self(unsafe { Buf::copy_from_bytes(&[0; mem::size_of::<Repr>()][..size], dim) });
1708 }
1709
1710 let raw = HeapRef { inner: infallible(Heap::alloc(size)), offset: 0 };
1711
1712 Self(unsafe { Buf::from_raw(raw, PackedSpans::new(), dim) })
1714
1715 }
1716
1717 #[inline]
1719 pub fn from_slice(values: &[T], dim: [usize; DIM]) -> Option<Self> {
1720 Buf::from_slice(values, dim).map(Self)
1721 }
1722
1723 #[inline]
1725 pub fn dim(&self) -> [usize; DIM] {
1726 self.0.dim
1727 }
1728
1729 #[inline]
1731 pub fn len(&self) -> usize {
1732 self.0.len()
1733 }
1734
1735 #[inline]
1736 pub fn is_empty(&self) -> bool {
1737 self.0.is_empty()
1738 }
1739
1740 #[inline]
1742 pub fn as_ptr(&self) -> *const T {
1743 self.0.as_ptr()
1744 }
1745
1746 #[inline]
1747 pub fn as_slice(&self) -> &[T] {
1748 self.0.as_slice()
1749 }
1750
1751 #[inline]
1752 pub fn as_mut_slice(&mut self) -> &mut [T] {
1753 let len = self.len();
1754 unsafe { slice::from_raw_parts_mut(self.0.base_mut().cast::<T>(), len) }
1756 }
1757
1758 #[inline]
1759 pub fn as_bytes(&self) -> &[u8] {
1760 self.0.as_bytes()
1761 }
1762
1763 #[inline]
1766 pub fn freeze(self) -> Buf<T, DIM> {
1767 self.0
1768 }
1769
1770}
1771
1772impl<T: PackedElement> BufMut<T, 1> {
1773
1774 #[inline]
1776 pub const fn new() -> Self {
1777 Self(Buf::new())
1778 }
1779
1780 #[inline]
1782 pub fn with_capacity(capacity: usize) -> Self {
1783 let mut buf = Self::new();
1784 buf.reserve(capacity);
1785 buf
1786 }
1787
1788 #[inline]
1790 pub fn capacity(&self) -> usize {
1791 let raw = self.0.raw();
1792 (raw.inner.capacity() - raw.offset) / mem::size_of::<T>()
1793 }
1794
1795 #[inline]
1798 fn ptr_at(&self, index: usize) -> *mut T {
1799 debug_assert!(index <= self.capacity());
1800 unsafe { self.0.raw().ptr().cast::<T>().add(index) }
1802 }
1803
1804 #[inline]
1806 pub fn reserve(&mut self, additional: usize) {
1807 infallible(self.alloc_reserve(additional))
1808 }
1809
1810 pub fn try_reserve(&mut self, additional: usize) -> Result<(), Error> {
1813 self.alloc_reserve(additional).map_err(|_| Error::new(ErrorKind::Internal)
1814 .with_description(format!("Failed to allocate room for {additional} more values behind {}", self.len())))
1815 }
1816
1817 fn alloc_reserve(&mut self, additional: usize) -> AllocResult<()> {
1818 let len = self.len();
1819 let raw = self.0.raw_mut();
1820 let end = len.checked_add(additional)
1821 .and_then(|len| len.checked_mul(mem::size_of::<T>()))
1822 .and_then(|size| raw.offset.checked_add(size))
1823 .ok_or(None)?;
1824 if end <= raw.inner.capacity() {
1825 return Ok(());
1826 }
1827 if raw.inner.is_immortal() {
1828 raw.inner = Heap::alloc(end)?;
1831 } else {
1832 unsafe { raw.inner.grow(end)? };
1834 }
1835 Ok(())
1836 }
1837
1838 #[inline]
1840 pub fn push(&mut self, value: T) {
1841 self.reserve(1);
1842 unsafe { self.ptr_at(self.len()).write(value) };
1844 self.0.dim[0] += 1;
1845 }
1846
1847 pub fn extend_from_slice(&mut self, values: &[T]) {
1849 self.reserve(values.len());
1850 unsafe { ptr::copy_nonoverlapping(values.as_ptr(), self.ptr_at(self.len()), values.len()) };
1852 self.0.dim[0] += values.len();
1853 }
1854
1855 pub fn resize(&mut self, len: usize, value: T) {
1860 let old_len = self.len();
1861 if len > old_len {
1862 let bytes = unsafe { slice::from_raw_parts(ptr::from_ref(&value).cast::<u8>(), mem::size_of::<T>()) };
1864 let end = if bytes.iter().all(|&octet| octet == 0) {
1865 let raw = self.0.raw();
1867 len.min((raw.inner.capacity() - raw.offset).div_ceil(mem::size_of::<T>()))
1868 } else {
1869 len
1870 };
1871 self.reserve(len - old_len);
1872 for index in old_len..end {
1873 unsafe { self.ptr_at(index).write(value) };
1875 }
1876 }
1877 self.0.dim[0] = len;
1878 }
1879
1880 #[inline]
1882 pub fn truncate(&mut self, len: usize) {
1883 self.0.truncate(len);
1884 }
1885
1886 pub fn clear(&mut self) {
1889 let raw = self.0.raw_mut();
1890 if !raw.inner.is_immortal() {
1891 unsafe { raw.inner.free_sides() };
1893 }
1894 raw.offset = 0;
1895 self.0.dim[0] = 0;
1896 }
1897
1898}
1899
1900impl BufMut<u8, 1> {
1901
1902 pub fn from_hex(s: &str) -> Option<Self> {
1905 if !s.len().is_multiple_of(2) {
1906 return None;
1907 }
1908 let mut buf = Self::with_capacity(s.len() / 2);
1909 for hex in s.as_bytes().as_chunks::<2>().0 {
1910 let hex = str::from_utf8(hex).ok()?;
1911 buf.push(u8::from_str_radix(hex, 16).ok()?);
1912 }
1913 Some(buf)
1914 }
1915
1916 pub fn set_len(&mut self, len: usize) {
1923 self.reserve(len.saturating_sub(self.len()));
1924 self.0.dim[0] = len;
1925 }
1926
1927}
1928
1929impl<T: PackedElement, const DIM: usize> Clone for BufMut<T, DIM> {
1932 #[inline]
1935 fn clone(&self) -> Self {
1936 Self(unsafe { Buf::copy_from_bytes(self.as_bytes(), self.dim()) })
1938 }
1939}
1940
1941impl<T: PackedElement> Default for BufMut<T, 1> {
1942 #[inline]
1943 fn default() -> Self {
1944 Self::new()
1945 }
1946}
1947
1948impl<T: PackedElement + PartialEq, const DIM: usize> PartialEq for BufMut<T, DIM> {
1949 #[inline]
1950 fn eq(&self, other: &Self) -> bool {
1951 self.dim() == other.dim() && self.as_slice() == other.as_slice()
1952 }
1953}
1954
1955impl<T: PackedElement + Eq, const DIM: usize> Eq for BufMut<T, DIM> {}
1956
1957impl<T: PackedElement> From<&[T]> for BufMut<T, 1> {
1958 #[inline]
1959 fn from(values: &[T]) -> Self {
1960 Self(Buf::from(values))
1961 }
1962}
1963
1964impl<T: PackedElement> From<Vec<T>> for BufMut<T, 1> {
1965 #[inline]
1966 fn from(values: Vec<T>) -> Self {
1967 Self::from(values.as_slice())
1968 }
1969}
1970
1971impl<T: PackedElement, const DIM: usize> Debug for BufMut<T, DIM> {
1974 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1976 fmt_buf::<T, _>(f, "BufMut", &self.0.dim, self.0.iter())
1977 }
1978}
1979
1980impl<T: PackedElement> UpperHex for BufMut<T, 1> {
1981 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1985 fmt_hex::<T>(self.as_bytes(), f, true)
1986 }
1987}
1988
1989impl<T: PackedElement> LowerHex for BufMut<T, 1> {
1990 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1994 fmt_hex::<T>(self.as_bytes(), f, false)
1995 }
1996}
1997
1998#[cfg(test)]
1999#[allow(clippy::single_range_in_vec_init)]
2000mod tests {
2001
2002 use super::*;
2003
2004 #[test]
2007 fn scalar() {
2008 let scalar = Buf::<f64, 0>::from(1.5);
2009 assert_eq!(scalar.value(), 1.5);
2010 assert_eq!(scalar.get([]), Some(1.5));
2011 assert_eq!(scalar.len(), 1);
2012 let clone = scalar.clone();
2013 assert!(scalar.is_unique() && clone.is_unique());
2014 }
2015
2016 #[test]
2017 fn one_dim() {
2018 let buf = Buf::<i32, 1>::from(vec![1, 2, 3]);
2019 assert_eq!(buf.dim(), [3]);
2020 assert_eq!(buf.get([1]), Some(2));
2021 assert_eq!(buf.get([3]), None);
2022 assert_eq!(buf.as_slice(), &[1, 2, 3]);
2023 assert_eq!(buf.iter().sum::<i32>(), 6);
2024 }
2025
2026 #[test]
2029 fn two_dim() {
2030 let buf = Buf::<u8, 2>::from_slice(&[1, 2, 3, 4, 5, 6], [3, 2]).unwrap();
2031 assert_eq!(buf.get([0, 1]), Some(4));
2032 assert_eq!(buf.get([2, 1]), Some(6));
2033 assert_eq!(buf.get([3, 0]), None);
2034 assert_eq!(buf.raw_index([1, 1]), Some(4));
2035 assert_eq!(buf.get_raw(4), Some(5));
2036 assert!(Buf::<u8, 2>::from_slice(&[1, 2, 3], [2, 2]).is_none());
2038 let flat = buf.reshape([6]).unwrap();
2040 assert_eq!(flat.as_slice(), &[1, 2, 3, 4, 5, 6]);
2041 }
2042
2043 #[test]
2046 fn empty() {
2047 const EMPTY: Buf<u32, 2> = Buf::new();
2048 const EMPTY_MUT: BufMut<u8, 1> = BufMut::new();
2049 assert_eq!(EMPTY.dim(), [0, 0]);
2050 assert!(!EMPTY.is_unique());
2051 let mut values = Buf::<u32, 1>::from(vec![]);
2052 assert_eq!(values.as_ptr().cast::<u8>(), EMPTY_MUT.as_ptr());
2053 assert_eq!(values.make_mut().as_mut_slice(), &mut []);
2054 assert!(Buf::<str, 1>::from(&[] as &[&str]).iter().next().is_none());
2055 let strings = Buf::<str, 1>::from_spans(values.into_bytes(), [0..0, 0..0], [2]).unwrap();
2057 assert_eq!(strings.iter().collect::<Vec<_>>(), ["", ""]);
2058 let mut buf = EMPTY_MUT;
2059 assert_eq!(buf.capacity(), 0);
2060 buf.clear();
2061 buf.extend_from_slice(&[]);
2062 assert_eq!(buf.as_ptr(), EMPTY_MUT.as_ptr());
2063 buf.extend_from_slice(&[1, 2]);
2064 assert_ne!(buf.as_ptr(), EMPTY_MUT.as_ptr());
2065 let mut shared = EMPTY.reshape::<1>([0]).unwrap();
2066 shared.get_mut().unwrap().resize(3, 7);
2067 assert_eq!(shared.as_slice(), [7; 3]);
2068 }
2069
2070 #[test]
2072 fn writable_clone() {
2073 let mut buf = BufMut::from(&[1u16, 2][..]);
2074 let mut copy = buf.clone();
2075 assert_ne!(copy.as_ptr(), buf.as_ptr());
2076 copy.as_mut_slice()[0] = 0;
2077 buf.push(3);
2078 assert_eq!((buf.as_slice(), copy.as_slice()), (&[1, 2, 3][..], &[0, 2][..]));
2079 assert!(buf.freeze().is_unique() && copy.freeze().is_unique());
2080 }
2081
2082 #[test]
2085 fn slicing_by_ref() {
2086 let values = Buf::<u16, 1>::from(vec![1, 2, 3, 4]);
2087 let part = values.slice_ref(&values.as_slice()[1..3]);
2088 assert_eq!(part.as_slice(), &[2, 3]);
2089 assert_eq!(part.as_ptr(), values.as_slice()[1..].as_ptr());
2090 let rows = values.reshape([2, 2]).unwrap();
2091 assert_eq!(rows.slice_ref(&rows.as_slice()[2..]).dim(), [2, 1]);
2092 let res = std::panic::catch_unwind(|| rows.slice_ref(&rows.as_slice()[1..3]));
2093 assert!(res.is_err());
2094 let other = [3, 4];
2095 let res = std::panic::catch_unwind(|| rows.slice_ref(&other));
2096 assert!(res.is_err());
2097 }
2098
2099 #[test]
2101 fn octets_by_ref() {
2102 let buf = Buf::from(&b"hello world"[..]);
2103 let part = buf.slice_ref(&buf.as_slice()[6..]);
2104 assert_eq!(part.as_slice(), b"world");
2105 assert!(buf.slice_ref(&buf.as_slice()[11..]).is_empty());
2106 }
2107
2108 #[test]
2111 fn slicing() {
2112 let buf = Buf::<u8, 2>::from_slice(&[1, 2, 3, 4, 5, 6], [2, 3]).unwrap();
2113 let rows = buf.slice(1..);
2114 assert_eq!(rows.dim(), [2, 2]);
2115 assert_eq!(rows.as_slice(), &[3, 4, 5, 6]);
2116 assert!(!buf.is_unique());
2117 assert_eq!(rows.slice(..1).as_slice(), &[3, 4]);
2118 }
2119
2120 #[test]
2123 fn scalar_shapes() {
2124 let scalar = Buf::<u16, 0>::from(7);
2125 let square = scalar.clone().reshape([1, 1]).unwrap();
2126 assert_eq!(square.as_slice(), &[7]);
2127 assert!(scalar.clone().reshape([2]).is_none());
2128 assert_eq!(square.into_scalar().unwrap(), scalar);
2129 assert_eq!(scalar.clone().into_scalar().unwrap(), scalar);
2130 let string = Buf::<str, 0>::from("ab");
2131 let strings = string.clone().reshape([1]).unwrap();
2132 assert!(!string.is_unique());
2133 assert_eq!(strings.into_scalar().unwrap().value(), "ab");
2134 }
2135
2136 #[test]
2138 fn splitting() {
2139 let mut buf = Buf::from(&b"headtail"[..]);
2140 let head = buf.split_to(4);
2141 assert_eq!((head.as_slice(), buf.as_slice()), (&b"head"[..], &b"tail"[..]));
2142 let tail = buf.split_off(2);
2143 assert_eq!((buf.as_slice(), tail.as_slice()), (&b"ta"[..], &b"il"[..]));
2144 assert!(!head.is_unique());
2145 let mut rows = Buf::<u8, 2>::from_slice(&[1, 2, 3, 4, 5, 6], [2, 3]).unwrap();
2146 assert_eq!(rows.split_to(1).as_slice(), &[1, 2]);
2147 assert_eq!(rows.dim(), [2, 2]);
2148 }
2149
2150 #[test]
2151 #[should_panic(expected = "out of range")]
2152 fn slice_out_of_range() {
2153 Buf::<u8, 1>::from(vec![1, 2]).slice(1..3);
2154 }
2155
2156 #[test]
2158 fn scalar_mutation() {
2159 let mut scalar = Buf::<i32, 0>::from(1);
2160 scalar.make_mut().as_mut_slice()[0] = 2;
2161 assert_eq!(scalar.value(), 2);
2162 assert_eq!(BufMut::<i32, 0>::zeroed([]).freeze().value(), 0);
2163 }
2164
2165 #[test]
2168 fn scalar_extraction() {
2169 let values = Buf::<f64, 1>::from(vec![1.5, 2.5]);
2170 assert_eq!(values.slice(1..).into_scalar().unwrap().value(), 2.5);
2171 assert!(values.is_unique());
2172 assert!(values.clone().into_scalar().is_none());
2173 let strings = Buf::<str, 1>::from(&["ab", "cd"][..]);
2174 let scalar = strings.slice(1..).into_scalar().unwrap();
2175 assert_eq!(scalar.value(), "cd");
2176 assert!(!strings.is_unique());
2177 assert_eq!(strings.get_scalar([0]).unwrap().value(), "ab");
2178 assert!(strings.get_scalar([2]).is_none());
2179 let image = Buf::<u8, 2>::from_slice(&[1, 2, 3, 4, 5, 6], [2, 3]).unwrap();
2180 assert_eq!(image.get_scalar([1, 2]).unwrap().value(), 6);
2181 assert_eq!(Buf::<u16, 0>::from(7).get_scalar([]).unwrap().value(), 7);
2182 }
2183
2184 #[test]
2187 fn copy_on_write() {
2188 let mut values = Buf::<u16, 1>::from(vec![1, 2, 3, 4]);
2189 let part = values.slice(1..3);
2190 values.make_mut().as_mut_slice()[1] = 9;
2191 assert_eq!(values.as_slice(), &[1, 9, 3, 4]);
2192 assert_eq!(part.as_slice(), &[2, 3]);
2193 assert!(values.is_unique());
2194 let ptr = values.as_ptr();
2196 values.make_mut().as_mut_slice()[0] = 0;
2197 assert_eq!(values.as_ptr(), ptr);
2198 let rest = Buf::from(vec![0u16; 64]).slice(1..);
2200 let part = rest.slice(..2).into_mut();
2201 assert_ne!(part.as_ptr(), rest.as_ptr());
2202 assert!(part.capacity() < rest.len());
2203 }
2204
2205 #[test]
2208 fn copy_on_write_growth() {
2209 let mut buf = Buf::from(&b"head"[..]);
2210 let head = buf.clone();
2211 buf.make_mut().extend_from_slice(b" tail");
2212 assert_eq!((buf.as_slice(), head.as_slice()), (&b"head tail"[..], &b"head"[..]));
2213 }
2214
2215 #[test]
2217 fn growth() {
2218 let mut buf = BufMut::<u32, 1>::with_capacity(4);
2219 buf.extend_from_slice(&[1, 2]);
2220 buf.resize(5, 0);
2221 buf.extend_from_slice(&[7; 100]);
2222 buf.push(8);
2223 assert_eq!(buf.len(), 106);
2224 assert_eq!(buf.as_slice()[..6], [1, 2, 0, 0, 0, 7]);
2225 assert_eq!(buf.as_slice()[105], 8);
2226 buf.truncate(2);
2227 assert_eq!(buf.as_slice(), &[1, 2]);
2228 }
2229
2230 #[test]
2233 fn length() {
2234 let mut buf = BufMut::from(&[0xAA; 8][..]);
2235 buf.truncate(4);
2236 buf.set_len(12);
2237 assert_eq!(buf.as_slice(), [&[0xAA; 8][..], &[0; 4]].concat());
2238 buf.truncate(4);
2239 buf.resize(8, 0);
2240 assert_eq!(buf.as_slice(), [0xAA, 0xAA, 0xAA, 0xAA, 0, 0, 0, 0]);
2241 }
2242
2243 #[test]
2246 fn zero_resize() {
2247 let mut buf = BufMut::from(&[0xAAAAu16; 4][..]);
2248 buf.clear();
2249 buf.resize(100, 0);
2250 assert_eq!(buf.as_slice(), [0; 100]);
2251 buf.clear();
2252 buf.resize(2, 0xBBBB);
2253 buf.resize(3, 0);
2254 assert_eq!(buf.as_slice(), [0xBBBB, 0xBBBB, 0]);
2255 }
2256
2257 #[test]
2259 fn reservation() {
2260 let mut buf = BufMut::from(&[1u16, 2][..]);
2261 assert!(buf.try_reserve(usize::MAX).is_err());
2262 assert!(buf.try_reserve(isize::MAX as usize).is_err());
2263 assert_eq!(buf.as_slice(), [1, 2]);
2264 buf.reserve(64);
2265 assert!(buf.capacity() >= 66);
2266 }
2267
2268 #[test]
2271 fn recycling() {
2272 let mut buf = BufMut::from(&b"first"[..]);
2273 let ptr = buf.as_ptr();
2274 buf.clear();
2275 buf.extend_from_slice(b"second");
2276 assert_eq!(buf.as_ptr(), ptr);
2277
2278 let buf = buf.freeze();
2279 let first = Buf::<str, 0>::from_spans(buf.slice(..3), [0..3], []).unwrap();
2280 let buf = buf.try_into_mut().unwrap_err();
2281 drop(first);
2282 let mut buf = buf.try_into_mut().unwrap();
2283 buf.clear();
2284 assert_eq!(buf.as_ptr(), ptr);
2285 }
2286
2287 #[test]
2290 fn unique_buffer() {
2291 let buf = Buf::from(&[1u8, 2, 3][..]);
2292 let ptr = buf.as_ptr();
2293 let part = buf.slice(1..);
2294 let mut buf = buf.try_into_mut().unwrap_err();
2295 assert!(buf.get_mut().is_none());
2296 drop(part);
2297 buf.get_mut().unwrap().truncate(1);
2298 let buf = buf.try_into_mut().unwrap();
2299 assert_eq!(buf.as_ptr(), ptr);
2300 assert_eq!(buf.as_slice(), [1]);
2301 }
2302
2303 #[test]
2306 fn packed_cast() {
2307 let buf = Buf::<u32, 1>::from(vec![1, 2, 3, 4]).into_bytes();
2308 let aligned = buf.slice(8..).cast::<u32, 1>([2]).unwrap();
2309 assert_eq!(aligned.as_slice(), &[3, 4]);
2310 assert!(!aligned.is_unique());
2311 let unaligned = buf.slice(1..9).cast::<u32, 1>([2]).unwrap();
2312 assert!(unaligned.is_unique());
2313 let buf = buf.cast::<u32, 1>([3]).unwrap_err();
2316 assert!(buf.slice(..2).cast::<u16, 0>([]).unwrap().is_unique());
2318 let halves = aligned.cast::<u16, 2>([2, 2]).unwrap();
2320 assert_eq!(halves.cast::<u64, 0>([]).unwrap().value(), 3 | 4 << 32);
2321 }
2322
2323 #[test]
2326 fn storage_alignment() {
2327 let buf = Buf::from(&[0u8; 16][..]);
2328 assert_eq!(buf.as_ptr().addr() % ALIGN, 0);
2329 assert!(!buf.clone().cast::<f64, 1>([2]).unwrap().is_unique());
2330 }
2331
2332 #[test]
2334 fn invalid_values() {
2335 let buf = Buf::from(&[0u8, 1, 2][..]);
2336 assert!(buf.slice(..2).cast::<bool, 1>([2]).is_ok());
2337 assert!(buf.cast::<bool, 1>([3]).is_err());
2338 }
2339
2340 #[test]
2342 fn octets_round_trip() {
2343 let values = Buf::<u16, 1>::from(vec![1, 2]);
2344 assert_eq!(values.as_bytes(), [1u16.to_ne_bytes(), 2u16.to_ne_bytes()].concat());
2345 let buf = values.into_bytes();
2346 assert_eq!(buf.cast::<u16, 1>([2]).unwrap().as_slice(), &[1, 2]);
2347 }
2348
2349 #[test]
2350 fn strings() {
2351 let strings = Buf::<str, 1>::from(&["ab", "", "cde"][..]);
2352 assert_eq!(strings.get([2]), Some("cde"));
2353 assert_eq!(strings.iter().collect::<Vec<_>>(), ["ab", "", "cde"]);
2354 assert_eq!(strings.slice(1..).get([1]), Some("cde"));
2355 assert_eq!(Buf::<str, 0>::from("scalar").value(), "scalar");
2356 }
2357
2358 #[test]
2361 fn strings_from_iter() {
2362 let strings = Buf::<str, 1>::from_strs(["ab", "", "cde"].into_iter().filter(|_| true)).unwrap();
2363 assert_eq!(strings.dim(), [3]);
2364 assert_eq!(strings.iter().collect::<Vec<_>>(), ["ab", "", "cde"]);
2365 let empty = Buf::<str, 1>::from_strs(std::iter::empty::<&str>()).unwrap();
2366 assert!(empty.is_empty());
2367 }
2368
2369 #[test]
2372 fn string_spans() {
2373 let msg = Buf::from(&b"..hello world"[..]);
2374 let strings = Buf::<str, 1>::from_spans(msg.slice(2..), [0..5, 6..11], [2]).unwrap();
2375 drop(msg);
2376 assert_eq!(strings.iter().collect::<Vec<_>>(), ["hello", "world"]);
2377 let buf = Buf::from(&[b'a', 0xff][..]);
2379 let buf = Buf::<str, 1>::from_spans(buf, [0..3], [1]).unwrap_err();
2380 let buf = Buf::<str, 1>::from_spans(buf, [1..2], [1]).unwrap_err();
2381 #[allow(clippy::reversed_empty_ranges)]
2382 let buf = Buf::<str, 1>::from_spans(buf, [1..0], [1]).unwrap_err();
2383 assert!(Buf::<str, 0>::from_spans(buf, [0..1], []).is_ok());
2384 }
2385
2386 #[test]
2389 fn single_string() {
2390 let msg = Buf::from(&b"..hello world"[..]);
2391 let hello = Buf::<str, 0>::from_spans(msg.slice(2..), [0..5], []).unwrap();
2392 let world = Buf::<str, 1>::from_spans(msg.slice(2..), [6..11], [1]).unwrap();
2393 drop(msg);
2394 assert_eq!(hello.value(), "hello");
2395 assert_eq!(world.iter().collect::<Vec<_>>(), ["world"]);
2396 assert_eq!(world.get_scalar([0]).unwrap().value(), "world");
2397 assert!(world.slice(1..).is_empty());
2398 assert_eq!(world.slice(..1).reshape([1, 1]).unwrap().get([0, 0]), Some("world"));
2399 assert_eq!(world.into_scalar().unwrap().value(), "world");
2400 let buf = Buf::from(&b"ab"[..]);
2401 let buf = Buf::<str, 0>::from_spans(buf, [0..1, 1..2], []).unwrap_err();
2402 assert!(Buf::<str, 0>::from_spans(buf, [], []).is_err());
2403 let empty = Buf::<str, 0>::from("");
2404 assert_eq!(empty.value(), "");
2405 assert!(!empty.is_unique());
2406 }
2407
2408 #[test]
2411 fn span_iterator() {
2412 let msg = Buf::from(&b"a,bc,def"[..]);
2413 let spans = msg.as_slice().split(|&b| b == b',').scan(0, |start, part| {
2414 let span = *start..*start + part.len() as u32;
2415 *start = span.end + 1;
2416 Some(span)
2417 }).collect::<Vec<_>>();
2418 let strings = Buf::<str, 1>::from_spans(msg.clone(), spans.clone(), [3]).unwrap();
2419 assert_eq!(strings.iter().collect::<Vec<_>>(), ["a", "bc", "def"]);
2420 let msg = Buf::<str, 1>::from_spans(msg, spans.clone(), [2]).unwrap_err();
2421 let msg = Buf::<str, 1>::from_spans(msg, spans.clone(), [4]).unwrap_err();
2422 let msg = Buf::<str, 1>::from_spans(msg, spans.clone(), [usize::MAX]).unwrap_err();
2423 assert!(Buf::<str, 1>::from_spans(msg, [], [0]).is_ok());
2424 }
2425
2426 #[test]
2427 fn thread_sharing() {
2428 let values = Buf::<f64, 1>::from(vec![1.0, 2.0]);
2429 let sum = std::thread::spawn({
2430 let values = values.clone();
2431 move || values.iter().sum::<f64>()
2432 });
2433 assert_eq!(sum.join().unwrap(), 3.0);
2434 }
2435
2436 #[test]
2438 fn states() {
2439 let buf = Buf::from(&[DevState::Moving as u8, 200][..]);
2440 let buf = buf.cast::<DevState, 1>([2]).unwrap_err();
2441 assert_eq!(buf.slice(..1).cast::<DevState, 0>([]).unwrap().value(), DevState::Moving);
2442 }
2443
2444 #[test]
2446 fn equality() {
2447 let values = Buf::<i32, 1>::from([1, 2, 3, 4]);
2448 assert_eq!(values.slice(2..), Buf::from([3, 4]));
2449 assert_ne!(values.clone().reshape([2, 2]).unwrap(), Buf::from_slice(&[1, 2, 3, 4], [4, 1]).unwrap());
2450 }
2451
2452 #[test]
2454 fn debug() {
2455 assert_eq!(format!("{:?}", Buf::<u16, 1>::from([7; 3])), "Buf<3>[7, 7, 7]");
2456 assert_eq!(format!("{:?}", Buf::<u16, 0>::from(7)), "Buf(7)");
2457 let rows = Buf::<i32, 2>::from_slice(&[1, 2, 3, 4, 5, 6], [3, 2]).unwrap();
2458 assert_eq!(format!("{rows:?}"), "Buf<3, 2>[[1, 2, 3], [4, 5, 6]]");
2459 assert_eq!(format!("{rows:#?}"), "Buf<3, 2>[\n [1, 2, 3],\n [4, 5, 6],\n]");
2460 assert_eq!(format!("{:?}", BufMut::<u8, 2>::zeroed([2, 0])), "BufMut<2, 0>[]");
2461 assert_eq!(format!("{:?}", Buf::<u8, 2>::new().reshape([0, 2]).unwrap()), "Buf<0, 2>[[], []]");
2462 assert_eq!(format!("{:?}", Buf::<str, 1>::from(&["a", "b"][..])), r#"Buf<2>["a", "b"]"#);
2463 }
2464
2465 #[test]
2467 fn octets_debug() {
2468 assert_eq!(format!("{:?}", Buf::from(&b"\x01\x02GIOP\x00"[..])), "Buf<7>[01 02 'GIOP' 00]");
2469 assert_eq!(format!("{:?}", BufMut::<u8, 1>::from(vec![0xAB; 20])), format!("BufMut<20>[{}AB]", "AB ".repeat(19)));
2470 let rows = Buf::<u8, 2>::from_slice(b"ab\x01\x02", [2, 2]).unwrap();
2471 assert_eq!(format!("{rows:?}"), "Buf<2, 2>[['ab'], [01 02]]");
2472 }
2473
2474 #[test]
2477 fn hex() {
2478 let buf = Buf::from(&[0x01, 0xAB, 0x00][..]);
2479 assert_eq!(format!("{buf:X}"), "01AB00");
2480 assert_eq!(format!("{buf:x}"), "01ab00");
2481 assert_eq!(format!("{:X}", buf.clone().into_mut()), "01AB00");
2482 assert_eq!(BufMut::from_hex("01AB00").unwrap().freeze(), buf);
2483 assert_eq!(BufMut::from_hex("01ab00").unwrap().freeze(), buf);
2484 assert!(BufMut::from_hex("01A").is_none());
2485 assert!(BufMut::from_hex("0G").is_none());
2486 let words = Buf::<u16, 1>::from([0x0102, 0xABCD]);
2488 let expected = if cfg!(target_endian = "little") { "0201 cdab" } else { "0102 abcd" };
2489 assert_eq!(format!("{words:x}"), expected);
2490 assert_eq!(format!("{:X}", Buf::<u32, 1>::new()), "");
2491 }
2492
2493 #[test]
2496 fn sizes() {
2497 assert_eq!(mem::size_of::<Buf<f64, 0>>(), 16);
2498 assert_eq!(mem::size_of::<Buf<u8, 1>>(), 24);
2499 assert_eq!(mem::size_of::<Buf<f64, 2>>(), 32);
2500 assert_eq!(mem::size_of::<Buf<str, 1>>(), 32);
2501 assert_eq!(mem::size_of::<BufMut<u8, 1>>(), 24);
2502 }
2503
2504}