Simplified constructor template

downs default_357-line at yahoo.de
Sun Sep 30 05:26:54 PDT 2007


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))~" }");
}



More information about the Digitalmars-d mailing list