View source code
Display the source code in std/format.d from which this page was generated on github.
Report a bug
If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using local clone.

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 overridden Object.toString, it is used.
  • 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

NameDescription
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 like ubyte[].
  • 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

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

License

Boost License 1.0.