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

Simen Kjærås simen.kjaras at gmail.com
Thu Jun 4 13:05:04 UTC 2020


On Thursday, 4 June 2020 at 12:44:30 UTC, Stefan Koch wrote:

> Wow That's amazing.
> You found them all. (All I put it deliberately ;) and more)

Cool, I didn't expect that. :)


> Your expansion also looks much nicer.
> Although it does not quite reflect the order in which it 
> happens it helps explaining.
>
> Did  you do them by hand as well or did you use a script?

By hand. I first established the pattern, so it was easy to see 
where each number would go, then just filled it in and did the 
opposite of what you did when you deliberately inserted mistakes. 
:p

Bonus, here's the divide-and-conquer version:

template Iota(int from, int to) {
     static assert (from <= to);
     static if (from == to) {
         alias Iota = AliasSeq!();
     } else static if (from == to-1) {
         alias Iota = AliasSeq!from;
     } else {
         alias Iota = AliasSeq!(
             Iota!(from, (from + to) / 2),
             Iota!((from + to) / 2, to));
     }
}

Iota!(1, 5):
{
     alias Iota = Seq!(Iota!(1, 3), Iota!(3, 5));
     Seq!(Iota!(1, 3), Iota!(3, 5)):
     {
         alias Seq = (Iota!(1, 3), Iota!(3, 5));
         Iota!(1, 3):
         {
             alias Iota = Seq!(Iota!(1, 2), Iota!(2, 3));
             Seq!(Iota!(1, 2), Iota!(2, 3)):
             {
                 alias Seq = (Iota!(1, 2), Iota!(2, 3));
                 Iota!(1, 2):
                 {
                     alias Iota = Seq!1;
                     Seq!1:
                     {
                         alias Seq = (1);
                     }.Seq => (1)
                 }.Iota => (1)
                 Iota!(2, 3):
                 {
                     alias Iota = Seq!2;
                     Seq!2:
                     {
                         alias Seq = (2);
                     }.Seq => (2)
                 }.Iota => (2)
             }.Seq => ((2), (3))
         }.Iota => ((2), (3))
         Iota!(3, 5):
         {
             alias Iota = Seq!(Iota!(3, 4), Iota!(4, 5));
             Seq!(Iota!(3, 4), Iota!(4, 5)):
             {
                 alias Seq = (Iota!(3, 4), Iota!(4, 5));
                 Iota!(3, 4):
                 {
                     alias Iota = Seq!3;
                     Seq!3:
                     {
                         alias Seq = (3);
                     }.Seq => (3)
                 }.Iota => (3)
                 Iota!(4, 5):
                 {
                     alias Iota = Seq!4;
                     Seq!4:
                     {
                         alias Seq = (4);
                     }.Seq => (4)
                 }.Iota => (4)
             }.Seq => ((3), (4))
         }.Iota => ((3), (4))
     }.Seq => (((2), (3)), ((3), (4)))
}.Iota => (((2), (3)), ((3), (4)))

Haven't checked that for mistakes as rigorously as the other 
version, so there might be some.

--
   Simen



More information about the Digitalmars-d mailing list