 |
Changeset 2927
- Timestamp:
- 11/25/07 02:08:49
(1 year ago)
- Author:
- kris
- Message:
* fixes [124] E,e format specifier is not supported
* resolves [753] Layout format strings
* fixes [780] Problem in tango.text.convert.Integer.format
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r2913 |
r2927 |
|
| 108 | 108 | to the output. |
|---|
| 109 | 109 | |
|---|
| 110 | | ******************************************************************************/ |
|---|
| 111 | | |
|---|
| 112 | | T[] format(T, D=double, U=uint) (T[] dst, D x, U decimals = 2, bool scientific = false) |
|---|
| 113 | | {return format!(T)(dst, x, decimals, scientific);} |
|---|
| 114 | | |
|---|
| 115 | | T[] format(T) (T[] dst, NumType x, uint decimals = 2, bool scientific = false) |
|---|
| | 110 | TODO: this should be replaced, as it is not sufficiently accurate |
|---|
| | 111 | |
|---|
| | 112 | ******************************************************************************/ |
|---|
| | 113 | |
|---|
| | 114 | T[] format(T, D=double, U=uint) (T[] dst, D x, U decimals = 2, bool e = false) |
|---|
| | 115 | {return format!(T)(dst, x, decimals, e);} |
|---|
| | 116 | |
|---|
| | 117 | T[] format(T) (T[] dst, NumType x, uint decimals = 2, bool e = false) |
|---|
| 116 | 118 | { |
|---|
| 117 | 119 | static T[] inf = "-inf"; |
|---|
| … | … | |
| 140 | 142 | // Don't exceed max digits storable in a real |
|---|
| 141 | 143 | // (-1 because the last digit is not always storable) |
|---|
| 142 | | if (++count > NumType.dig-1) |
|---|
| | 144 | if (--count <= 0) |
|---|
| 143 | 145 | digit = 0; |
|---|
| 144 | 146 | else |
|---|
| … | … | |
| 171 | 173 | if (x > 0.0) |
|---|
| 172 | 174 | { |
|---|
| 173 | | // round up a bit (should do even/odd test?) |
|---|
| 174 | | x += 0.5 / pow10 (decimals); |
|---|
| | 175 | // round up a bit |
|---|
| | 176 | if (e is false) |
|---|
| | 177 | x += 0.5 / pow10 (decimals); |
|---|
| 175 | 178 | |
|---|
| 176 | 179 | // extract base10 exponent |
|---|
| … | … | |
| 186 | 189 | // switch to short display if not enough space |
|---|
| 187 | 190 | if (len + 32 > dst.length) |
|---|
| 188 | | scientific = true; |
|---|
| | 191 | e = true; |
|---|
| 189 | 192 | } |
|---|
| 190 | 193 | |
|---|
| 191 | 194 | T* p = dst.ptr; |
|---|
| 192 | | int count = 0; |
|---|
| | 195 | int count = NumType.dig; |
|---|
| 193 | 196 | |
|---|
| 194 | 197 | // emit sign |
|---|
| … | … | |
| 197 | 200 | |
|---|
| 198 | 201 | // are we doing +/-exp format? |
|---|
| 199 | | if (scientific) |
|---|
| | 202 | if (e) |
|---|
| 200 | 203 | { |
|---|
| 201 | 204 | // emit first digit, and decimal point |
|---|
| 202 | 205 | *p++ = toDigit (x, count); |
|---|
| 203 | | *p++ = '.'; |
|---|
| | 206 | if (decimals) |
|---|
| | 207 | { |
|---|
| | 208 | *p++ = '.'; |
|---|
| | 209 | if (exp < 0) |
|---|
| | 210 | count += exp; |
|---|
| | 211 | } |
|---|
| 204 | 212 | |
|---|
| 205 | 213 | // emit rest of mantissa |
|---|
| … | … | |
| 236 | 244 | |
|---|
| 237 | 245 | // emit point |
|---|
| 238 | | *p++ = '.'; |
|---|
| | 246 | if (decimals) |
|---|
| | 247 | *p++ = '.'; |
|---|
| 239 | 248 | |
|---|
| 240 | 249 | // emit leading fractional zeros? |
|---|
| … | … | |
| 389 | 398 | debug (UnitTest) |
|---|
| 390 | 399 | { |
|---|
| 391 | | // void main() {} |
|---|
| 392 | | |
|---|
| 393 | 400 | unittest |
|---|
| 394 | 401 | { |
|---|
| … | … | |
| 412 | 419 | |
|---|
| 413 | 420 | |
|---|
| | 421 | debug (Float) |
|---|
| | 422 | { |
|---|
| | 423 | void main() {} |
|---|
| | 424 | } |
|---|
| r2913 |
r2927 |
|
| 191 | 191 | T[] prefix; |
|---|
| 192 | 192 | auto len = dst.length; |
|---|
| | 193 | |
|---|
| | 194 | static T[] error (T[] msg) |
|---|
| | 195 | { |
|---|
| | 196 | if (1 & Flags.Throw) |
|---|
| | 197 | throw new IllegalArgumentException ("Integer.format :: invalid arguments"); |
|---|
| | 198 | return msg; |
|---|
| | 199 | } |
|---|
| 193 | 200 | |
|---|
| 194 | 201 | // must have some buffer space to operate within! |
|---|
| … | … | |
| 201 | 208 | switch (cast(byte) fmt) |
|---|
| 202 | 209 | { |
|---|
| 203 | | default: |
|---|
| 204 | 210 | case 'd': |
|---|
| 205 | 211 | case 'D': |
|---|
| … | … | |
| 247 | 253 | prefix = "0X"; |
|---|
| 248 | 254 | break; |
|---|
| | 255 | |
|---|
| | 256 | default: |
|---|
| | 257 | return error (cast(T[])"{unknown format '"~cast(T)fmt~"'}"); |
|---|
| 249 | 258 | } |
|---|
| 250 | 259 | |
|---|
| … | … | |
| 283 | 292 | } |
|---|
| 284 | 293 | else |
|---|
| 285 | | if (flags & Flags.Throw) |
|---|
| 286 | | throw new IllegalArgumentException ("Integer.format :: output truncated"); |
|---|
| | 294 | return error ("{output width too small}"); |
|---|
| 287 | 295 | |
|---|
| 288 | 296 | // return slice of provided output buffer |
|---|
| … | … | |
| 581 | 589 | assert (format (tmp[0..8], 0x5L, Style.Binary, Flags.Prefix | Flags.Zero) == "0b000101"); |
|---|
| 582 | 590 | |
|---|
| 583 | | assert (format (tmp[0..8], -1, Style.Binary, Flags.Prefix | Flags.Zero) == "11111111"); |
|---|
| | 591 | assert (format (tmp[0..8], -1, Style.Binary, Flags.Prefix | Flags.Zero) == "{output width too small}"); |
|---|
| 584 | 592 | assert (format (tmp[0..2], 0x3, Style.Binary, Flags.Throw) == "11"); |
|---|
| 585 | 593 | assert (format (tmp[0..4], 0x3, Style.Binary, Flags.Prefix | Flags.Zero | Flags.Throw) == "0b11"); |
|---|
| r2913 |
r2927 |
|
| 373 | 373 | fragment = ++s; |
|---|
| 374 | 374 | |
|---|
| 375 | | void process( T[] str ){ |
|---|
| 376 | | int padding = width - str.length; |
|---|
| 377 | | |
|---|
| 378 | | // if not left aligned, pad out with spaces |
|---|
| 379 | | if (! leftAlign && padding > 0) |
|---|
| 380 | | length += spaces (sink, padding); |
|---|
| 381 | | |
|---|
| 382 | | // emit formatted argument |
|---|
| 383 | | length += sink (str); |
|---|
| 384 | | |
|---|
| 385 | | // finally, pad out on right |
|---|
| 386 | | if (leftAlign && padding > 0) |
|---|
| 387 | | length += spaces (sink, padding); |
|---|
| 388 | | |
|---|
| | 375 | // handle alignment |
|---|
| | 376 | void process (T[] str) |
|---|
| | 377 | { |
|---|
| | 378 | int padding = width - str.length; |
|---|
| | 379 | |
|---|
| | 380 | // if not left aligned, pad out with spaces |
|---|
| | 381 | if (! leftAlign && padding > 0) |
|---|
| | 382 | length += spaces (sink, padding); |
|---|
| | 383 | |
|---|
| | 384 | // emit formatted argument |
|---|
| | 385 | length += sink (str); |
|---|
| | 386 | |
|---|
| | 387 | // finally, pad out on right |
|---|
| | 388 | if (leftAlign && padding > 0) |
|---|
| | 389 | length += spaces (sink, padding); |
|---|
| 389 | 390 | } |
|---|
| 390 | 391 | |
|---|
| 391 | | void processElement( TypeInfo _ti, Arg _arg ){ |
|---|
| 392 | | if( _ti.classinfo.name.length == 20 && _ti.classinfo.name[9..$] == "StaticArray" ) |
|---|
| 393 | | { |
|---|
| 394 | | auto tiStat = cast(TypeInfo_StaticArray)_ti; |
|---|
| 395 | | auto p = _arg; |
|---|
| 396 | | length += sink ("[ "); |
|---|
| 397 | | for( int i = 0; i < tiStat.len; i++ ){ |
|---|
| 398 | | if( p !is _arg ){ |
|---|
| 399 | | length += sink (", "); |
|---|
| 400 | | } |
|---|
| 401 | | processElement( tiStat.value, p ); |
|---|
| 402 | | |
|---|
| 403 | | p += tiStat.tsize; |
|---|
| 404 | | } |
|---|
| 405 | | length += sink (" ]"); |
|---|
| 406 | | } |
|---|
| 407 | | else if( _ti.classinfo.name.length == 25 && _ti.classinfo.name[9..$] == "AssociativeArray" ) |
|---|
| 408 | | { |
|---|
| 409 | | auto tiAsso = cast(TypeInfo_AssociativeArray)_ti; |
|---|
| 410 | | TypeInfo tiKey = tiAsso.key; |
|---|
| 411 | | TypeInfo tiVal = tiAsso.next(); |
|---|
| 412 | | // the knowledge of the internal k/v storage is used |
|---|
| 413 | | // so this might break if, that internal storage changes |
|---|
| 414 | | alias ubyte AV; // any type for key, value might be ok, the sizes are corrected later |
|---|
| 415 | | alias ubyte AK; |
|---|
| 416 | | AV[AK] aa = *cast(AV[AK]*) _arg; |
|---|
| 417 | | |
|---|
| 418 | | length += sink ("{ "); |
|---|
| 419 | | bool first = true; |
|---|
| 420 | | foreach( inout v; aa ) |
|---|
| 421 | | { |
|---|
| 422 | | int roundUp (int sz) |
|---|
| 423 | | { |
|---|
| 424 | | return ( sz + (void*).sizeof -1 ) & ~((void*).sizeof - 1); |
|---|
| 425 | | } |
|---|
| 426 | | |
|---|
| 427 | | // the key is befor the value, so substrace with fixed key size from above |
|---|
| 428 | | Arg pk = cast(Arg)( &v - roundUp(AK.sizeof)); |
|---|
| 429 | | // now the real value pos is plus the real key size |
|---|
| 430 | | Arg pv = cast(Arg)(pk + roundUp(tiKey.tsize())); |
|---|
| 431 | | |
|---|
| 432 | | if( !first ) |
|---|
| 433 | | { |
|---|
| 434 | | length += sink (", "); |
|---|
| 435 | | } |
|---|
| 436 | | |
|---|
| 437 | | processElement (tiKey, pk); |
|---|
| 438 | | length += sink ("=>"); |
|---|
| 439 | | processElement (tiVal, pv); |
|---|
| 440 | | first = false; |
|---|
| 441 | | } |
|---|
| 442 | | length += sink (" }"); |
|---|
| 443 | | } |
|---|
| 444 | | else if( _ti.classinfo.name[9] == TypeCode.ARRAY |
|---|
| 445 | | && (_ti !is typeid( char[])) |
|---|
| 446 | | && (_ti !is typeid(wchar[])) |
|---|
| 447 | | && (_ti !is typeid(dchar[])) ) |
|---|
| 448 | | { |
|---|
| 449 | | // for all non string array types (including char[][]) |
|---|
| 450 | | void[] arr = *cast(void[]*)_arg; |
|---|
| 451 | | int len = arr.length; |
|---|
| 452 | | Arg ptr = cast(Arg) arr.ptr; |
|---|
| 453 | | TypeInfo elTi = _ti.next(); |
|---|
| 454 | | int size = elTi.tsize(); |
|---|
| 455 | | length += sink ("[ "); |
|---|
| 456 | | while (len > 0) |
|---|
| 457 | | { |
|---|
| 458 | | if (ptr !is arr.ptr) |
|---|
| 459 | | { |
|---|
| 460 | | length += sink (", "); |
|---|
| 461 | | } |
|---|
| 462 | | processElement (elTi, ptr); |
|---|
| 463 | | |
|---|
| 464 | | len -= 1; |
|---|
| 465 | | ptr += size; |
|---|
| 466 | | } |
|---|
| 467 | | length += sink (" ]"); |
|---|
| 468 | | } |
|---|
| 469 | | else |
|---|
| 470 | | { |
|---|
| 471 | | // the standard processing |
|---|
| 472 | | process( munge (result, format, _ti, _arg ) ); |
|---|
| 473 | | } |
|---|
| 474 | | } |
|---|
| 475 | | |
|---|
| 476 | | if( index >= ti.length ) |
|---|
| 477 | | { |
|---|
| 478 | | process( "{invalid index}" ); |
|---|
| 479 | | } |
|---|
| 480 | | else |
|---|
| 481 | | { |
|---|
| 482 | | processElement( ti[index], args[index] ); |
|---|
| 483 | | } |
|---|
| 484 | | |
|---|
| 485 | | } |
|---|
| | 392 | // an astonishing number of typehacks needed to handle arrays :( |
|---|
| | 393 | void processElement (TypeInfo _ti, Arg _arg) |
|---|
| | 394 | { |
|---|
| | 395 | if (_ti.classinfo.name.length is 20 && _ti.classinfo.name[9..$] == "StaticArray" ) |
|---|
| | 396 | { |
|---|
| | 397 | auto tiStat = cast(TypeInfo_StaticArray)_ti; |
|---|
| | 398 | auto p = _arg; |
|---|
| | 399 | length += sink ("[ "); |
|---|
| | 400 | for (int i = 0; i < tiStat.len; i++) |
|---|
| | 401 | { |
|---|
| | 402 | if (p !is _arg ) |
|---|
| | 403 | length += sink (", "); |
|---|
| | 404 | processElement (tiStat.value, p); |
|---|
| | 405 | p += tiStat.tsize; |
|---|
| | 406 | } |
|---|
| | 407 | length += sink (" ]"); |
|---|
| | 408 | } |
|---|
| | 409 | else |
|---|
| | 410 | if (_ti.classinfo.name.length is 25 && _ti.classinfo.name[9..$] == "AssociativeArray") |
|---|
| | 411 | { |
|---|
| | 412 | auto tiAsso = cast(TypeInfo_AssociativeArray)_ti; |
|---|
| | 413 | auto tiKey = tiAsso.key; |
|---|
| | 414 | auto tiVal = tiAsso.next(); |
|---|
| | 415 | // the knowledge of the internal k/v storage is used |
|---|
| | 416 | // so this might break if, that internal storage changes |
|---|
| | 417 | alias ubyte AV; // any type for key, value might be ok, the sizes are corrected later |
|---|
| | 418 | alias ubyte AK; |
|---|
| | 419 | auto aa = *cast(AV[AK]*) _arg; |
|---|
| | 420 | |
|---|
| | 421 | length += sink ("{ "); |
|---|
| | 422 | bool first = true; |
|---|
| | 423 | |
|---|
| | 424 | int roundUp (int sz) |
|---|
| | 425 | { |
|---|
| | 426 | return (sz + (void*).sizeof -1) & ~((void*).sizeof - 1); |
|---|
| | 427 | } |
|---|
| | 428 | |
|---|
| | 429 | foreach (inout v; aa) |
|---|
| | 430 | { |
|---|
| | 431 | // the key is befor the value, so substrace with fixed key size from above |
|---|
| | 432 | auto pk = cast(Arg)( &v - roundUp(AK.sizeof)); |
|---|
| | 433 | // now the real value pos is plus the real key size |
|---|
| | 434 | auto pv = cast(Arg)(pk + roundUp(tiKey.tsize())); |
|---|
| | 435 | |
|---|
| | 436 | if (!first) |
|---|
| | 437 | length += sink (", "); |
|---|
| | 438 | processElement (tiKey, pk); |
|---|
| | 439 | length += sink ("=>"); |
|---|
| | 440 | processElement (tiVal, pv); |
|---|
| | 441 | first = false; |
|---|
| | 442 | } |
|---|
| | 443 | length += sink (" }"); |
|---|
| | 444 | } |
|---|
| | 445 | else |
|---|
| | 446 | if (_ti.classinfo.name[9] is TypeCode.ARRAY && |
|---|
| | 447 | (_ti !is typeid(char[])) && |
|---|
| | 448 | (_ti !is typeid(wchar[])) && |
|---|
| | 449 | (_ti !is typeid(dchar[]))) |
|---|
| | 450 | { |
|---|
| | 451 | // for all non string array types (including char[][]) |
|---|
| | 452 | auto arr = *cast(void[]*)_arg; |
|---|
| | 453 | auto len = arr.length; |
|---|
| | 454 | auto ptr = cast(Arg) arr.ptr; |
|---|
| | 455 | auto elTi = _ti.next(); |
|---|
| | 456 | auto size = elTi.tsize(); |
|---|
| | 457 | length += sink ("[ "); |
|---|
| | 458 | while (len > 0) |
|---|
| | 459 | { |
|---|
| | 460 | if (ptr !is arr.ptr) |
|---|
| | 461 | length += sink (", "); |
|---|
| | 462 | processElement (elTi, ptr); |
|---|
| | 463 | len -= 1; |
|---|
| | 464 | ptr += size; |
|---|
| | 465 | } |
|---|
| | 466 | length += sink (" ]"); |
|---|
| | 467 | } |
|---|
| | 468 | else |
|---|
| | 469 | // the standard processing |
|---|
| | 470 | process (munge(result, format, _ti, _arg)); |
|---|
| | 471 | } |
|---|
| | 472 | |
|---|
| | 473 | |
|---|
| | 474 | // process this argument |
|---|
| | 475 | if (index >= ti.length) |
|---|
| | 476 | process ("{invalid index}"); |
|---|
| | 477 | else |
|---|
| | 478 | processElement (ti[index], args[index]); |
|---|
| | 479 | } |
|---|
| 486 | 480 | return length; |
|---|
| 487 | 481 | } |
|---|
| … | … | |
| 531 | 525 | return fromUtf32 (*cast(dchar[]*) p, result); |
|---|
| 532 | 526 | |
|---|
| 533 | | // Currently we only format d/w/char[] arrays. |
|---|
| 534 | 527 | return fromUtf8 (type.toString, result); |
|---|
| 535 | 528 | |
|---|
| … | … | |
| 606 | 599 | } |
|---|
| 607 | 600 | |
|---|
| 608 | | static T[] Null = "{null}"; |
|---|
| 609 | | return Null; |
|---|
| | 601 | return cast(T[]) "{null}"; |
|---|
| 610 | 602 | } |
|---|
| 611 | 603 | |
|---|
| … | … | |
| 623 | 615 | **********************************************************************/ |
|---|
| 624 | 616 | |
|---|
| 625 | | protected T[] integer (T[] output, long v, T[] alt, T format = 'd') |
|---|
| 626 | | { |
|---|
| 627 | | uint width; |
|---|
| 628 | | auto style = cast(Integer.Style) parse2 (alt, width, format); |
|---|
| 629 | | |
|---|
| | 617 | protected T[] integer (T[] output, long v, T[] format, T style = 'd') |
|---|
| | 618 | { |
|---|
| 630 | 619 | Integer.Flags flags; |
|---|
| 631 | | if (width) |
|---|
| | 620 | uint width = output.length; |
|---|
| | 621 | |
|---|
| | 622 | if (parseGeneric (format, width, style)) |
|---|
| | 623 | if (width <= output.length) |
|---|
| | 624 | { |
|---|
| | 625 | output = output [0 .. width]; |
|---|
| | 626 | flags |= flags.Zero; |
|---|
| | 627 | } |
|---|
| | 628 | return Integer.format (output, v, cast(Integer.Style) style, flags); |
|---|
| | 629 | } |
|---|
| | 630 | |
|---|
| | 631 | /********************************************************************** |
|---|
| | 632 | |
|---|
| | 633 | **********************************************************************/ |
|---|
| | 634 | |
|---|
| | 635 | protected T[] floater (T[] output, real v, T[] format) |
|---|
| | 636 | { |
|---|
| | 637 | T style = 'f'; |
|---|
| | 638 | uint places = 2; |
|---|
| | 639 | |
|---|
| | 640 | parseGeneric (format, places, style); |
|---|
| | 641 | return Float.format (output, v, places, (style is 'e' || style is 'E')); |
|---|
| | 642 | } |
|---|
| | 643 | |
|---|
| | 644 | /********************************************************************** |
|---|
| | 645 | |
|---|
| | 646 | **********************************************************************/ |
|---|
| | 647 | |
|---|
| | 648 | private bool parseGeneric (T[] format, ref uint width, ref T style) |
|---|
| | 649 | { |
|---|
| | 650 | if (format.length) |
|---|
| 632 | 651 | { |
|---|
| 633 | | output = output [0 .. width]; |
|---|
| 634 | | flags = flags.Zero; |
|---|
| | 652 | uint number; |
|---|
| | 653 | auto p = format.ptr; |
|---|
| | 654 | auto e = p + format.length; |
|---|
| | 655 | style = *p; |
|---|
| | 656 | while (++p < e) |
|---|
| | 657 | if (*p >= '0' && *p <= '9') |
|---|
| | 658 | number = number * 10 + *p - '0'; |
|---|
| | 659 | else |
|---|
| | 660 | break; |
|---|
| | 661 | |
|---|
| | 662 | if (p - format.ptr > 1) |
|---|
| | 663 | { |
|---|
| | 664 | width = number; |
|---|
| | 665 | return true; |
|---|
| | 666 | } |
|---|
| 635 | 667 | } |
|---|
| 636 | | |
|---|
| 637 | | return Integer.format (output, v, style, flags); |
|---|
| 638 | | } |
|---|
| 639 | | |
|---|
| 640 | | /********************************************************************** |
|---|
| 641 | | |
|---|
| 642 | | **********************************************************************/ |
|---|
| 643 | | |
|---|
| 644 | | protected T[] floater (T[] output, real v, T[] format) |
|---|
| 645 | | { |
|---|
| 646 | | uint places; |
|---|
| 647 | | bool scientific; |
|---|
| 648 | | |
|---|
| 649 | | if (parse2(format, places) is 'e') |
|---|
| 650 | | scientific = true; |
|---|
| 651 | | |
|---|
| 652 | | if (places is 0) |
|---|
| 653 | | places = 2; |
|---|
| 654 | | |
|---|
| 655 | | return Float.format (output, v, places, scientific); |
|---|
| 656 | | } |
|---|
| 657 | | |
|---|
| 658 | | /********************************************************************** |
|---|
| 659 | | |
|---|
| 660 | | **********************************************************************/ |
|---|
| 661 | | |
|---|
| 662 | | private T parse2 (T[] format, inout uint width, T def=T.init) |
|---|
| 663 | | { |
|---|
| 664 | | uint number; |
|---|
| 665 | | foreach (c; format) |
|---|
| 666 | | if (c >= '0' && c <= '9') |
|---|
| 667 | | number = number * 10 + c - '0'; |
|---|
| 668 | | |
|---|
| 669 | | width = number; |
|---|
| 670 | | return format.length > 0 ? format[0] : def; |
|---|
| | 668 | return false; |
|---|
| 671 | 669 | } |
|---|
| 672 | 670 | |
|---|
| … | … | |
| 858 | 856 | |
|---|
| 859 | 857 | assert( Formatter( "{0:f}", 1.23f ) == "1.23" , Formatter( "{0:f}", 1.23f )); |
|---|
| 860 | | assert( Formatter( "{0:f4}", 1.23456789L ) == "1.2346" ); |
|---|
| | 858 | assert( Formatter( "{0:f4}", 1.23456789L ) == "1.2345" ); |
|---|
| | 859 | assert( Formatter( "{0:e4}", 0.0001) == "", Formatter( "{0:e4}", 0.0001) ); |
|---|
| 861 | 860 | |
|---|
| 862 | 861 | int[] a = [ 51, 52, 53, 54, 55 ]; |
|---|
| … | … | |
| 874 | 873 | d[234] = 2; |
|---|
| 875 | 874 | d[345] = 3; |
|---|
| 876 | | Stdout.formatln( "{}", d ); |
|---|
| 877 | 875 | assert( Formatter( "{}", d ) == "{ 234=>2, 345=>3 }" ); |
|---|
| 878 | 876 | |
|---|
| … | … | |
| 895 | 893 | import tango.io.Console; |
|---|
| 896 | 894 | |
|---|
| 897 | | interface foo {} |
|---|
| 898 | | |
|---|
| 899 | | class X : foo {char[] toString() {return "hello";}} |
|---|
| 900 | | |
|---|
| 901 | 895 | void main () |
|---|
| 902 | 896 | { |
|---|
| 903 | | int i = int.max; |
|---|
| 904 | | auto Formatter = new Layout!(char); |
|---|
| 905 | | |
|---|
| 906 | | auto x = new X; |
|---|
| 907 | | foo f = x; |
|---|
| 908 | | Cout (Formatter ("{:x8} {} {} bottles", -1, f, x)); |
|---|
| | 897 | auto layout = new Layout!(char); |
|---|
| | 898 | |
|---|
| | 899 | Cout (layout ("{:d2}", 56)).newline; |
|---|
| | 900 | Cout (layout ("{:f4}", 0.001)).newline; |
|---|
| | 901 | Cout (layout ("{:f8}", 3.14159)).newline; |
|---|
| | 902 | Cout (layout ("{:e20}", 0.001)).newline; |
|---|
| | 903 | Cout (layout ("{:e4}", 0.0000001)).newline; |
|---|
| 909 | 904 | } |
|---|
| 910 | 905 | } |
|---|
Download in other formats:
|
 |