Output range and writeln style functions

Ali Çehreli via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Jan 23 00:03:14 PST 2017


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



More information about the Digitalmars-d-learn mailing list