|  | 
| 1 | 1 | use crate::ffi::OsString; | 
| 2 | 2 | use crate::fmt; | 
|  | 3 | +use crate::num::NonZero; | 
| 3 | 4 | use crate::sys::os_str; | 
| 4 | 5 | use crate::sys::pal::{WORD_SIZE, abi}; | 
| 5 | 6 | use crate::sys_common::FromInner; | 
| 6 | 7 | 
 | 
|  | 8 | +#[derive(Clone)] | 
| 7 | 9 | pub struct Args { | 
| 8 |  | -    i_forward: usize, | 
| 9 |  | -    i_back: usize, | 
| 10 |  | -    count: usize, | 
|  | 10 | +    front: usize, | 
|  | 11 | +    back: usize, | 
| 11 | 12 | } | 
| 12 | 13 | 
 | 
| 13 | 14 | pub fn args() -> Args { | 
| 14 | 15 |     let count = unsafe { abi::sys_argc() }; | 
| 15 |  | -    Args { i_forward: 0, i_back: 0, count } | 
|  | 16 | +    Args { front: 0, back: count } | 
| 16 | 17 | } | 
| 17 | 18 | 
 | 
| 18 | 19 | impl Args { | 
| @@ -40,42 +41,75 @@ impl Args { | 
| 40 | 41 | 
 | 
| 41 | 42 | impl fmt::Debug for Args { | 
| 42 | 43 |     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | 
| 43 |  | -        f.debug_list().finish() | 
|  | 44 | +        f.debug_list().entries(self.clone()).finish() | 
| 44 | 45 |     } | 
| 45 | 46 | } | 
| 46 | 47 | 
 | 
| 47 | 48 | impl Iterator for Args { | 
| 48 | 49 |     type Item = OsString; | 
| 49 | 50 | 
 | 
|  | 51 | +    #[inline] | 
| 50 | 52 |     fn next(&mut self) -> Option<OsString> { | 
| 51 |  | -        if self.i_forward >= self.count - self.i_back { | 
|  | 53 | +        if self.front == self.back { | 
| 52 | 54 |             None | 
| 53 | 55 |         } else { | 
| 54 |  | -            let arg = Self::argv(self.i_forward); | 
| 55 |  | -            self.i_forward += 1; | 
|  | 56 | +            let arg = Self::argv(self.front); | 
|  | 57 | +            self.front += 1; | 
| 56 | 58 |             Some(arg) | 
| 57 | 59 |         } | 
| 58 | 60 |     } | 
| 59 | 61 | 
 | 
|  | 62 | +    #[inline] | 
| 60 | 63 |     fn size_hint(&self) -> (usize, Option<usize>) { | 
| 61 |  | -        (self.count, Some(self.count)) | 
|  | 64 | +        let len = self.len(); | 
|  | 65 | +        (len, Some(len)) | 
| 62 | 66 |     } | 
| 63 |  | -} | 
| 64 | 67 | 
 | 
| 65 |  | -impl ExactSizeIterator for Args { | 
| 66 |  | -    fn len(&self) -> usize { | 
| 67 |  | -        self.count | 
|  | 68 | +    #[inline] | 
|  | 69 | +    fn count(self) -> usize { | 
|  | 70 | +        self.len() | 
|  | 71 | +    } | 
|  | 72 | + | 
|  | 73 | +    #[inline] | 
|  | 74 | +    fn last(mut self) -> Option<OsString> { | 
|  | 75 | +        self.next_back() | 
|  | 76 | +    } | 
|  | 77 | + | 
|  | 78 | +    #[inline] | 
|  | 79 | +    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> { | 
|  | 80 | +        let step_size = self.len().min(n); | 
|  | 81 | +        self.front += step_size; | 
|  | 82 | +        NonZero::new(n - step_size).map_or(Ok(()), Err) | 
| 68 | 83 |     } | 
| 69 | 84 | } | 
| 70 | 85 | 
 | 
| 71 | 86 | impl DoubleEndedIterator for Args { | 
|  | 87 | +    #[inline] | 
| 72 | 88 |     fn next_back(&mut self) -> Option<OsString> { | 
| 73 |  | -        if self.i_back >= self.count - self.i_forward { | 
|  | 89 | +        if self.back == self.front { | 
| 74 | 90 |             None | 
| 75 | 91 |         } else { | 
| 76 |  | -            let arg = Self::argv(self.count - 1 - self.i_back); | 
| 77 |  | -            self.i_back += 1; | 
| 78 |  | -            Some(arg) | 
|  | 92 | +            self.back -= 1; | 
|  | 93 | +            Some(Self::argv(self.back)) | 
| 79 | 94 |         } | 
| 80 | 95 |     } | 
|  | 96 | + | 
|  | 97 | +    #[inline] | 
|  | 98 | +    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> { | 
|  | 99 | +        let step_size = self.len().min(n); | 
|  | 100 | +        self.back -= step_size; | 
|  | 101 | +        NonZero::new(n - step_size).map_or(Ok(()), Err) | 
|  | 102 | +    } | 
|  | 103 | +} | 
|  | 104 | + | 
|  | 105 | +impl ExactSizeIterator for Args { | 
|  | 106 | +    #[inline] | 
|  | 107 | +    fn len(&self) -> usize { | 
|  | 108 | +        self.back - self.front | 
|  | 109 | +    } | 
|  | 110 | + | 
|  | 111 | +    #[inline] | 
|  | 112 | +    fn is_empty(&self) -> bool { | 
|  | 113 | +        self.front == self.back | 
|  | 114 | +    } | 
| 81 | 115 | } | 
0 commit comments