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(Writer, Char)(ref Writer w, scope const ref FormatSpec!Char fmt)
void toString(Writer)(ref Writer w)
string toString();
Where Writer
is an output range
which accepts characters. The template type does not have to be called Writer
.
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!char 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
toString
has 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
bool
s 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
enum
s 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
Known Bug: Function attributes are not always correct. See Bugzilla 18269 for more details.
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