Making recursively-defined traits iterative using `static foreach`

Nordlöw per.nordlow at gmail.com
Sat Mar 10 15:24:20 UTC 2018


On Saturday, 10 March 2018 at 13:30:18 UTC, Nordlöw wrote:
> On Saturday, 10 March 2018 at 09:47:55 UTC, Nordlöw wrote:
>> Now that we have `static foreach` I just realized we can 
>> start...
>
> My recent definition now looks like
>
> template allSameTypeIterative(V...)
> // TODO restrict `V` to types only
> {
>     static if (V.length <= 1)
>     {
>         enum allSameTypeIterative = true;
>     }
>     else
>     {
>         static foreach (Vi; V[1 .. $])
>         {
>             static if (!is(typeof(allSameTypeIterative) == 
> bool) && // not yet defined
>                        !is(V[0] == Vi)) // 10% faster than 
> `!isSame(V[0], Vi)`
>             {
>                 enum allSameTypeIterative = false;
>             }
>         }
>         static if (!is(typeof(allSameTypeIterative) == bool)) 
> // if not yet defined
>         {
>             enum allSameTypeIterative = true;
>         }
>     }
> }
>
> Is there a way to break the `static foreach` loop prematurely 
> as quickly as `allSameTypeIterative` becomes false?

After benchmarking using

https://github.com/nordlow/phobos-next/blob/master/benchmarks/iterative-traits/source/app.d

the iterative-version speed-up ranges from 1.1 to 10x for my 
specific sets of input. The higher speed-up is thanks to

- reducing the template instantiation count from log(n), in the 
recursive case, to 1 in iterative case and
- a static if loop that prevents successive calls when, for 
instance,
   - predicate is true in `anySatisfyIterative and
   - predicate is false in `allSatisfyIterative and

At

https://github.com/nordlow/phobos-next/blob/master/benchmarks/iterative-traits/source/app.d

the compilation-times are written in the comments for each kind 
of benchmark.


More information about the Digitalmars-d mailing list