@@ -17,9 +17,13 @@ use T_SIGNED = self::inst::T_SIGNED;
17
17
18
18
use char;
19
19
use cmp:: { Eq , Ord } ;
20
+ use cmp;
21
+ use to_str:: ToStr ;
20
22
use from_str:: FromStr ;
23
+ use num:: { ToStrRadix , FromStrRadix } ;
21
24
use num;
22
25
use option:: { None , Option , Some } ;
26
+ use prelude:: * ;
23
27
use str;
24
28
use uint;
25
29
use vec;
@@ -172,135 +176,97 @@ impl T: num::Round {
172
176
pure fn fract(&self) -> T { 0 }
173
177
}
174
178
175
- /**
176
- * Parse a buffer of bytes
177
- *
178
- * # Arguments
179
- *
180
- * * buf - A byte buffer
181
- * * radix - The base of the number
182
- *
183
- * # Failure
184
- *
185
- * `buf` must not be empty
186
- */
187
- pub pure fn parse_bytes(buf: &[const u8], radix: uint) -> Option<T> {
188
- if vec::len(buf) == 0u { return None; }
189
- let mut i = vec::len(buf) - 1u;
190
- let mut power = 1u as T;
191
- let mut n = 0u as T;
192
- loop {
193
- match char::to_digit(buf[i] as char, radix) {
194
- Some(d) => n += d as T * power,
195
- None => return None
196
- }
197
- power *= radix as T;
198
- if i == 0u { return Some(n); }
199
- i -= 1u;
200
- };
201
- }
179
+ // String conversion functions and impl str -> num
202
180
203
- /// Parse a string to an int
181
+ /// Parse a string as a number in base 10.
204
182
#[inline(always)]
205
- pub pure fn from_str(s: &str) -> Option<T>
206
- {
207
- parse_bytes(str::to_bytes(s), 10u )
183
+ pub pure fn from_str(s: &str) -> Option<T> {
184
+ num::from_str_common(s, 10u, false, false, false,
185
+ num::ExpNone, false )
208
186
}
209
187
210
- impl T : FromStr {
211
- #[inline(always)]
212
- static pure fn from_str(s: &str) -> Option<T> { from_str(s) }
188
+ /// Parse a string as a number in the given base.
189
+ #[inline(always)]
190
+ pub pure fn from_str_radix(s: &str, radix: uint) -> Option<T> {
191
+ num::from_str_common(s, radix, false, false, false,
192
+ num::ExpNone, false)
213
193
}
214
194
215
- /// Parse a string as an unsigned integer.
216
- pub fn from_str_radix(buf: &str, radix: u64) -> Option<u64> {
217
- if str::len(buf) == 0u { return None; }
218
- let mut i = str::len(buf) - 1u;
219
- let mut power = 1u64, n = 0u64;
220
- loop {
221
- match char::to_digit(buf[i] as char, radix as uint) {
222
- Some(d) => n += d as u64 * power,
223
- None => return None
224
- }
225
- power *= radix;
226
- if i == 0u { return Some(n); }
227
- i -= 1u;
228
- };
195
+ /// Parse a byte slice as a number in the given base.
196
+ #[inline(always)]
197
+ pub pure fn parse_bytes(buf: &[u8], radix: uint) -> Option<T> {
198
+ num::from_str_bytes_common(buf, radix, false, false, false,
199
+ num::ExpNone, false)
229
200
}
230
201
231
- /**
232
- * Convert to a string in a given base
233
- *
234
- * # Failure
235
- *
236
- * Fails if `radix` < 2 or `radix` > 16
237
- */
238
- #[inline(always)]
239
- pub pure fn to_str(num: T, radix: uint) -> ~str {
240
- do to_str_bytes(false, num, radix) |slice| {
241
- do vec::as_imm_buf(slice) |p, len| {
242
- unsafe { str::raw::from_buf_len(p, len) }
243
- }
202
+ impl T : FromStr {
203
+ #[inline(always)]
204
+ static pure fn from_str(s: &str) -> Option<T> {
205
+ from_str(s)
244
206
}
245
207
}
246
208
247
- /// Low-level helper routine for string conversion.
248
- pub pure fn to_str_bytes<U>(neg: bool, num: T, radix: uint,
249
- f: fn(v: &[u8]) -> U) -> U {
250
-
209
+ impl T : FromStrRadix {
251
210
#[inline(always)]
252
- pure fn digit(n: T) -> u8 {
253
- if n <= 9u as T {
254
- n as u8 + '0' as u8
255
- } else if n <= 15u as T {
256
- (n - 10 as T) as u8 + 'a' as u8
257
- } else {
258
- die!();
259
- }
211
+ static pure fn from_str_radix(&self, s: &str, radix: uint) -> Option<T> {
212
+ from_str_radix(s, radix)
260
213
}
214
+ }
261
215
262
- assert (1u < radix && radix <= 16u);
263
-
264
- // Enough room to hold any number in any radix.
265
- // Worst case: 64-bit number, binary-radix, with
266
- // a leading negative sign = 65 bytes.
267
- let buf : [mut u8 * 65] = [mut 0u8, ..65];
268
- let len = buf.len();
269
-
270
- let mut i = len;
271
- let mut n = num;
272
- let radix = radix as T;
273
- loop {
274
- i -= 1u;
275
- assert 0u < i && i < len;
276
- buf[i] = digit(n % radix);
277
- n /= radix;
278
- if n == 0 as T { break; }
279
- }
216
+ // String conversion functions and impl num -> str
280
217
281
- assert 0u < i && i < len;
218
+ /// Convert to a string as a byte slice in a given base.
219
+ #[inline(always)]
220
+ pub pure fn to_str_bytes<U>(n: T, radix: uint, f: fn(v: &[u8]) -> U) -> U {
221
+ let (buf, _) = num::to_str_bytes_common(&n, radix, false, false,
222
+ num::SignNeg, num::DigAll);
223
+ f(buf)
224
+ }
282
225
283
- if neg {
284
- i -= 1u;
285
- buf[i] = '-' as u8;
286
- }
226
+ /// Convert to a string in base 10.
227
+ #[inline(always)]
228
+ pub pure fn to_str(num: T) -> ~str {
229
+ let (buf, _) = num::to_str_common(&num, 10u, false, false,
230
+ num::SignNeg, num::DigAll);
231
+ buf
232
+ }
287
233
288
- f(vec::view(buf, i, len))
234
+ /// Convert to a string in a given base.
235
+ #[inline(always)]
236
+ pub pure fn to_str_radix(num: T, radix: uint) -> ~str {
237
+ let (buf, _) = num::to_str_common(&num, radix, false, false,
238
+ num::SignNeg, num::DigAll);
239
+ buf
289
240
}
290
241
291
- /// Convert to a string
242
+ /// Convert to a string.
243
+ /// *Deprecated*, use to_str() instead.
292
244
#[inline(always)]
293
- pub pure fn str(i: T) -> ~str { return to_str(i, 10u); }
245
+ pub pure fn str(i: T) -> ~str { to_str(i) }
246
+
247
+ impl T : ToStr {
248
+ #[inline(always)]
249
+ pure fn to_str() -> ~str {
250
+ to_str(self)
251
+ }
252
+ }
253
+
254
+ impl T : ToStrRadix {
255
+ #[inline(always)]
256
+ pure fn to_str_radix(&self, radix: uint) -> ~str {
257
+ to_str_radix(*self, radix)
258
+ }
259
+ }
294
260
295
261
#[test]
296
262
pub fn test_to_str() {
297
- assert to_str (0 as T, 10u) == ~" 0 ";
298
- assert to_str (1 as T, 10u) == ~" 1 ";
299
- assert to_str (2 as T, 10u) == ~" 2 ";
300
- assert to_str (11 as T, 10u) == ~" 11 ";
301
- assert to_str (11 as T, 16u) == ~" b";
302
- assert to_str (255 as T, 16u) == ~" ff";
303
- assert to_str (0xff as T, 10u) == ~" 255 ";
263
+ assert to_str_radix (0 as T, 10u) == ~" 0 ";
264
+ assert to_str_radix (1 as T, 10u) == ~" 1 ";
265
+ assert to_str_radix (2 as T, 10u) == ~" 2 ";
266
+ assert to_str_radix (11 as T, 10u) == ~" 11 ";
267
+ assert to_str_radix (11 as T, 16u) == ~" b";
268
+ assert to_str_radix (255 as T, 16u) == ~" ff";
269
+ assert to_str_radix (0xff as T, 10u) == ~" 255 ";
304
270
}
305
271
306
272
#[test]
@@ -330,18 +296,72 @@ pub fn test_parse_bytes() {
330
296
assert parse_bytes(to_bytes(~" _"), 2u).is_none();
331
297
}
332
298
299
+ #[test]
300
+ fn test_uint_to_str_overflow() {
301
+ let mut u8_val: u8 = 255_u8;
302
+ assert (u8::to_str(u8_val) == ~" 255 ");
303
+
304
+ u8_val += 1 as u8;
305
+ assert (u8::to_str(u8_val) == ~" 0 ");
306
+
307
+ let mut u16_val: u16 = 65_535_u16;
308
+ assert (u16::to_str(u16_val) == ~" 65535 ");
309
+
310
+ u16_val += 1 as u16;
311
+ assert (u16::to_str(u16_val) == ~" 0 ");
312
+
313
+ let mut u32_val: u32 = 4_294_967_295_u32;
314
+ assert (u32::to_str(u32_val) == ~" 4294967295 ");
315
+
316
+ u32_val += 1 as u32;
317
+ assert (u32::to_str(u32_val) == ~" 0 ");
318
+
319
+ let mut u64_val: u64 = 18_446_744_073_709_551_615_u64;
320
+ assert (u64::to_str(u64_val) == ~" 18446744073709551615 ");
321
+
322
+ u64_val += 1 as u64;
323
+ assert (u64::to_str(u64_val) == ~" 0 ");
324
+ }
325
+
326
+ #[test]
327
+ fn test_uint_from_str_overflow() {
328
+ let mut u8_val: u8 = 255_u8;
329
+ assert (u8::from_str(~" 255 ") == Some(u8_val));
330
+
331
+ u8_val += 1 as u8;
332
+ assert (u8::from_str(~" 0 ") == Some(u8_val));
333
+
334
+ let mut u16_val: u16 = 65_535_u16;
335
+ assert (u16::from_str(~" 65535 ") == Some(u16_val));
336
+
337
+ u16_val += 1 as u16;
338
+ assert (u16::from_str(~" 0 ") == Some(u16_val));
339
+
340
+ let mut u32_val: u32 = 4_294_967_295_u32;
341
+ assert (u32::from_str(~" 4294967295 ") == Some(u32_val));
342
+
343
+ u32_val += 1 as u32;
344
+ assert (u32::from_str(~" 0 ") == Some(u32_val));
345
+
346
+ let mut u64_val: u64 = 18_446_744_073_709_551_615_u64;
347
+ assert (u64::from_str(~" 18446744073709551615 ") == Some(u64_val));
348
+
349
+ u64_val += 1 as u64;
350
+ assert (u64::from_str(~" 0 ") == Some(u64_val));
351
+ }
352
+
333
353
#[test]
334
354
#[should_fail]
335
355
#[ignore(cfg(windows))]
336
356
pub fn to_str_radix1() {
337
- uint::to_str (100u, 1u);
357
+ uint::to_str_radix (100u, 1u);
338
358
}
339
359
340
360
#[test]
341
361
#[should_fail]
342
362
#[ignore(cfg(windows))]
343
- pub fn to_str_radix17 () {
344
- uint::to_str (100u, 17u );
363
+ pub fn to_str_radix37 () {
364
+ uint::to_str_radix (100u, 37u );
345
365
}
346
366
347
367
use io;
0 commit comments