Advertisement
Guest User

Untitled

a guest
Aug 18th, 2019
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.13 KB | None | 0 0
  1. #![feature(generators, generator_trait, type_alias_impl_trait)]
  2. use std::{
  3. ops::{Generator, GeneratorState},
  4. pin::Pin,
  5. };
  6.  
  7. /// A wrapper struct around Generators,
  8. /// providing a safe implementation of the [`Iterator`] trait.
  9. pub struct GenIter<G>(Option<G>);
  10.  
  11. impl<G: Generator + Unpin> GenIter<G> {
  12. /// Creates a new `GenIter` instance from a generator.
  13. /// The returned instance can be iterated over,
  14. /// consuming the generator.
  15. #[inline]
  16. pub fn new(gen: G) -> Self {
  17. Self(Some(gen))
  18. }
  19. }
  20.  
  21. impl<G: Generator + Unpin> Iterator for GenIter<G> {
  22. type Item = G::Yield;
  23.  
  24. #[inline]
  25. fn next(&mut self) -> Option<Self::Item> {
  26. Pin::new(self).next()
  27. }
  28. }
  29.  
  30. impl<G: Generator> Iterator for Pin<&mut GenIter<G>> {
  31. type Item = G::Yield;
  32.  
  33. fn next(&mut self) -> Option<Self::Item> {
  34. let this: Pin<&mut GenIter<G>> = self.as_mut();
  35.  
  36. // This should be safe.
  37. // this Iterator implementation is on a Pin<&mut GenIter<G>> where G: Generator.
  38. // In order to acquire such a Pin<&mut GenIter<G>> if G does *NOT* implement Unpin,
  39. // the unsafe `new_unchecked` function from the Pin type must be used anyway.
  40. //
  41. // Note that if G: Unpin, the Iterator implementation of GenIter<G> itself is used,
  42. // which just creates a Pin safely, and then delegates to this implementation.
  43. let gen: Pin<&mut Option<G>> = unsafe { this.map_unchecked_mut(|geniter| &mut geniter.0) };
  44.  
  45. let gen: Option<Pin<&mut G>> = Option::as_pin_mut(gen);
  46.  
  47. match gen.map(Generator::resume) {
  48. Some(GeneratorState::Yielded(y)) => Some(y),
  49. Some(GeneratorState::Complete(_)) => {
  50. self.set(GenIter(None));
  51. None
  52. }
  53. None => None,
  54. }
  55. }
  56. }
  57.  
  58. macro_rules! try_yield {
  59. ($option:expr) => {
  60. match $option {
  61. Some(x) => yield x,
  62. None => return,
  63. }
  64. };
  65. }
  66.  
  67. macro_rules! iter {
  68. ($($b:tt)*) => {
  69. $crate::GenIter::new(move || { $($b)* })
  70. };
  71. }
  72.  
  73. trait AlternateExt: Iterator {
  74. type Alternate: Iterator<Item = Self::Item>;
  75.  
  76. fn alternate(self) -> Self::Alternate;
  77. }
  78.  
  79. impl <I: DoubleEndedIterator> AlternateExt for I {
  80. type Alternate = impl Iterator<Item = Self::Item>;
  81.  
  82. fn alternate(mut self) -> Self::Alternate {
  83. iter! {
  84. loop {
  85. try_yield!(self.next());
  86. try_yield!(self.next_back());
  87. }
  88. }
  89. }
  90. }
  91.  
  92. trait AlternateByExt: Iterator {
  93. type AlternateBy: Iterator<Item = Self::Item>;
  94.  
  95. fn alternate_by(self, count: usize) -> Self::AlternateBy;
  96. }
  97.  
  98. impl <I: DoubleEndedIterator> AlternateByExt for I {
  99. type AlternateBy = impl Iterator<Item = Self::Item>;
  100.  
  101. fn alternate_by(mut self, count: usize) -> Self::AlternateBy {
  102. iter! {
  103. loop {
  104. for _ in 0..count {
  105. try_yield!(self.next());
  106. }
  107. for _ in 0..count {
  108. try_yield!(self.next_back());
  109. }
  110. }
  111. }
  112. }
  113. }
  114.  
  115. fn main() {
  116. for x in (0..10).alternate_by(3) {
  117. dbg!(x);
  118. }
  119. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement