Modern C++ Lamentations

Steven Schveighoffer schveiguy at gmail.com
Sat Dec 29 22:01:58 UTC 2018


On 12/29/18 4:29 AM, Walter Bright wrote:
> http://aras-p.info/blog/2018/12/28/Modern-C-Lamentations/
> 
> Time to show off your leet D skilz and see how good we can do it in D!

Ugh, ranges really aren't a good fit for emulating nested loops, unless 
you write a specialized one.

I tried my best, but it kind of sucks:

     foreach(z, x, y;
     iota(size_t.max)
         .map!(a =>
              zip(StoppingPolicy.shortest, a.repeat, iota(1, a)))
         .joiner
         .map!(t =>
              zip(StoppingPolicy.shortest, t[0].repeat, t[1].repeat, 
iota(t[1], t[0])))
         .joiner
         .filter!(t => t[0]*t[0] == t[1]*t[1] + t[2]*t[2])
         .take(100))
     {
         writeln(x, " ", y, " ", z);
     }

Now, a specialized range looks much better and more efficient to me. 
This is essentially what the author wrote.

And as is typical for D, we can split the tasks into more generic 
pieces. For instance:

struct PossiblePythags(T)
{
     T z = 2;
     T x = 1;
     T y = 1;

     auto front() { return tuple!(T, "x", T, "y", T, "z")(x, y, z); }
     void popFront() {
         if(++y == z)
         {
             if(++x == z)
             {
                 ++z;
                 x = 1;
             }
             y = x;
         }
     }
     enum empty = false;
}

auto pythagrange(T = size_t)()
{
     return PossiblePythags!T()
         .filter!(p => p.x * p.x + p.y * p.y == p.z * p.z);
}

No measuring of either compilation or runtime, but I would expect the 
specialized range version to be pretty close to the author's measurements.

I'm wondering if some generic "emulate N nested loops" with given 
stopping and starting conditions might be a useful addition for 
std.range or std.algorithm. I'm thinking of other looping algorithms 
like Floyd Warshall that might benefit from such building blocks.

-Steve


More information about the Digitalmars-d mailing list