On Wed, Aug 02, 2017 at 11:06:03AM -0700, H. S. Teoh via Digitalmars-d-learn wrote: [...] > auto byPair(AA)(inout(AA) aa) > { > alias Modifiers = std.traits.getModifiers!AA; > struct Result { > std.traits.ApplyModifiers!(Slot*, Modifiers) slot; > ... // range methods here > } > return Result(aa); > } > > Of course, getModifiers and ApplyModifiers are fictitious Phobos > templates, but you get the idea. [...]
Hmm, actually, they don't have to be fictitious; here's an actual, compilable example: struct Slot { Slot* next; string key; int value; } struct AA { Slot*[] slots; } auto byPair(AA)(AA aa) { import std.traits : QualifierOf; alias Qual = QualifierOf!AA; struct Result { Qual!(Slot)* slot; bool empty() { return slot is null; } auto front() { struct Front { Qual!string key; Qual!int value; } return Front(slot.key, slot.value); } void popFront() { slot = slot.next; } } return Result(aa.slots[0]); } unittest { AA aa; const(AA) constAa; immutable(AA) immAa; auto mutPair = aa.byPair; static assert(is(typeof(mutPair.front.value) == int)); auto constPair = constAa.byPair; static assert(is(typeof(constPair.front.value) == const(int))); auto immPair = immAa.byPair; static assert(is(typeof(immPair.front.value) == immutable(int))); } T -- If Java had true garbage collection, most programs would delete themselves upon execution. -- Robert Sewell