How templates work (bonus) - Full instantiation of Iota!(1,5)

Steven Schveighoffer schveiguy at gmail.com
Thu Jun 4 17:03:38 UTC 2020


On 6/4/20 9:21 AM, Stanislav Blinov wrote:
> On Thursday, 4 June 2020 at 11:33:48 UTC, Stefan Koch wrote:
>> As part of my series of templates
>> I have done a a full instantiation of Iota!(1,5).
>> (By hand!)
>> And here is the result:
>>
>> // ...
>>
>> Because it has been done manually there are probably some bugs.
>> Can you find them all?
> 
> Is that really full? I.e. you're not counting the instantiations of Seq 
> on purpose? :)
> 
> If I understand correctly, the below (basically manually written version 
> of std.meta.aliasSeqOf) would just be Iota!(1, 5) => Iota?
> 
> template Iota(size_t first, size_t last) {
>      struct Result {
>          static foreach (i; first .. last)
>              mixin("auto e", i, " = ", i, ";");
>      }
>      enum Iota = Result.init.tupleof;
> }

That's a cool trick. I like the fact that it uses mixins to output the 
numbers as well.

It might be faster though, to generate using a fully CTFE function 
instead of using static foreach. Can't use the numbers directly, so I 
have to write a crude "number to string" converter.

template iota(size_t first, size_t last)
{
     import std.meta : AliasSeq;
     string genMixin()
     {
         char[11] num = "0x00000000,";
         string result = "alias iota = AliasSeq!(";
         immutable char[16] vals = "0123456789abcdef";
         foreach(i; first .. last)
         {
             int j = num.length - 1;
             while(i)
             {
                 num[--j] = vals[i & 0xf];
                 i >>= 4;
             }
             result ~= num;
         }
         return result ~ ");";
     }
     mixin(genMixin());
}

alias iota(size_t last) = iota!(0, last);

And of course, the fastest would be for the compiler to just do it.

-Steve


More information about the Digitalmars-d mailing list