www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Simplified constructor template

reply downs <default_357-line yahoo.de> writes:
Here's a simplified constructor template to help alleviate the
redundancy of D's constructors.

Example:
class A {
	int foo;
	this(int f) { foo=f; }
}

class B : A {
	float bar;
	this(int f, float bar/* redundant */) {
		this.bar=bar; /* redundant */
		super(f);
	}
}

With the attached template, the second constructor can be abbreviated to:

class B : A {
	float bar;
	mixin This!("super(f), bar");
}

Here's a more complex example from a Tower Defense game I'm toying
around with:

class Home : LivingThing {
  TargetGroup targets;
  float fx, fy;
  float speed;
  mixin This!("targets, speed, super(onDeath, x, y, radius=3, life=10)
  #fx=cast(float)x; #fy=cast(float)y; ");
  [...]
}

which expands to:

this(typeof(targets) _targets, typeof(speed) _speed,
  typeof(onDeath) _onDeath,
  typeof(x) _x, typeof(y) _y,
  typeof(radius) _radius=3, typeof(life) _life=10)
{
  this.targets = _targets;
  this.speed = _speed;
  super(_onDeath, _x, _y, _radius, _life);
  fx=cast(float)x;
  fy=cast(float)y;
}

Oh, and to finally clear up this matter, I quote from the DigitalMars
homepage:
 14.

 Note: All posters to the Digital Mars newsgroups or mailing list
 agree to place in the public domain all claims to intellectual
 property rights in any posted or emailed feedback to Digital Mars.
 Any exceptions to this condition must be clearly identified as
 copyrighted, patented, or trademarked.

So there you go. Public domain. :) Have fun with it! --downs Source: template cutOff(string what, string where) { static if (what.length<where.length) const string cutOff=what; else static if (what[0..where.length]==where) const string cutOff=""; else const string cutOff=what[0]~cutOff!(what[1..$], where); } template rmSpace(string s, bool command=false) { static if (!s.length) const string rmSpace=""; else static if (command) { static if (s[0]==';') const string rmSpace=';'~rmSpace!(s[1..$]); else const string rmSpace=s[0]~rmSpace!(s[1..$], true); } else static if (s[0]=='#') const string rmSpace='#'~rmSpace!(s[1..$], true); else static if (s[0]==' ' || s[0]=='\r' || s[0]=='\n' || s[0]=='\t') const string rmSpace=rmSpace!(s[1..$]); else const string rmSpace=s[0]~rmSpace!(s[1..$]); } template thisHeader(string s, string buffer="", bool command=false) { static if (!s.length) static if (!buffer.length) const string thisHeader=""; else const string thisHeader="typeof("~cutOff!(buffer, "=")~") _"~buffer; else static if (command) static if (s[0]==';') const string thisHeader=thisHeader!(s[1..$]); else const string thisHeader=thisHeader!(s[1..$], buffer~s[0], true); else static if (s[0] == '#') const string thisHeader=thisHeader!(s[1..$], "", true); else static if (s[0]=='(') const string thisHeader=thisHeader!(s[1..$]); else static if (s[0]==')' || s[0]==',') { static if (!buffer.length) const string thisHeader=thisHeader!(s[1..$]); else const string thisHeader="typeof("~cutOff!(buffer, "=")~") _"~buffer~( (s.length>1) ?((s[0]==')'?"":", ")~thisHeader!(s[1..$])) :"" ); } else const string thisHeader=thisHeader!(s[1..$], buffer~s[0], command); } template assigns(string s, string buffer="", bool sup=false, bool command=false) { static if (!s.length) { static if (buffer.length) const string assigns="this."~cutOff!(buffer, "=")~" = _"~cutOff!(buffer, "=")~"; "; else const string assigns=""; } else static if (command) { static if (s[0]==';') const string assigns=buffer~"; "~assigns!(s[1..$]); else const string assigns=assigns!(s[1..$], buffer~s[0], false, true); } else static if (s[0]=='#') { static assert(!sup, "# invalid in super"); const string assigns=assigns!(s[1..$], "", false, true); } else static if (s[0]=='(') { static assert(buffer=="super", "Invalid code "~buffer); const string assigns=buffer~"("~assigns!(s[1..$], "", true); } else static if (s[0]==')') { static assert(sup, "Parenthesis Mismatch"); const string assigns="_"~cutOff!(buffer, "=")~"); "~assigns!(s[1..$]); } else static if (s[0]==',') { static if (!buffer.length) const string assigns=assigns!(s[1..$], "", sup); else static if (sup) const string assigns="_"~cutOff!(buffer, "=")~", "~assigns!(s[1..$], "", true); else const string assigns="this."~cutOff!(buffer, "=")~" = _"~cutOff!(buffer, "=")~"; "~assigns!(s[1..$]); } else const string assigns=assigns!(s[1..$], buffer~s[0], sup, command); } template This(string T) { mixin("this("~thisHeader!(rmSpace!(T))~") { "~assigns!(rmSpace!(T))~" }"); }
Sep 30 2007
parent downs <default_357-line yahoo.de> writes:
DAMNIT!
That's what I get for making last-minute changes without properly
checking if they actually worked.

