d2 - Late static binding in d -


i'm working on generic collection class template, let's list(t) i'd able php's late static binding. might best illustrated simplified sample code. code compiles fine on dmd, needs small change way want.

module main;  import std.stdio; import std.string;  class list(t) {     private t[] _list;      public void append(t t)     {         _list ~= t;     }      // needed...     public list select(bool delegate(t t) dg)     {             // auto should whatever subclass of list(t) calling method.         auto result = new list!t();         foreach(t; _list)         {             if (dg(t)) result.append(t);         }         return result;     }      int opapply(int delegate(ref t) dg)     {         int result = 0;          (int = 0; < _list.length; i++)         {             result = dg(_list[i]);             if (result)                 break;         }         return result;     } }  enum gender {     male,     female,     secret }  class person {     private string _firstname;     private string _lastname;     private string _email;     private gender _gender;      @property public string firstname() {return _firstname;}     @property public string lastname() {return _lastname;}     @property public string email() {return _email;}     @property public gender gender() {return _gender;}       public this()     {     }      public this(string firstname, string lastname, gender gender = gender.secret, string email = "info@example.com")     {         this();          this._firstname = firstname;         this._lastname = lastname;         this._gender = gender;         this._email = email;     }      override public string tostring()     {         if (email.length > 0)         {             return "%s %s <%s>".format(firstname, lastname, email);         }         else         {             return "%s %s".format(firstname, lastname);         }     } }  class peoplelist : list!person {     // able make this: public peoplelist selectbygender(gender gender)     public list!person selectbygender(gender gender)     {         return select(p => p.gender == gender);     } }  void main(string[] args) {     auto people = new peoplelist();     people.append(new person("kris", "herlaar", gender.male));     people.append(new person("john", "doe", gender.male));     people.append(new person("steve", "wozniak", gender.male));     people.append(new person("walter", "bright", gender.male));     people.append(new person("amelia", "earhart", gender.female, null));     people.append(new person("susan", "anthony", gender.female, null));      foreach(p; people.selectbygender(gender.female))     {         writeln(p);     } } 

how go making sure peoplelist.select return instance of peoplelist instead of list!person commented out declaration of selectbygender correct?

i mock object.factory(this.classinfo.name) inside implementation , correct type of instance result figure not declared return-type.

i'd want make chaining methods possible i'd need compiler allow me return instances of whatever subclass calling list(t).select imagine done nested template, haven't been able come compile, let alone seem elegant.

additional info in reply received feedback

i aware of std.algorithm , of filter, in real life; code not represent actual use-case thought experiment learn more of abilities/limits of d , its' templates.

you can use template parameters described in http://dlang.org/template.html#templatethisparameter

here's example code page.

interface addable(t) {     final r add(this r)(t t) {         return cast(r)this; // cast necessary, safe     } }  class list(t) : addable!t {     list remove(t t) {         return this;     } }  void main() {     auto list = new list!int;     list.add(1).remove(1); // ok } 

and here's code using it.

module main;  import std.stdio; import std.string;  class list(t) {     private t[] _list;      public void append(t t)     {         _list ~= t;     }      // select templatized based on derived class     public select(this this)(bool delegate(t t) dg)     {         // auto should whatever subclass of list(t) calling method.         auto result = new this();         foreach(t; _list)         {             if (dg(t)) result.append(t);         }         return result;     }      int opapply(int delegate(ref t) dg)     {         int result = 0;          (int = 0; < _list.length; i++)         {             result = dg(_list[i]);             if (result)                 break;         }         return result;     } }  enum gender {     male,     female,     secret }  class person {     private string _firstname;     private string _lastname;     private string _email;     private gender _gender;      @property public string firstname() {return _firstname;}     @property public string lastname() {return _lastname;}     @property public string email() {return _email;}     @property public gender gender() {return _gender;}       public this()     {     }      public this(string firstname, string lastname, gender gender = gender.secret, string email = "info@example.com")     {         this();          this._firstname = firstname;         this._lastname = lastname;         this._gender = gender;         this._email = email;     }      override public string tostring()     {         if (email.length > 0)         {             return "%s %s <%s>".format(firstname, lastname, email);         }         else         {             return "%s %s".format(firstname, lastname);         }     } }  class peoplelist : list!person {     public peoplelist selectbygender(gender gender)     {         return this.select(p => p.gender == gender);     } }  void main(string[] args) {     auto people = new peoplelist();     people.append(new person("kris", "herlaar", gender.male));     people.append(new person("john", "doe", gender.male));     people.append(new person("steve", "wozniak", gender.male));     people.append(new person("walter", "bright", gender.male));     people.append(new person("amelia", "earhart", gender.female, null));     people.append(new person("susan", "anthony", gender.female, null));      foreach(p; people.selectbygender(gender.female))     {         writeln(p);     } } 

Comments

Popular posts from this blog

ios - UICollectionView Self Sizing Cells with Auto Layout -

node.js - ldapjs - write after end error -

DOM Manipulation in Wordpress (and elsewhere) using php -