Wolfgang Thallergcc 15.1.0ada185d1 year agoHistory
1356 lines · 38.7 KB · D
RawDownload
// Written in the D programming language. /**This is a submodule of $(MREF std, format). It provides two functions for writing formatted output: $(LREFformatValue) and $(LREF formattedWrite). The former writes a singlevalue. The latter writes several values at once, interspersed withunformatted text. The following combinations of format characters and types areavailable: $(BOOKTABLE ,$(TR $(TH) $(TH s) $(TH c) $(TH d, u, b, o) $(TH x, X) $(TH e, E, f, F, g, G, a, A) $(TH r) $(TH compound))$(TR $(TD `bool`) $(TD yes) $(TD $(MDASH)) $(TD yes) $(TD yes) $(TD $(MDASH)) $(TD yes) $(TD $(MDASH)))$(TR $(TD `null`) $(TD yes) $(TD $(MDASH)) $(TD $(MDASH)) $(TD $(MDASH)) $(TD $(MDASH)) $(TD $(MDASH)) $(TD $(MDASH)))$(TR $(TD $(I integer)) $(TD yes) $(TD $(MDASH)) $(TD yes) $(TD yes) $(TD yes) $(TD yes) $(TD $(MDASH)))$(TR $(TD $(I floating point)) $(TD yes) $(TD $(MDASH)) $(TD $(MDASH)) $(TD $(MDASH)) $(TD yes) $(TD yes) $(TD $(MDASH)))$(TR $(TD $(I character)) $(TD yes) $(TD yes) $(TD yes) $(TD yes) $(TD $(MDASH)) $(TD yes) $(TD $(MDASH)))$(TR $(TD $(I string)) $(TD yes) $(TD $(MDASH)) $(TD $(MDASH)) $(TD $(MDASH)) $(TD $(MDASH)) $(TD yes) $(TD yes))$(TR $(TD $(I array)) $(TD yes) $(TD $(MDASH)) $(TD $(MDASH)) $(TD $(MDASH)) $(TD $(MDASH)) $(TD yes) $(TD yes))$(TR $(TD $(I associative array)) $(TD yes) $(TD $(MDASH)) $(TD $(MDASH)) $(TD $(MDASH)) $(TD $(MDASH)) $(TD $(MDASH)) $(TD yes))$(TR $(TD $(I pointer)) $(TD yes) $(TD $(MDASH)) $(TD $(MDASH)) $(TD yes) $(TD $(MDASH)) $(TD $(MDASH)) $(TD $(MDASH)))$(TR $(TD $(I SIMD vectors)) $(TD yes) $(TD $(MDASH)) $(TD $(MDASH)) $(TD $(MDASH)) $(TD $(MDASH)) $(TD yes) $(TD yes))$(TR $(TD $(I delegates)) $(TD yes) $(TD $(MDASH)) $(TD $(MDASH)) $(TD $(MDASH)) $(TD $(MDASH)) $(TD yes) $(TD yes))) Enums can be used with all format characters of the base type. $(H3 $(LNAME2 aggregates, Structs, Unions, Classes, and Interfaces)) Aggregate types can define various `toString` functions. If thisfunction takes a $(REF_ALTTEXT FormatSpec, FormatSpec, std, format,spec) or a $(I format string) as argument, the function decideswhich format characters are accepted. If no `toString` is defined andthe aggregate is an $(REF_ALTTEXT input range, isInputRange, std,range, primitives), it is treated like a range, that is $(B 's'), $(B'r') and a compound specifier are accepted. In all other casesaggregate types only accept $(B 's'). `toString` should have one of the following signatures: ---void toString(Writer, Char)(ref Writer w, const ref FormatSpec!Char fmt)void toString(Writer)(ref Writer w)string toString();--- Where `Writer` is an $(REF_ALTTEXT output range, isOutputRange,std,range,primitives) which accepts characters $(LPAREN)of type`Char` in the first version$(RPAREN). The template type does not haveto be called `Writer`. Sometimes it's not possible to use a template, for example when`toString` overrides `Object.toString`. In this case, the following$(LPAREN)slower and less flexible$(RPAREN) functions can be used: ---void toString(void delegate(const(char)[]) sink, const ref FormatSpec!char fmt);void toString(void delegate(const(char)[]) sink, string fmt);void toString(void delegate(const(char)[]) sink);--- When several of the above `toString` versions are available, theversions with `Writer` take precedence over the versions with a`sink`. `string toString()` has the lowest priority. If none of the above mentioned `toString` versions are available, theaggregates will be formatted by other means, in the followingorder: If an aggregate is an $(REF_ALTTEXT input range, isInputRange, std,range, primitives), it is formatted like an input range. If an aggregate is a builtin type (using `alias this`), it is formattedlike the builtin type. If all else fails, structs are formatted like `Type(field1, field2, ...)`,classes and interfaces are formatted with their fully qualified nameand unions with their base name. Copyright: Copyright The D Language Foundation 2000-2013. License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). Authors: $(HTTP walterbright.com, Walter Bright), $(HTTP erdani.com,Andrei Alexandrescu), and Kenji Hara Source: $(PHOBOSSRC std/format/write.d) */module std.format.write; /**`bool`s are formatted as `"true"` or `"false"` with `%s` and like the`byte`s 1 and 0 with all other format characters. */@safe pure unittest{    import std.array : appender;    import std.format.spec : singleSpec;     auto w1 = appender!string();    auto spec1 = singleSpec("%s");    formatValue(w1, true, spec1);     assert(w1.data == "true");     auto w2 = appender!string();    auto spec2 = singleSpec("%#x");    formatValue(w2, true, spec2);     assert(w2.data == "0x1");} /// The `null` literal is formatted as `"null"`.@safe pure unittest{    import std.array : appender;    import std.format.spec : singleSpec;     auto w = appender!string();    auto spec = singleSpec("%s");    formatValue(w, null, spec);     assert(w.data == "null");} /**Integrals are formatted in (signed) every day notation with `%s` and`%d` and as an (unsigned) image of the underlying bit representationwith `%b` (binary), `%u` (decimal), `%o` (octal), and `%x` (hexadecimal). */@safe pure unittest{    import std.array : appender;    import std.format.spec : singleSpec;     auto w1 = appender!string();    auto spec1 = singleSpec("%d");    formatValue(w1, -1337, spec1);     assert(w1.data == "-1337");     auto w2 = appender!string();    auto spec2 = singleSpec("%x");    formatValue(w2, -1337, spec2);     assert(w2.data == "fffffac7");} /**Floating-point values are formatted in natural notation with `%f`, inscientific notation with `%e`, in short notation with `%g`, and inhexadecimal scientific notation with `%a`. If a rounding mode isavailable, they are rounded according to this rounding mode, otherwisethey are rounded to the nearest value, ties to even. */@safe unittest{    import std.array : appender;    import std.format.spec : singleSpec;     auto w1 = appender!string();    auto spec1 = singleSpec("%.3f");    formatValue(w1, 1337.7779, spec1);     assert(w1.data == "1337.778");     auto w2 = appender!string();    auto spec2 = singleSpec("%.3e");    formatValue(w2, 1337.7779, spec2);     assert(w2.data == "1.338e+03");     auto w3 = appender!string();    auto spec3 = singleSpec("%.3g");    formatValue(w3, 1337.7779, spec3);     assert(w3.data == "1.34e+03");     auto w4 = appender!string();    auto spec4 = singleSpec("%.3a");    formatValue(w4, 1337.7779, spec4);     assert(w4.data == "0x1.4e7p+10");} /**Individual characters (`char`, `wchar`, or `dchar`) are formatted asUnicode characters with `%s` and `%c` and as integers (`ubyte`,`ushort`, `uint`) with all other format characters. With$(MREF_ALTTEXT compound specifiers, std,format) characters aretreated differently. */@safe pure unittest{    import std.array : appender;    import std.format.spec : singleSpec;     auto w1 = appender!string();    auto spec1 = singleSpec("%c");    formatValue(w1, 'ì', spec1);     assert(w1.data == "ì");     auto w2 = appender!string();    auto spec2 = singleSpec("%#x");    formatValue(w2, 'ì', spec2);     assert(w2.data == "0xec");} /**Strings are formatted as a sequence of characters with `%s`.Non-printable characters are not escaped. With a compound specifierthe string is treated like a range of characters. With $(MREF_ALTTEXTcompound specifiers, std,format) strings are treated differently. */@safe pure unittest{    import std.array : appender;    import std.format.spec : singleSpec;     auto w1 = appender!string();    auto spec1 = singleSpec("%s");    formatValue(w1, "hello", spec1);     assert(w1.data == "hello");     auto w2 = appender!string();    auto spec2 = singleSpec("%(%#x%|/%)");    formatValue(w2, "hello", spec2);     assert(w2.data == "0x68/0x65/0x6c/0x6c/0x6f");} /// Static arrays are formatted as dynamic arrays.@safe pure unittest{    import std.array : appender;    import std.format.spec : singleSpec;     auto w = appender!string();    auto spec = singleSpec("%s");    int[2] two = [1, 2];    formatValue(w, two, spec);     assert(w.data == "[1, 2]");} /**Dynamic arrays are formatted as input ranges. */@safe pure unittest{    import std.array : appender;    import std.format.spec : singleSpec;     auto w1 = appender!string();    auto spec1 = singleSpec("%s");    auto two = [1, 2];    formatValue(w1, two, spec1);     assert(w1.data == "[1, 2]");     auto w2 = appender!string();    auto spec2 = singleSpec("%(%g%|, %)");    auto consts = [3.1415926, 299792458, 6.67430e-11];    formatValue(w2, consts, spec2);     assert(w2.data == "3.14159, 2.99792e+08, 6.6743e-11");     // void[] is treated like ubyte[]    auto w3 = appender!string();    auto spec3 = singleSpec("%s");    void[] val = cast(void[]) cast(ubyte[])[1, 2, 3];    formatValue(w3, val, spec3);     assert(w3.data == "[1, 2, 3]");} /**Associative arrays are formatted by using `':'` and `", "` asseparators, enclosed by `'['` and `']'` when used with `%s`. It'salso possible to use a compound specifier for better control. Please note, that the order of the elements is not defined, thereforethe result of this function might differ. */@safe pure unittest{    import std.array : appender;    import std.format.spec : singleSpec;     auto aa = [10:17.5, 20:9.99];     auto w1 = appender!string();    auto spec1 = singleSpec("%s");    formatValue(w1, aa, spec1);     assert(w1.data == "[10:17.5, 20:9.99]" || w1.data == "[20:9.99, 10:17.5]");     auto w2 = appender!string();    auto spec2 = singleSpec("%(%x = %.0e%| # %)");    formatValue(w2, aa, spec2);     assert(w2.data == "a = 2e+01 # 14 = 1e+01" || w2.data == "14 = 1e+01 # a = 2e+01");} /**`enum`s are formatted as their name when used with `%s` and liketheir base value else. */@safe pure unittest{    import std.array : appender;    import std.format.spec : singleSpec;     enum A { first, second, third }     auto w1 = appender!string();    auto spec1 = singleSpec("%s");    formatValue(w1, A.second, spec1);     assert(w1.data == "second");     auto w2 = appender!string();    auto spec2 = singleSpec("%d");    formatValue(w2, A.second, spec2);     assert(w2.data == "1");     // values of an enum that have no name are formatted with %s using a cast    A a = A.third;    a++;     auto w3 = appender!string();    auto spec3 = singleSpec("%s");    formatValue(w3, a, spec3);     assert(w3.data == "cast(A)3");} /**`structs`, `unions`, `classes` and `interfaces` can be formatted inseveral different ways. The following example highlights `struct`formatting, however, it applies to other aggregates as well. */@safe unittest{    import std.array : appender;    import std.format.spec : FormatSpec, singleSpec;     // Using a `toString` with a writer    static struct Point1    {        import std.range.primitives : isOutputRange, put;         int x, y;         void toString(W)(ref W writer, scope const ref FormatSpec!char f)        if (isOutputRange!(W, char))        {            put(writer, "(");            formatValue(writer, x, f);            put(writer, ",");            formatValue(writer, y, f);            put(writer, ")");        }    }     auto w1 = appender!string();    auto spec1 = singleSpec("%s");    auto p1 = Point1(16, 11);     formatValue(w1, p1, spec1);    assert(w1.data == "(16,11)");     // Using a `toString` with a sink    static struct Point2    {        int x, y;         void toString(scope void delegate(scope const(char)[]) @safe sink,                      scope const FormatSpec!char fmt) const        {            sink("(");            sink.formatValue(x, fmt);            sink(",");            sink.formatValue(y, fmt);            sink(")");        }    }     auto w2 = appender!string();    auto spec2 = singleSpec("%03d");    auto p2 = Point2(16,11);     formatValue(w2, p2, spec2);    assert(w2.data == "(016,011)");     // Using `string toString()`    static struct Point3    {        int x, y;         string toString()        {            import std.conv : to;             return "(" ~ to!string(x) ~ "," ~ to!string(y) ~ ")";        }    }     auto w3 = appender!string();    auto spec3 = singleSpec("%s"); // has to be %s    auto p3 = Point3(16,11);     formatValue(w3, p3, spec3);    assert(w3.data == "(16,11)");     // without `toString`    static struct Point4    {        int x, y;    }     auto w4 = appender!string();    auto spec4 = singleSpec("%s"); // has to be %s    auto p4 = Point4(16,11);     formatValue(w4, p4, spec3);    assert(w4.data == "Point4(16, 11)");} /// Pointers are formatted as hexadecimal integers.@safe pure unittest{    import std.array : appender;    import std.format.spec : singleSpec;     auto w1 = appender!string();    auto spec1 = singleSpec("%s");    auto p1 = () @trusted { return cast(void*) 0xFFEECCAA; } ();    formatValue(w1, p1, spec1);     assert(w1.data == "FFEECCAA");     // null pointers are printed as `"null"` when used with `%s` and as hexadecimal integer else    auto w2 = appender!string();    auto spec2 = singleSpec("%s");    auto p2 = () @trusted { return cast(void*) 0x00000000; } ();    formatValue(w2, p2, spec2);     assert(w2.data == "null");     auto w3 = appender!string();    auto spec3 = singleSpec("%x");    formatValue(w3, p2, spec3);     assert(w3.data == "0");} /// SIMD vectors are formatted as arrays.@safe unittest{    import core.simd; // cannot be selective, because float4 might not be defined    import std.array : appender;    import std.format.spec : singleSpec;     auto w = appender!string();    auto spec = singleSpec("%s");     static if (is(float4))    {        version (X86) {}        else        {            float4 f4;            f4.array[0] = 1;            f4.array[1] = 2;            f4.array[2] = 3;            f4.array[3] = 4;             formatValue(w, f4, spec);            assert(w.data == "[1, 2, 3, 4]");        }    }} import std.format.internal.write; import std.format.spec : FormatSpec;import std.traits : isSomeString; /**Converts its arguments according to a format string and writesthe result to an output range. 

Lines 1–500 of 1356.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t