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








 
  
  
 
 "Jack Applegame" <japplegame gmail.com>
 "Jack Applegame" <japplegame gmail.com> 