Arrays of functions, function signatures and template instantiation

anonymous anonymous at example.com
Tue Apr 30 05:27:14 PDT 2013


On Tuesday, 30 April 2013 at 10:02:07 UTC, JR wrote:
[...]
> For instance, is it possible to have MatrixWalker's F type to 
> have a default value of a NOP void function(), have the 
> innermost foreach loop check if the element is a function, and 
> if so call it directly without needing FuncRunner at all?

Let's start by turning MatrixWalker into a function template 
(fixing the matrix template parameter on the way):
---
void walkMatrix(F,M: E[I][T],E,I,T)(F func, M matrix) {
	/* those foreaches */
}
---

This way it can be called without explicitly instantiating the 
template:
---
walkMatrix(&runner, funcyMatrix);
---

Now add an overload for callable elements:
---
void walkMatrix(M: E[I][T],E,I,T)(M matrix) 
if(is(typeof(&FuncRunner!M.run))) {
	walkMatrix(&FuncRunner!M.run, matrix);
}
---

A call:
---
walkMatrix(funcyMatrix);
---

Of course, FuncRunner is now only needed by that overload, so you 
could move its implementation in there.

> Also, is there a clever approach to have MatrixWalker call its 
> passed function variadically with only the arguments that its 
> signature allows? As in;
>
> -------------
>> import std.stdio;
>> import std.concurrency;
>>
>> struct Event { /* ... type, sender, target, content and 
>> friends ... */ };
>>
>> template MatrixWalker(F,E: E[I][T],I,T) {
>>    // note addition of Event below
>>    void applyFunc(ref Event evt, F func, E[I][T] matrix) {
>>        /* ... Inception foreach ... */
>>        func(evt, /* only the arguments of E, I and/or T that 
>> type F accepts */);
>>    }
>> }
>>
>> const alias Blaawp MAJOR;
>> const alias Oorgle MINOR;
>> static void function(ref Event, MINOR)[MINOR][MAJOR] 
>> funcyMatrix;
>> // note no MAJOR in func sig
>>
>> void populate() {
>>    /* ... */
>> }
>>
>> void traverse() {
>>    sendMessageAdapter = void function(ref Event evt, Tid) {
>>        std.concurrency.send(tid, evt);
>>    };
>>
>>    alias 
>> MatrixWalker!(typeof(&sendMessageAdapter),typeof(funkyMatrix)).applyFunc 
>> apply;
>>
>>    writeln("Traversing funcy matrix");
>>    apply(&sendMessageAdapter, funkyMatrix);
>> }
>>
>> void main(string[] args) {
>>    populate();
>>    traverse();
>> }
> -------------
>
> That sounds too good to be true, but it would make me warm and 
> fuzzy inside if I didn't have to resort to keeping a dozen 
> adapter/shim functions around.

I don't have a clever solution for that.


More information about the Digitalmars-d-learn mailing list