www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Stacking policies

reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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
Jul 02 2016
parent reply ZombineDev <petar.p.kirov gmail.com> writes:
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
Jul 02 2016
parent ZombineDev <petar.p.kirov gmail.com> writes:
On Saturday, 2 July 2016 at 21:37:12 UTC, ZombineDev wrote:
 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
[...] Anyway, here's a working solution using string mixins: https://dpaste.dzfl.pl/4b1c702c00b8
Here's a more complete version that handles access to stateful members correctly: https://dpaste.dzfl.pl/aa19a428adfe Unfortunately, I bumped into a language limitation that allows aliases of the form: alias newName = this.member.oldName; ... only if `oldName` is manifest constant (enum). In other words, unlike "alias this", "alias" can't refer to instance members, because you get: Error: need 'this' for 'oldName' of type '<typeof(oldName)>'. Look for Error 1) in the latest link for more details. IMO, "alias" should be at least as powerful as "alias this" in this situation. What's your opinion about this, Andrei?
Jul 02 2016