## digitalmars.D - Stacking policies

- Andrei Alexandrescu (47/47) Jul 02 2016 So I'm working on this checked integral thing and starting to really get...
- ZombineDev (28/77) Jul 02 2016 It looks like multiple alias this should be able to handle this,
- ZombineDev (14/80) Jul 02 2016 Here's a more complete version that handles access to stateful

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

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, AndreiIt 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

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: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?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

Jul 02 2016