| 
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