On 2016-01-14 17:59, Ali Çehreli wrote:

Here is an experiment that wraps the third party type to provide a lazy
toString:

import std.stdio;
import std.format;
import std.array;
import std.algorithm;
import std.range;

/* Wraps an element and provides a lazy toString that dispatches the
work to a
  * user-provided 'formatter' function. E is the element type. */
struct Formatted(alias formatter, E) {
     E element;

     void toString(void delegate(const(char)[]) sink) const {
         formatter(sink, element);
     }
}

Wrap the object, why didn't I think of that :)

/* Adapts a range by converting the elements to 'Formatted'. R is the range
  * type. */
auto formatted(alias formatter, R)(R range) {
     return range.map!(e => Formatted!(formatter, ElementType!R)(e));
}

/* A third party test type that does not have a lazy toString member
  * function. */
struct Foo {
     double d;
     string s;
}

void main() {
     auto data = [ Foo(1.5, "hello"), Foo(2.5, "world") ];

     auto buf = appender!string();
     formattedWrite(buf, "%(%s\n%)",
                    data.formatted!(
                        (sink, a) => formattedWrite(sink, "%s and %s",
                                                    a.d, a.s)));

     writeln(buf.data);
}

Prints the objects according to the user's lambda:

1.5 and hello
2.5 and world

Thanks.

--
/Jacob Carlborg

Reply via email to