Again, my apologies.

 --downs

Fixed version:


template cutOff(string what, string where) {
  static if (what.length<where.length) const string cutOff=what;
  else static if (what[0..where.length]==where) const string cutOff="";
  else const string cutOff=what[0]~cutOff!(what[1..$], where);
}

template rmSpace(string s, bool command=false) {
  static if (!s.length) const string rmSpace=""; else
  static if (command) {
    static if (s[0]==';') const string rmSpace=';'~rmSpace!(s[1..$]);
    else const string rmSpace=s[0]~rmSpace!(s[1..$], true);
  } else
  static if (s[0]=='#') const string rmSpace='#'~rmSpace!(s[1..$],
true); else
  static if (s[0]==' ' || s[0]=='\r' || s[0]=='\n' || s[0]=='\t') const
string rmSpace=rmSpace!(s[1..$]); else
  const string rmSpace=s[0]~rmSpace!(s[1..$]);
}

template thisHeader(string s, string buffer="", bool command=false) {
  static if (!s.length)
    static if (!buffer.length) const string thisHeader="";
    else const string thisHeader="typeof("~cutOff!(buffer, "=")~")
_"~buffer;
  else static if (command)
    static if (s[0]==';') const string thisHeader=thisHeader!(s[1..$]);
    else const string thisHeader=thisHeader!(s[1..$], buffer~s[0], true);
  else static if (s[0] == '#') const string
thisHeader=thisHeader!(s[1..$], "", true);
  else static if (s[0]=='(') const string thisHeader=thisHeader!(s[1..$]);
  else static if (s[0]==')' || s[0]==',') {
    static if (!buffer.length) const string thisHeader=thisHeader!(s[1..$]);
    else const string thisHeader="typeof("~cutOff!(buffer, "=")~")
_"~buffer~(
      (s.length>1)
      ?(thisHeader!(s[1..$]).length?(", "~thisHeader!(s[1..$])):"")
      :""
    );
  } else const string thisHeader=thisHeader!(s[1..$], buffer~s[0], command);
}

template assigns(string s, string buffer="", bool sup=false, bool
command=false) {
  static if (!s.length) {
    static if (buffer.length) const string
assigns="this."~cutOff!(buffer, "=")~" = _"~cutOff!(buffer, "=")~"; ";
    else const string assigns="";
  } else static if (command) {
    static if (s[0]==';') const string assigns=buffer~";
"~assigns!(s[1..$]);
    else const string assigns=assigns!(s[1..$], buffer~s[0], false, true);
  } else static if (s[0]=='#') {
    static assert(!sup, "# invalid in super");
    const string assigns=assigns!(s[1..$], "", false, true);
  } else static if (s[0]=='(') {
    static assert(buffer=="super", "Invalid code "~buffer);
    const string assigns=buffer~"("~assigns!(s[1..$], "", true);
  } else static if (s[0]==')') {
    static assert(sup, "Parenthesis Mismatch");
    const string assigns="_"~cutOff!(buffer, "=")~"); "~assigns!(s[1..$]);
  } else static if (s[0]==',') {
    static if (!buffer.length) const string assigns=assigns!(s[1..$],
"", sup);
    else static if (sup) const string assigns="_"~cutOff!(buffer,
"=")~", "~assigns!(s[1..$], "", true);
    else const string assigns="this."~cutOff!(buffer, "=")~" =
_"~cutOff!(buffer, "=")~"; "~assigns!(s[1..$]);
  } else const string assigns=assigns!(s[1..$], buffer~s[0], sup, command);
}

template This(string T) {
  mixin("this("~thisHeader!(rmSpace!(T))~") { "~assigns!(rmSpace!(T))~" }");
}
Sep 30 2007