bolts
bolts copied to clipboard
Remove the long-winded use of __MODULE__.ReturnType in refraction module
Try and remove need for verbosity for return type. If we can get this to work we can probably do the same for Parameters
@jll63 what do you think?
@jll63 what do you think?
It would break everything.
Let's split the GrandTour
example into two modules, and change it a tiny bit. To make it simpler, I'll just drop them in experimental
:
module bolts.experimental.problem;
import bolts.experimental.mock;
struct Problem {}
interface GrandTour {
pure Problem foo() immutable; // Ha!
@nogc @trusted nothrow ref int foo(out real, return ref int, lazy int) const;
@safe shared scope void bar(scope Object);
}
unittest {
auto gt = new Mock!GrandTour();
}
module bolts.experimental.mock;
import bolts.experimental.refraction;
import std.format;
import std.traits;
class Mock(Interface) : Interface {
static foreach (member; __traits(allMembers, Interface)) {
static foreach (fun; __traits(getOverloads, Interface, member)) {
mixin({
enum Model = refract!(fun, "fun");
if (is(ReturnType!fun == void)) {
return Model.withBody("{}").mixture;
} else if (Model.attributes & FunctionAttribute.ref_) {
return Model.withBody(q{{
static %s rv;
return rv;
}}.format(Model.returnType)).mixture;
} else {
return Model.withBody(q{{
return %s.init;
}}.format(Model.returnType)).mixture;
}
}());
}
}
}
Now, dub test
:
mixins.txt(238,32): Error: undefined identifier `Problem`
Problem
is not accessible from bolts.experimental.mock
. Well not directly: ReturnType
can grab it.
I am putting this in a branch in case you want to play with it.
I have an idea for trimming the mixture in some circumstances. I will try it during the weekend.
Also, don't you think that ParameterAttribute
should move somewhere in bolts.traits
? It should be in std.traits
, really, but in the meantime...
And this would be better than the current version:
import std.meta;
template ParameterAttributes(alias fun, int i) {
static if (is(typeof(fun) P == __parameters)) {
alias ParameterAttributes = __traits(getAttributes, P[i..i+1]);
}
}
struct virtual;
void kick(int times, @virtual @("Animal") Object animal);
pragma(msg, ParameterAttributes!(kick, 1).length);
pragma(msg, ParameterAttributes!(kick, 1));
2LU
tuple((virtual), "Animal")
Branch with less verbose mixtures is here: https://github.com/jll63/bolts/tree/refraction-compact-mixture
Basically, it avoids unpacking the parameter list unless it is modified. Then it avoids unpacking the parameters into type, storage classes and UDAs unless they are modified.