1use std::sync::atomic::{self, AtomicPtr, AtomicUsize, Ordering};
27use std::mem::{self, ManuallyDrop, MaybeUninit};
28use std::fmt::{self, Debug, LowerHex, UpperHex};
29use std::ops::{Bound, Range, RangeBounds};
30use std::alloc::{self, Layout};
31use std::ptr::{self, NonNull};
32use std::marker::PhantomData;
33use std::{slice, str};
34
35use crate::error::{Error, ErrorKind};
36use crate::value::DevEnum;
37use crate::dev::DevState;
38
39
40#[repr(C)]
47struct HeapHeader {
48 count: AtomicUsize,
50 cap: usize,
52 side: AtomicPtr<SideHeader>,
54}
55
56#[repr(C)]
60struct SideHeader {
61 next: *mut SideHeader,
63 size: usize,
65}
66
67const ALIGN: usize = 8;
70
71type AllocResult<T> = Result<T, Option<Layout>>;
74
75fn infallible<T>(res: AllocResult<T>) -> T {
78 match res {
79 Ok(value) => value,
80 Err(Some(layout)) => alloc::handle_alloc_error(layout),
81 Err(None) => panic!("capacity overflow"),
82 }
83}
84
85#[derive(Clone, Copy)]
88#[repr(transparent)]
89struct Heap(NonNull<HeapHeader>);
90
91#[repr(C, align(8))]
93struct EmptyHeapHeader(HeapHeader);
94
95static EMPTY_HEAP_HEADER: EmptyHeapHeader = EmptyHeapHeader(HeapHeader {
99 count: AtomicUsize::new(usize::MAX),
100 cap: 0,
101 side: AtomicPtr::new(ptr::null_mut()),
102});
103
104impl Heap {
105
106 const EMPTY: Self = Self(unsafe { NonNull::new_unchecked((&raw const EMPTY_HEAP_HEADER.0).cast_mut()) });
109
110 #[inline]
112 fn is_immortal(self) -> bool {
113 self.0 == Self::EMPTY.0
114 }
115
116 fn layout(cap: usize) -> Option<Layout> {
119 cap.checked_mul(ALIGN)
120 .and_then(|size| size.checked_add(mem::size_of::<HeapHeader>()))
121 .and_then(|size| Layout::from_size_align(size, ALIGN).ok())
122 }
123
124 fn alloc(len: usize) -> AllocResult<Self> {
129 let cap = len.div_ceil(ALIGN);
130 let layout = Self::layout(cap).ok_or(None)?;
131 let ptr = unsafe { alloc::alloc_zeroed(layout) };
133 let ptr = NonNull::new(ptr.cast::<HeapHeader>()).ok_or(Some(layout))?;
134 unsafe { ptr.write(HeapHeader { count: AtomicUsize::new(1), cap, side: AtomicPtr::new(ptr::null_mut()) }) };
136 Ok(Self(ptr))
137 }
138
139 #[inline]
141 fn data(self) -> *mut u8 {
142 unsafe { self.0.as_ptr().add(1).cast::<u8>() }
144 }
145
146 #[inline]
148 fn capacity(self) -> usize {
149 unsafe { (*self.0.as_ptr()).cap * ALIGN }
151 }
152
153 #[inline]
154 fn header(&self) -> &HeapHeader {
155 unsafe { self.0.as_ref() }
157 }
158
159 #[inline]
162 fn is_unique(self) -> bool {
163 self.header().count.load(Ordering::Acquire) == 1
164 }
165
166 #[inline]
168 fn acquire(self) {
169 if self.is_immortal() {
170 return;
171 }
172 let old = self.header().count.fetch_add(1, Ordering::Relaxed);
173 if old > isize::MAX as usize {
175 std::process::abort();
176 }
177 }
178
179 #[inline]
186 unsafe fn release(self) {
187 if self.is_immortal() || self.header().count.fetch_sub(1, Ordering::Release) != 1 {
188 return;
189 }
190 atomic::fence(Ordering::Acquire);
191 unsafe { self.free() }
193 }
194
195 #[cold]
196 unsafe fn free(self) {
197 let header = self.0.as_ptr();
198 unsafe {
200 self.free_sides();
201 alloc::dealloc(header.cast(), Self::layout((*header).cap).unwrap_unchecked());
202 }
203 }
204
205 fn side_layout(size: usize) -> Option<Layout> {
207 size.checked_add(mem::size_of::<SideHeader>())
208 .and_then(|size| Layout::from_size_align(size, ALIGN).ok())
209 }
210
211 fn push_side(self, side: DetachedSide) {
216 debug_assert!(!self.is_immortal(), "nothing is attached to the empty storage");
217 let side = ManuallyDrop::new(side).0;
218 let head = &self.header().side;
219 let mut next = head.load(Ordering::Relaxed);
220 loop {
221 unsafe { (*side.as_ptr()).next = next };
223 match head.compare_exchange_weak(next, side.as_ptr(), Ordering::Release, Ordering::Relaxed) {
224 Ok(_) => break,
225 Err(current) => next = current,
226 }
227 }
228 }
229
230 unsafe fn free_sides(self) {
237 let mut side = self.header().side.swap(ptr::null_mut(), Ordering::Relaxed);
238 while !side.is_null() {
239 unsafe {
242 let next = (*side).next;
243 alloc::dealloc(side.cast(), Self::side_layout((*side).size).unwrap_unchecked());
244 side = next;
245 }
246 }
247 }
248
249 #[cold]
259 unsafe fn grow(&mut self, capacity: usize) -> AllocResult<()> {
260 let old_cap = self.header().cap;
261 let cap = capacity.div_ceil(ALIGN).max(old_cap * 2);
262 let old_layout = unsafe { Self::layout(old_cap).unwrap_unchecked() };
264 let new_layout = Self::layout(cap).ok_or(None)?;
265 let ptr = unsafe { alloc::realloc(self.0.as_ptr().cast(), old_layout, new_layout.size()) };
267 self.0 = NonNull::new(ptr.cast::<HeapHeader>()).ok_or(Some(new_layout))?;
268 unsafe {
270 (*self.0.as_ptr()).cap = cap;
271 self.data().add(old_cap * ALIGN).write_bytes(0, (cap - old_cap) * ALIGN);
272 }
273 Ok(())
274 }
275
276}
277
278struct DetachedSide(NonNull<SideHeader>);
282
283impl DetachedSide {
284
285 fn new(size: usize) -> AllocResult<Self> {
288 let layout = Heap::side_layout(size).ok_or(None)?;
289 let side = NonNull::new(unsafe { alloc::alloc(layout) }.cast::<SideHeader>()).ok_or(Some(layout))?;
291 unsafe { side.write(SideHeader { next: ptr::null_mut(), size }) };
293 Ok(Self(side))
294 }
295
296 #[inline]
298 fn payload(&self) -> NonNull<u8> {
299 unsafe { self.0.add(1).cast::<u8>() }
301 }
302
303}
304
305impl Drop for DetachedSide {
306 fn drop(&mut self) {
307 unsafe { alloc::dealloc(self.0.as_ptr().cast(), Heap::side_layout((*self.0.as_ptr()).size).unwrap_unchecked()) }
310 }
311}
312
313struct HeapRef {
316 inner: Heap,
318 offset: usize,
320}
321
322impl HeapRef {
323
324 const EMPTY: Self = Self {
326 inner: Heap::EMPTY,
327 offset: 0,
328 };
329
330 fn copy(bytes: &[u8], capacity: usize) -> AllocResult<Self> {
332 let storage = Heap::alloc(bytes.len().max(capacity))?;
333 unsafe { ptr::copy_nonoverlapping(bytes.as_ptr(), storage.data(), bytes.len()) };
335 Ok(Self { inner: storage, offset: 0 })
336 }
337
338 #[inline]
340 fn ptr(&self) -> *mut u8 {
341 unsafe { self.inner.data().add(self.offset) }
343 }
344
345 #[inline]
347 fn clone_at(&self, count: usize) -> Self {
348 self.inner.acquire();
349 Self { inner: self.inner, offset: self.offset + count }
350 }
351
352 #[inline]
353 fn is_unique(&self) -> bool {
354 self.inner.is_unique()
355 }
356
357 #[inline]
361 fn is_writable(&self) -> bool {
362 self.inner.is_immortal() || self.inner.is_unique()
363 }
364
365}
366
367impl Clone for HeapRef {
368 #[inline]
369 fn clone(&self) -> Self {
370 self.clone_at(0)
371 }
372}
373
374impl Drop for HeapRef {
375 #[inline]
376 fn drop(&mut self) {
377 unsafe { self.inner.release() }
379 }
380}
381
382
383pub unsafe trait Spans: Copy + Send + Sync + 'static {
394
395 const EMPTY: Self;
397
398 unsafe fn span(self, index: usize) -> (usize, usize);
405
406 unsafe fn advance(self, count: usize) -> (usize, Self);
413
414}
415
416pub struct PackedSpans<T>(PhantomData<fn() -> T>);
419
420impl<T> PackedSpans<T> {
421 #[inline]
422 const fn new() -> Self {
423 Self(PhantomData)
424 }
425}
426
427impl<T> Clone for PackedSpans<T> {
428 #[inline]
429 fn clone(&self) -> Self {
430 *self
431 }
432}
433
434impl<T> Copy for PackedSpans<T> {}
435
436unsafe impl<T: 'static> Spans for PackedSpans<T> {
438
439 const EMPTY: Self = Self::new();
440
441 #[inline]
442 unsafe fn span(self, index: usize) -> (usize, usize) {
443 (index * mem::size_of::<T>(), mem::size_of::<T>())
444 }
445
446 #[inline]
447 unsafe fn advance(self, count: usize) -> (usize, Self) {
448 (count * mem::size_of::<T>(), self)
449 }
450
451}
452
453#[derive(Clone, Copy)]
458pub struct TableSpans(NonNull<Range<u32>>);
459
460unsafe impl Send for TableSpans {}
462unsafe impl Sync for TableSpans {}
463
464unsafe impl Spans for TableSpans {
466
467 const EMPTY: Self = Self(NonNull::dangling());
468
469 #[inline]
470 unsafe fn span(self, index: usize) -> (usize, usize) {
471 let Range { start, end } = unsafe { self.0.add(index).read() };
474 (start as usize, (end - start) as usize)
475 }
476
477 #[inline]
478 unsafe fn advance(self, count: usize) -> (usize, Self) {
479 (0, Self(unsafe { self.0.add(count) }))
481 }
482
483}
484
485
486pub unsafe trait Element: Send + Sync + 'static {
500
501 type Ref<'a>: Copy + Debug;
503
504 type Spans: Spans;
506
507 const INLINE_FIXED: bool;
510
511 fn validate(bytes: &[u8]) -> bool;
513
514 unsafe fn read<'a>(ptr: *const u8, len: usize) -> Self::Ref<'a>
521 where
522 Self: 'a;
523
524 fn fmt_row<'a, I>(values: I, f: &mut fmt::Formatter<'_>) -> fmt::Result
527 where
528 I: Iterator<Item = Self::Ref<'a>>,
529 Self: 'a,
530 {
531 for (index, value) in values.enumerate() {
532 if index != 0 {
533 f.write_str(", ")?;
534 }
535 Debug::fmt(&value, f)?;
536 }
537 Ok(())
538 }
539
540}
541
542pub unsafe trait PackedElement: Element<Spans = PackedSpans<Self>> + Copy {
552
553 fn validate_all(bytes: &[u8]) -> bool;
557
558}
559
560const fn inline_fixed<T>() -> bool {
562 assert!(mem::size_of::<T>() > 0, "a packed type is not zero-sized");
563 assert!(mem::size_of::<T>() <= mem::size_of::<Repr>(), "a packed type fits in place of a storage");
564 assert!(mem::align_of::<T>() <= ALIGN, "a packed type is aligned on at most 8 octets");
565 true
566}
567
568macro_rules! impl_packed_element {
571 ($($ty:ty $(where |$octet:ident| $valid:expr)? $(, debug $debug:path)?);* $(;)?) => { $(
572 unsafe impl Element for $ty {
574
575 type Ref<'a> = $ty;
576 type Spans = PackedSpans<$ty>;
577
578 const INLINE_FIXED: bool = inline_fixed::<$ty>();
579
580 #[inline]
581 fn validate(bytes: &[u8]) -> bool {
582 bytes.len() == mem::size_of::<$ty>() && Self::validate_all(bytes)
583 }
584
585 #[inline]
586 unsafe fn read<'a>(ptr: *const u8, _len: usize) -> $ty
587 where
588 $ty: 'a,
589 {
590 unsafe { ptr.cast::<$ty>().read() }
592 }
593
594 $(
595 #[inline]
596 fn fmt_row<'a, I>(values: I, f: &mut fmt::Formatter<'_>) -> fmt::Result
597 where
598 I: Iterator<Item = $ty>,
599 $ty: 'a,
600 {
601 $debug(values, f)
602 }
603 )?
604
605 }
606
607 unsafe impl PackedElement for $ty {
609 #[inline]
610 fn validate_all(_bytes: &[u8]) -> bool {
611 true $(&& _bytes.iter().all(|&$octet| $valid))?
612 }
613 }
614 )* };
615}
616
617impl_packed_element!(
618 u8, debug fmt_octets;
619 i8; u16; i16; u32; i32; u64; i64; f32; f64; DevEnum;
620 bool where |octet| octet <= 1;
621 DevState where |octet| octet <= DevState::Unknown as u8;
622);
623
624fn fmt_octets(octets: impl Iterator<Item = u8>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
627
628 let mut ascii = false;
629
630 for (index, byte) in octets.enumerate() {
631
632 if index != 0 && !ascii {
633 f.write_str(" ")?;
634 }
635
636 if byte.is_ascii_alphanumeric() || matches!(byte, b' ' | b':' | b'/' | b'.' | b'-' | b'_') {
637 if !ascii {
638 f.write_str("'")?;
639 ascii = true;
640 }
641 write!(f, "{}", byte as char)?;
642 } else {
643 if ascii {
644 f.write_str("' ")?;
645 ascii = false;
646 }
647 write!(f, "{byte:02X}")?;
648 }
649
650 }
651
652 if ascii {
653 f.write_str("'")?;
654 }
655
656 Ok(())
657
658}
659
660fn fmt_hex<T: PackedElement>(octets: &[u8], f: &mut fmt::Formatter<'_>, upper: bool) -> fmt::Result {
664 let size = mem::size_of::<T>();
665 for (index, &byte) in octets.iter().enumerate() {
666 if size > 1 && index != 0 && index % size == 0 {
667 f.write_str(" ")?;
668 }
669 if upper { write!(f, "{byte:02X}")? } else { write!(f, "{byte:02x}")? }
670 }
671 Ok(())
672}
673
674unsafe impl Element for str {
676
677 type Ref<'a> = &'a str;
678 type Spans = TableSpans;
679
680 const INLINE_FIXED: bool = false;
681
682 #[inline]
683 fn validate(bytes: &[u8]) -> bool {
684 str::from_utf8(bytes).is_ok()
685 }
686
687 #[inline]
688 unsafe fn read<'a>(ptr: *const u8, len: usize) -> &'a str
689 where
690 str: 'a,
691 {
692 unsafe { str::from_utf8_unchecked(slice::from_raw_parts(ptr, len)) }
694 }
695
696}
697
698
699#[repr(C)]
706union Repr {
707 raw: ManuallyDrop<HeapRef>,
708 inline: [MaybeUninit<u64>; mem::size_of::<HeapRef>() / 8],
709}
710
711pub struct Buf<T: Element + ?Sized, const DIM: usize> {
719 repr: Repr,
720 spans: T::Spans,
721 dim: [usize; DIM],
722 _t: PhantomData<*const T>,
723}
724
725unsafe impl<T: Element + ?Sized, const DIM: usize> Send for Buf<T, DIM> {}
728unsafe impl<T: Element + ?Sized, const DIM: usize> Sync for Buf<T, DIM> {}
729
730#[inline]
732fn checked_len(dim: &[usize]) -> Option<usize> {
733 dim.iter().try_fold(1usize, |len, &d| len.checked_mul(d))
734}
735
736#[track_caller]
738fn range_bounds<R: RangeBounds<usize>>(range: R, len: usize) -> Range<usize> {
739 let start = match range.start_bound() {
740 Bound::Included(&start) => start,
741 Bound::Excluded(&start) => start.checked_add(1).expect("range start overflow"),
742 Bound::Unbounded => 0,
743 };
744 let end = match range.end_bound() {
745 Bound::Included(&end) => end.checked_add(1).expect("range end overflow"),
746 Bound::Excluded(&end) => end,
747 Bound::Unbounded => len,
748 };
749 assert!(start <= end, "slice index starts at {start} but ends at {end}");
750 assert!(end <= len, "range end index {end} out of range for length {len}");
751 start..end
752}
753
754
755impl<T: Element + ?Sized, const DIM: usize> Buf<T, DIM> {
756
757 const INLINE: bool = DIM == 0 && T::INLINE_FIXED;
760
761 #[inline]
764 pub const fn new() -> Self {
765 const { assert!(DIM >= 1, "a scalar always holds one value") };
766 let raw = ManuallyDrop::new(HeapRef::EMPTY);
767 Self {
768 repr: Repr { raw },
769 spans: T::Spans::EMPTY,
770 dim: [0; DIM],
771 _t: PhantomData,
772 }
773 }
774
775 #[inline]
782 unsafe fn from_raw(raw: HeapRef, spans: T::Spans, dim: [usize; DIM]) -> Self {
783 debug_assert!(!Self::INLINE);
784 Self {
785 repr: Repr { raw: ManuallyDrop::new(raw) },
786 spans,
787 dim,
788 _t: PhantomData,
789 }
790 }
791
792 #[inline]
794 fn raw(&self) -> &HeapRef {
795 debug_assert!(!Self::INLINE);
796 unsafe { &self.repr.raw }
798 }
799
800 #[inline]
802 fn raw_mut(&mut self) -> &mut HeapRef {
803 debug_assert!(!Self::INLINE);
804 unsafe { &mut self.repr.raw }
806 }
807
808 #[inline]
811 fn into_raw(self) -> HeapRef {
812 let this = ManuallyDrop::new(self);
813 unsafe { ptr::read(this.raw()) }
815 }
816
817 #[inline]
819 fn base(&self) -> *const u8 {
820 if Self::INLINE {
821 ptr::addr_of!(self.repr).cast::<u8>()
822 } else {
823 self.raw().ptr()
824 }
825 }
826
827 #[inline]
830 fn base_mut(&mut self) -> *mut u8 {
831 if Self::INLINE {
832 ptr::addr_of_mut!(self.repr).cast::<u8>()
833 } else {
834 self.raw().ptr()
835 }
836 }
837
838 #[inline]
844 unsafe fn read(&self, index: usize) -> T::Ref<'_> {
845 unsafe {
847 let (offset, len) = self.spans.span(index);
848 T::read(self.base().add(offset), len)
849 }
850 }
851
852 #[inline]
854 pub fn dim(&self) -> [usize; DIM] {
855 self.dim
856 }
857
858 #[inline]
860 pub fn len(&self) -> usize {
861 self.dim.iter().product()
862 }
863
864 #[inline]
865 pub fn is_empty(&self) -> bool {
866 self.len() == 0
867 }
868
869 #[inline]
873 pub fn raw_index(&self, pos: [usize; DIM]) -> Option<usize> {
874 let mut index = 0;
875 let mut stride = 1;
876 for (&coord, &dim) in pos.iter().zip(&self.dim) {
877 if coord >= dim {
878 return None;
879 }
880 index += coord * stride;
881 stride *= dim;
882 }
883 Some(index)
884 }
885
886 #[inline]
890 pub fn get(&self, pos: [usize; DIM]) -> Option<T::Ref<'_>> {
891 let index = self.raw_index(pos)?;
892 Some(unsafe { self.read(index) })
894 }
895
896 pub fn get_scalar(&self, pos: [usize; DIM]) -> Option<Buf<T, 0>> {
900
901 let index = self.raw_index(pos)?;
902
903 if Buf::<T, 0>::INLINE {
904 let mut repr = Repr { inline: [MaybeUninit::uninit(); _] };
905 unsafe {
908 let (offset, len) = self.spans.span(index);
909 ptr::copy_nonoverlapping(self.base().add(offset), ptr::addr_of_mut!(repr).cast::<u8>(), len);
910 }
911 Some(Buf { repr, spans: self.spans, dim: [], _t: PhantomData })
912 } else {
913 unsafe {
917 let (octets, spans) = self.spans.advance(index);
918 Some(Buf::from_raw(self.raw().clone_at(octets), spans, []))
919 }
920 }
921
922 }
923
924 #[inline]
927 pub fn get_raw(&self, index: usize) -> Option<T::Ref<'_>> {
928 (index < self.len()).then(|| unsafe { self.read(index) })
930 }
931
932 #[inline]
934 pub fn iter(&self) -> impl ExactSizeIterator<Item = T::Ref<'_>> + '_ {
935 (0..self.len()).map(move |index| unsafe { self.read(index) })
937 }
938
939 #[track_caller]
947 pub fn slice<R: RangeBounds<usize>>(&self, range: R) -> Self {
948
949 const { assert!(DIM >= 1, "a scalar cannot be sliced") };
950 let Range { start, end } = range_bounds(range, self.dim[DIM - 1]);
951
952 let stride: usize = self.dim[..DIM - 1].iter().product();
953
954 let (octets, spans) = unsafe { self.spans.advance(start * stride) };
956 let mut dim = self.dim;
957 dim[DIM - 1] = end - start;
958
959 unsafe { Self::from_raw(self.raw().clone_at(octets), spans, dim) }
962
963 }
964
965 #[track_caller]
974 pub fn split_to(&mut self, at: usize) -> Self {
975 let front = self.slice(..at);
976 *self = self.slice(at..);
977 front
978 }
979
980 #[track_caller]
987 pub fn split_off(&mut self, at: usize) -> Self {
988 let back = self.slice(at..);
989 *self = self.slice(..at);
990 back
991 }
992
993 pub fn reshape<const D: usize>(self, dim: [usize; D]) -> Option<Buf<T, D>> {
998 if checked_len(&dim)? != self.len() {
999 return None;
1000 }
1001 let spans = self.spans;
1002 Some(match (Self::INLINE, Buf::<T, D>::INLINE) {
1004 (false, false) => unsafe { Buf::from_raw(self.into_raw(), spans, dim) },
1005 (true, true) => Buf { repr: Repr { inline: unsafe { self.repr.inline } }, spans, dim, _t: PhantomData },
1007 (true, false) => unsafe {
1008 let (offset, len) = spans.span(0);
1009 let bytes = slice::from_raw_parts(self.base().add(offset), len);
1010 Buf::from_raw(infallible(HeapRef::copy(bytes, len)), spans, dim)
1011 },
1012 (false, true) => {
1013 let raw = self.into_raw();
1014 let mut repr = Repr { inline: [MaybeUninit::uninit(); _] };
1015 unsafe {
1018 let (offset, len) = spans.span(0);
1019 ptr::copy_nonoverlapping(raw.ptr().add(offset), ptr::addr_of_mut!(repr).cast::<u8>(), len);
1020 }
1021 Buf { repr, spans, dim, _t: PhantomData }
1022 }
1023 })
1024 }
1025
1026 #[inline]
1029 pub fn into_scalar(self) -> Option<Buf<T, 0>> {
1030 self.reshape([])
1031 }
1032
1033 #[inline]
1036 pub fn is_unique(&self) -> bool {
1037 Self::INLINE || self.raw().is_unique()
1038 }
1039
1040 #[inline]
1042 fn is_writable(&self) -> bool {
1043 Self::INLINE || self.raw().is_writable()
1044 }
1045
1046}
1047
1048impl<T: Element + ?Sized> Buf<T, 1> {
1049
1050 #[inline]
1052 pub fn truncate(&mut self, len: usize) {
1053 self.dim[0] = self.dim[0].min(len);
1054 }
1055
1056}
1057
1058impl<T: Element + ?Sized> Buf<T, 0> {
1059
1060 #[inline]
1062 pub fn value(&self) -> T::Ref<'_> {
1063 unsafe { self.read(0) }
1065 }
1066
1067}
1068
1069impl<T: Element + ?Sized, const DIM: usize> Clone for Buf<T, DIM> {
1072 #[inline]
1073 fn clone(&self) -> Self {
1074 let repr = if Self::INLINE {
1075 Repr { inline: unsafe { self.repr.inline } }
1077 } else {
1078 Repr { raw: ManuallyDrop::new(self.raw().clone()) }
1079 };
1080 Self { repr, spans: self.spans, dim: self.dim, _t: PhantomData }
1081 }
1082}
1083
1084impl<T: Element + ?Sized, const DIM: usize> Drop for Buf<T, DIM> {
1085 #[inline]
1086 fn drop(&mut self) {
1087 if !Self::INLINE {
1088 unsafe { ManuallyDrop::drop(&mut self.repr.raw) }
1090 }
1091 }
1092}
1093
1094impl<T: Element + ?Sized, const DIM: usize> Default for Buf<T, DIM> {
1095 #[inline]
1097 fn default() -> Self {
1098 Self::new()
1099 }
1100}
1101
1102impl<T: Element + ?Sized, const DIM: usize> PartialEq for Buf<T, DIM>
1103where
1104 for<'a> T::Ref<'a>: PartialEq,
1105{
1106 fn eq(&self, other: &Self) -> bool {
1109 self.dim == other.dim && self.iter().eq(other.iter())
1110 }
1111}
1112
1113impl<T: Element + ?Sized, const DIM: usize> Eq for Buf<T, DIM>
1114where
1115 for<'a> T::Ref<'a>: Eq,
1116{}
1117
1118fn fmt_buf<'a, T, I>(f: &mut fmt::Formatter<'_>, name: &str, dim: &[usize], mut values: I) -> fmt::Result
1124where
1125 T: Element + ?Sized + 'a,
1126 I: Iterator<Item = T::Ref<'a>>,
1127{
1128 f.write_str(name)?;
1129 if dim.is_empty() {
1130 f.write_str("(")?;
1131 T::fmt_row(values, f)?;
1132 return f.write_str(")");
1133 }
1134 f.write_str("<")?;
1135 for (index, d) in dim.iter().enumerate() {
1136 if index != 0 {
1137 f.write_str(", ")?;
1138 }
1139 write!(f, "{d}")?;
1140 }
1141 f.write_str(">")?;
1142 fmt_level::<T, I>(f, dim, 0, &mut values)
1143}
1144
1145fn fmt_level<'a, T, I>(f: &mut fmt::Formatter<'_>, dim: &[usize], depth: usize, values: &mut I) -> fmt::Result
1147where
1148 T: Element + ?Sized + 'a,
1149 I: Iterator<Item = T::Ref<'a>>,
1150{
1151 const INDENT: usize = 4;
1152 let (&len, inner) = dim.split_last().expect("at least one dimension");
1153 f.write_str("[")?;
1154 if inner.is_empty() {
1155 T::fmt_row(values.by_ref().take(len), f)?;
1156 } else {
1157 let pretty = f.alternate();
1158 for index in 0..len {
1159 if pretty {
1160 write!(f, "\n{:1$}", "", (depth + 1) * INDENT)?;
1161 } else if index != 0 {
1162 f.write_str(", ")?;
1163 }
1164 fmt_level::<T, I>(f, inner, depth + 1, values)?;
1165 if pretty {
1166 f.write_str(",")?;
1167 }
1168 }
1169 if pretty && len != 0 {
1170 write!(f, "\n{:1$}", "", depth * INDENT)?;
1171 }
1172 }
1173 f.write_str("]")
1174}
1175
1176impl<T: Element + ?Sized, const DIM: usize> Debug for Buf<T, DIM> {
1177 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1179 fmt_buf::<T, _>(f, "Buf", &self.dim, self.iter())
1180 }
1181}
1182
1183impl<T: PackedElement> UpperHex for Buf<T, 1> {
1184 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1188 fmt_hex::<T>(self.as_bytes(), f, true)
1189 }
1190}
1191
1192impl<T: PackedElement> LowerHex for Buf<T, 1> {
1193 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1197 fmt_hex::<T>(self.as_bytes(), f, false)
1198 }
1199}
1200
1201impl<T: PackedElement, const DIM: usize> Buf<T, DIM> {
1204
1205 #[inline]
1209 fn check_packed(bytes: &[u8], dim: [usize; DIM]) -> Option<bool> {
1210 let size = checked_len(&dim)?.checked_mul(mem::size_of::<T>())?;
1211 if bytes.len() != size || !T::validate_all(bytes) {
1212 return None;
1213 }
1214 Some(!Self::INLINE && bytes.as_ptr().addr() % mem::align_of::<T>() == 0)
1215 }
1216
1217 unsafe fn copy_from_bytes(bytes: &[u8], dim: [usize; DIM]) -> Self {
1224 if Self::INLINE {
1225 let mut repr = Repr { inline: [MaybeUninit::uninit(); _] };
1226 unsafe { ptr::copy_nonoverlapping(bytes.as_ptr(), ptr::addr_of_mut!(repr).cast::<u8>(), bytes.len()) };
1228 Self { repr, spans: PackedSpans::new(), dim, _t: PhantomData }
1229 } else if bytes.is_empty() {
1230 unsafe { Self::from_raw(HeapRef::EMPTY, PackedSpans::new(), dim) }
1232 } else {
1233 unsafe { Self::from_raw(infallible(HeapRef::copy(bytes, bytes.len())), PackedSpans::new(), dim) }
1235 }
1236 }
1237
1238 pub fn from_slice(values: &[T], dim: [usize; DIM]) -> Option<Self> {
1242 if checked_len(&dim)? != values.len() {
1243 return None;
1244 }
1245 let bytes = unsafe { slice::from_raw_parts(values.as_ptr().cast::<u8>(), mem::size_of_val(values)) };
1247 Some(unsafe { Self::copy_from_bytes(bytes, dim) })
1249 }
1250
1251 #[inline]
1253 pub fn zeroed(dim: [usize; DIM]) -> Self {
1254 BufMut::zeroed(dim).freeze()
1255 }
1256
1257 #[inline]
1259 pub fn as_ptr(&self) -> *const T {
1260 self.base().cast::<T>()
1261 }
1262
1263 #[inline]
1265 pub fn as_slice(&self) -> &[T] {
1266 unsafe { slice::from_raw_parts(self.as_ptr(), self.len()) }
1268 }
1269
1270 #[inline]
1272 pub fn as_bytes(&self) -> &[u8] {
1273 unsafe { slice::from_raw_parts(self.base(), self.len() * mem::size_of::<T>()) }
1275 }
1276
1277 pub fn cast<U: PackedElement, const D: usize>(self, dim: [usize; D]) -> Result<Buf<U, D>, Self> {
1285
1286 let Some(share) = Buf::<U, D>::check_packed(self.as_bytes(), dim) else {
1287 return Err(self);
1288 };
1289
1290 Ok(unsafe {
1292 if share && !Self::INLINE {
1293 Buf::from_raw(self.into_raw(), PackedSpans::new(), dim)
1294 } else {
1295 Buf::copy_from_bytes(self.as_bytes(), dim)
1296 }
1297 })
1298
1299 }
1300
1301 pub fn into_bytes(self) -> Buf<u8, 1> {
1303 let len = self.as_bytes().len();
1304 match self.cast([len]) {
1305 Ok(bytes) => bytes,
1306 Err(_) => unreachable!("every octet is a valid one"),
1307 }
1308 }
1309
1310 #[inline]
1313 pub fn get_mut(&mut self) -> Option<&mut BufMut<T, DIM>> {
1314 self.is_writable().then(|| unsafe { &mut *(self as *mut Self).cast::<BufMut<T, DIM>>() })
1317 }
1318
1319 #[inline]
1323 pub fn make_mut(&mut self) -> &mut BufMut<T, DIM> {
1324 if !self.is_writable() {
1325 *self = unsafe { Self::copy_from_bytes(self.as_bytes(), self.dim) };
1327 }
1328 unsafe { &mut *(self as *mut Self).cast::<BufMut<T, DIM>>() }
1330 }
1331
1332 #[inline]
1335 pub fn try_into_mut(self) -> Result<BufMut<T, DIM>, Self> {
1336 if self.is_writable() {
1337 Ok(BufMut(self))
1338 } else {
1339 Err(self)
1340 }
1341 }
1342
1343 #[inline]
1347 pub fn into_mut(mut self) -> BufMut<T, DIM> {
1348 self.make_mut();
1349 BufMut(self)
1350 }
1351
1352 #[track_caller]
1361 pub fn slice_ref(&self, subset: &[T]) -> Self {
1362
1363 const { assert!(DIM >= 1, "a scalar cannot be sliced") };
1364
1365 let size = mem::size_of::<T>();
1366 let offset = subset.as_ptr().addr().wrapping_sub(self.base().addr());
1367 let (start, len) = (offset / size, self.len());
1368
1369 assert!(offset % size == 0 && start <= len && subset.len() <= len - start,
1370 "the values at {:p} are not within the buffer at {:p}, of {len} values",
1371 subset.as_ptr(),
1372 self.base());
1373
1374 let stride: usize = self.dim[..DIM - 1].iter().product();
1375 if stride == 0 {
1376 return self.slice(..0);
1377 }
1378
1379 assert!(start % stride == 0 && subset.len() % stride == 0,
1380 "the values {start}..{} are not whole rows of {stride} values",
1381 start + subset.len());
1382
1383 self.slice(start / stride..(start + subset.len()) / stride)
1384
1385 }
1386
1387}
1388
1389impl<T: PackedElement> From<T> for Buf<T, 0> {
1390 #[inline]
1392 fn from(value: T) -> Self {
1393 Self::from_slice(slice::from_ref(&value), []).expect("a scalar holds one value")
1394 }
1395}
1396
1397impl<T: PackedElement> From<&[T]> for Buf<T, 1> {
1398 #[inline]
1399 fn from(values: &[T]) -> Self {
1400 Self::from_slice(values, [values.len()]).expect("same length")
1401 }
1402}
1403
1404impl<T: PackedElement> From<Vec<T>> for Buf<T, 1> {
1405 #[inline]
1406 fn from(values: Vec<T>) -> Self {
1407 Self::from(values.as_slice())
1408 }
1409}
1410
1411impl<T: PackedElement> From<Box<[T]>> for Buf<T, 1> {
1412 #[inline]
1413 fn from(values: Box<[T]>) -> Self {
1414 Self::from(&*values)
1415 }
1416}
1417
1418impl<T: PackedElement, const N: usize> From<[T; N]> for Buf<T, 1> {
1419 #[inline]
1420 fn from(values: [T; N]) -> Self {
1421 Self::from(values.as_slice())
1422 }
1423}
1424
1425impl<T: PackedElement, const DIM: usize> From<BufMut<T, DIM>> for Buf<T, DIM> {
1426 #[inline]
1427 fn from(buf: BufMut<T, DIM>) -> Self {
1428 buf.freeze()
1429 }
1430}
1431
1432impl<T: Element<Spans = TableSpans> + ?Sized, const DIM: usize> Buf<T, DIM> {
1435
1436 fn with_spans<I, F>(bytes: Buf<u8, 1>, spans: I, dim: [usize; DIM], mut check: F) -> Result<Self, Buf<u8, 1>>
1442 where
1443 I: IntoIterator<Item = Range<u32>>,
1444 F: FnMut(&[u8], &Range<u32>) -> bool,
1445 {
1446
1447 let Some(len) = checked_len(&dim) else {
1448 return Err(bytes);
1449 };
1450
1451 let mut spans = spans.into_iter();
1452
1453 if len == 0 {
1454 if spans.next().is_some() {
1455 return Err(bytes);
1456 }
1457 return Ok(unsafe { Self::from_raw(bytes.into_raw(), TableSpans::EMPTY, dim) });
1459 }
1460
1461 let Some(size) = len.checked_mul(mem::size_of::<Range<u32>>()) else {
1462 return Err(bytes);
1463 };
1464
1465 let Ok(side) = DetachedSide::new(size) else {
1466 return Err(bytes);
1467 };
1468
1469 let table = side.payload().cast::<Range<u32>>();
1470 for index in 0..len {
1471 let Some(span) = spans.next().filter(|span| check(bytes.as_slice(), span)) else {
1472 return Err(bytes);
1473 };
1474 unsafe { table.add(index).write(span) };
1476 }
1477
1478 if spans.next().is_some() {
1479 return Err(bytes);
1480 }
1481
1482 let mut raw = bytes.into_raw();
1483 if raw.inner.is_immortal() {
1486 raw = HeapRef { inner: infallible(Heap::alloc(0)), offset: 0 };
1487 }
1488 raw.inner.push_side(side);
1489
1490 Ok(unsafe { Self::from_raw(raw, TableSpans(table), dim) })
1492
1493 }
1494
1495}
1496
1497impl<const DIM: usize> Buf<str, DIM> {
1498
1499 pub fn from_spans<I>(bytes: Buf<u8, 1>, spans: I, dim: [usize; DIM]) -> Result<Self, Buf<u8, 1>>
1506 where
1507 I: IntoIterator<Item = Range<u32>>,
1508 {
1509 Self::with_spans(bytes, spans, dim, |bytes, span| {
1510 bytes.get(span.start as usize..span.end as usize).is_some_and(str::validate)
1511 })
1512 }
1513
1514 #[inline]
1526 #[track_caller]
1527 pub unsafe fn from_spans_unchecked<I>(bytes: Buf<u8, 1>, spans: I, dim: [usize; DIM]) -> Self
1528 where
1529 I: IntoIterator<Item = Range<u32>>,
1530 {
1531 Self::with_spans(bytes, spans, dim, |_, _| true)
1532 .unwrap_or_else(|_| panic!("no table of as many spans as the dimensions {dim:?} say"))
1533 }
1534
1535}
1536
1537impl Buf<str, 1> {
1538
1539 pub fn from_strs<I>(values: I) -> Option<Self>
1542 where
1543 I: IntoIterator,
1544 I::Item: AsRef<str>,
1545 {
1546
1547 let mut buf = BufMut::<u8, 1>::new();
1548 let mut spans = Vec::new();
1549
1550 let values = values.into_iter();
1553 spans.reserve(values.size_hint().0);
1554
1555 for value in values {
1556 let start = u32::try_from(buf.len()).ok()?;
1557 buf.extend_from_slice(value.as_ref().as_bytes());
1558 spans.push(start..u32::try_from(buf.len()).ok()?);
1559 }
1560
1561 let len = spans.len();
1562 if len == 0 {
1563 return Some(unsafe { Self::from_raw(HeapRef::EMPTY, TableSpans::EMPTY, [0]) });
1565 }
1566
1567 Some(unsafe { Self::from_spans_unchecked(buf.freeze(), spans, [len]) })
1570
1571 }
1572
1573}
1574
1575impl From<&str> for Buf<str, 0> {
1576 #[inline]
1578 fn from(value: &str) -> Self {
1579 Buf::<str, 1>::from_strs([value])
1580 .and_then(Buf::into_scalar)
1581 .expect("a string of more than 4 GiB")
1582 }
1583}
1584
1585impl<S: AsRef<str>> From<&[S]> for Buf<str, 1> {
1586 #[inline]
1587 fn from(values: &[S]) -> Self {
1588 Self::from_strs(values).expect("strings of more than 4 GiB")
1589 }
1590}
1591
1592
1593#[repr(transparent)]
1606pub struct BufMut<T: PackedElement, const DIM: usize>(Buf<T, DIM>);
1607
1608impl<T: PackedElement, const DIM: usize> BufMut<T, DIM> {
1609
1610 pub fn zeroed(dim: [usize; DIM]) -> Self {
1616
1617 let size = checked_len(&dim)
1618 .and_then(|len| len.checked_mul(mem::size_of::<T>()))
1619 .expect("capacity overflow");
1620
1621 if Buf::<T, DIM>::INLINE || size == 0 {
1622 return Self(unsafe { Buf::copy_from_bytes(&[0; mem::size_of::<Repr>()][..size], dim) });
1624 }
1625
1626 let raw = HeapRef { inner: infallible(Heap::alloc(size)), offset: 0 };
1627
1628 Self(unsafe { Buf::from_raw(raw, PackedSpans::new(), dim) })
1630
1631 }
1632
1633 #[inline]
1635 pub fn from_slice(values: &[T], dim: [usize; DIM]) -> Option<Self> {
1636 Buf::from_slice(values, dim).map(Self)
1637 }
1638
1639 #[inline]
1641 pub fn dim(&self) -> [usize; DIM] {
1642 self.0.dim
1643 }
1644
1645 #[inline]
1647 pub fn len(&self) -> usize {
1648 self.0.len()
1649 }
1650
1651 #[inline]
1652 pub fn is_empty(&self) -> bool {
1653 self.0.is_empty()
1654 }
1655
1656 #[inline]
1658 pub fn as_ptr(&self) -> *const T {
1659 self.0.as_ptr()
1660 }
1661
1662 #[inline]
1663 pub fn as_slice(&self) -> &[T] {
1664 self.0.as_slice()
1665 }
1666
1667 #[inline]
1668 pub fn as_mut_slice(&mut self) -> &mut [T] {
1669 let len = self.len();
1670 unsafe { slice::from_raw_parts_mut(self.0.base_mut().cast::<T>(), len) }
1672 }
1673
1674 #[inline]
1675 pub fn as_bytes(&self) -> &[u8] {
1676 self.0.as_bytes()
1677 }
1678
1679 #[inline]
1682 pub fn freeze(self) -> Buf<T, DIM> {
1683 self.0
1684 }
1685
1686}
1687
1688impl<T: PackedElement> BufMut<T, 1> {
1689
1690 #[inline]
1692 pub const fn new() -> Self {
1693 Self(Buf::new())
1694 }
1695
1696 #[inline]
1698 pub fn with_capacity(capacity: usize) -> Self {
1699 let mut buf = Self::new();
1700 buf.reserve(capacity);
1701 buf
1702 }
1703
1704 #[inline]
1706 pub fn capacity(&self) -> usize {
1707 let raw = self.0.raw();
1708 (raw.inner.capacity() - raw.offset) / mem::size_of::<T>()
1709 }
1710
1711 #[inline]
1714 fn ptr_at(&self, index: usize) -> *mut T {
1715 debug_assert!(index <= self.capacity());
1716 unsafe { self.0.raw().ptr().cast::<T>().add(index) }
1718 }
1719
1720 #[inline]
1722 pub fn reserve(&mut self, additional: usize) {
1723 infallible(self.alloc_reserve(additional))
1724 }
1725
1726 pub fn try_reserve(&mut self, additional: usize) -> Result<(), Error> {
1729 self.alloc_reserve(additional).map_err(|_| Error::new(ErrorKind::Internal)
1730 .with_description(format!("Could not allocate room for {additional} more values behind {}", self.len())))
1731 }
1732
1733 fn alloc_reserve(&mut self, additional: usize) -> AllocResult<()> {
1734 let len = self.len();
1735 let raw = self.0.raw_mut();
1736 let end = len.checked_add(additional)
1737 .and_then(|len| len.checked_mul(mem::size_of::<T>()))
1738 .and_then(|size| raw.offset.checked_add(size))
1739 .ok_or(None)?;
1740 if end <= raw.inner.capacity() {
1741 return Ok(());
1742 }
1743 if raw.inner.is_immortal() {
1744 raw.inner = Heap::alloc(end)?;
1747 } else {
1748 unsafe { raw.inner.grow(end)? };
1750 }
1751 Ok(())
1752 }
1753
1754 #[inline]
1756 pub fn push(&mut self, value: T) {
1757 self.reserve(1);
1758 unsafe { self.ptr_at(self.len()).write(value) };
1760 self.0.dim[0] += 1;
1761 }
1762
1763 pub fn extend_from_slice(&mut self, values: &[T]) {
1765 self.reserve(values.len());
1766 unsafe { ptr::copy_nonoverlapping(values.as_ptr(), self.ptr_at(self.len()), values.len()) };
1768 self.0.dim[0] += values.len();
1769 }
1770
1771 pub fn resize(&mut self, len: usize, value: T) {
1776 let old_len = self.len();
1777 if len > old_len {
1778 let bytes = unsafe { slice::from_raw_parts(ptr::from_ref(&value).cast::<u8>(), mem::size_of::<T>()) };
1780 let end = if bytes.iter().all(|&octet| octet == 0) {
1781 let raw = self.0.raw();
1783 len.min((raw.inner.capacity() - raw.offset).div_ceil(mem::size_of::<T>()))
1784 } else {
1785 len
1786 };
1787 self.reserve(len - old_len);
1788 for index in old_len..end {
1789 unsafe { self.ptr_at(index).write(value) };
1791 }
1792 }
1793 self.0.dim[0] = len;
1794 }
1795
1796 #[inline]
1798 pub fn truncate(&mut self, len: usize) {
1799 self.0.truncate(len);
1800 }
1801
1802 pub fn clear(&mut self) {
1805 let raw = self.0.raw_mut();
1806 if !raw.inner.is_immortal() {
1807 unsafe { raw.inner.free_sides() };
1809 }
1810 raw.offset = 0;
1811 self.0.dim[0] = 0;
1812 }
1813
1814}
1815
1816impl BufMut<u8, 1> {
1817
1818 pub fn from_hex(s: &str) -> Option<Self> {
1821 if s.len() % 2 != 0 {
1822 return None;
1823 }
1824 let mut buf = Self::with_capacity(s.len() / 2);
1825 for hex in s.as_bytes().chunks_exact(2) {
1826 let hex = str::from_utf8(hex).ok()?;
1827 buf.push(u8::from_str_radix(hex, 16).ok()?);
1828 }
1829 Some(buf)
1830 }
1831
1832 pub fn set_len(&mut self, len: usize) {
1839 self.reserve(len.saturating_sub(self.len()));
1840 self.0.dim[0] = len;
1841 }
1842
1843}
1844
1845impl<T: PackedElement, const DIM: usize> Clone for BufMut<T, DIM> {
1848 #[inline]
1851 fn clone(&self) -> Self {
1852 Self(unsafe { Buf::copy_from_bytes(self.as_bytes(), self.dim()) })
1854 }
1855}
1856
1857impl<T: PackedElement> Default for BufMut<T, 1> {
1858 #[inline]
1859 fn default() -> Self {
1860 Self::new()
1861 }
1862}
1863
1864impl<T: PackedElement + PartialEq, const DIM: usize> PartialEq for BufMut<T, DIM> {
1865 #[inline]
1866 fn eq(&self, other: &Self) -> bool {
1867 self.dim() == other.dim() && self.as_slice() == other.as_slice()
1868 }
1869}
1870
1871impl<T: PackedElement + Eq, const DIM: usize> Eq for BufMut<T, DIM> {}
1872
1873impl<T: PackedElement> From<&[T]> for BufMut<T, 1> {
1874 #[inline]
1875 fn from(values: &[T]) -> Self {
1876 Self(Buf::from(values))
1877 }
1878}
1879
1880impl<T: PackedElement> From<Vec<T>> for BufMut<T, 1> {
1881 #[inline]
1882 fn from(values: Vec<T>) -> Self {
1883 Self::from(values.as_slice())
1884 }
1885}
1886
1887impl<T: PackedElement, const DIM: usize> Debug for BufMut<T, DIM> {
1890 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1892 fmt_buf::<T, _>(f, "BufMut", &self.0.dim, self.0.iter())
1893 }
1894}
1895
1896impl<T: PackedElement> UpperHex for BufMut<T, 1> {
1897 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1901 fmt_hex::<T>(self.as_bytes(), f, true)
1902 }
1903}
1904
1905impl<T: PackedElement> LowerHex for BufMut<T, 1> {
1906 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1910 fmt_hex::<T>(self.as_bytes(), f, false)
1911 }
1912}
1913
1914#[cfg(test)]
1915#[allow(clippy::single_range_in_vec_init)]
1916mod tests {
1917
1918 use super::*;
1919
1920 #[test]
1923 fn scalar() {
1924 let scalar = Buf::<f64, 0>::from(1.5);
1925 assert_eq!(scalar.value(), 1.5);
1926 assert_eq!(scalar.get([]), Some(1.5));
1927 assert_eq!(scalar.len(), 1);
1928 let clone = scalar.clone();
1929 assert!(scalar.is_unique() && clone.is_unique());
1930 }
1931
1932 #[test]
1933 fn one_dim() {
1934 let buf = Buf::<i32, 1>::from(vec![1, 2, 3]);
1935 assert_eq!(buf.dim(), [3]);
1936 assert_eq!(buf.get([1]), Some(2));
1937 assert_eq!(buf.get([3]), None);
1938 assert_eq!(buf.as_slice(), &[1, 2, 3]);
1939 assert_eq!(buf.iter().sum::<i32>(), 6);
1940 }
1941
1942 #[test]
1945 fn two_dim() {
1946 let buf = Buf::<u8, 2>::from_slice(&[1, 2, 3, 4, 5, 6], [3, 2]).unwrap();
1947 assert_eq!(buf.get([0, 1]), Some(4));
1948 assert_eq!(buf.get([2, 1]), Some(6));
1949 assert_eq!(buf.get([3, 0]), None);
1950 assert_eq!(buf.raw_index([1, 1]), Some(4));
1951 assert_eq!(buf.get_raw(4), Some(5));
1952 assert!(Buf::<u8, 2>::from_slice(&[1, 2, 3], [2, 2]).is_none());
1954 let flat = buf.reshape([6]).unwrap();
1956 assert_eq!(flat.as_slice(), &[1, 2, 3, 4, 5, 6]);
1957 }
1958
1959 #[test]
1962 fn empty() {
1963 const EMPTY: Buf<u32, 2> = Buf::new();
1964 const EMPTY_MUT: BufMut<u8, 1> = BufMut::new();
1965 assert_eq!(EMPTY.dim(), [0, 0]);
1966 assert!(!EMPTY.is_unique());
1967 let mut values = Buf::<u32, 1>::from(vec![]);
1968 assert_eq!(values.as_ptr().cast::<u8>(), EMPTY_MUT.as_ptr());
1969 assert_eq!(values.make_mut().as_mut_slice(), &mut []);
1970 assert!(Buf::<str, 1>::from(&[] as &[&str]).iter().next().is_none());
1971 let strings = Buf::<str, 1>::from_spans(values.into_bytes(), [0..0, 0..0], [2]).unwrap();
1973 assert_eq!(strings.iter().collect::<Vec<_>>(), ["", ""]);
1974 let mut buf = EMPTY_MUT;
1975 assert_eq!(buf.capacity(), 0);
1976 buf.clear();
1977 buf.extend_from_slice(&[]);
1978 assert_eq!(buf.as_ptr(), EMPTY_MUT.as_ptr());
1979 buf.extend_from_slice(&[1, 2]);
1980 assert_ne!(buf.as_ptr(), EMPTY_MUT.as_ptr());
1981 let mut shared = EMPTY.reshape::<1>([0]).unwrap();
1982 shared.get_mut().unwrap().resize(3, 7);
1983 assert_eq!(shared.as_slice(), [7; 3]);
1984 }
1985
1986 #[test]
1988 fn writable_clone() {
1989 let mut buf = BufMut::from(&[1u16, 2][..]);
1990 let mut copy = buf.clone();
1991 assert_ne!(copy.as_ptr(), buf.as_ptr());
1992 copy.as_mut_slice()[0] = 0;
1993 buf.push(3);
1994 assert_eq!((buf.as_slice(), copy.as_slice()), (&[1, 2, 3][..], &[0, 2][..]));
1995 assert!(buf.freeze().is_unique() && copy.freeze().is_unique());
1996 }
1997
1998 #[test]
2001 fn slicing_by_ref() {
2002 let values = Buf::<u16, 1>::from(vec![1, 2, 3, 4]);
2003 let part = values.slice_ref(&values.as_slice()[1..3]);
2004 assert_eq!(part.as_slice(), &[2, 3]);
2005 assert_eq!(part.as_ptr(), values.as_slice()[1..].as_ptr());
2006 let rows = values.reshape([2, 2]).unwrap();
2007 assert_eq!(rows.slice_ref(&rows.as_slice()[2..]).dim(), [2, 1]);
2008 let res = std::panic::catch_unwind(|| rows.slice_ref(&rows.as_slice()[1..3]));
2009 assert!(res.is_err());
2010 let other = [3, 4];
2011 let res = std::panic::catch_unwind(|| rows.slice_ref(&other));
2012 assert!(res.is_err());
2013 }
2014
2015 #[test]
2017 fn octets_by_ref() {
2018 let buf = Buf::from(&b"hello world"[..]);
2019 let part = buf.slice_ref(&buf.as_slice()[6..]);
2020 assert_eq!(part.as_slice(), b"world");
2021 assert!(buf.slice_ref(&buf.as_slice()[11..]).is_empty());
2022 }
2023
2024 #[test]
2027 fn slicing() {
2028 let buf = Buf::<u8, 2>::from_slice(&[1, 2, 3, 4, 5, 6], [2, 3]).unwrap();
2029 let rows = buf.slice(1..);
2030 assert_eq!(rows.dim(), [2, 2]);
2031 assert_eq!(rows.as_slice(), &[3, 4, 5, 6]);
2032 assert!(!buf.is_unique());
2033 assert_eq!(rows.slice(..1).as_slice(), &[3, 4]);
2034 }
2035
2036 #[test]
2039 fn scalar_shapes() {
2040 let scalar = Buf::<u16, 0>::from(7);
2041 let square = scalar.clone().reshape([1, 1]).unwrap();
2042 assert_eq!(square.as_slice(), &[7]);
2043 assert!(scalar.clone().reshape([2]).is_none());
2044 assert_eq!(square.into_scalar().unwrap(), scalar);
2045 assert_eq!(scalar.clone().into_scalar().unwrap(), scalar);
2046 let string = Buf::<str, 0>::from("ab");
2047 let strings = string.clone().reshape([1]).unwrap();
2048 assert!(!string.is_unique());
2049 assert_eq!(strings.into_scalar().unwrap().value(), "ab");
2050 }
2051
2052 #[test]
2054 fn splitting() {
2055 let mut buf = Buf::from(&b"headtail"[..]);
2056 let head = buf.split_to(4);
2057 assert_eq!((head.as_slice(), buf.as_slice()), (&b"head"[..], &b"tail"[..]));
2058 let tail = buf.split_off(2);
2059 assert_eq!((buf.as_slice(), tail.as_slice()), (&b"ta"[..], &b"il"[..]));
2060 assert!(!head.is_unique());
2061 let mut rows = Buf::<u8, 2>::from_slice(&[1, 2, 3, 4, 5, 6], [2, 3]).unwrap();
2062 assert_eq!(rows.split_to(1).as_slice(), &[1, 2]);
2063 assert_eq!(rows.dim(), [2, 2]);
2064 }
2065
2066 #[test]
2067 #[should_panic(expected = "out of range")]
2068 fn slice_out_of_range() {
2069 Buf::<u8, 1>::from(vec![1, 2]).slice(1..3);
2070 }
2071
2072 #[test]
2074 fn scalar_mutation() {
2075 let mut scalar = Buf::<i32, 0>::from(1);
2076 scalar.make_mut().as_mut_slice()[0] = 2;
2077 assert_eq!(scalar.value(), 2);
2078 assert_eq!(BufMut::<i32, 0>::zeroed([]).freeze().value(), 0);
2079 }
2080
2081 #[test]
2084 fn scalar_extraction() {
2085 let values = Buf::<f64, 1>::from(vec![1.5, 2.5]);
2086 assert_eq!(values.slice(1..).into_scalar().unwrap().value(), 2.5);
2087 assert!(values.is_unique());
2088 assert!(values.clone().into_scalar().is_none());
2089 let strings = Buf::<str, 1>::from(&["ab", "cd"][..]);
2090 let scalar = strings.slice(1..).into_scalar().unwrap();
2091 assert_eq!(scalar.value(), "cd");
2092 assert!(!strings.is_unique());
2093 assert_eq!(strings.get_scalar([0]).unwrap().value(), "ab");
2094 assert!(strings.get_scalar([2]).is_none());
2095 let image = Buf::<u8, 2>::from_slice(&[1, 2, 3, 4, 5, 6], [2, 3]).unwrap();
2096 assert_eq!(image.get_scalar([1, 2]).unwrap().value(), 6);
2097 assert_eq!(Buf::<u16, 0>::from(7).get_scalar([]).unwrap().value(), 7);
2098 }
2099
2100 #[test]
2103 fn copy_on_write() {
2104 let mut values = Buf::<u16, 1>::from(vec![1, 2, 3, 4]);
2105 let part = values.slice(1..3);
2106 values.make_mut().as_mut_slice()[1] = 9;
2107 assert_eq!(values.as_slice(), &[1, 9, 3, 4]);
2108 assert_eq!(part.as_slice(), &[2, 3]);
2109 assert!(values.is_unique());
2110 let ptr = values.as_ptr();
2112 values.make_mut().as_mut_slice()[0] = 0;
2113 assert_eq!(values.as_ptr(), ptr);
2114 let rest = Buf::from(vec![0u16; 64]).slice(1..);
2116 let part = rest.slice(..2).into_mut();
2117 assert_ne!(part.as_ptr(), rest.as_ptr());
2118 assert!(part.capacity() < rest.len());
2119 }
2120
2121 #[test]
2124 fn copy_on_write_growth() {
2125 let mut buf = Buf::from(&b"head"[..]);
2126 let head = buf.clone();
2127 buf.make_mut().extend_from_slice(b" tail");
2128 assert_eq!((buf.as_slice(), head.as_slice()), (&b"head tail"[..], &b"head"[..]));
2129 }
2130
2131 #[test]
2133 fn growth() {
2134 let mut buf = BufMut::<u32, 1>::with_capacity(4);
2135 buf.extend_from_slice(&[1, 2]);
2136 buf.resize(5, 0);
2137 buf.extend_from_slice(&[7; 100]);
2138 buf.push(8);
2139 assert_eq!(buf.len(), 106);
2140 assert_eq!(buf.as_slice()[..6], [1, 2, 0, 0, 0, 7]);
2141 assert_eq!(buf.as_slice()[105], 8);
2142 buf.truncate(2);
2143 assert_eq!(buf.as_slice(), &[1, 2]);
2144 }
2145
2146 #[test]
2149 fn length() {
2150 let mut buf = BufMut::from(&[0xAA; 8][..]);
2151 buf.truncate(4);
2152 buf.set_len(12);
2153 assert_eq!(buf.as_slice(), [&[0xAA; 8][..], &[0; 4]].concat());
2154 buf.truncate(4);
2155 buf.resize(8, 0);
2156 assert_eq!(buf.as_slice(), [0xAA, 0xAA, 0xAA, 0xAA, 0, 0, 0, 0]);
2157 }
2158
2159 #[test]
2162 fn zero_resize() {
2163 let mut buf = BufMut::from(&[0xAAAAu16; 4][..]);
2164 buf.clear();
2165 buf.resize(100, 0);
2166 assert_eq!(buf.as_slice(), [0; 100]);
2167 buf.clear();
2168 buf.resize(2, 0xBBBB);
2169 buf.resize(3, 0);
2170 assert_eq!(buf.as_slice(), [0xBBBB, 0xBBBB, 0]);
2171 }
2172
2173 #[test]
2175 fn reservation() {
2176 let mut buf = BufMut::from(&[1u16, 2][..]);
2177 assert!(buf.try_reserve(usize::MAX).is_err());
2178 assert!(buf.try_reserve(isize::MAX as usize).is_err());
2179 assert_eq!(buf.as_slice(), [1, 2]);
2180 buf.reserve(64);
2181 assert!(buf.capacity() >= 66);
2182 }
2183
2184 #[test]
2187 fn recycling() {
2188 let mut buf = BufMut::from(&b"first"[..]);
2189 let ptr = buf.as_ptr();
2190 buf.clear();
2191 buf.extend_from_slice(b"second");
2192 assert_eq!(buf.as_ptr(), ptr);
2193
2194 let buf = buf.freeze();
2195 let first = Buf::<str, 0>::from_spans(buf.slice(..3), [0..3], []).unwrap();
2196 let buf = buf.try_into_mut().unwrap_err();
2197 drop(first);
2198 let mut buf = buf.try_into_mut().unwrap();
2199 buf.clear();
2200 assert_eq!(buf.as_ptr(), ptr);
2201 }
2202
2203 #[test]
2206 fn unique_buffer() {
2207 let buf = Buf::from(&[1u8, 2, 3][..]);
2208 let ptr = buf.as_ptr();
2209 let part = buf.slice(1..);
2210 let mut buf = buf.try_into_mut().unwrap_err();
2211 assert!(buf.get_mut().is_none());
2212 drop(part);
2213 buf.get_mut().unwrap().truncate(1);
2214 let buf = buf.try_into_mut().unwrap();
2215 assert_eq!(buf.as_ptr(), ptr);
2216 assert_eq!(buf.as_slice(), [1]);
2217 }
2218
2219 #[test]
2222 fn packed_cast() {
2223 let buf = Buf::<u32, 1>::from(vec![1, 2, 3, 4]).into_bytes();
2224 let aligned = buf.slice(8..).cast::<u32, 1>([2]).unwrap();
2225 assert_eq!(aligned.as_slice(), &[3, 4]);
2226 assert!(!aligned.is_unique());
2227 let unaligned = buf.slice(1..9).cast::<u32, 1>([2]).unwrap();
2228 assert!(unaligned.is_unique());
2229 let buf = buf.cast::<u32, 1>([3]).unwrap_err();
2232 assert!(buf.slice(..2).cast::<u16, 0>([]).unwrap().is_unique());
2234 let halves = aligned.cast::<u16, 2>([2, 2]).unwrap();
2236 assert_eq!(halves.cast::<u64, 0>([]).unwrap().value(), 3 | 4 << 32);
2237 }
2238
2239 #[test]
2242 fn storage_alignment() {
2243 let buf = Buf::from(&[0u8; 16][..]);
2244 assert_eq!(buf.as_ptr().addr() % ALIGN, 0);
2245 assert!(!buf.clone().cast::<f64, 1>([2]).unwrap().is_unique());
2246 }
2247
2248 #[test]
2250 fn invalid_values() {
2251 let buf = Buf::from(&[0u8, 1, 2][..]);
2252 assert!(buf.slice(..2).cast::<bool, 1>([2]).is_ok());
2253 assert!(buf.cast::<bool, 1>([3]).is_err());
2254 }
2255
2256 #[test]
2258 fn octets_round_trip() {
2259 let values = Buf::<u16, 1>::from(vec![1, 2]);
2260 assert_eq!(values.as_bytes(), [1u16.to_ne_bytes(), 2u16.to_ne_bytes()].concat());
2261 let buf = values.into_bytes();
2262 assert_eq!(buf.cast::<u16, 1>([2]).unwrap().as_slice(), &[1, 2]);
2263 }
2264
2265 #[test]
2266 fn strings() {
2267 let strings = Buf::<str, 1>::from(&["ab", "", "cde"][..]);
2268 assert_eq!(strings.get([2]), Some("cde"));
2269 assert_eq!(strings.iter().collect::<Vec<_>>(), ["ab", "", "cde"]);
2270 assert_eq!(strings.slice(1..).get([1]), Some("cde"));
2271 assert_eq!(Buf::<str, 0>::from("scalar").value(), "scalar");
2272 }
2273
2274 #[test]
2277 fn strings_from_iter() {
2278 let strings = Buf::<str, 1>::from_strs(["ab", "", "cde"].into_iter().filter(|_| true)).unwrap();
2279 assert_eq!(strings.dim(), [3]);
2280 assert_eq!(strings.iter().collect::<Vec<_>>(), ["ab", "", "cde"]);
2281 let empty = Buf::<str, 1>::from_strs(std::iter::empty::<&str>()).unwrap();
2282 assert!(empty.is_empty());
2283 }
2284
2285 #[test]
2288 fn string_spans() {
2289 let msg = Buf::from(&b"..hello world"[..]);
2290 let strings = Buf::<str, 1>::from_spans(msg.slice(2..), [0..5, 6..11], [2]).unwrap();
2291 drop(msg);
2292 assert_eq!(strings.iter().collect::<Vec<_>>(), ["hello", "world"]);
2293 let buf = Buf::from(&[b'a', 0xff][..]);
2295 let buf = Buf::<str, 1>::from_spans(buf, [0..3], [1]).unwrap_err();
2296 let buf = Buf::<str, 1>::from_spans(buf, [1..2], [1]).unwrap_err();
2297 #[allow(clippy::reversed_empty_ranges)]
2298 let buf = Buf::<str, 1>::from_spans(buf, [1..0], [1]).unwrap_err();
2299 assert!(Buf::<str, 0>::from_spans(buf, [0..1], []).is_ok());
2300 }
2301
2302 #[test]
2305 fn span_iterator() {
2306 let msg = Buf::from(&b"a,bc,def"[..]);
2307 let spans = msg.as_slice().split(|&b| b == b',').scan(0, |start, part| {
2308 let span = *start..*start + part.len() as u32;
2309 *start = span.end + 1;
2310 Some(span)
2311 }).collect::<Vec<_>>();
2312 let strings = Buf::<str, 1>::from_spans(msg.clone(), spans.clone(), [3]).unwrap();
2313 assert_eq!(strings.iter().collect::<Vec<_>>(), ["a", "bc", "def"]);
2314 let msg = Buf::<str, 1>::from_spans(msg, spans.clone(), [2]).unwrap_err();
2315 let msg = Buf::<str, 1>::from_spans(msg, spans.clone(), [4]).unwrap_err();
2316 let msg = Buf::<str, 1>::from_spans(msg, spans.clone(), [usize::MAX]).unwrap_err();
2317 assert!(Buf::<str, 1>::from_spans(msg, [], [0]).is_ok());
2318 }
2319
2320 #[test]
2321 fn thread_sharing() {
2322 let values = Buf::<f64, 1>::from(vec![1.0, 2.0]);
2323 let sum = std::thread::spawn({
2324 let values = values.clone();
2325 move || values.iter().sum::<f64>()
2326 });
2327 assert_eq!(sum.join().unwrap(), 3.0);
2328 }
2329
2330 #[test]
2332 fn states() {
2333 let buf = Buf::from(&[DevState::Moving as u8, 200][..]);
2334 let buf = buf.cast::<DevState, 1>([2]).unwrap_err();
2335 assert_eq!(buf.slice(..1).cast::<DevState, 0>([]).unwrap().value(), DevState::Moving);
2336 }
2337
2338 #[test]
2340 fn equality() {
2341 let values = Buf::<i32, 1>::from([1, 2, 3, 4]);
2342 assert_eq!(values.slice(2..), Buf::from([3, 4]));
2343 assert_ne!(values.clone().reshape([2, 2]).unwrap(), Buf::from_slice(&[1, 2, 3, 4], [4, 1]).unwrap());
2344 }
2345
2346 #[test]
2348 fn debug() {
2349 assert_eq!(format!("{:?}", Buf::<u16, 1>::from([7; 3])), "Buf<3>[7, 7, 7]");
2350 assert_eq!(format!("{:?}", Buf::<u16, 0>::from(7)), "Buf(7)");
2351 let rows = Buf::<i32, 2>::from_slice(&[1, 2, 3, 4, 5, 6], [3, 2]).unwrap();
2352 assert_eq!(format!("{rows:?}"), "Buf<3, 2>[[1, 2, 3], [4, 5, 6]]");
2353 assert_eq!(format!("{rows:#?}"), "Buf<3, 2>[\n [1, 2, 3],\n [4, 5, 6],\n]");
2354 assert_eq!(format!("{:?}", BufMut::<u8, 2>::zeroed([2, 0])), "BufMut<2, 0>[]");
2355 assert_eq!(format!("{:?}", Buf::<u8, 2>::new().reshape([0, 2]).unwrap()), "Buf<0, 2>[[], []]");
2356 assert_eq!(format!("{:?}", Buf::<str, 1>::from(&["a", "b"][..])), r#"Buf<2>["a", "b"]"#);
2357 }
2358
2359 #[test]
2361 fn octets_debug() {
2362 assert_eq!(format!("{:?}", Buf::from(&b"\x01\x02GIOP\x00"[..])), "Buf<7>[01 02 'GIOP' 00]");
2363 assert_eq!(format!("{:?}", BufMut::<u8, 1>::from(vec![0xAB; 20])), format!("BufMut<20>[{}AB]", "AB ".repeat(19)));
2364 let rows = Buf::<u8, 2>::from_slice(b"ab\x01\x02", [2, 2]).unwrap();
2365 assert_eq!(format!("{rows:?}"), "Buf<2, 2>[['ab'], [01 02]]");
2366 }
2367
2368 #[test]
2371 fn hex() {
2372 let buf = Buf::from(&[0x01, 0xAB, 0x00][..]);
2373 assert_eq!(format!("{buf:X}"), "01AB00");
2374 assert_eq!(format!("{buf:x}"), "01ab00");
2375 assert_eq!(format!("{:X}", buf.clone().into_mut()), "01AB00");
2376 assert_eq!(BufMut::from_hex("01AB00").unwrap().freeze(), buf);
2377 assert_eq!(BufMut::from_hex("01ab00").unwrap().freeze(), buf);
2378 assert!(BufMut::from_hex("01A").is_none());
2379 assert!(BufMut::from_hex("0G").is_none());
2380 let words = Buf::<u16, 1>::from([0x0102, 0xABCD]);
2382 let expected = if cfg!(target_endian = "little") { "0201 cdab" } else { "0102 abcd" };
2383 assert_eq!(format!("{words:x}"), expected);
2384 assert_eq!(format!("{:X}", Buf::<u32, 1>::new()), "");
2385 }
2386
2387 #[test]
2390 fn sizes() {
2391 assert_eq!(mem::size_of::<Buf<f64, 0>>(), 16);
2392 assert_eq!(mem::size_of::<Buf<u8, 1>>(), 24);
2393 assert_eq!(mem::size_of::<Buf<f64, 2>>(), 32);
2394 assert_eq!(mem::size_of::<Buf<str, 1>>(), 32);
2395 assert_eq!(mem::size_of::<BufMut<u8, 1>>(), 24);
2396 }
2397
2398}