Guest User

Untitled

a guest
Oct 21st, 2018
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.86 KB | None | 0 0
  1. use std::mem::{ManuallyDrop, zeroed};
  2. use std::ptr;
  3.  
  4. const MAX_ARRAY_INTO_ITER_SIZE: usize = 8;
  5.  
  6. #[derive(Clone)]
  7. struct ArrayIntoIter<T> {
  8. data: ManuallyDrop<[T; MAX_ARRAY_INTO_ITER_SIZE]>,
  9. len: usize,
  10. cur: usize,
  11. }
  12.  
  13. impl<T> Iterator for ArrayIntoIter<T> {
  14. type Item = T;
  15.  
  16. fn next(&mut self) -> Option<Self::Item> {
  17. if self.cur >= self.len {
  18. return None;
  19. }
  20.  
  21. let idx = self.cur;
  22. self.cur += 1;
  23. Some(unsafe { ptr::read(self.data.get_unchecked_mut(idx)) })
  24. }
  25. }
  26.  
  27. impl<T> Drop for ArrayIntoIter<T> {
  28. fn drop(&mut self) {
  29. unsafe {
  30. let elems = std::slice::from_raw_parts_mut(
  31. self.data.get_unchecked_mut(self.cur) as *mut T,
  32. self.len - self.cur
  33. );
  34.  
  35. self.len = 0;
  36. self.cur = 0;
  37. std::ptr::drop_in_place(elems);
  38. }
  39. }
  40. }
  41.  
  42. trait IntoIterator {
  43. type Item;
  44. type IntoIter: Iterator<Item = Self::Item>;
  45. fn into_iter(self) -> Self::IntoIter;
  46. }
  47.  
  48. macro_rules! array_intoiter {
  49. ($($n:expr),+) => { $(
  50. impl<T> IntoIterator for [T; $n] {
  51. type Item = T;
  52. type IntoIter = ArrayIntoIter<T>;
  53.  
  54. fn into_iter(self) -> Self::IntoIter {
  55. let len = self.len();
  56. ArrayIntoIter {
  57. data: ManuallyDrop::new(unsafe {
  58. let mut data: [T; MAX_ARRAY_INTO_ITER_SIZE] = zeroed();
  59. ptr::copy_nonoverlapping(self.as_ptr(), data.as_mut_ptr(), $n);
  60. data
  61. }),
  62. len,
  63. cur: 0,
  64. }
  65. }
  66. }
  67. )+ }
  68. }
  69.  
  70. array_intoiter!(0, 1, 2, 3, 4, 5, 6, 7, 8);
  71.  
  72. fn main() {
  73. // All perfectly safe code.
  74. let array: [&i32; 0] = [];
  75. let iter = array.into_iter();
  76. println!("{:?}", Some(iter).is_some());
  77. }
Add Comment
Please, Sign In to add comment