Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

Changeset 3971

Show
Ignore:
Timestamp:
10/05/08 00:59:53 (2 months ago)
Author:
kris
Message:

fixes #1244 :: SortedMap? now supports directional iterators, plus proximal key-matching

Kudos to tslam for providing patches ... thanks!

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/tango/util/container/RedBlack.d

    r3713 r3971  
    77        version:        Apr 2008: Initial release 
    88 
    9         authors:        Kris 
     9        authors:        Kris, tsalm 
    1010 
    1111        Since:          0.99.7 
     
    266266 
    267267        /** 
     268         * Return node of subtree matching "value"  
     269         * or, if none found, the one just after or before   
     270         * if it doesn't exist, return null 
     271         * Uses Comparator cmp to find and to check equality. 
     272        **/ 
     273        Ref findFirst (V value, Compare!(V) cmp, bool after = true) 
     274        { 
     275                auto t = this; 
     276                auto tLower = this; 
     277                auto tGreater  = this; 
     278             
     279                for (;;) 
     280                    { 
     281                    auto diff = cmp (value, t.value); 
     282                    if (diff is 0) 
     283                        return t; 
     284                   else 
     285                      if (diff < 0) 
     286                         { 
     287                         tGreater = t; 
     288                         t = t.left; 
     289                         } 
     290                      else 
     291                         { 
     292                         tLower = t; 
     293                         t = t.right; 
     294                         } 
     295                   if (t is null) 
     296                       break; 
     297                   } 
     298     
     299                if (after) 
     300                   {  
     301                   if (cmp (value, tGreater.value) > 0) 
     302                       return null; 
     303                   else  
     304                      if (cmp (value , tGreater.value) < 0) 
     305                          return tGreater; 
     306                   } 
     307                else 
     308                   { 
     309                   if (cmp (value, tLower.value) < 0) 
     310                       return null; 
     311                   else  
     312                      if (cmp (value , tLower.value) > 0) 
     313                          return tLower; 
     314                   } 
     315        } 
     316         
     317        /** 
    268318         * Return number of nodes of current subtree containing value. 
    269319         * Uses Comparator cmp to find and to check equality. 
  • trunk/tango/util/container/SortedMap.d

    r3966 r3971  
    3030 
    3131        --- 
    32         Iterator iterator () 
     32        Iterator iterator (bool forward) 
     33        Iterator iterator (K key, bool forward) 
    3334        int opApply (int delegate (ref V value) dg) 
    3435        int opApply (int delegate (ref K key, ref V value) dg) 
     
    5051        bool replacePair (K key, V oldElement, V newElement) 
    5152        bool opIndexAssign (V element, K key) 
     53        K    nearbyKey (K key, bool greater) 
    5254        V    opIndex (K key) 
    5355        V*   opIn_r (K key) 
     
    141143        ***********************************************************************/ 
    142144 
    143         final Iterator iterator (
     145        final Iterator iterator (bool forward = true
    144146        { 
    145147                Iterator i = void; 
    146                 i.node = tree ? tree.leftmost : null; 
     148                i.node = tree ? (forward ? tree.leftmost : tree.rightmost) : null; 
     149                i.bump = forward ? &Iterator.fore : &Iterator.back; 
    147150                i.mutation = mutation; 
    148151                i.owner = this; 
    149152                i.prior = null; 
     153                return i; 
     154        } 
     155       
     156        /*********************************************************************** 
     157 
     158                Return an iterator which return all elements matching  
     159                or greater/lesser than the key in argument. The second 
     160                argument dictates traversal direction. 
     161 
     162                Return a generic iterator for contained elements 
     163                 
     164        ***********************************************************************/ 
     165 
     166        final Iterator iterator (K key, bool forward) 
     167        { 
     168                Iterator i = iterator (forward); 
     169                i.node = tree ? tree.findFirst(key, cmp, forward) : null; 
    150170                return i; 
    151171        } 
     
    288308                   } 
    289309                return false; 
     310        } 
     311 
     312        /*********************************************************************** 
     313 
     314                Return the value of the key exactly matching the provided 
     315                key or, if none, the key just after/before it based on the 
     316                setting of the second argument 
     317     
     318                param: key a key 
     319                param: after indicates whether to look beyond or before 
     320                       the given key, where there is no exact match 
     321                Throws: NoSUchElementException if none found 
     322                Returns: a pointer to the value, or null if not present 
     323              
     324        ***********************************************************************/ 
     325        K nearbyKey (K key, bool after) 
     326        { 
     327                if (count) 
     328                   { 
     329                   auto p = tree.findFirst (key, cmp, after); 
     330                   if (p) 
     331                       return p.value; 
     332                   } 
     333             
     334                throw new NoSuchElementException ("Element not found"); 
    290335        } 
    291336 
     
    791836        /*********************************************************************** 
    792837 
    793                 foreach support for iterators 
    794                  
    795         ***********************************************************************/ 
    796  
    797         private struct Freach 
    798         { 
    799                 bool delegate(ref K, ref V) next; 
    800                  
    801                 int opApply (int delegate(ref K key, ref V value) dg) 
    802                 { 
    803                         K   key; 
    804                         V   value; 
    805                         int result; 
    806  
    807                         while (next (key, value)) 
    808                                if ((result = dg(key, value)) != 0) 
    809                                     break; 
    810                         return result; 
    811                 }                
    812         } 
    813          
    814         /*********************************************************************** 
    815  
    816838                Iterator with no filtering 
    817839 
     
    820842        private struct Iterator 
    821843        { 
    822                 Ref             node, 
    823                                 prior; 
    824                 SortedMap       owner; 
    825                 uint            mutation; 
     844                Ref function(Ref) bump; 
     845                Ref               node, 
     846                                  prior; 
     847                SortedMap         owner; 
     848                uint              mutation; 
    826849 
    827850                /*************************************************************** 
     
    865888                           k = node.value; 
    866889                           r = &node.attribute; 
    867                            node = node.successor
     890                           node = bump (node)
    868891                           } 
    869892                        return r; 
     
    884907                              { 
    885908                              prior = n; 
    886                               auto next = n.successor
     909                              auto next = bump (n)
    887910                              if ((result = dg(n.value, n.attribute)) != 0) 
    888911                                   break; 
     
    913936                        return false; 
    914937                } 
     938 
     939                /*************************************************************** 
     940 
     941                ***************************************************************/ 
     942 
     943                Iterator reverse () 
     944                { 
     945                        if (bump is &fore) 
     946                            bump = &back; 
     947                        else 
     948                           bump = &fore; 
     949                        return *this; 
     950                } 
     951 
     952                /*************************************************************** 
     953 
     954                ***************************************************************/ 
     955 
     956                private static Ref fore (Ref p) 
     957                { 
     958                        return p.successor; 
     959                } 
     960 
     961                /*************************************************************** 
     962 
     963                ***************************************************************/ 
     964 
     965                private static Ref back (Ref p) 
     966                { 
     967                        return p.predecessor; 
     968                } 
    915969        } 
    916970} 
     
    941995                         Stdout.formatln ("{}:{}", key, value); 
    942996 
     997                // explicit iteration 
     998                foreach (key, value; map.iterator("foo", false)) 
     999                         Stdout.formatln ("{}:{}", key, value); 
     1000 
    9431001                // generic iteration with optional remove 
    9441002                auto s = map.iterator; 
    9451003                foreach (key, value; s) 
    946                         s.remove; 
     1004                        {} // s.remove; 
    9471005 
    9481006                // incremental iteration, with optional remove