88/// Add inc to the string val[start..end]. This operates on ASCII digits, assuming
99/// val and inc are well formed.
1010///
11- /// Returns the new value for start (can be less that the original value if we
12- /// have a carry or if inc > start).
11+ /// Updates `start` if we have a carry, or if inc > start.
1312///
1413/// We also assume that there is enough space in val to expand if start needs
1514/// to be updated.
2221/// let end = val.len();
2322/// let inc = "6".as_bytes();
2423/// assert_eq!(&val[start..end], "0".as_bytes());
25- /// start = fast_inc(val.as_mut(), start, end, inc);
24+ /// fast_inc(val.as_mut(), &mut start, end, inc);
2625/// assert_eq!(&val[start..end], "6".as_bytes());
27- /// start = fast_inc(val.as_mut(), start, end, inc);
26+ /// fast_inc(val.as_mut(), &mut start, end, inc);
2827/// assert_eq!(&val[start..end], "12".as_bytes());
2928/// ```
3029#[ inline]
31- pub fn fast_inc ( val : & mut [ u8 ] , start : usize , end : usize , inc : & [ u8 ] ) -> usize {
30+ pub fn fast_inc ( val : & mut [ u8 ] , start : & mut usize , end : usize , inc : & [ u8 ] ) {
3231 // To avoid a lot of casts to signed integers, we make sure to decrement pos
3332 // as late as possible, so that it does not ever go negative.
3433 let mut pos = end;
@@ -40,7 +39,7 @@ pub fn fast_inc(val: &mut [u8], start: usize, end: usize, inc: &[u8]) -> usize {
4039
4140 let mut new_val = inc[ inc_pos] + carry;
4241 // Be careful here, only add existing digit of val.
43- if pos >= start {
42+ if pos >= * start {
4443 new_val += val[ pos] - b'0' ;
4544 }
4645 if new_val > b'9' {
@@ -54,7 +53,8 @@ pub fn fast_inc(val: &mut [u8], start: usize, end: usize, inc: &[u8]) -> usize {
5453
5554 // Done, now, if we have a carry, add that to the upper digits of val.
5655 if carry == 0 {
57- return start. min ( pos) ;
56+ * start = ( * start) . min ( pos) ;
57+ return ;
5858 }
5959
6060 fast_inc_one ( val, start, pos)
@@ -65,8 +65,7 @@ pub fn fast_inc(val: &mut [u8], start: usize, end: usize, inc: &[u8]) -> usize {
6565/// Add 1 to the string val[start..end]. This operates on ASCII digits, assuming
6666/// val is well formed.
6767///
68- /// Returns the new value for start (can be less that the original value if we
69- /// have a carry).
68+ /// Updates `start` if we have a carry, or if inc > start.
7069///
7170/// We also assume that there is enough space in val to expand if start needs
7271/// to be updated.
@@ -78,16 +77,16 @@ pub fn fast_inc(val: &mut [u8], start: usize, end: usize, inc: &[u8]) -> usize {
7877/// let mut start = val.len()-1;
7978/// let end = val.len();
8079/// assert_eq!(&val[start..end], "8".as_bytes());
81- /// start = fast_inc_one(val.as_mut(), start, end);
80+ /// fast_inc_one(val.as_mut(), &mut start, end);
8281/// assert_eq!(&val[start..end], "9".as_bytes());
83- /// start = fast_inc_one(val.as_mut(), start, end);
82+ /// fast_inc_one(val.as_mut(), &mut start, end);
8483/// assert_eq!(&val[start..end], "10".as_bytes());
8584/// ```
8685#[ inline]
87- pub fn fast_inc_one ( val : & mut [ u8 ] , start : usize , end : usize ) -> usize {
86+ pub fn fast_inc_one ( val : & mut [ u8 ] , start : & mut usize , end : usize ) {
8887 let mut pos = end;
8988
90- while pos > start {
89+ while pos > * start {
9190 pos -= 1 ;
9291
9392 if val[ pos] == b'9' {
@@ -96,13 +95,13 @@ pub fn fast_inc_one(val: &mut [u8], start: usize, end: usize) -> usize {
9695 } else {
9796 // Carry stopped propagating, return unchanged start.
9897 val[ pos] += 1 ;
99- return start ;
98+ return ;
10099 }
101100 }
102101
103102 // The carry propagated so far that a new digit was added.
104- val[ start - 1 ] = b'1' ;
105- start - 1
103+ val[ * start - 1 ] = b'1' ;
104+ * start -= 1 ;
106105}
107106
108107#[ cfg( test) ]
@@ -113,65 +112,88 @@ mod tests {
113112 #[ test]
114113 fn test_fast_inc_simple ( ) {
115114 let mut val = Vec :: from ( "...0_" . as_bytes ( ) ) ;
115+ let mut start: usize = 3 ;
116116 let inc = "4" . as_bytes ( ) ;
117- assert_eq ! ( fast_inc( val. as_mut( ) , 3 , 4 , inc) , 3 ) ;
117+ fast_inc ( val. as_mut ( ) , & mut start, 4 , inc) ;
118+ assert_eq ! ( start, 3 ) ;
118119 assert_eq ! ( val, "...4_" . as_bytes( ) ) ;
119- assert_eq ! ( fast_inc( val. as_mut( ) , 3 , 4 , inc) , 3 ) ;
120+ fast_inc ( val. as_mut ( ) , & mut start, 4 , inc) ;
121+ assert_eq ! ( start, 3 ) ;
120122 assert_eq ! ( val, "...8_" . as_bytes( ) ) ;
121- assert_eq ! ( fast_inc( val. as_mut( ) , 3 , 4 , inc) , 2 ) ; // carried 1 more digit
123+ fast_inc ( val. as_mut ( ) , & mut start, 4 , inc) ;
124+ assert_eq ! ( start, 2 ) ; // carried 1 more digit
122125 assert_eq ! ( val, "..12_" . as_bytes( ) ) ;
123126
124127 let mut val = Vec :: from ( "0_" . as_bytes ( ) ) ;
128+ let mut start: usize = 0 ;
125129 let inc = "2" . as_bytes ( ) ;
126- assert_eq ! ( fast_inc( val. as_mut( ) , 0 , 1 , inc) , 0 ) ;
130+ fast_inc ( val. as_mut ( ) , & mut start, 1 , inc) ;
131+ assert_eq ! ( start, 0 ) ;
127132 assert_eq ! ( val, "2_" . as_bytes( ) ) ;
128- assert_eq ! ( fast_inc( val. as_mut( ) , 0 , 1 , inc) , 0 ) ;
133+ fast_inc ( val. as_mut ( ) , & mut start, 1 , inc) ;
134+ assert_eq ! ( start, 0 ) ;
129135 assert_eq ! ( val, "4_" . as_bytes( ) ) ;
130- assert_eq ! ( fast_inc( val. as_mut( ) , 0 , 1 , inc) , 0 ) ;
136+ fast_inc ( val. as_mut ( ) , & mut start, 1 , inc) ;
137+ assert_eq ! ( start, 0 ) ;
131138 assert_eq ! ( val, "6_" . as_bytes( ) ) ;
132139 }
133140
134141 // Check that we handle increment > val correctly.
135142 #[ test]
136143 fn test_fast_inc_large_inc ( ) {
137144 let mut val = Vec :: from ( "...7_" . as_bytes ( ) ) ;
145+ let mut start: usize = 3 ;
138146 let inc = "543" . as_bytes ( ) ;
139- assert_eq ! ( fast_inc( val. as_mut( ) , 3 , 4 , inc) , 1 ) ; // carried 2 more digits
147+ fast_inc ( val. as_mut ( ) , & mut start, 4 , inc) ;
148+ assert_eq ! ( start, 1 ) ; // carried 2 more digits
140149 assert_eq ! ( val, ".550_" . as_bytes( ) ) ;
141- assert_eq ! ( fast_inc( val. as_mut( ) , 1 , 4 , inc) , 0 ) ; // carried 1 more digit
150+ fast_inc ( val. as_mut ( ) , & mut start, 4 , inc) ;
151+ assert_eq ! ( start, 0 ) ; // carried 1 more digit
142152 assert_eq ! ( val, "1093_" . as_bytes( ) ) ;
143153 }
144154
145155 // Check that we handle longer carries
146156 #[ test]
147157 fn test_fast_inc_carry ( ) {
148158 let mut val = Vec :: from ( ".999_" . as_bytes ( ) ) ;
159+ let mut start: usize = 1 ;
149160 let inc = "1" . as_bytes ( ) ;
150- assert_eq ! ( fast_inc( val. as_mut( ) , 1 , 4 , inc) , 0 ) ;
161+ fast_inc ( val. as_mut ( ) , & mut start, 4 , inc) ;
162+ assert_eq ! ( start, 0 ) ;
151163 assert_eq ! ( val, "1000_" . as_bytes( ) ) ;
152164
153165 let mut val = Vec :: from ( ".999_" . as_bytes ( ) ) ;
166+ let mut start: usize = 1 ;
154167 let inc = "11" . as_bytes ( ) ;
155- assert_eq ! ( fast_inc( val. as_mut( ) , 1 , 4 , inc) , 0 ) ;
168+ fast_inc ( val. as_mut ( ) , & mut start, 4 , inc) ;
169+ assert_eq ! ( start, 0 ) ;
156170 assert_eq ! ( val, "1010_" . as_bytes( ) ) ;
157171 }
158172
159173 #[ test]
160174 fn test_fast_inc_one_simple ( ) {
161175 let mut val = Vec :: from ( "...8_" . as_bytes ( ) ) ;
162- assert_eq ! ( fast_inc_one( val. as_mut( ) , 3 , 4 ) , 3 ) ;
176+ let mut start: usize = 3 ;
177+ fast_inc_one ( val. as_mut ( ) , & mut start, 4 ) ;
178+ assert_eq ! ( start, 3 ) ;
163179 assert_eq ! ( val, "...9_" . as_bytes( ) ) ;
164- assert_eq ! ( fast_inc_one( val. as_mut( ) , 3 , 4 ) , 2 ) ; // carried 1 more digit
180+ fast_inc_one ( val. as_mut ( ) , & mut start, 4 ) ;
181+ assert_eq ! ( start, 2 ) ; // carried 1 more digit
165182 assert_eq ! ( val, "..10_" . as_bytes( ) ) ;
166- assert_eq ! ( fast_inc_one( val. as_mut( ) , 2 , 4 ) , 2 ) ;
183+ fast_inc_one ( val. as_mut ( ) , & mut start, 4 ) ;
184+ assert_eq ! ( start, 2 ) ;
167185 assert_eq ! ( val, "..11_" . as_bytes( ) ) ;
168186
169187 let mut val = Vec :: from ( "0_" . as_bytes ( ) ) ;
170- assert_eq ! ( fast_inc_one( val. as_mut( ) , 0 , 1 ) , 0 ) ;
188+ let mut start: usize = 0 ;
189+ fast_inc_one ( val. as_mut ( ) , & mut start, 1 ) ;
190+ assert_eq ! ( start, 0 ) ;
171191 assert_eq ! ( val, "1_" . as_bytes( ) ) ;
172- assert_eq ! ( fast_inc_one( val. as_mut( ) , 0 , 1 ) , 0 ) ;
192+ fast_inc_one ( val. as_mut ( ) , & mut start, 1 ) ;
193+ assert_eq ! ( start, 0 ) ;
173194 assert_eq ! ( val, "2_" . as_bytes( ) ) ;
174- assert_eq ! ( fast_inc_one( val. as_mut( ) , 0 , 1 ) , 0 ) ;
195+ fast_inc_one ( val. as_mut ( ) , & mut start, 1 ) ;
196+ assert_eq ! ( start, 0 ) ;
175197 assert_eq ! ( val, "3_" . as_bytes( ) ) ;
176198 }
177199}
0 commit comments