Re: How to forward format specifiers ?

2014-06-29 Thread H. S. Teoh via Digitalmars-d-learn
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 ?

2014-06-29 Thread Element 126 via Digitalmars-d-learn

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 ?

2014-06-29 Thread Ali Çehreli via Digitalmars-d-learn

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 ?

2014-06-29 Thread Element 126 via Digitalmars-d-learn
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