Guest User

Untitled

a guest
Nov 16th, 2018
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.28 KB | None | 0 0
  1. #[derive(Clone, Debug)]
  2. pub struct Grid<T> {
  3. width: usize,
  4. height: usize,
  5. // data.len() == width * height
  6. data: Box<[T]>,
  7. }
  8.  
  9. /// An `Iterator<Item = (Coord, &mut T)>` over a sub-section of a Grid<T>.
  10. pub struct IterRectMut<'a, T: 'a> {
  11. // Iterator over the subrect
  12. ri: RectIter,
  13. grid_width: usize,
  14. // XXX: can this be `&mut [T]` safely?
  15. // XXX: if not, can/should it and len be replaced by `*mut [T]`?
  16. data: *mut T,
  17. len: usize,
  18. // Is this the right param?
  19. _marker: std::marker::PhantomData<&'a mut T>,
  20. }
  21.  
  22. impl<T> Grid<T> {
  23. pub fn iter_rect_mut(&mut self, c: Coord, w: usize, h: usize) -> IterRectMut<T> {
  24. assert!(self.contains_entire_rect(c, w, h));
  25. IterRectMut {
  26. ri: rect_iter(c, w, h),
  27. grid_width: self.width,
  28. len: self.data.len(),
  29. data: self.data.as_mut_ptr(),
  30. _marker: std::marker::PhantomData,
  31. }
  32. }
  33. }
  34.  
  35. impl<'a, T: 'a> Iterator for IterRectMut<'a, T> {
  36. type Item = (Coord, &'a mut T);
  37. #[inline]
  38. fn next(&mut self) -> Option<Self::Item> {
  39. let c = self.ri.next()?;
  40. let xu = c.x as usize;
  41. let yu = c.y as usize;
  42. assert!(xu < self.grid_width && yu < (self.len / self.grid_width));
  43.  
  44. let idx = xu + yu * self.grid_width;
  45. assert!(idx < self.len);
  46. let item = unsafe { &mut *self.data.add(idx) };
  47. Some((c, item))
  48. }
  49. }
  50.  
  51. // Misc details below, not really what I'm asking about but included to make
  52. // things compile and for clarity. I've cut out as much as I reasonably could.
  53. // at the bottom there's a (not super relevant) example
  54.  
  55. impl<T> Grid<T> {
  56. pub fn contains_entire_rect(&self, c: Coord, w: usize, h: usize) -> bool {
  57. if c.x < 0 || c.y < 0 {
  58. return false;
  59. }
  60. let right = (c.x as usize).saturating_add(w);
  61. let bottom = (c.y as usize).saturating_add(h);
  62. right <= self.width && bottom <= self.height
  63. }
  64.  
  65. pub fn new(width: usize, height: usize, data: Box<[T]>) -> Self {
  66. assert_eq!(width * height, data.len());
  67. Self { width, height, data }
  68. }
  69.  
  70. pub fn build<F: FnMut(Coord) -> T>(width: usize, height: usize, mut builder: F) -> Grid<T> {
  71. let mut data = Vec::with_capacity(width * height);
  72. for y in 0..height {
  73. for x in 0..width {
  74. data.push(builder(Coord::new(x as i32, y as i32)));
  75. }
  76. }
  77. Grid::new(width, height, data.into())
  78. }
  79. }
  80. // Several things omitted for simplicity
  81. #[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord, Debug, Default)]
  82. pub struct Coord { pub x: i32, pub y: i32 }
  83. impl Coord {
  84. pub fn new(x: i32, y: i32) -> Self { Self { x, y } }
  85. }
  86.  
  87. // Several things omitted for simplicity
  88. #[derive(Copy, Clone, Eq, Hash, PartialEq, PartialOrd, Ord, Debug)]
  89. pub struct RectIter {
  90. ix: usize, iy: usize,
  91. w: usize, h: usize,
  92. c: Coord
  93. }
  94.  
  95. #[inline]
  96. pub fn rect_iter(c: Coord, w: usize, h: usize) -> RectIter {
  97. let h = if w == 0 { 0 } else { h };
  98. RectIter { ix: 0, iy: 0, w, h, c }
  99. }
  100.  
  101. impl Iterator for RectIter {
  102. type Item = Coord;
  103. #[inline]
  104. fn next(&mut self) -> Option<Self::Item> {
  105. if self.iy >= self.h {
  106. return None;
  107. }
  108. // Checked on construction
  109. debug_assert!(self.w != 0);
  110. let item = Coord::new(
  111. self.ix as i32 + self.c.x,
  112. self.iy as i32 + self.c.y
  113. );
  114. self.ix += 1;
  115. if self.ix >= self.w {
  116. self.ix = 0;
  117. self.iy += 1;
  118. }
  119. Some(item)
  120. }
  121. // more crap omitted here
  122. }
  123.  
  124.  
  125. // not super relevant example
  126. fn main() {
  127. let mut g = Grid::build(5, 5, |c| (c, 0u8));
  128.  
  129. for (coord, cell) in g.iter_rect_mut(Coord::new(1, 1), 3, 3) {
  130. assert_eq!(coord, cell.0);
  131. cell.1 += 1;
  132. }
  133. assert_eq!(&g.data.iter().map(|(_, n)| *n).collect::<Vec<_>>(), &[
  134. 0, 0, 0, 0, 0,
  135. 0, 1, 1, 1, 0,
  136. 0, 1, 1, 1, 0,
  137. 0, 1, 1, 1, 0,
  138. 0, 0, 0, 0, 0,
  139. ]);
  140.  
  141. for (coord, cell) in g.iter_rect_mut(Coord::new(0, 0), 5, 5) {
  142. assert_eq!(coord, cell.0);
  143. cell.1 += 1;
  144. }
  145.  
  146. assert_eq!(&g.data.iter().map(|(_, n)| *n).collect::<Vec<_>>(), &[
  147. 1, 1, 1, 1, 1,
  148. 1, 2, 2, 2, 1,
  149. 1, 2, 2, 2, 1,
  150. 1, 2, 2, 2, 1,
  151. 1, 1, 1, 1, 1,
  152. ]);
  153. }
Add Comment
Please, Sign In to add comment