Re: How to forward format specifiers ?
On Sun, Jun 29, 2014 at 06:08:24PM +0200, Element 126 via Digitalmars-d-learn wrote: [...] > I have used formattedWrite for months without noticing formatValue, > even though it was on the wiki. > Maybe I should add an example to the documentation of std.format. > formatValue is present but without any example, compared to the > extensive documentation of formattedWrite. Please do! We need all the help we can get to improve Phobos documentation. T -- "Real programmers can write assembly code in any language. :-)" -- Larry Wall
Re: How to forward format specifiers ?
On 06/29/2014 04:22 PM, Ali Çehreli wrote: On 06/29/2014 04:55 AM, Element 126 wrote: > I've certainly missed something formatValue passes your tests: import std.stdio; import std.format: formattedWrite, FormatSpec, formatValue; import std.string: format; struct wrapper(T) { private T val; public this(T newVal) pure { val = newVal; } public void toString( scope void delegate(const(char)[]) sink, FormatSpec!char fmt ) const { formatValue(sink, val, fmt);// <-- HERE } } unittest { immutable uint base = 16; auto a = wrapper!uint(base); assert(format("%x", a) == format("%x", base)); assert(format("%08x", a) == format("%08x", base)); } void main() {} Ali Thanks a lot ! I just checked if it also worked for structs and classes and it does the job perfectly. I have used formattedWrite for months without noticing formatValue, even though it was on the wiki. Maybe I should add an example to the documentation of std.format. formatValue is present but without any example, compared to the extensive documentation of formattedWrite.
Re: How to forward format specifiers ?
On 06/29/2014 04:55 AM, Element 126 wrote: > I've certainly missed something formatValue passes your tests: import std.stdio; import std.format: formattedWrite, FormatSpec, formatValue; import std.string: format; struct wrapper(T) { private T val; public this(T newVal) pure { val = newVal; } public void toString( scope void delegate(const(char)[]) sink, FormatSpec!char fmt ) const { formatValue(sink, val, fmt);// <-- HERE } } unittest { immutable uint base = 16; auto a = wrapper!uint(base); assert(format("%x", a) == format("%x", base)); assert(format("%08x", a) == format("%08x", base)); } void main() {} Ali
How to forward format specifiers ?
I am trying to define custom format specifiers (as described here [1]) for the following wrapper struct : import std.stdio; import std.format: formattedWrite, FormatSpec; import std.string: format; struct wrapper(T) { private T val; public this(T newVal) pure { val = newVal; } public void toString( scope void delegate(const(char)[]) sink, FormatSpec!char fmt ) const { formattedWrite(sink, /+ Format string +/ , val); } } unittest { immutable uint base = 16; auto a = wrapper!uint(base); assert(format("%x", a) == format("%x", base)); assert(format("%08x", a) == format("%08x", base)); } More precisely, I want to forward the format specifier fmt received by wrapper!T.toString to formattedWrite. Since formattedWrite expects a const(char)[] "string" as its second argument, I first naively tried to use : formattedWrite(sink, to!string(fmt), val); but to!string(fmt) gives something similar to : address = 7FFFE91C54C0 width = 0 precision = 2147483646 spec = x indexStart = 0 indexEnd = 0 flDash = false flZero = false flSpace = false flPlus = false flHash = false nested = trailing = instead of the original format string, thus causing toString to fail at runtime. The documentation for std.format [2] mentions a second prototype (among four) for toString : const void toString( scope void delegate(const(char)[]) sink, string fmt ); So I tried to modify wrapper!T.toString as follows : public void toString( scope void delegate(const(char)[]) sink, string fmt ) const { formattedWrite(sink, fmt, val); } but this one throws exception at runtime : std.format.FormatException@/usr/include/dlang/dmd/std/format.d(2537): Expected '%s' format specifier for type 'wrapper!uint'. I can make it work for simple cases by manually creating the format string using format() with the FormatSpec attributes, but this approach is not generic and will fail for complex format strings. I've certainly missed something, but I can't figure out what is the right way to do it. What did I do wrong here ? I remember having seen the "void toString(scope void delegate(/*...*/), /*...*/) const" prototypes being deprecated, but I don't know where it was. Maybe there is a better solution now ? [1] http://wiki.dlang.org/Defining_custom_print_format_specifiers [2] http://dlang.org/phobos-prerelease/std_format.html#.formatValue