|
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