Stacking policies
ZombineDev via Digitalmars-d
digitalmars-d at puremagic.com
Sat Jul 2 14:37:12 PDT 2016
On Saturday, 2 July 2016 at 20:48:51 UTC, Andrei Alexandrescu
wrote:
> So I'm working on this checked integral thing and starting to
> really get into the possibilities offered by DbI. One core
> operation is "stacking" two policies on top of each other, i.e.
> an operation is first offered to the first one, and then the
> second one. Here's an excerpt:
>
> struct HookStack(H1, H2)
> {
> import std.experimental.allocator.common : stateSize;
> import std.traits : hasMember;
>
> private:
> static if (stateSize!H1) H1 h1;
> else alias h1 = H1;
> static if (stateSize!H2) H2 h2;
> else alias h2 = H2;
>
> public:
> static if (hasMember!(H1, "defaultValue"))
> alias defaultValue = H1.defaultValue;
> else static if (hasMember!(H2, "defaultValue"))
> alias defaultValue = H2.defaultValue;
>
> static if (hasMember!(H1, "min"))
> alias min = H1.min;
> else static if (hasMember!(H2, "min"))
> alias min = H2.min;
>
>
> static if (hasMember!(H1, "max"))
> alias max = H1.max;
> else static if (hasMember!(H2, "max"))
> alias max = H2.max;
>
> static if (hasMember!(H1, "hookOpCast"))
> Dst hookOpCast(Dst, Src)(Src value)
> {
> return h1.hookOpCast!Dst(value);
> }
> else static if (hasMember!(H2, "hookOpCast"))
> Dst hookOpCast(Dst, Src)(Src value)
> {
> return h2.hookOpCast!Dst(value);
> }
> ...
> }
>
> There's a bunch more stuff that looks very similar. This should
> be automated, i.e. depending on the types, aliases, enums,
> methods etc. that H1 and/or H2 define, there should be
> appropriate definitions in the composition.
>
> This is the kind of stuff that makes D awesome. Is anyone
> interested in exploring this? I'm already in an interruption
> from RCStr working on the checked int. I'll continue with the
> manual implementation.
>
>
> Thanks,
>
> Andrei
It looks like multiple alias this should be able to handle this,
shouldn't it?
Otherwise, something like static foreach could be handy:
mixin template DbIOr(alias A, alias B, members...)
{
static foreach (member; members)
static if (hasMember!(A, member))
mixin (`alias member = A.` ~ member ~ `;`);
else static if (hasMember!(B, member))
mixin (`alias member = B.` ~ member ~ `;`);
}
struct HookStack(H1, H2)
{
import std.experimental.allocator.common : stateSize;
import std.traits : hasMember;
private:
static if (stateSize!H1) H1 h1;
else alias h1 = H1;
static if (stateSize!H2) H2 h2;
else alias h2 = H2;
public:
mixin DbIOr!(h1, h2, AliasSeq!(__traits(allMembers, h1),
__traits(allMembers, h1)));
}
Anyway, here's a working solution using string mixins:
https://dpaste.dzfl.pl/4b1c702c00b8
More information about the Digitalmars-d
mailing list