Advertisement
Guest User

Untitled

a guest
Sep 17th, 2019
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.77 KB | None | 0 0
  1. #![feature(try_trait)]
  2.  
  3. use std::marker::PhantomData;
  4. use std::ops::Try;
  5.  
  6. trait VecExt: Sized {
  7. type T;
  8.  
  9. fn map<U, F: FnMut(Self::T) -> U>(self, mut f: F) -> Vec<U> {
  10. use std::convert::Infallible;
  11.  
  12. match self.try_map(move |x| Ok::<_, Infallible>(f(x))) {
  13. Ok(x) => x,
  14. Err(x) => match x {}
  15. }
  16. }
  17.  
  18. fn try_map<U, R: Try<Ok = U>, F: FnMut(Self::T) -> R>(self, f: F) -> Result<Vec<U>, R::Error>;
  19. }
  20.  
  21. impl<T> VecExt for Vec<T> {
  22. type T = T;
  23.  
  24. fn try_map<U, R: Try<Ok = U>, F: FnMut(Self::T) -> R>(mut self, f: F) -> Result<Vec<U>, R::Error> {
  25. use std::alloc::Layout;
  26.  
  27. if Layout::new::<T>() == Layout::new::<U>() {
  28. let len = self.len();
  29. let cap = self.capacity();
  30. let ptr = self.as_mut_ptr();
  31.  
  32. std::mem::forget(self);
  33.  
  34. let iter = MapIter {
  35. start: ptr as *mut U,
  36. ptr,
  37. init_len: 0,
  38. len,
  39. cap,
  40. drop: PhantomData
  41. };
  42.  
  43. iter.try_into_vec(f)
  44. } else {
  45. self.into_iter().map(f).map(R::into_result).collect()
  46. }
  47. }
  48. }
  49.  
  50. struct MapIter<T, U> {
  51. start: *mut U,
  52. ptr: *mut T,
  53. init_len: usize,
  54. len: usize,
  55. cap: usize,
  56. drop: PhantomData<(T, U)>
  57. }
  58.  
  59. impl<T, U> MapIter<T, U> {
  60. fn try_into_vec<R: Try<Ok = U>, F: FnMut(T) -> R>(mut self, mut f: F) -> Result<Vec<U>, R::Error> {
  61. while self.init_len < self.len {
  62. unsafe {
  63. let value = f(self.ptr.read())?;
  64.  
  65. (self.ptr as *mut U).write(value);
  66.  
  67. self.ptr = self.ptr.add(1);
  68. self.init_len += 1;
  69. }
  70. }
  71.  
  72. let ptr = self.start;
  73. let len = self.len;
  74. let cap = self.cap;
  75.  
  76. // we don't want to free the memory
  77. // which is what dropping this `MapIter` will do
  78. std::mem::forget(self);
  79.  
  80. unsafe {
  81. Ok(Vec::from_raw_parts(ptr, len, cap))
  82. }
  83. }
  84. }
  85.  
  86. impl<T, U> Drop for MapIter<T, U> {
  87. fn drop(&mut self) {
  88. unsafe {
  89. // assert!(std::thread::panicking());
  90.  
  91. // offset by 1 because self.ptr is pointing to
  92. // memory that was just read from, dropping that
  93. // would lead to a double free
  94. std::ptr::drop_in_place(
  95. std::slice::from_raw_parts_mut(
  96. self.ptr.add(1),
  97. self.len - self.init_len - 1,
  98. )
  99. );
  100.  
  101. Vec::from_raw_parts(
  102. self.start,
  103. self.init_len,
  104. self.cap
  105. );
  106. }
  107. }
  108. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement