Re: tupleof for inherited classes.

2012-07-25 Thread Chris NS
I know you specifically asked for a way to do this without 
templates, but this was my first thought on how to make it work 
(and I confirmed it):


##
import  std.stdio   ,
std.traits  ;

class Engine {

int publicField ;

void enumFields ( this Self ) ( bool heading = true ) {
auto self = cast( Self ) this;
if ( heading ) {
writeln( "Engine prints:" );
}
foreach( base ; BaseClassesTuple!Self ) {
static if ( is( base : Engine ) ) {
( cast( base ) self ).enumFields( false );
}
}
foreach( ref field ; self.tupleof ) {
writeln( '\t', field );
}
}

protected string protectedField = "s" ;

private bool privateField ;

}

class Some : Engine {

int oneMoreField = 11;

void enumFields2 () {
writeln( "Some prints:" );
foreach( field ; this.tupleof ) {
writeln( '\t', field );
}
}

protected string protectedField = "o";

}

void main () {
auto objE = new Engine;
auto objS = new Some;

objE.enumFields();

objS.publicField = 4;
objS.enumFields();
objS.enumFields2();

( cast( Engine ) objS ).enumFields();
}
##

The downside is that the reference you invoke enumFields() 
against must be of the lowest type to get all members, as that 
last line demonstrates.  Beyond this, I don't believe there is 
any way for methods defined by Engine to see members of derived 
classes.  The first alternative I could think of, is to use NVI 
(non-virtual interfaces).


##
import  std.stdio   ;

class Engine {

int publicField ;

final void enumFields () {
writeln( this.classinfo.name, " prints:" );
enumFieldsImpl();
}

protected string protectedField = "s" ;

protected void enumFieldsImpl () {
foreach ( field ; this.tupleof ) {
writeln( '\t', field );
}
}

private bool privateField ;

}

class Some : Engine {

int oneMoreField = 11;

protected override void enumFieldsImpl () {
super.enumFieldsImpl();
foreach ( field ; this.tupleof ) {
writeln( '\t', field );
}
}

protected string protectedField = "o";

}

void main () {
auto objE = new Engine;
auto objS = new Some;

objE.enumFields();

objS.publicField = 4;
objS.enumFields();

( cast( Engine ) objS ).enumFields();
}
##

This works even in the last (previously degenerate) case, however 
it naturally results in code duplication.  Depending on what your 
real scenario is, however, that may not be a severe issue.


-- Chris NS


tupleof for inherited classes.

2012-07-24 Thread mrdarksys

[Problem]
How can I use enumFields() function of Engine class for enumerate 
all fields of inherited classes?

I want to do without templates if possibly.

Code [example]:
//
import std.stdio;

class Engine
  {
public:
  int publicField;

  void enumFields()
{
  writeln("Engine prints:");
  foreach(ref field; this.tupleof)
writeln(field);
}

private:
  bool privateField;

protected:
  string protectedField = "s";
  }

class Some : Engine
  {
public:
  int oneMoreField = 11;

  void enumFields2()
{
  writeln("Some prints:");
  foreach(field; this.tupleof)
writeln(field);
}

protected:
  string protectedField = "o";
  }

int main()
  {
auto objE = new Engine();
auto objS = new Some();

objE.enumFields();

objS.publicField = 4;

objS.enumFields();

objS.enumFields2();

return 0;
  }
//==

[Actual] output is:
//==
Engine prints:
0
false
s
Engine prints:
4
false
s
Some prints:
11
o
//==

[Expected] output is:
//==
Engine prints:
0
false
s
Engine prints:
4
false
o
11
Some prints:
4
false
o
11
//==