On 01/22/2017 01:54 PM, Jon Degenhardt wrote:
I've been increasingly using output ranges in my code (the "component
programming" model described in several articles on the D site). It
works very well, except that it would often be more convenient to use
writeln style functions rather than 'put'. Especially when you start by
drafting a sketch of code using writeln functions, then convert it an
output range.
Seems an obvious thing, I'm wondering if I missed something. Are there
ways to use writeln style functions with output ranges?
--Jon
I don't think I understand the question. :)
If you need a variadic put(), then I've come up with the following
mildly tested AllAppender. Just as a reminder, I've also used
std.range.tee that allows tapping into the stream to see what's flying
through:
import std.array : Appender, appender;
import std.stdio : writeln;
struct AllAppender(T) {
Appender!T app;
alias app this;
void put(Args...)(Args args) {
foreach (arg; args) {
static if (__traits(compiles, app.put(arg))) {
app.put(arg);
}
else {
import std.conv : to;
app.put(arg.to!T);
}
}
}
}
import std.range : isOutputRange;
static assert(isOutputRange!(AllAppender!string, int));
static assert(isOutputRange!(AllAppender!string, double));
auto allAppender(T)() {
return AllAppender!T();
}
void main() {
auto a = allAppender!string();
a.put(1, "hello");
import std.range : tee;
import std.algorithm : copy;
[ 10, 20, 30 ]
.tee!(e => writeln("appending ", e))
.copy(a);
writeln(a.data);
}
Ali