Another interesting hack: expand a static array into parameter arguments

Artur Skawina art.08.09 at gmail.com
Thu Apr 3 07:32:11 PDT 2014


On 04/03/14 15:38, Andrej Mitrovic wrote:
> On 4/3/14, Artur Skawina <art.08.09 at gmail.com> wrote:
>> Actually, they are *much easier* to debug than the recursive templates
>> -- because you can always look at the generated code, something that
>> is impossible when using the templates.
> 
> Personally I think we need a third mechanism. I would totally love to
> be able to write CTFE-style template code. Here's a demonstration:

Yes. But that would make D a very different language, so introducing
something like it isn't really practical right now...

I've turned the pseudocode below into real working D code, just to
see how close to your solutions I could get. 

(And before somebody suggests it - yes, it can easily be done via
templates. The whole point of this exercise is to see how the code
looks without them.)


> template FilterInts(Args...)
> {
>     foreach (T; Args)
>     {
>         static if (is(T == int))
>             FilterInts ~= T;  // populate a type tuple
>     }
> }
> 
> void main()
> {
>     static assert(is(FilterInts!(int, float, int, string) == TypeTuple!(int, int)));
> }

   template FilterInts(Args...) {
      mixin (q{
         alias FilterInts = TypeTuple!(} ~ {
            string r;
            foreach (I, T; Args) if (is(T==int))
               r ~= ",Args["[!r..$] ~ I.stringof ~ "]";
            return r;
      }() ~ ");");
   }

Well, ugh. One can hardly see what is going on in there.

One solution would be to support tuple indexing by tuples -- this
would allow a simple implementation, similar to the one below.
[IOW: (int, double, string)[0,2] == (int, string) ]


> template GetFirstArray(Args...)
> {
>     foreach (T; Args)
>     {
>         static if (isArray!T)
>         {
>             GetFirstArray = T;
>             break;
>         }
>     }
> }
> 
> void main()
> {
>     static assert(is(GetFirstArray!(int, int[], float, float[]) == int[]));
> }

   alias GetFirstArray(Args...) =
      Args[{ foreach (I, T; Args) if (isArray!T) return I; assert(0); }()];


> This is so much better and easier to understand than recursive
> templates. Imperative-style type extraction/manipulation rather than
> writing hard-to-grok recursive templates. Thinking about it, I think
> the only reason why recursive templates are a popular approach is
> because of C++ heritage. But I really think we can do better.

Yep. But static-foreach is a non-trivial language addition (eg it must
be able to build arg-lists aka tuples).

artur


More information about the Digitalmars-d mailing list