 |
Changeset 2526
- Timestamp:
- 08/30/07 04:28:26
(1 year ago)
- Author:
- kris
- Message:
After extended discussions, Integer.parse() and Integer.trim() have been adjusted such that an optional radix-prefix in the text must match an explicit radix argument (where both are provided). Set the numeric radix argument to zero in order to retain prior behavior (which it defaults to).
closes #546, and thanks to eao197 for the ticket :)
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r2475 |
r2526 |
|
| 251 | 251 | int exp; |
|---|
| 252 | 252 | bool sign; |
|---|
| 253 | | uint radix = 10; |
|---|
| | 253 | uint radix; |
|---|
| 254 | 254 | NumType value = 0.0; |
|---|
| 255 | 255 | |
|---|
| … | … | |
| 300 | 300 | { |
|---|
| 301 | 301 | uint eaten; |
|---|
| 302 | | exp += Integer.parse (src[(++p-src.ptr) .. $], 10u, &eaten); |
|---|
| | 302 | exp += Integer.parse (src[(++p-src.ptr) .. $], 0, &eaten); |
|---|
| 303 | 303 | p += eaten; |
|---|
| 304 | 304 | } |
|---|
| r2525 |
r2526 |
|
| 61 | 61 | |
|---|
| 62 | 62 | Parse an integer value from the provided 'digits' string. |
|---|
| 63 | | The string is inspected for a sign and radix, where the |
|---|
| 64 | | latter will override the default radix provided. |
|---|
| | 63 | |
|---|
| | 64 | The string is inspected for a sign and an optional radix |
|---|
| | 65 | prefix. A radix may be provided as an argument instead, |
|---|
| | 66 | whereupon it must match the prefix (where present). When |
|---|
| | 67 | radix is set to zero, conversion will default to decimal. |
|---|
| 65 | 68 | |
|---|
| 66 | 69 | Throws an exception where the input text is not parsable |
|---|
| … | … | |
| 69 | 72 | ******************************************************************************/ |
|---|
| 70 | 73 | |
|---|
| 71 | | int toInt(T, U=uint) (T[] digits, U radix=10) |
|---|
| | 74 | int toInt(T, U=uint) (T[] digits, U radix=0) |
|---|
| 72 | 75 | {return toInt!(T)(digits, radix);} |
|---|
| 73 | 76 | |
|---|
| 74 | | int toInt(T) (T[] digits, uint radix=10) |
|---|
| | 77 | int toInt(T) (T[] digits, uint radix=0) |
|---|
| 75 | 78 | { |
|---|
| 76 | 79 | auto x = toLong (digits, radix); |
|---|
| 77 | 80 | if (x > int.max) |
|---|
| 78 | | throw new IllegalArgumentException ("Integer.toInt :: numeric overflow"); |
|---|
| | 81 | throw new IllegalArgumentException ("Integer.toInt :: integer overflow on: "~digits); |
|---|
| 79 | 82 | return cast(int) x; |
|---|
| 80 | 83 | } |
|---|
| … | … | |
| 82 | 85 | /****************************************************************************** |
|---|
| 83 | 86 | |
|---|
| 84 | | Parse an integer value from the provided 'digits' string. |
|---|
| 85 | | The string is inspected for a sign and radix, where the |
|---|
| 86 | | latter will override the default radix provided. |
|---|
| | 87 | Parse an integer value from the provided 'digits' string. |
|---|
| | 88 | |
|---|
| | 89 | The string is inspected for a sign and an optional radix |
|---|
| | 90 | prefix. A radix may be provided as an argument instead, |
|---|
| | 91 | whereupon it must match the prefix (where present). When |
|---|
| | 92 | radix is set to zero, conversion will default to decimal. |
|---|
| 87 | 93 | |
|---|
| 88 | 94 | Throws an exception where the input text is not parsable |
|---|
| … | … | |
| 91 | 97 | ******************************************************************************/ |
|---|
| 92 | 98 | |
|---|
| 93 | | long toLong(T, U=uint) (T[] digits, U radix=10) |
|---|
| | 99 | long toLong(T, U=uint) (T[] digits, U radix=0) |
|---|
| 94 | 100 | {return toLong!(T)(digits, radix);} |
|---|
| 95 | 101 | |
|---|
| 96 | | long toLong(T) (T[] digits, uint radix=10) |
|---|
| | 102 | long toLong(T) (T[] digits, uint radix=0) |
|---|
| 97 | 103 | { |
|---|
| 98 | 104 | uint len; |
|---|
| … | … | |
| 100 | 106 | auto x = parse (digits, radix, &len); |
|---|
| 101 | 107 | if (len < digits.length) |
|---|
| 102 | | throw new IllegalArgumentException ("Integer.toLong :: invalid number"); |
|---|
| | 108 | throw new IllegalArgumentException ("Integer.toLong :: invalid literal: "~digits); |
|---|
| 103 | 109 | return x; |
|---|
| 104 | 110 | } |
|---|
| … | … | |
| 288 | 294 | |
|---|
| 289 | 295 | Parse an integer value from the provided 'digits' string. |
|---|
| 290 | | The string is inspected for a sign and radix, where the |
|---|
| 291 | | latter will override the default radix provided. |
|---|
| | 296 | |
|---|
| | 297 | The string is inspected for a sign and an optional radix |
|---|
| | 298 | prefix. A radix may be provided as an argument instead, |
|---|
| | 299 | whereupon it must match the prefix (where present). When |
|---|
| | 300 | radix is set to zero, conversion will default to decimal. |
|---|
| 292 | 301 | |
|---|
| 293 | 302 | A non-null 'ate' will return the number of characters used |
|---|
| … | … | |
| 296 | 305 | ******************************************************************************/ |
|---|
| 297 | 306 | |
|---|
| 298 | | long parse(T, U=uint) (T[] digits, U radix=10, uint* ate=null) |
|---|
| | 307 | long parse(T, U=uint) (T[] digits, U radix=0, uint* ate=null) |
|---|
| 299 | 308 | {return parse!(T)(digits, radix, ate);} |
|---|
| 300 | 309 | |
|---|
| 301 | | long parse(T) (T[] digits, uint radix=10, uint* ate=null) |
|---|
| | 310 | long parse(T) (T[] digits, uint radix=0, uint* ate=null) |
|---|
| 302 | 311 | { |
|---|
| 303 | 312 | bool sign; |
|---|
| … | … | |
| 315 | 324 | |
|---|
| 316 | 325 | Convert the provided 'digits' into an integer value, |
|---|
| 317 | | without looking for a sign or radix. |
|---|
| 318 | | |
|---|
| 319 | | Returns the value and updates 'ate' with the number |
|---|
| 320 | | of characters parsed. |
|---|
| | 326 | without checking for a sign or radix. The radix defaults |
|---|
| | 327 | to decimal (10). |
|---|
| | 328 | |
|---|
| | 329 | Returns the value and updates 'ate' with the number of |
|---|
| | 330 | characters consumed. |
|---|
| 321 | 331 | |
|---|
| 322 | 332 | ******************************************************************************/ |
|---|
| … | … | |
| 362 | 372 | |
|---|
| 363 | 373 | Strip leading whitespace, extract an optional +/- sign, |
|---|
| 364 | | and an optional radix prefix. This can be used as a |
|---|
| 365 | | precursor to the conversion of digits into a number. |
|---|
| 366 | | |
|---|
| 367 | | Returns the number of matching characters. |
|---|
| | 374 | and an optional radix prefix. If the radix value matches |
|---|
| | 375 | an optional prefix, or the radix is zero, the prefix will |
|---|
| | 376 | be consumed and assigned. Where the radix is non zero and |
|---|
| | 377 | does not match an explicit prefix, the latter will remain |
|---|
| | 378 | unconsumed. Otherwise, radix will default to 10. |
|---|
| | 379 | |
|---|
| | 380 | Returns the number of characters consumed. |
|---|
| 368 | 381 | |
|---|
| 369 | 382 | ******************************************************************************/ |
|---|
| … | … | |
| 394 | 407 | |
|---|
| 395 | 408 | // strip off a radix specifier also? |
|---|
| | 409 | auto r = radix; |
|---|
| 396 | 410 | if (c is '0' && len > 1) |
|---|
| 397 | 411 | switch (*++p) |
|---|
| … | … | |
| 399 | 413 | case 'x': |
|---|
| 400 | 414 | case 'X': |
|---|
| 401 | | ++p; |
|---|
| 402 | | radix = 16; |
|---|
| | 415 | r = 16, ++p; |
|---|
| 403 | 416 | break; |
|---|
| 404 | | |
|---|
| | 417 | |
|---|
| 405 | 418 | case 'b': |
|---|
| 406 | 419 | case 'B': |
|---|
| 407 | | ++p; |
|---|
| 408 | | radix = 2; |
|---|
| | 420 | r = 2, ++p; |
|---|
| 409 | 421 | break; |
|---|
| 410 | | |
|---|
| | 422 | |
|---|
| 411 | 423 | case 'o': |
|---|
| 412 | 424 | case 'O': |
|---|
| 413 | | ++p; |
|---|
| 414 | | radix = 8; |
|---|
| | 425 | r = 8, ++p; |
|---|
| 415 | 426 | break; |
|---|
| 416 | | |
|---|
| 417 | | default: |
|---|
| 418 | | --p; |
|---|
| | 427 | |
|---|
| | 428 | default: |
|---|
| 419 | 429 | break; |
|---|
| 420 | 430 | } |
|---|
| | 431 | |
|---|
| | 432 | // default the radix to 10 |
|---|
| | 433 | if (r is 0) |
|---|
| | 434 | radix = 10; |
|---|
| | 435 | else |
|---|
| | 436 | // explicit radix must match (optional) prefix |
|---|
| | 437 | if (radix != r) |
|---|
| | 438 | if (radix) |
|---|
| | 439 | --p; |
|---|
| | 440 | else |
|---|
| | 441 | radix = r; |
|---|
| 421 | 442 | } |
|---|
| 422 | 443 | |
|---|
| … | … | |
| 481 | 502 | { |
|---|
| 482 | 503 | char[64] tmp; |
|---|
| 483 | | |
|---|
| | 504 | |
|---|
| | 505 | assert (toInt("1") is 1); |
|---|
| | 506 | assert (toLong("1") is 1); |
|---|
| 484 | 507 | assert (toInt("1", 10) is 1); |
|---|
| 485 | | assert (toLong("1", 10U) is 1); |
|---|
| | 508 | assert (toLong("1", 10) is 1); |
|---|
| 486 | 509 | |
|---|
| 487 | 510 | assert (atoi ("12345") is 12345); |
|---|
| … | … | |
| 535 | 558 | assert(parse( "0B10000") == 0x10 ); |
|---|
| 536 | 559 | |
|---|
| 537 | | // regression tests |
|---|
| 538 | | |
|---|
| 539 | | // ticket #90 |
|---|
| | 560 | // prefix tests |
|---|
| 540 | 561 | char[] str = "0x"; |
|---|
| 541 | 562 | assert(parse( str[0..1] ) == 0 ); |
|---|
| 542 | | |
|---|
| | 563 | assert(parse("0x10", 10) == 0); |
|---|
| | 564 | assert(parse("0b10", 10) == 0); |
|---|
| | 565 | assert(parse("0o10", 10) == 0); |
|---|
| | 566 | assert(parse("0b10") == 0b10); |
|---|
| | 567 | assert(parse("0o10") == 010); |
|---|
| | 568 | assert(parse("0b10", 2) == 0b10); |
|---|
| | 569 | assert(parse("0o10", 8) == 010); |
|---|
| | 570 | |
|---|
| | 571 | // format tests |
|---|
| 543 | 572 | assert (format (tmp, 12345L) == "12345"); |
|---|
| 544 | 573 | assert (format (tmp, 0) == "0"); |
|---|
| … | … | |
| 560 | 589 | } |
|---|
| 561 | 590 | |
|---|
| 562 | | |
|---|
| 563 | | debug (Integer) |
|---|
| 564 | | { |
|---|
| 565 | | void main() |
|---|
| 566 | | { |
|---|
| 567 | | } |
|---|
| 568 | | } |
|---|
| 569 | | |
|---|
Download in other formats:
|
 |