1use alloc::{vec, vec::Vec};
6use core::{
7 fmt::{self, Debug, Formatter},
8 iter,
9 ops::{Deref, DerefMut},
10};
11
12use super::Dims;
13
14use inner::Inner;
15
16pub trait AsSlice2<T> {
22 fn as_slice2(&self) -> Slice2<'_, T>;
24}
25
26pub trait AsMutSlice2<T> {
29 fn as_mut_slice2(&mut self) -> MutSlice2<'_, T>;
31}
32
33#[derive(Clone, Eq, PartialEq)]
60#[repr(transparent)]
61pub struct Buf2<T>(Inner<T, Vec<T>>);
62
63#[derive(Copy, Clone, Eq, PartialEq)]
77#[repr(transparent)]
78pub struct Slice2<'a, T>(Inner<T, &'a [T]>);
79
80#[repr(transparent)]
83pub struct MutSlice2<'a, T>(Inner<T, &'a mut [T]>);
84
85impl<T> Buf2<T> {
90 pub fn new_from<I>((w, h): Dims, init: I) -> Self
112 where
113 I: IntoIterator<Item = T>,
114 {
115 let ww = isize::try_from(w).ok();
116 let hh = isize::try_from(h).ok();
117 let len = ww.and_then(|w| hh.and_then(|h| w.checked_mul(h)));
118 let Some(len) = len else {
119 panic!(
120 "w * h cannot exceed isize::MAX ({w} * {h} > {})",
121 isize::MAX
122 );
123 };
124 let data: Vec<_> = init.into_iter().take(len as usize).collect();
125 assert_eq!(
126 data.len(),
127 len as usize,
128 "insufficient items in iterator ({} < {len}",
129 data.len()
130 );
131 Self(Inner::new((w, h), w, data))
132 }
133
134 pub fn new((w, h): Dims) -> Self
154 where
155 T: Default + Clone,
156 {
157 let data = vec![T::default(); (w * h) as usize];
158 Self(Inner::new((w, h), w, data))
159 }
160
161 pub fn new_with<F>((w, h): Dims, mut init_fn: F) -> Self
183 where
184 F: FnMut(u32, u32) -> T,
185 {
186 let (mut x, mut y) = (0, 0);
187 Self::new_from(
188 (w, h),
189 iter::from_fn(|| {
190 let res = init_fn(x, y);
191 x += 1;
192 if x == w {
193 (x, y) = (0, y + 1);
194 }
195 Some(res)
196 }),
197 )
198 }
199
200 pub fn data(&self) -> &[T] {
202 self.0.data()
203 }
204
205 pub fn data_mut(&mut self) -> &mut [T] {
207 self.0.data_mut()
208 }
209
210 pub fn reshape(&mut self, dims: Dims) {
216 self.0.reshape(dims);
217 }
218}
219
220impl<'a, T> Slice2<'a, T> {
221 pub fn new(dims: Dims, stride: u32, data: &'a [T]) -> Self {
251 Self(Inner::new(dims, stride, data))
252 }
253}
254
255impl<'a, T> MutSlice2<'a, T> {
256 pub fn new(dims: Dims, stride: u32, data: &'a mut [T]) -> Self {
261 Self(Inner::new(dims, stride, data))
262 }
263}
264
265impl<T> AsSlice2<T> for Buf2<T> {
270 #[inline]
271 fn as_slice2(&self) -> Slice2<'_, T> {
272 self.0.as_slice2()
273 }
274}
275impl<T> AsSlice2<T> for &Buf2<T> {
276 #[inline]
277 fn as_slice2(&self) -> Slice2<'_, T> {
278 self.0.as_slice2()
279 }
280}
281impl<T> AsSlice2<T> for Slice2<'_, T> {
282 #[inline]
283 fn as_slice2(&self) -> Slice2<'_, T> {
284 self.0.as_slice2()
285 }
286}
287impl<T> AsSlice2<T> for MutSlice2<'_, T> {
288 #[inline]
289 fn as_slice2(&self) -> Slice2<'_, T> {
290 self.0.as_slice2()
291 }
292}
293
294impl<T> AsMutSlice2<T> for Buf2<T> {
295 #[inline]
296 fn as_mut_slice2(&mut self) -> MutSlice2<'_, T> {
297 self.0.as_mut_slice2()
298 }
299}
300impl<T> AsMutSlice2<T> for &mut Buf2<T> {
301 #[inline]
302 fn as_mut_slice2(&mut self) -> MutSlice2<'_, T> {
303 self.0.as_mut_slice2()
304 }
305}
306impl<T> AsMutSlice2<T> for MutSlice2<'_, T> {
307 #[inline]
308 fn as_mut_slice2(&mut self) -> MutSlice2<'_, T> {
309 self.0.as_mut_slice2()
310 }
311}
312
313impl<T> Debug for Buf2<T> {
318 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
319 self.0.debug_fmt(f, "Buf2")
320 }
321}
322impl<T> Debug for Slice2<'_, T> {
323 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
324 self.0.debug_fmt(f, "Slice2")
325 }
326}
327impl<T> Debug for MutSlice2<'_, T> {
328 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
329 self.0.debug_fmt(f, "MutSlice2")
330 }
331}
332
333impl<T> Deref for Buf2<T> {
334 type Target = Inner<T, Vec<T>>;
335 fn deref(&self) -> &Self::Target {
336 &self.0
337 }
338}
339impl<'a, T> Deref for Slice2<'a, T> {
340 type Target = Inner<T, &'a [T]>;
341 fn deref(&self) -> &Self::Target {
342 &self.0
343 }
344}
345impl<'a, T> Deref for MutSlice2<'a, T> {
346 type Target = Inner<T, &'a mut [T]>;
347 fn deref(&self) -> &Self::Target {
348 &self.0
349 }
350}
351
352impl<T> DerefMut for Buf2<T> {
353 fn deref_mut(&mut self) -> &mut Self::Target {
354 &mut self.0
355 }
356}
357impl<'a, T> DerefMut for MutSlice2<'a, T> {
358 fn deref_mut(&mut self) -> &mut Self::Target {
359 &mut self.0
360 }
361}
362
363pub mod inner {
364 use core::{
365 fmt::Formatter,
366 iter::zip,
367 marker::PhantomData,
368 ops::{Deref, DerefMut, Index, IndexMut, Range},
369 };
370
371 use crate::{
372 math::point::Point2u,
373 util::{Dims, rect::Rect},
374 };
375
376 use super::{AsSlice2, MutSlice2, Slice2};
377
378 #[derive(Copy, Clone, Eq, PartialEq)]
382 pub struct Inner<T, D> {
383 dims: Dims,
384 stride: u32,
385 data: D,
386 _pd: PhantomData<T>,
387 }
388
389 impl<T, D> Inner<T, D> {
390 #[inline]
392 pub fn width(&self) -> u32 {
393 self.dims.0
394 }
395 #[inline]
397 pub fn height(&self) -> u32 {
398 self.dims.1
399 }
400 #[inline]
402 pub fn dims(&self) -> Dims {
403 self.dims
404 }
405 #[inline]
407 pub fn stride(&self) -> u32 {
408 self.stride
409 }
410 pub fn is_contiguous(&self) -> bool {
417 let (w, h) = self.dims;
418 self.stride == w || h <= 1 || w == 0
419 }
420 pub fn is_empty(&self) -> bool {
422 self.dims.0 == 0 || self.dims.1 == 0
423 }
424
425 #[inline]
428 fn to_index(&self, x: u32, y: u32) -> usize {
429 (y * self.stride + x) as usize
430 }
431
432 #[inline]
435 fn to_index_strict(&self, x: u32, y: u32) -> usize {
436 self.to_index_checked(x, y).unwrap_or_else(|| {
437 let (w, h) = self.dims;
438 panic!(
439 "position (x={x}, y={y}) out of bounds (0..{w}, 0..{h})",
440 )
441 })
442 }
443 #[inline]
446 fn to_index_checked(&self, x: u32, y: u32) -> Option<usize> {
447 let (w, h) = self.dims;
448 (x < w && y < h).then(|| self.to_index(x, y))
449 }
450
451 fn resolve_bounds(&self, rect: &Rect<u32>) -> (Dims, Range<usize>) {
453 let (w, h) = self.dims;
454
455 let l = rect.left.unwrap_or(0);
456 let t = rect.top.unwrap_or(0);
457 let r = rect.right.unwrap_or(w);
458 let b = rect.bottom.unwrap_or(h);
459
460 assert!(l <= r, "range left ({l}) > right ({r})");
465 assert!(t <= b, "range top ({l}) > bottom ({r})");
466 assert!(r <= w, "range right ({r}) > width ({w})");
467 assert!(b <= h, "range bottom ({b}) > height ({h})");
468
469 let start = self.to_index(l, t);
471 let end = if b == t {
473 self.to_index(r, t)
474 } else {
475 self.to_index(r, b - 1)
477 };
478 ((r - l, b - t), start..end)
479 }
480
481 pub(super) fn debug_fmt(
483 &self,
484 f: &mut Formatter,
485 name: &str,
486 ) -> core::fmt::Result {
487 f.debug_struct(name)
488 .field("dims", &self.dims)
489 .field("stride", &self.stride)
490 .finish()
491 }
492
493 pub(super) fn reshape(&mut self, dims: Dims) {
494 assert!(self.is_contiguous());
495 assert_eq!(dims.0 * dims.1, self.dims.0 * self.dims.1);
496 self.dims = dims;
497 }
498 }
499
500 impl<T, D: Deref<Target = [T]>> Inner<T, D> {
501 #[rustfmt::skip]
504 pub(super) fn new(dims @ (w, h): Dims, stride: u32, data: D) -> Self {
505 assert!(w <= stride, "width ({w}) > stride ({stride})");
506
507 let len = data.len();
508 assert!(
509 h <= 1 || stride as usize <= len,
510 "stride ({stride}) > data length ({len})"
511 );
512 assert!(h as usize <= len, "height ({h}) > data length ({len})");
513 if h > 0 {
514 let size = (h - 1) * stride + w;
515 assert!(
516 size as usize <= len,
517 "required size ({size}) > data length ({len})"
518 );
519 }
520 Self { dims, stride, data, _pd: PhantomData }
521 }
522
523 pub(super) fn data(&self) -> &[T] {
525 &self.data
526 }
527
528 #[inline]
530 pub fn as_slice2(&self) -> Slice2<'_, T> {
531 let Self { dims, stride, ref data, _pd } = *self;
532 Slice2(Inner { dims, stride, data, _pd })
533 }
534
535 pub fn slice(&self, rect: impl Into<Rect>) -> Slice2<'_, T> {
540 let (dims, rg) = self.resolve_bounds(&rect.into());
541 Slice2::new(dims, self.stride, &self.data[rg])
542 }
543
544 pub fn get(&self, pos: impl Into<Point2u>) -> Option<&T> {
547 let [x, y] = pos.into().0;
548 self.to_index_checked(x, y).map(|i| &self.data[i])
549 }
550
551 pub fn rows(&self) -> impl Iterator<Item = &[T]> {
555 self.data
556 .chunks(self.stride as usize)
557 .map(|row| &row[..self.dims.0 as usize])
558 }
559
560 pub fn iter(&self) -> impl Iterator<Item = &'_ T> {
565 self.rows().flatten()
566 }
567 }
568
569 impl<T, D: DerefMut<Target = [T]>> Inner<T, D> {
570 #[inline]
572 pub fn as_mut_slice2(&mut self) -> MutSlice2<'_, T> {
573 #[rustfmt::skip]
574 let Self { dims, stride, ref mut data, _pd, } = *self;
575 MutSlice2(Inner { dims, stride, data, _pd })
576 }
577
578 pub(super) fn data_mut(&mut self) -> &mut [T] {
580 &mut self.data
581 }
582
583 pub fn rows_mut(&mut self) -> impl Iterator<Item = &mut [T]> {
587 self.data
588 .chunks_mut(self.stride as usize)
589 .map(|row| &mut row[..self.dims.0 as usize])
590 }
591
592 pub fn iter_mut(&mut self) -> impl Iterator<Item = &'_ mut T> {
595 self.rows_mut().flatten()
596 }
597
598 pub fn fill(&mut self, val: T)
600 where
601 T: Clone,
602 {
603 if self.is_contiguous() {
604 self.data.fill(val);
605 } else {
606 self.rows_mut()
607 .for_each(|row| row.fill(val.clone()));
608 }
609 }
610 pub fn fill_with<F>(&mut self, mut fill_fn: F)
615 where
616 F: FnMut(u32, u32) -> T,
617 {
618 for (row, y) in zip(self.rows_mut(), 0..) {
619 for (item, x) in zip(row, 0..) {
620 *item = fill_fn(x, y);
621 }
622 }
623 }
624
625 #[doc(alias = "blit")]
632 pub fn copy_from(&mut self, other: impl AsSlice2<T>)
633 where
634 T: Copy,
635 {
636 let other = other.as_slice2();
637
638 assert_eq!(
639 self.dims, other.dims,
640 "dimension mismatch (self: {:?}, other: {:?})",
641 self.dims, other.dims
642 );
643 for (dest, src) in self.rows_mut().zip(other.rows()) {
644 dest.copy_from_slice(src);
645 }
646 }
647
648 pub fn get_mut(&mut self, pos: impl Into<Point2u>) -> Option<&mut T> {
651 let [x, y] = pos.into().0;
652 self.to_index_checked(x, y)
653 .map(|i| &mut self.data[i])
654 }
655
656 pub fn slice_mut(&mut self, rect: impl Into<Rect>) -> MutSlice2<'_, T> {
661 let (dims, rg) = self.resolve_bounds(&rect.into());
662 MutSlice2(Inner::new(dims, self.stride, &mut self.data[rg]))
663 }
664 }
665
666 impl<T, D: Deref<Target = [T]>> Index<usize> for Inner<T, D> {
667 type Output = [T];
668
669 #[inline]
676 fn index(&self, i: usize) -> &[T] {
677 let idx = self.to_index_strict(0, i as u32);
678 let w = self.dims.0 as usize;
679 &self.data[idx..][..w]
680 }
681 }
682
683 impl<T, D> IndexMut<usize> for Inner<T, D>
684 where
685 Self: Index<usize, Output = [T]>,
686 D: DerefMut<Target = [T]>,
687 {
688 #[inline]
695 fn index_mut(&mut self, row: usize) -> &mut [T] {
696 let idx = self.to_index_strict(0, row as u32);
697 let w = self.dims.0 as usize;
698 &mut self.data[idx..][..w]
699 }
700 }
701
702 impl<T, D, Pos> Index<Pos> for Inner<T, D>
703 where
704 D: Deref<Target = [T]>,
705 Pos: Into<Point2u>,
706 {
707 type Output = T;
708
709 #[inline]
714 fn index(&self, pos: Pos) -> &T {
715 let [x, y] = pos.into().0;
716 &self.data[self.to_index_strict(x, y)]
717 }
718 }
719
720 impl<T, D, Pos> IndexMut<Pos> for Inner<T, D>
721 where
722 D: DerefMut<Target = [T]>,
723 Pos: Into<Point2u>,
724 {
725 #[inline]
730 fn index_mut(&mut self, pos: Pos) -> &mut T {
731 let [x, y] = pos.into().0;
732 let idx = self.to_index_strict(x, y);
733 &mut self.data[idx]
734 }
735 }
736}
737
738#[cfg(test)]
739mod tests {
740 use crate::math::pt2;
741
742 use super::*;
743
744 #[test]
745 fn buf_new_from() {
746 let buf = Buf2::new_from((3, 2), 1..);
747 assert_eq!(buf.data(), &[1, 2, 3, 4, 5, 6]);
748 }
749
750 #[test]
751 fn buf_new() {
752 let buf: Buf2<i32> = Buf2::new((3, 2));
753 assert_eq!(buf.data(), &[0, 0, 0, 0, 0, 0]);
754 }
755
756 #[test]
757 fn buf_new_with() {
758 let buf = Buf2::new_with((3, 2), |x, y| x + y);
759 assert_eq!(buf.data(), &[0, 1, 2, 1, 2, 3]);
760 }
761
762 #[test]
763 fn buf_extents() {
764 let buf: Buf2<()> = Buf2::new((4, 5));
765 assert_eq!(buf.width(), 4);
766 assert_eq!(buf.height(), 5);
767 assert_eq!(buf.stride(), 4);
768 }
769
770 #[test]
771 fn buf_index_and_get() {
772 let buf = Buf2::new_with((4, 5), |x, y| x * 10 + y);
773
774 assert_eq!(buf[2usize], [2, 12, 22, 32]);
775
776 assert_eq!(buf[[0, 0]], 0);
777 assert_eq!(buf[[1, 0]], 10);
778 assert_eq!(buf[[3, 4]], 34);
779
780 assert_eq!(buf.get([2, 3]), Some(&23));
781 assert_eq!(buf.get([4, 4]), None);
782 assert_eq!(buf.get([3, 5]), None);
783 }
784
785 #[test]
786 fn buf_index_mut_and_get_mut() {
787 let mut buf = Buf2::new_with((4, 5), |x, y| x * 10 + y);
788
789 buf[2usize][1] = 123;
790 assert_eq!(buf[2usize], [2, 123, 22, 32]);
791
792 buf[[2, 3]] = 234;
793 assert_eq!(buf[[2, 3]], 234);
794
795 *buf.get_mut([3, 4]).unwrap() = 345;
796 assert_eq!(buf.get_mut([3, 4]), Some(&mut 345));
797 assert_eq!(buf.get_mut([4, 4]), None);
798 assert_eq!(buf.get_mut([3, 5]), None);
799 }
800
801 #[test]
802 #[should_panic = "position (x=4, y=0) out of bounds (0..4, 0..5)"]
803 fn buf_index_x_out_of_bounds_should_panic() {
804 let buf = Buf2::new((4, 5));
805 let _: i32 = buf[[4, 0]];
806 }
807
808 #[test]
809 #[should_panic = "position (x=0, y=4) out of bounds (0..5, 0..4)"]
810 fn buf_index_y_out_of_bounds_should_panic() {
811 let buf = Buf2::new((5, 4));
812 let _: i32 = buf[[0, 4]];
813 }
814
815 #[test]
816 #[should_panic = "position (x=0, y=5) out of bounds (0..4, 0..5)"]
817 fn buf_index_row_out_of_bounds_should_panic() {
818 let buf = Buf2::new((4, 5));
819 let _: &[i32] = &buf[5usize];
820 }
821
822 #[test]
823 fn buf_slice_range_full() {
824 let buf: Buf2<()> = Buf2::new((4, 5));
825
826 let slice = buf.slice(..);
827 assert_eq!(slice.width(), 4);
828 assert_eq!(slice.height(), 5);
829 assert_eq!(slice.stride(), 4);
830
831 let slice = buf.slice((.., ..));
832 assert_eq!(slice.width(), 4);
833 assert_eq!(slice.height(), 5);
834 assert_eq!(slice.stride(), 4);
835 }
836
837 #[test]
838 fn buf_slice_range_inclusive() {
839 let buf: Buf2<()> = Buf2::new((4, 5));
840 let slice = buf.slice((1..=3, 0..=3));
841 assert_eq!(slice.width(), 3);
842 assert_eq!(slice.height(), 4);
843 assert_eq!(slice.stride(), 4);
844 }
845
846 #[test]
847 fn buf_slice_range_to() {
848 let buf: Buf2<()> = Buf2::new((4, 5));
849
850 let slice = buf.slice((..2, ..4));
851 assert_eq!(slice.width(), 2);
852 assert_eq!(slice.height(), 4);
853 assert_eq!(slice.stride(), 4);
854 }
855
856 #[test]
857 fn buf_slice_range_from() {
858 let buf: Buf2<()> = Buf2::new((4, 5));
859
860 let slice = buf.slice((3.., 2..));
861 assert_eq!(slice.width(), 1);
862 assert_eq!(slice.height(), 3);
863 assert_eq!(slice.stride(), 4);
864 }
865
866 #[test]
867 fn buf_slice_empty_range() {
868 let buf: Buf2<()> = Buf2::new((4, 5));
869
870 let empty = buf.slice(pt2(1, 1)..pt2(1, 3));
871 assert_eq!(empty.width(), 0);
872 assert_eq!(empty.height(), 2);
873 assert_eq!(empty.stride(), 4);
874
875 let empty = buf.slice(pt2(1, 1)..pt2(3, 1));
876 assert_eq!(empty.width(), 2);
877 assert_eq!(empty.height(), 0);
878 assert_eq!(empty.stride(), 4);
879 }
880
881 #[test]
882 #[should_panic = "range right (5) > width (4)"]
883 fn buf_slice_x_out_of_bounds_should_panic() {
884 let buf: Buf2<()> = Buf2::new((4, 5));
885 buf.slice((0..5, 1..3));
886 }
887
888 #[test]
889 #[should_panic = "range bottom (6) > height (5)"]
890 fn buf_slice_y_out_of_bounds_should_panic() {
891 let buf: Buf2<()> = Buf2::new((4, 5));
892 buf.slice((1..3, 0..6));
893 }
894
895 #[test]
896 #[should_panic = "width (4) > stride (3)"]
897 fn slice_stride_less_than_width_should_panic() {
898 let _ = Slice2::new((4, 4), 3, &[0; 16]);
899 }
900
901 #[test]
902 #[should_panic = "required size (19) > data length (16)"]
903 fn slice_larger_than_data_should_panic() {
904 let _ = Slice2::new((4, 4), 5, &[0; 16]);
905 }
906
907 #[test]
908 fn slice_extents() {
909 let buf: Buf2<()> = Buf2::new((10, 10));
910
911 let slice = buf.slice((1..4, 2..8));
912 assert_eq!(slice.width(), 3);
913 assert_eq!(slice.height(), 6);
914 assert_eq!(slice.stride(), 10);
915 assert_eq!(slice.data().len(), 5 * 10 + 3);
916 }
917
918 #[test]
919 fn slice_contiguity() {
920 let buf: Buf2<()> = Buf2::new((10, 10));
921 assert!(buf.is_contiguous());
923
924 assert!(buf.slice((2..2, 2..8)).is_contiguous());
926 assert!(buf.slice((2..8, 2..2)).is_contiguous());
927 assert!(buf.slice((2..8, 2..3)).is_contiguous());
929 assert!(buf.slice((0..10, 2..8)).is_contiguous());
931 assert!(buf.slice((.., 2..8)).is_contiguous());
932
933 assert!(!buf.slice((2..=2, 1..9)).is_contiguous());
935 assert!(!buf.slice((2..4, 0..9)).is_contiguous());
936 assert!(!buf.slice((2..4, 1..10)).is_contiguous());
937 }
938
939 #[test]
940 #[rustfmt::skip]
941 fn slice_fill() {
942 let mut buf = Buf2::new((5, 4));
943 let mut slice = buf.slice_mut((2.., 1..3));
944
945 slice.fill(1);
946
947 assert_eq!(
948 buf.data(),
949 &[0, 0, 0, 0, 0,
950 0, 0, 1, 1, 1,
951 0, 0, 1, 1, 1,
952 0, 0, 0, 0, 0]
953 );
954 }
955
956 #[test]
957 #[rustfmt::skip]
958 fn slice_fill_with() {
959 let mut buf = Buf2::new((5, 4));
960 let mut slice = buf.slice_mut((2.., 1..3));
961
962 slice.fill_with(|x, y| x + y);
963
964 assert_eq!(
965 buf.data(),
966 &[0, 0, 0, 0, 0,
967 0, 0, 0, 1, 2,
968 0, 0, 1, 2, 3,
969 0, 0, 0, 0, 0]
970 );
971 }
972
973 #[test]
974 #[rustfmt::skip]
975 fn slice_copy_from() {
976 let mut dest = Buf2::new((5, 4));
977 let src = Buf2::new_with((3, 3), |x, y| x + y);
978
979 dest.slice_mut((1..4, 1..)).copy_from(src);
980
981 assert_eq!(
982 dest.data(),
983 &[0, 0, 0, 0, 0,
984 0, 0, 1, 2, 0,
985 0, 1, 2, 3, 0,
986 0, 2, 3, 4, 0]
987 );
988 }
989
990 #[test]
991 fn slice_index() {
992 let buf = Buf2::new_with((5, 4), |x, y| x * 10 + y);
993 let slice = buf.slice((2.., 1..3));
994
995 assert_eq!(slice[[0, 0]], 21);
996 assert_eq!(slice[[1, 0]], 31);
997 assert_eq!(slice[[2, 1]], 42);
998
999 assert_eq!(slice.get([2, 1]), Some(&42));
1000 assert_eq!(slice.get([2, 2]), None);
1001 }
1002
1003 #[test]
1004 fn slice_index_mut() {
1005 let mut buf = Buf2::new_with((5, 5), |x, y| x * 10 + y);
1006 let mut slice = buf.slice_mut((2.., 1..3));
1007
1008 slice[[2, 1]] = 123;
1009 assert_eq!(slice[[2, 1]], 123);
1010
1011 assert_eq!(slice.get_mut([2, 1]), Some(&mut 123));
1012 assert_eq!(slice.get([2, 2]), None);
1013
1014 buf[[2, 2]] = 321;
1015 let slice = buf.slice((1.., 2..));
1016 assert_eq!(slice[[1, 0]], 321);
1017 }
1018
1019 #[test]
1020 fn slice_rows() {
1021 let buf = Buf2::new_with((5, 4), |x, y| x * 10 + y);
1022 let slice = buf.slice((2..4, 1..));
1023
1024 let mut rows = slice.rows();
1025 assert_eq!(rows.next(), Some(&[21, 31][..]));
1026 assert_eq!(rows.next(), Some(&[22, 32][..]));
1027 assert_eq!(rows.next(), Some(&[23, 33][..]));
1028 assert_eq!(rows.next(), None);
1029 }
1030
1031 #[test]
1032 fn slice_rows_mut() {
1033 let mut buf = Buf2::new_with((5, 4), |x, y| x * 10 + y);
1034 let mut slice = buf.slice_mut((2..4, 1..));
1035
1036 let mut rows = slice.rows_mut();
1037 assert_eq!(rows.next(), Some(&mut [21, 31][..]));
1038 assert_eq!(rows.next(), Some(&mut [22, 32][..]));
1039 assert_eq!(rows.next(), Some(&mut [23, 33][..]));
1040 assert_eq!(rows.next(), None);
1041 }
1042
1043 #[test]
1044 fn buf_ref_as_slice() {
1045 fn foo<T: AsSlice2<u32>>(buf: T) -> u32 {
1046 buf.as_slice2().width()
1047 }
1048 let buf = Buf2::new((2, 2));
1049 let w = foo(&buf);
1050 assert_eq!(w, buf.width());
1051 }
1052
1053 #[test]
1054 fn buf_ref_as_slice_mut() {
1055 fn foo<T: AsMutSlice2<u32>>(mut buf: T) {
1056 buf.as_mut_slice2()[[1, 1]] = 42;
1057 }
1058 let mut buf = Buf2::new((2, 2));
1059 foo(&mut buf);
1060 assert_eq!(buf[[1, 1]], 42);
1061 }
1062}