TypeFunction example: ImplictConvTargets

Adam D. Ruppe destructionator at gmail.com
Tue Oct 6 23:27:10 UTC 2020


On Tuesday, 6 October 2020 at 20:57:10 UTC, claptrap wrote:
> Im less interested in performance than I am in being able to 
> express what I want to do in clear concise code.

Give me an example of what you'd like to use type functions for.

I betcha I can adapt it to current D with very few changes.

Take a look at this for example:

---
import std.algorithm;
template largestType(T...) {
         auto get() {
                 return reified!"a.sizeof".map!T
                     .sort!((a, b) => a > b).front; // or 
maxElement of course
         }
         alias largestType = T[get.idx];
}

pragma(msg, largestType!(long, int, real, byte)); // real
---


Or what about this, without even seeing the template keyword?

import std.algorithm;

pragma(msg,
   reified!"is(a : long)" // compile time lambda we need
     .run!(types => types.filter!(a => a)) // run the code over 
the fetched info
     .over!(string, int, float, Object)); // the list of types
);



Note it used std.algorithm's filter over the mapped compile time 
lambda! But, of course, you'll see it is a string. That is a 
limitation here, pity we don't have some kind of short syntax 
template lambda.




This is the reifiy and dereify implementations:

---

template reified(string mapCode, alias runCode = void) {
         template evaluate(alias a) { enum evaluate = 
mixin(mapCode); }

         template run(alias code) {
                 alias run = reified!(mapCode, code);
         }

         template over(T...) {
                 auto helper() {
                         static struct Result {
                                 size_t idx;
                                 typeof(evaluate!(T[0])) value;
                                 alias value this;
                         }

                         Result[] result;
                         foreach(idx, t; T)
                                 result ~= Result(idx, evaluate!t);

                         return result;
                 }

                 static if(is(runCode == void))
                         enum over = helper;
                 else
                         mixin("alias over = " ~ 
dereifiy(runCode(helper())) ~ ";");
         }
}

import std.meta;

string dereifiy(T)(T t, string localName = "T") {
         import std.conv;
         import std.range;
         static if(isInputRange!T) {
                 string result = "AliasSeq!(";
                 foreach(item; t)
                         result ~= localName ~ "[" ~ 
to!string(item.idx) ~ "],";
                 result ~= ")";
                 return result;
         } else
                 return localName ~ "[" ~ t.idx.to!string ~ "]";
}
---


More information about the Digitalmars-d mailing list