Function std.format.formatValue
Formats any value into Char accepting OutputRange, using the given FormatSpec.
void formatValue(Writer, T, Char)
(
auto ref Writer w,
auto ref T val,
scope const ref FormatSpec!Char f
);
Aggregates
struct, union, class, and interface are formatted by calling toString.
toString should have one of the following signatures:
void toString(W)(ref W w, scope const ref FormatSpec fmt)
void toString(W)(ref W w)
string toString();
Where W is an output range
which accepts characters. The template type does not have to be called W.
The following overloads are also accepted for legacy reasons or for use in virtual functions. It's recommended that any new code forgo these overloads if possible for speed and attribute acceptance reasons.
void toString(scope void delegate(const(char)[]) sink, const ref FormatSpec fmt);
void toString(scope void delegate(const(char)[]) sink, string fmt);
void toString(scope void delegate(const(char)[]) sink);
For the class objects which have input range interface,
- If the instance
toStringhas overriddenObject, it is used..toString - Otherwise, the objects are formatted as input range.
For the struct and union objects which does not have toString,
- If they have range interface, formatted as input range.
- Otherwise, they are formatted like
Type(field1, filed2, ...).
Otherwise, are formatted just as their type name.
Parameters
| Name | Description |
|---|---|
| w | The output range to write to. |
| val | The value to write. |
| f | The FormatSpec defining how to write the value. |
Example
The following code compares the use of formatValue and formattedWrite.
import std .array : appender;
auto writer1 = appender!string();
writer1 .formattedWrite("%08b", 42);
auto writer2 = appender!string();
auto f = singleSpec("%08b");
writer2 .formatValue(42, f);
assert(writer1 .data == writer2 .data && writer1 .data == "00101010");
Example
bools are formatted as "true" or "false" with %s and as 1 or
0 with integral-specific format specs.
import std .array : appender;
auto w = appender!string();
auto spec = singleSpec("%s");
formatValue(w, true, spec);
writeln(w .data); // "true"
Example
null literal is formatted as "null".
import std .array : appender;
auto w = appender!string();
auto spec = singleSpec("%s");
formatValue(w, null, spec);
writeln(w .data); // "null"
Example
Integrals are formatted like printf.
import std .array : appender;
auto w = appender!string();
auto spec = singleSpec("%d");
formatValue(w, 1337, spec);
writeln(w .data); // "1337"
Example
Floating-point values are formatted like printf
import std .array : appender;
auto w = appender!string();
auto spec = singleSpec("%.1f");
formatValue(w, 1337.7, spec);
writeln(w .data); // "1337.7"
Example
Individual characters (char, wchar, or dchar`) are formatted as
Unicode characters with %s and as integers with integral-specific format
specs.
import std .array : appender;
auto w = appender!string();
auto spec = singleSpec("%c");
formatValue(w, 'a', spec);
writeln(w .data); // "a"
Example
Strings are formatted like printf
import std .array : appender;
auto w = appender!string();
auto spec = singleSpec("%s");
formatValue(w, "hello", spec);
writeln(w .data); // "hello"
Example
Static-size arrays are formatted as dynamic arrays.
import std .array : appender;
auto w = appender!string();
auto spec = singleSpec("%s");
char[2] two = ['a', 'b'];
formatValue(w, two, spec);
writeln(w .data); // "ab"
Example
Dynamic arrays are formatted as input ranges.
Specializations
void[]is formatted likeubyte[].- Const array is converted to input range by removing its qualifier.
import std .array : appender;
auto w = appender!string();
auto spec = singleSpec("%s");
auto two = [1, 2];
formatValue(w, two, spec);
writeln(w .data); // "[1, 2]"
Example
Associative arrays are formatted by using ':' and ", " as
separators, and enclosed by '[' and ']'.
import std .array : appender;
auto w = appender!string();
auto spec = singleSpec("%s");
auto aa = ["H":"W"];
formatValue(w, aa, spec);
writeln(w .data); // "[\"H\":\"W\"]"
Example
enums are formatted like their base value
import std .array : appender;
auto w = appender!string();
auto spec = singleSpec("%s");
enum A { first, second, third }
formatValue(w, A .second, spec);
writeln(w .data); // "second"
Example
Formatting a struct by defining a method toString, which takes an output
range.
It's recommended that any toString using output ranges
use put rather than use the put method of the range
directly.
import std .array : appender;
import std .range .primitives;
static struct Point
{
int x, y;
void toString(W)(ref W writer, scope const ref FormatSpec!char f)
if (isOutputRange!(W, char))
{
// std.range.primitives.put
put(writer, "(");
formatValue(writer, x, f);
put(writer, ",");
formatValue(writer, y, f);
put(writer, ")");
}
}
auto w = appender!string();
auto spec = singleSpec("%s");
auto p = Point(16, 11);
formatValue(w, p, spec);
writeln(w .data); // "(16,11)"
Example
Another example of formatting a struct with a defined toString,
this time using the scope delegate method.
This method is now discouraged for non-virtual functions. If possible, please use the output range method instead.
static struct Point
{
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 p = Point(16,11);
writeln(format("%03d", p)); // "(016,011)"
writeln(format("%02x", p)); // "(10,0b)"
Example
Pointers are formatted as hex integers.
import std .array : appender;
auto w = appender!string();
auto spec = singleSpec("%s");
auto q = cast(void*) 0xFFEECCAA;
formatValue(w, q, spec);
writeln(w .data); // "FFEECCAA"
Example
SIMD vectors are formatted as arrays.
import core .simd;
import std .array : appender;
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);
writeln(w .data); // "[1, 2, 3, 4]"
}
}
Example
Delegates are formatted by ReturnType delegate(Parameters) FunctionAttributes
import std .conv : to;
int i;
int foo(short k) @nogc
{
return i + k;
}
@system int delegate(short) @nogc bar() nothrow pure
{
int* p = new int(1);
i = *p;
return &foo;
}
writeln(to!string(&bar)); // "int delegate(short) @nogc delegate() pure nothrow @system"
writeln(() @trusted
{ return bar()(3);
}()); // 4
Example
import std .array : appender;
auto w = appender!string();
auto spec = singleSpec("%s");
formatElement(w, "H", spec);
writeln(w .data); // "\"H\""
Authors
Walter Bright, Andrei Alexandrescu, and Kenji Hara