Advertisement
WeltEnSTurm

List

Nov 1st, 2012
399
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
D 3.25 KB | None | 0 0
  1.  
  2. module ws.list;
  3.  
  4. import io = ws.io;
  5. import std.conv;
  6.  
  7. struct List(T) {
  8.    
  9.     T opIndex(size_t idx){
  10.         assert(idx < length);
  11.         Iterator it = first;
  12.         while(idx--) it = it.next;
  13.         return it.obj;
  14.     }
  15.    
  16.     void opOpAssign(string op)(T e){
  17.         static if(op=="~")
  18.             push(e);
  19.         else static if(op=="-")
  20.             remove(e);
  21.         else static assert(0, "Operator " ~ op ~ " not implemented");
  22.     }
  23.    
  24.     void push(T e){
  25.         if(!first){
  26.             first = new Iterator;
  27.             first.obj = e;
  28.             last = first;
  29.         }else{
  30.             last.next = new Iterator;
  31.             last.next.prev = last;
  32.             last.next.obj = e;
  33.             last = last.next;
  34.         }
  35.         ++size;
  36.     }
  37.    
  38.     void pushFront(T e){
  39.         if(!first){
  40.             first = new Iterator;
  41.             first.obj = e;
  42.             last = first;
  43.         }else{
  44.             first.prev = new Iterator;
  45.             first.prev.next = first;
  46.             first.prev.obj = e;
  47.             first = first.prev;
  48.         }
  49.         ++size;
  50.     }
  51.    
  52.     ref T popBack(){
  53.         assert(size, "list is empty");
  54.         auto tmp = last;
  55.         if(last.prev){
  56.             last.prev.next = null;
  57.             last = last.prev;
  58.         }else{
  59.             first = null;
  60.             last = null;
  61.         }
  62.         --size;
  63.         return tmp.obj;
  64.     }
  65.    
  66.     ref T popFront(){
  67.         assert(size, "list is empty");
  68.         auto tmp = first;
  69.         if(first.next){
  70.             first.next.prev = null;
  71.             first = first.next;
  72.         }else{
  73.             first = null;
  74.             last = null;
  75.         }
  76.         --size;
  77.         return tmp.obj;
  78.     }
  79.    
  80.     void remove(T e){
  81.         auto it = first;
  82.         while(it){
  83.             if(it.obj == e) break;
  84.             it = it.next;
  85.         }
  86.         if(!it)
  87.             throw new Exception("element not in list");
  88.         if(it.prev) it.prev.next = it.next;
  89.         else first = it.next;
  90.         if(it.next) it.next.prev = it.prev;
  91.         else last = it.prev;
  92.         --size;
  93.     }
  94.    
  95.     int opApply(int delegate(ref T) dg){
  96.         int result = 0;
  97.         auto it = first;
  98.         while(it){
  99.             auto obj = it.obj;
  100.             it = it.next;
  101.             result = dg(obj);
  102.             if(result) break;
  103.         }
  104.         return result;
  105.     }
  106.    
  107.     int opApplyReverse(int delegate(ref T) dg){
  108.         int result = 0;
  109.         auto it = last;
  110.         while(it){
  111.             auto obj = it.obj;
  112.             it = it.prev;
  113.             result = dg(obj);
  114.             if(result) break;
  115.         }
  116.         return result;
  117.     }
  118.    
  119.     @property string toString(){
  120.         string tmp = "List!" ~ typeid(T).toString ~ " = [\n";
  121.         auto it = first;
  122.         while(it){
  123.             tmp ~= "\t" ~ to!string(it.obj) ~ ",\n";
  124.             it = it.next;
  125.         }
  126.         tmp ~= "]";
  127.         return tmp;
  128.     }
  129.    
  130.     @property bool empty() const {
  131.         return !first;
  132.     }
  133.    
  134.     @property size_t length(){
  135.         return size;
  136.     }
  137.    
  138.     @property T front(){
  139.         return first.obj;
  140.     }
  141.    
  142.     @property T back(){
  143.         return last.obj;
  144.     }
  145.    
  146.     @property Iterator begin(){
  147.         return first;
  148.     }
  149.    
  150.     @property Iterator end(){
  151.         return last;
  152.     }
  153.    
  154.     @property List save(){
  155.         List n;
  156.         for(auto it = first; it != last; it = it.next)
  157.             n.push(it.obj);
  158.         return n;
  159.     }
  160.    
  161.     private:
  162.    
  163.         Iterator first;
  164.         Iterator last;
  165.         size_t size;
  166.        
  167.         class Iterator {
  168.             Iterator next;
  169.             Iterator prev;
  170.             T obj;
  171.         }
  172.            
  173.     unittest {
  174.         List!int test;
  175.         test.push(5);
  176.         test.push(10);
  177.        
  178.         assert(test[0]*test[1] == 5*10);
  179.        
  180.         test.remove(5);
  181.        
  182.         assert(test[0] == 10);
  183.        
  184.         test.push(11);
  185.         test.push(12);
  186.        
  187.         foreach(i; test)
  188.             if(i == 11){
  189.                 test.remove(i);
  190.                 test.push(100);
  191.             }
  192.        
  193.         assert(test[0] == 10);
  194.         assert(test[1] == 12);
  195.         assert(test[2] == 100);
  196.         assert(test.length == 3);
  197.        
  198.         foreach(i; test)
  199.             test.popFront();
  200.     }
  201.  
  202. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement