digitalmars.D.learn - Template magic exercise
- Jack Applegame (18/18) Mar 30 2014 Target is to create a template for mapping member "array
- Jack Applegame (1/1) Mar 30 2014 Sorry. Not "getter", should be "elementsAccessor" instead.
- anonymous (18/36) Mar 30 2014 Maybe less is more here:
- Jack Applegame (1/1) Mar 30 2014 Wraper structure again. Is there solution without it?
- Artur Skawina (24/25) Mar 30 2014 No. D only allows op overloading in structs/unions/classes, so
- Frustrated (51/69) Mar 30 2014 While this doesn't work maybe you can put in a request to add the
Target is to create a template for mapping member "array accessor" to member function. For example: class Foo { ... int elementsAccessor(size_t index) { ... } ... mixin MagicTemplateMixin!("elements", elementsAccessor); // or better alias elements = SuperMagicTemplate!elementsAccessor; } and now we can call Foo.getter like this: auto foo = new Foo; int el = foo.elements[10]; // int el = foo.getter(10); I wrote poor and ugly solution with proxy structure: http://dpaste.dzfl.pl/93085910f8c7 I hate it. :) I need more powerful spell, but my magic level is too low.
Mar 30 2014
Sorry. Not "getter", should be "elementsAccessor" instead.
Mar 30 2014
On Sunday, 30 March 2014 at 12:42:16 UTC, Jack Applegame wrote:Target is to create a template for mapping member "array accessor" to member function. For example: class Foo { ... int elementsAccessor(size_t index) { ... } ... mixin MagicTemplateMixin!("elements", elementsAccessor); // or better alias elements = SuperMagicTemplate!elementsAccessor; } and now we can call Foo.getter like this: auto foo = new Foo; int el = foo.elements[10]; // int el = foo.getter(10); I wrote poor and ugly solution with proxy structure: http://dpaste.dzfl.pl/93085910f8c7 I hate it. :) I need more powerful spell, but my magic level is too low.Maybe less is more here: --- struct OpIndexFromAccessor(R, PS) { R delegate(PS) dg; R opIndex(PS ps) { return dg(ps); } } auto opIndexFromAccessor(R, PS)(R delegate(PS) accessor) { return OpIndexFromAccessor!(R, PS)(accessor); } class Foo { int elementsAccessor(size_t index) { ... } auto elements() {return opIndexFromAccessor(&elementsAccessor);} /* This is hardly more complex than the mixin or alias variants. */ } ---
Mar 30 2014
Wraper structure again. Is there solution without it?
Mar 30 2014
On 03/30/14 15:36, Jack Applegame wrote:Wraper structure again. Is there solution without it?No. D only allows op overloading in structs/unions/classes, so one of those will be necessary. The simpliest solution would be something like: class C { int elementsAccessor(size_t index) { ... } property ref elements() { struct Elements(O) { auto opIndex(size_t i) { auto o = *cast(O*)&this; return o.elementsAccessor(i); } disable this(this); } return *cast(Elements!(typeof(this))*)&this; } } and if you need that code to be safe: auto opIndex(size_t i) safe { auto o = (f) trusted { return *cast(O*)f; }(&this); return o.elementsAccessor(i); } // etc artur
Mar 30 2014
On Sunday, 30 March 2014 at 12:42:16 UTC, Jack Applegame wrote:Target is to create a template for mapping member "array accessor" to member function. For example: class Foo { ... int elementsAccessor(size_t index) { ... } ... mixin MagicTemplateMixin!("elements", elementsAccessor); // or better alias elements = SuperMagicTemplate!elementsAccessor; } and now we can call Foo.getter like this: auto foo = new Foo; int el = foo.elements[10]; // int el = foo.getter(10); I wrote poor and ugly solution with proxy structure: http://dpaste.dzfl.pl/93085910f8c7 I hate it. :) I need more powerful spell, but my magic level is too low.While this doesn't work maybe you can put in a request to add the functionality: import std.stdio, std.cstream; import std.variant; import std.conv; class Foo { Variant[] opDispatchIndex(string name, E...)(E elements) { writeln(name); return null; } } void main() { auto f = new Foo; f.elements[3]; // Works if opDispatchIndex existed din.getc(); } alternatively, if you don't mind the extra bloat: import std.stdio, std.cstream; import std.variant; import std.conv; struct opIndexStruct { void opIndex(in size_t i) { writeln("op - ", i); } } class Foo { property opIndexStruct elements() { opIndexStruct o; return o; } } void main() { auto f = new Foo; f.elements[3]; din.getc(); } this works because elements is a property and we don't have to call with parenthesis. e.g., f.elements()[3]. Hence f.elements works. [3] is acted on by the return value of elements(), which is a struct that supports opIndex(one could alternative use alias this to wrap the struct in a type that supports indexing. As is the code isn't very useful but should provide you with the ability to achieve what you want.
Mar 30 2014