Creating a custom iota()

Ali Çehreli acehreli at yahoo.com
Thu May 12 20:12:19 UTC 2022


On 5/12/22 12:51, ag0aep6g wrote:

 >> auto iota(B, E, S)(B begin, E end, S step)
 > [...]
 >> {
 >>     static struct Result
 >>     {
 >>         B current;
 > [...]
 >>         void popFront()
 >>         {
 > [...]
 >>             current += step;
 >>         }
 >>     }
 > [...]
 >> }
 >
 > Mark iota's `begin` parameter as const. Then you don't need the cast,
 > because `B` will be mutable.

Cool trick! Like this:

auto iota(B, E, S)(const(B) begin, E end, S step)
{
   // ...
}

It works with non-const values as well. So apparently it makes the 
function parameter const(B) and deduces B to be the non-const version of 
that, which always produces the non-const version.

And I've been thinking 'iota' may not be as suitable as I thought at 
first. I like the following even more:

   auto r0 = st
             .by(Duration(2))
             .take(5);

   auto r1 = st
             .by(Duration(2))
             .until(en);

A family of 'by' ovenloads can be defined or it can be templatized to be 
used as 'by!Duration(2)' etc.:

auto by(DateTime dt, Duration dur) {
   struct Result {
     DateTime front;
     Duration dur;

     enum empty = false;
     void popFront() { front += dur; }
   }

   return Result(dt, dur);
}

Just works. But one may want to provide an accessor for front().

Ali



More information about the Digitalmars-d-learn mailing list