11use crate :: ffi:: OsString ;
22use crate :: fmt;
3+ use crate :: num:: NonZero ;
34use crate :: sys:: os_str;
45use crate :: sys:: pal:: { WORD_SIZE , abi} ;
56use crate :: sys_common:: FromInner ;
67
8+ #[ derive( Clone ) ]
79pub struct Args {
8- i_forward : usize ,
9- i_back : usize ,
10- count : usize ,
10+ front : usize ,
11+ back : usize ,
1112}
1213
1314pub fn args ( ) -> Args {
1415 let count = unsafe { abi:: sys_argc ( ) } ;
15- Args { i_forward : 0 , i_back : 0 , count }
16+ Args { front : 0 , back : count }
1617}
1718
1819impl Args {
@@ -38,44 +39,80 @@ impl Args {
3839 }
3940}
4041
42+ impl !Send for Args { }
43+ impl !Sync for Args { }
44+
4145impl fmt:: Debug for Args {
4246 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
43- f. debug_list ( ) . finish ( )
47+ f. debug_list ( ) . entries ( self . clone ( ) ) . finish ( )
4448 }
4549}
4650
4751impl Iterator for Args {
4852 type Item = OsString ;
4953
54+ #[ inline]
5055 fn next ( & mut self ) -> Option < OsString > {
51- if self . i_forward >= self . count - self . i_back {
56+ if self . front == self . back {
5257 None
5358 } else {
54- let arg = Self :: argv ( self . i_forward ) ;
55- self . i_forward += 1 ;
59+ let arg = Self :: argv ( self . front ) ;
60+ self . front += 1 ;
5661 Some ( arg)
5762 }
5863 }
5964
65+ #[ inline]
6066 fn size_hint ( & self ) -> ( usize , Option < usize > ) {
61- ( self . count , Some ( self . count ) )
67+ let len = self . len ( ) ;
68+ ( len, Some ( len) )
6269 }
63- }
6470
65- impl ExactSizeIterator for Args {
66- fn len ( & self ) -> usize {
67- self . count
71+ #[ inline]
72+ fn count ( self ) -> usize {
73+ self . len ( )
74+ }
75+
76+ #[ inline]
77+ fn last ( mut self ) -> Option < OsString > {
78+ self . next_back ( )
79+ }
80+
81+ #[ inline]
82+ fn advance_by ( & mut self , n : usize ) -> Result < ( ) , NonZero < usize > > {
83+ let step_size = self . len ( ) . min ( n) ;
84+ self . front += step_size;
85+ NonZero :: new ( n - step_size) . map_or ( Ok ( ( ) ) , Err )
6886 }
6987}
7088
7189impl DoubleEndedIterator for Args {
90+ #[ inline]
7291 fn next_back ( & mut self ) -> Option < OsString > {
73- if self . i_back >= self . count - self . i_forward {
92+ if self . back == self . front {
7493 None
7594 } else {
76- let arg = Self :: argv ( self . count - 1 - self . i_back ) ;
77- self . i_back += 1 ;
78- Some ( arg)
95+ self . back -= 1 ;
96+ Some ( Self :: argv ( self . back ) )
7997 }
8098 }
99+
100+ #[ inline]
101+ fn advance_back_by ( & mut self , n : usize ) -> Result < ( ) , NonZero < usize > > {
102+ let step_size = self . len ( ) . min ( n) ;
103+ self . back -= step_size;
104+ NonZero :: new ( n - step_size) . map_or ( Ok ( ( ) ) , Err )
105+ }
106+ }
107+
108+ impl ExactSizeIterator for Args {
109+ #[ inline]
110+ fn len ( & self ) -> usize {
111+ self . back - self . front
112+ }
113+
114+ #[ inline]
115+ fn is_empty ( & self ) -> bool {
116+ self . front == self . back
117+ }
81118}
0 commit comments