memoize (is this a fix for overloading?)
Lars T. Kyllingstad
public at kyllingen.NOSPAMnet
Wed Jan 5 01:21:41 PST 2011
On Tue, 04 Jan 2011 17:06:45 -0600, Andrei Alexandrescu wrote:
> On 1/4/11 4:49 PM, %u wrote:
>>> There's still the risk of keeping multiple hashes. Consider:
>>
>>> ulong fun(ulong n) { ... }
>>> alias memoize!fun mfun;
>>
>>> mfun(5); // creates hash ulong[int]
>>> mfun(5u); // creates hash ulong[uint] mfun('5'); // creates hash
>>> ulong[char]
>>
>>
>> Ohhh I see... so you're basically looking for a compile-time version of
>> overload resolution, right? Because things seem to be getting
>> complicated very quickly.
>
> It's not that complicated; we'll be able to achieve it somehow.
> Overloads are compile-time entities so they should be easily
> inspectable.
Since this is likely to be useful in other cases as well, maybe it would
be better to make a general template that selects an overload? So you'd
use it like this:
alias memoize!(selectOverload!(sqrt, double)) msqrt;
A first step towards this would be to make __traits(getOverloads) work
with module-level functions. Currently it only works for member
functions. Also it would probably be better if it accepted a function
alias instead of a string containing the function name.
Anyway, I've been able to make the following work for selecting overloads
of member functions:
import std.traits, std.stdio;
struct S
{
void foo(int i, double d) { writeln("Overload 1"); }
void foo(double d, int i) { writeln("Overload 2"); }
void test()
{
alias selectOverload!(S, "foo", int, double) bar;
bar(1, 3.0); // Prints "Overload 1"
alias selectOverload!(S, "foo", double, int) baz;
baz(4.0, 2); // Prints "Overload 2"
}
}
void main()
{
S s;
s.test();
}
template selectOverload(T, string fun, Params...)
{
alias selectOverloadImpl!(Params.length, Params,
__traits(getOverloads, T, fun)) selectOverload;
}
template selectOverloadImpl(size_t lenP, A...)
{
static assert (A.length > lenP, "No overload matches");
static if (equalTuples!(lenP,
A[0 .. lenP],
ParameterTypeTuple!(A[lenP])))
{
alias A[lenP] selectOverloadImpl;
}
else
{
alias selectOverloadImpl!(lenP, A[0 .. lenP], A[lenP+1 .. $])
selectOverloadImpl;
}
}
template equalTuples(size_t len, T...)
{
static if (len == 0 && T.length == 0)
enum equalTuples = true;
else static if (T.length != len*2)
enum equalTuples = false;
else static if (!is (T[0] == T[len]))
enum equalTuples = false;
else
enum equalTuples =
equalTuples!(len-1, T[1 .. len], T[len+1 .. $]);
}
More information about the Digitalmars-d
mailing list