digitalmars.D - Simplified constructor template
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 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); 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); 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
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 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); 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); 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