1use alloc::{vec, vec::Vec};
6use core::fmt::{Debug, Formatter};
7use core::ops::{Deref, DerefMut};
8
9use crate::util::Dims;
10use inner::Inner;
11
12pub trait AsSlice2<T> {
18 fn as_slice2(&self) -> Slice2<T>;
20}
21
22pub trait AsMutSlice2<T> {
25 fn as_mut_slice2(&mut self) -> MutSlice2<T>;
27}
28
29#[derive(Clone)]
59#[repr(transparent)]
60pub struct Buf2<T>(Inner<T, Vec<T>>);
61
62#[derive(Copy, Clone)]
76#[repr(transparent)]
77pub struct Slice2<'a, T>(Inner<T, &'a [T]>);
78
79#[repr(transparent)]
82pub struct MutSlice2<'a, T>(Inner<T, &'a mut [T]>);
83
84impl<T> Buf2<T> {
89 pub fn new_from<I>(dims: Dims, init: I) -> Self
95 where
96 I: IntoIterator<Item = T>,
97 {
98 let len = (dims.0 * dims.1) as usize;
99 let data: Vec<_> = init.into_iter().take(len).collect();
100 assert_eq!(data.len(), len);
101 Self(Inner::new(dims, dims.0, data))
102 }
103 pub fn new(dims: Dims) -> Self
106 where
107 T: Clone + Default,
108 {
109 let data = vec![T::default(); (dims.0 * dims.1) as usize];
110 Self(Inner::new(dims, dims.0, data))
111 }
112 pub fn new_with<F>(dims: Dims, init_fn: F) -> Self
116 where
117 F: Clone + FnMut(u32, u32) -> T,
118 {
119 let init = (0..dims.1).flat_map(move |y| {
120 let mut init_fn = init_fn.clone();
121 (0..dims.0).map(move |x| init_fn(x, y)) });
123 Self::new_from(dims, init)
124 }
125
126 pub fn data(&self) -> &[T] {
128 self.0.data()
129 }
130 pub fn data_mut(&mut self) -> &mut [T] {
132 self.0.data_mut()
133 }
134}
135
136impl<'a, T> Slice2<'a, T> {
137 pub fn new(dims: Dims, stride: u32, data: &'a [T]) -> Self {
167 Self(Inner::new(dims, stride, data))
168 }
169}
170
171impl<'a, T> MutSlice2<'a, T> {
172 pub fn new(dims: Dims, stride: u32, data: &'a mut [T]) -> Self {
177 Self(Inner::new(dims, stride, data))
178 }
179}
180
181impl<T> AsSlice2<T> for Buf2<T> {
186 #[inline]
187 fn as_slice2(&self) -> Slice2<T> {
188 self.0.as_slice2()
189 }
190}
191impl<T> AsSlice2<T> for &Buf2<T> {
192 #[inline]
193 fn as_slice2(&self) -> Slice2<T> {
194 self.0.as_slice2()
195 }
196}
197impl<T> AsSlice2<T> for Slice2<'_, T> {
198 #[inline]
199 fn as_slice2(&self) -> Slice2<T> {
200 self.0.as_slice2()
201 }
202}
203impl<T> AsSlice2<T> for MutSlice2<'_, T> {
204 #[inline]
205 fn as_slice2(&self) -> Slice2<T> {
206 self.0.as_slice2()
207 }
208}
209
210impl<T> AsMutSlice2<T> for Buf2<T> {
211 #[inline]
212 fn as_mut_slice2(&mut self) -> MutSlice2<T> {
213 self.0.as_mut_slice2()
214 }
215}
216impl<T> AsMutSlice2<T> for &mut Buf2<T> {
217 #[inline]
218 fn as_mut_slice2(&mut self) -> MutSlice2<T> {
219 self.0.as_mut_slice2()
220 }
221}
222impl<T> AsMutSlice2<T> for MutSlice2<'_, T> {
223 #[inline]
224 fn as_mut_slice2(&mut self) -> MutSlice2<T> {
225 self.0.as_mut_slice2()
226 }
227}
228
229impl<T> Debug for Buf2<T> {
234 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
235 self.0.debug_fmt(f, "Buf2")
236 }
237}
238impl<T> Debug for Slice2<'_, T> {
239 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
240 self.0.debug_fmt(f, "Slice2")
241 }
242}
243impl<T> Debug for MutSlice2<'_, T> {
244 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
245 self.0.debug_fmt(f, "Slice2Mut")
246 }
247}
248
249impl<T> Deref for Buf2<T> {
250 type Target = Inner<T, Vec<T>>;
251
252 fn deref(&self) -> &Self::Target {
253 &self.0
254 }
255}
256impl<'a, T> Deref for Slice2<'a, T> {
257 type Target = Inner<T, &'a [T]>;
258
259 fn deref(&self) -> &Self::Target {
260 &self.0
261 }
262}
263impl<'a, T> Deref for MutSlice2<'a, T> {
264 type Target = Inner<T, &'a mut [T]>;
265 fn deref(&self) -> &Self::Target {
266 &self.0
267 }
268}
269
270impl<T> DerefMut for Buf2<T> {
271 fn deref_mut(&mut self) -> &mut Self::Target {
272 &mut self.0
273 }
274}
275impl<'a, T> DerefMut for MutSlice2<'a, T> {
276 fn deref_mut(&mut self) -> &mut Self::Target {
277 &mut self.0
278 }
279}
280
281mod inner {
282 use core::fmt::Formatter;
283 use core::marker::PhantomData;
284 use core::ops::{Deref, DerefMut, Index, IndexMut, Range};
285
286 use crate::math::vec::Vec2u;
287 use crate::util::rect::Rect;
288 use crate::util::Dims;
289
290 use super::{AsSlice2, MutSlice2, Slice2};
291
292 #[derive(Copy, Clone)]
295 pub struct Inner<T, D> {
296 dims: Dims,
297 stride: u32,
298 data: D,
299 _pd: PhantomData<T>,
300 }
301
302 impl<T, D> Inner<T, D> {
303 #[inline]
305 pub fn width(&self) -> u32 {
306 self.dims.0
307 }
308 #[inline]
310 pub fn height(&self) -> u32 {
311 self.dims.1
312 }
313 #[inline]
315 pub fn stride(&self) -> u32 {
316 self.stride
317 }
318 pub fn is_contiguous(&self) -> bool {
325 let (w, h) = self.dims;
326 self.stride == w || h <= 1 || w == 0
327 }
328 pub fn is_empty(&self) -> bool {
330 self.dims.0 == 0 || self.dims.1 == 0
331 }
332
333 #[inline]
334 fn to_index(&self, x: u32, y: u32) -> usize {
335 (y * self.stride + x) as usize
336 }
337 #[inline]
338 fn to_index_strict(&self, x: u32, y: u32) -> usize {
339 self.to_index_checked(x, y).unwrap_or_else(|| {
340 let (w, h) = self.dims;
341 panic!(
342 "position (x={x}, y={y}) out of bounds (0..{w}, 0..{h})",
343 )
344 })
345 }
346 #[inline]
347 fn to_index_checked(&self, x: u32, y: u32) -> Option<usize> {
348 let (w, h) = self.dims;
349 (x < w && y < h).then(|| self.to_index(x, y))
350 }
351
352 fn resolve_bounds(&self, rect: &Rect<u32>) -> (Dims, Range<usize>) {
353 let (w, h) = self.dims;
354 let l = rect.left.unwrap_or(0);
355 let t = rect.top.unwrap_or(0);
356 let r = rect.right.unwrap_or(w);
357 let b = rect.bottom.unwrap_or(h);
358
359 assert!(l <= r, "range left ({l}) > right ({r})");
360 assert!(t <= b, "range top ({l}) > bottom ({r})");
361 assert!(r <= w, "range right ({r}) > width ({w})");
362 assert!(b <= h, "range bottom ({b}) > height ({h})");
363
364 let start = self.to_index(l, t);
365 let end = if b == t {
367 self.to_index(r, t)
368 } else {
369 self.to_index(r, b - 1)
371 };
372 ((r - l, b - t), start..end)
373 }
374
375 pub(super) fn debug_fmt(
377 &self,
378 f: &mut Formatter,
379 name: &str,
380 ) -> core::fmt::Result {
381 f.debug_struct(name)
382 .field("dims", &self.dims)
383 .field("stride", &self.stride)
384 .finish()
385 }
386 }
387
388 impl<T, D: Deref<Target = [T]>> Inner<T, D> {
389 #[rustfmt::skip]
392 pub(super) fn new(dims: Dims, stride: u32, data: D) -> Self {
393 let (w, h) = dims;
394 let len = data.len() as u32;
395 assert!(w <= stride, "width ({w}) > stride ({stride})");
396 assert!(
397 h <= 1 || stride <= len,
398 "stride ({stride}) > data length ({len})"
399 );
400 assert!(h <= len, "height ({h}) > data length ({len})");
401 if h > 0 {
402 let size = (h - 1) * stride + w;
403 assert!(
404 size <= len,
405 "required size ({size}) > data length ({len})"
406 );
407 }
408 Self { dims, stride, data, _pd: PhantomData }
409 }
410
411 pub(super) fn data(&self) -> &[T] {
413 &self.data
414 }
415
416 pub fn as_slice2(&self) -> Slice2<T> {
418 Slice2::new(self.dims, self.stride, &self.data)
419 }
420
421 pub fn slice(&self, rect: impl Into<Rect>) -> Slice2<T> {
426 let (dims, rg) = self.resolve_bounds(&rect.into());
427 Slice2::new(dims, self.stride, &self.data[rg])
428 }
429
430 pub fn get(&self, pos: impl Into<Vec2u>) -> Option<&T> {
433 let [x, y] = pos.into().0;
434 self.to_index_checked(x, y).map(|i| &self.data[i])
435 }
436
437 pub fn rows(&self) -> impl Iterator<Item = &[T]> {
440 self.data
441 .chunks(self.stride as usize)
442 .map(|row| &row[..self.dims.0 as usize])
443 }
444
445 pub fn iter(&self) -> impl Iterator<Item = &'_ T> {
449 self.rows().flatten()
450 }
451 }
452
453 impl<T, D: DerefMut<Target = [T]>> Inner<T, D> {
454 pub fn as_mut_slice2(&mut self) -> MutSlice2<T> {
456 MutSlice2::new(self.dims, self.stride, &mut self.data)
457 }
458 pub(super) fn data_mut(&mut self) -> &mut [T] {
460 &mut self.data
461 }
462 pub fn rows_mut(&mut self) -> impl Iterator<Item = &mut [T]> {
465 self.data
466 .chunks_mut(self.stride as usize)
467 .map(|row| &mut row[..self.dims.0 as usize])
468 }
469
470 pub fn iter_mut(&mut self) -> impl Iterator<Item = &'_ mut T> {
474 self.rows_mut().flatten()
475 }
476
477 pub fn fill(&mut self, val: T)
479 where
480 T: Clone,
481 {
482 if self.is_contiguous() {
483 self.data.fill(val);
484 } else {
485 self.rows_mut()
486 .for_each(|row| row.fill(val.clone()));
487 }
488 }
489 pub fn fill_with<F>(&mut self, mut fill_fn: F)
492 where
493 F: Copy + FnMut(u32, u32) -> T,
494 {
495 let (w, h) = self.dims;
496 let mut fill = (0..h).flat_map(move |y| {
497 (0..w).map(move |x| fill_fn(x, y)) });
499 if self.is_contiguous() {
500 self.data.fill_with(|| fill.next().unwrap());
501 } else {
502 self.rows_mut().for_each(|row| {
503 row.fill_with(|| fill.next().unwrap()); })
505 }
506 }
507
508 #[doc(alias = "blit")]
515 pub fn copy_from(&mut self, src: impl AsSlice2<T>)
516 where
517 T: Copy,
518 {
519 let src = src.as_slice2();
520 let (sw, sh) = self.dims;
521 let (ow, oh) = src.dims;
522 assert_eq!(sw, ow, "width ({sw}) != source width ({ow})",);
523 assert_eq!(sh, oh, "height ({sh}) != source height ({oh})",);
524 for (dest, src) in self.rows_mut().zip(src.rows()) {
525 dest.copy_from_slice(src);
526 }
527 }
528
529 pub fn get_mut(&mut self, pos: impl Into<Vec2u>) -> Option<&mut T> {
532 let [x, y] = pos.into().0;
533 self.to_index_checked(x, y)
534 .map(|i| &mut self.data[i])
535 }
536
537 pub fn slice_mut(&mut self, rect: impl Into<Rect>) -> MutSlice2<T> {
542 let (dims, rg) = self.resolve_bounds(&rect.into());
543 MutSlice2(Inner::new(dims, self.stride, &mut self.data[rg]))
544 }
545 }
546
547 impl<T, D: Deref<Target = [T]>> Index<usize> for Inner<T, D> {
548 type Output = [T];
549
550 #[inline]
553 fn index(&self, i: usize) -> &[T] {
554 let idx = self.to_index_strict(0, i as u32);
555 let w = self.dims.0 as usize;
556 &self.data[idx..][..w]
557 }
558 }
559
560 impl<T, D> IndexMut<usize> for Inner<T, D>
561 where
562 Self: Index<usize, Output = [T]>,
563 D: DerefMut<Target = [T]>,
564 {
565 #[inline]
568 fn index_mut(&mut self, row: usize) -> &mut [T] {
569 let idx = self.to_index_strict(0, row as u32);
570 let w = self.dims.0 as usize;
571 &mut self.data[idx..][..w]
572 }
573 }
574
575 impl<T, D, Pos> Index<Pos> for Inner<T, D>
576 where
577 D: Deref<Target = [T]>,
578 Pos: Into<Vec2u>,
579 {
580 type Output = T;
581
582 #[inline]
586 fn index(&self, pos: Pos) -> &T {
587 let [x, y] = pos.into().0;
588 &self.data[self.to_index_strict(x, y)]
589 }
590 }
591
592 impl<T, D, Pos> IndexMut<Pos> for Inner<T, D>
593 where
594 D: DerefMut<Target = [T]>,
595 Pos: Into<Vec2u>,
596 {
597 #[inline]
602 fn index_mut(&mut self, pos: Pos) -> &mut T {
603 let [x, y] = pos.into().0;
604 let idx = self.to_index_strict(x, y);
605 &mut self.data[idx]
606 }
607 }
608}
609
610#[cfg(test)]
611mod tests {
612 use crate::math::vec::vec2;
613
614 use super::*;
615
616 #[test]
617 fn buf_new_from() {
618 let buf = Buf2::new_from((3, 2), 1..);
619 assert_eq!(buf.data(), &[1, 2, 3, 4, 5, 6]);
620 }
621
622 #[test]
623 fn buf_new() {
624 let buf: Buf2<i32> = Buf2::new((3, 2));
625 assert_eq!(buf.data(), &[0, 0, 0, 0, 0, 0]);
626 }
627
628 #[test]
629 fn buf_new_with() {
630 let buf = Buf2::new_with((3, 2), |x, y| x + y);
631 assert_eq!(buf.data(), &[0, 1, 2, 1, 2, 3]);
632 }
633
634 #[test]
635 fn buf_extents() {
636 let buf: Buf2<()> = Buf2::new((4, 5));
637 assert_eq!(buf.width(), 4);
638 assert_eq!(buf.height(), 5);
639 assert_eq!(buf.stride(), 4);
640 }
641
642 #[test]
643 fn buf_index_and_get() {
644 let buf = Buf2::new_with((4, 5), |x, y| x * 10 + y);
645
646 assert_eq!(buf[2usize], [2, 12, 22, 32]);
647
648 assert_eq!(buf[[0, 0]], 0);
649 assert_eq!(buf[vec2(1, 0)], 10);
650 assert_eq!(buf[vec2(3, 4)], 34);
651
652 assert_eq!(buf.get([2, 3]), Some(&23));
653 assert_eq!(buf.get([4, 4]), None);
654 assert_eq!(buf.get([3, 5]), None);
655 }
656
657 #[test]
658 fn buf_index_mut_and_get_mut() {
659 let mut buf = Buf2::new_with((4, 5), |x, y| x * 10 + y);
660
661 buf[2usize][1] = 123;
662 assert_eq!(buf[2usize], [2, 123, 22, 32]);
663
664 buf[vec2(2, 3)] = 234;
665 assert_eq!(buf[[2, 3]], 234);
666
667 *buf.get_mut([3, 4]).unwrap() = 345;
668 assert_eq!(buf.get_mut([3, 4]), Some(&mut 345));
669 assert_eq!(buf.get_mut([4, 4]), None);
670 assert_eq!(buf.get_mut([3, 5]), None);
671 }
672
673 #[test]
674 #[should_panic = "position (x=4, y=0) out of bounds (0..4, 0..5)"]
675 fn buf_index_x_out_of_bounds_should_panic() {
676 let buf = Buf2::new((4, 5));
677 let _: i32 = buf[[4, 0]];
678 }
679
680 #[test]
681 #[should_panic = "position (x=0, y=4) out of bounds (0..5, 0..4)"]
682 fn buf_index_y_out_of_bounds_should_panic() {
683 let buf = Buf2::new((5, 4));
684 let _: i32 = buf[[0, 4]];
685 }
686
687 #[test]
688 #[should_panic = "position (x=0, y=5) out of bounds (0..4, 0..5)"]
689 fn buf_index_row_out_of_bounds_should_panic() {
690 let buf = Buf2::new((4, 5));
691 let _: &[i32] = &buf[5usize];
692 }
693
694 #[test]
695 fn buf_slice_range_full() {
696 let buf: Buf2<()> = Buf2::new((4, 5));
697
698 let slice = buf.slice(..);
699 assert_eq!(slice.width(), 4);
700 assert_eq!(slice.height(), 5);
701 assert_eq!(slice.stride(), 4);
702
703 let slice = buf.slice((.., ..));
704 assert_eq!(slice.width(), 4);
705 assert_eq!(slice.height(), 5);
706 assert_eq!(slice.stride(), 4);
707 }
708
709 #[test]
710 fn buf_slice_range_inclusive() {
711 let buf: Buf2<()> = Buf2::new((4, 5));
712 let slice = buf.slice((1..=3, 0..=3));
713 assert_eq!(slice.width(), 3);
714 assert_eq!(slice.height(), 4);
715 assert_eq!(slice.stride(), 4);
716 }
717
718 #[test]
719 fn buf_slice_range_to() {
720 let buf: Buf2<()> = Buf2::new((4, 5));
721
722 let slice = buf.slice((..2, ..4));
723 assert_eq!(slice.width(), 2);
724 assert_eq!(slice.height(), 4);
725 assert_eq!(slice.stride(), 4);
726 }
727
728 #[test]
729 fn buf_slice_range_from() {
730 let buf: Buf2<()> = Buf2::new((4, 5));
731
732 let slice = buf.slice((3.., 2..));
733 assert_eq!(slice.width(), 1);
734 assert_eq!(slice.height(), 3);
735 assert_eq!(slice.stride(), 4);
736 }
737
738 #[test]
739 fn buf_slice_empty_range() {
740 let buf: Buf2<()> = Buf2::new((4, 5));
741
742 let empty = buf.slice(vec2(1, 1)..vec2(1, 3));
743 assert_eq!(empty.width(), 0);
744 assert_eq!(empty.height(), 2);
745 assert_eq!(empty.stride(), 4);
746
747 let empty = buf.slice(vec2(1, 1)..vec2(3, 1));
748 assert_eq!(empty.width(), 2);
749 assert_eq!(empty.height(), 0);
750 assert_eq!(empty.stride(), 4);
751 }
752
753 #[test]
754 #[should_panic = "range right (5) > width (4)"]
755 fn buf_slice_x_out_of_bounds_should_panic() {
756 let buf: Buf2<()> = Buf2::new((4, 5));
757 buf.slice((0..5, 1..3));
758 }
759
760 #[test]
761 #[should_panic = "range bottom (6) > height (5)"]
762 fn buf_slice_y_out_of_bounds_should_panic() {
763 let buf: Buf2<()> = Buf2::new((4, 5));
764 buf.slice((1..3, 0..6));
765 }
766
767 #[test]
768 #[should_panic = "width (4) > stride (3)"]
769 fn slice_stride_less_than_width_should_panic() {
770 let _ = Slice2::new((4, 4), 3, &[0; 16]);
771 }
772
773 #[test]
774 #[should_panic = "required size (19) > data length (16)"]
775 fn slice_larger_than_data_should_panic() {
776 let _ = Slice2::new((4, 4), 5, &[0; 16]);
777 }
778
779 #[test]
780 fn slice_extents() {
781 let buf: Buf2<()> = Buf2::new((10, 10));
782
783 let slice = buf.slice((1..4, 2..8));
784 assert_eq!(slice.width(), 3);
785 assert_eq!(slice.height(), 6);
786 assert_eq!(slice.stride(), 10);
787 assert_eq!(slice.data().len(), 5 * 10 + 3);
788 }
789
790 #[test]
791 fn slice_contiguity() {
792 let buf: Buf2<()> = Buf2::new((10, 10));
793 assert!(buf.is_contiguous());
795
796 assert!(buf.slice((2..2, 2..8)).is_contiguous());
798 assert!(buf.slice((2..8, 2..2)).is_contiguous());
799 assert!(buf.slice((2..8, 2..3)).is_contiguous());
801 assert!(buf.slice((0..10, 2..8)).is_contiguous());
803 assert!(buf.slice((.., 2..8)).is_contiguous());
804
805 assert!(!buf.slice((2..=2, 1..9)).is_contiguous());
807 assert!(!buf.slice((2..4, 0..9)).is_contiguous());
808 assert!(!buf.slice((2..4, 1..10)).is_contiguous());
809 }
810
811 #[test]
812 #[rustfmt::skip]
813 fn slice_fill() {
814 let mut buf = Buf2::new((5, 4));
815 let mut slice = buf.slice_mut((2.., 1..3));
816
817 slice.fill(1);
818
819 assert_eq!(
820 buf.data(),
821 &[0, 0, 0, 0, 0,
822 0, 0, 1, 1, 1,
823 0, 0, 1, 1, 1,
824 0, 0, 0, 0, 0]
825 );
826 }
827
828 #[test]
829 #[rustfmt::skip]
830 fn slice_fill_with() {
831 let mut buf = Buf2::new((5, 4));
832 let mut slice = buf.slice_mut((2.., 1..3));
833
834 slice.fill_with(|x, y| x + y);
835
836 assert_eq!(
837 buf.data(),
838 &[0, 0, 0, 0, 0,
839 0, 0, 0, 1, 2,
840 0, 0, 1, 2, 3,
841 0, 0, 0, 0, 0]
842 );
843 }
844
845 #[test]
846 #[rustfmt::skip]
847 fn slice_copy_from() {
848 let mut dest = Buf2::new((5, 4));
849 let src = Buf2::new_with((3, 3), |x, y| x + y);
850
851 dest.slice_mut((1..4, 1..)).copy_from(src);
852
853 assert_eq!(
854 dest.data(),
855 &[0, 0, 0, 0, 0,
856 0, 0, 1, 2, 0,
857 0, 1, 2, 3, 0,
858 0, 2, 3, 4, 0]
859 );
860 }
861
862 #[test]
863 fn slice_index() {
864 let buf = Buf2::new_with((5, 4), |x, y| x * 10 + y);
865 let slice = buf.slice((2.., 1..3));
866
867 assert_eq!(slice[vec2(0, 0)], 21);
868 assert_eq!(slice[vec2(1, 0)], 31);
869 assert_eq!(slice[vec2(2, 1)], 42);
870
871 assert_eq!(slice.get(vec2(2, 1)), Some(&42));
872 assert_eq!(slice.get(vec2(2, 2)), None);
873 }
874
875 #[test]
876 fn slice_index_mut() {
877 let mut buf = Buf2::new_with((5, 5), |x, y| x * 10 + y);
878 let mut slice = buf.slice_mut((2.., 1..3));
879
880 slice[[2, 1]] = 123;
881 assert_eq!(slice[vec2(2, 1)], 123);
882
883 assert_eq!(slice.get_mut(vec2(2, 1)), Some(&mut 123));
884 assert_eq!(slice.get(vec2(2, 2)), None);
885
886 buf[[2, 2]] = 321;
887 let slice = buf.slice((1.., 2..));
888 assert_eq!(slice[[1, 0]], 321);
889 }
890
891 #[test]
892 fn slice_rows() {
893 let buf = Buf2::new_with((5, 4), |x, y| x * 10 + y);
894 let slice = buf.slice((2..4, 1..));
895
896 let mut rows = slice.rows();
897 assert_eq!(rows.next(), Some(&[21, 31][..]));
898 assert_eq!(rows.next(), Some(&[22, 32][..]));
899 assert_eq!(rows.next(), Some(&[23, 33][..]));
900 assert_eq!(rows.next(), None);
901 }
902
903 #[test]
904 fn slice_rows_mut() {
905 let mut buf = Buf2::new_with((5, 4), |x, y| x * 10 + y);
906 let mut slice = buf.slice_mut((2..4, 1..));
907
908 let mut rows = slice.rows_mut();
909 assert_eq!(rows.next(), Some(&mut [21, 31][..]));
910 assert_eq!(rows.next(), Some(&mut [22, 32][..]));
911 assert_eq!(rows.next(), Some(&mut [23, 33][..]));
912 assert_eq!(rows.next(), None);
913 }
914
915 #[test]
916 fn buf_ref_as_slice() {
917 fn foo<T: AsSlice2<u32>>(buf: T) -> u32 {
918 buf.as_slice2().width()
919 }
920 let buf = Buf2::new((2, 2));
921 let w = foo(&buf);
922 assert_eq!(w, buf.width());
923 }
924
925 #[test]
926 fn buf_ref_as_slice_mut() {
927 fn foo<T: AsMutSlice2<u32>>(mut buf: T) {
928 buf.as_mut_slice2()[[1, 1]] = 42;
929 }
930 let mut buf = Buf2::new((2, 2));
931 foo(&mut buf);
932 assert_eq!(buf[[1, 1]], 42);
933 }
934}