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