 |
Changeset 3971
- 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
| r3713 |
r3971 |
|
| 7 | 7 | version: Apr 2008: Initial release |
|---|
| 8 | 8 | |
|---|
| 9 | | authors: Kris |
|---|
| | 9 | authors: Kris, tsalm |
|---|
| 10 | 10 | |
|---|
| 11 | 11 | Since: 0.99.7 |
|---|
| … | … | |
| 266 | 266 | |
|---|
| 267 | 267 | /** |
|---|
| | 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 | /** |
|---|
| 268 | 318 | * Return number of nodes of current subtree containing value. |
|---|
| 269 | 319 | * Uses Comparator cmp to find and to check equality. |
|---|
| r3966 |
r3971 |
|
| 30 | 30 | |
|---|
| 31 | 31 | --- |
|---|
| 32 | | Iterator iterator () |
|---|
| | 32 | Iterator iterator (bool forward) |
|---|
| | 33 | Iterator iterator (K key, bool forward) |
|---|
| 33 | 34 | int opApply (int delegate (ref V value) dg) |
|---|
| 34 | 35 | int opApply (int delegate (ref K key, ref V value) dg) |
|---|
| … | … | |
| 50 | 51 | bool replacePair (K key, V oldElement, V newElement) |
|---|
| 51 | 52 | bool opIndexAssign (V element, K key) |
|---|
| | 53 | K nearbyKey (K key, bool greater) |
|---|
| 52 | 54 | V opIndex (K key) |
|---|
| 53 | 55 | V* opIn_r (K key) |
|---|
| … | … | |
| 141 | 143 | ***********************************************************************/ |
|---|
| 142 | 144 | |
|---|
| 143 | | final Iterator iterator () |
|---|
| | 145 | final Iterator iterator (bool forward = true) |
|---|
| 144 | 146 | { |
|---|
| 145 | 147 | 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; |
|---|
| 147 | 150 | i.mutation = mutation; |
|---|
| 148 | 151 | i.owner = this; |
|---|
| 149 | 152 | 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; |
|---|
| 150 | 170 | return i; |
|---|
| 151 | 171 | } |
|---|
| … | … | |
| 288 | 308 | } |
|---|
| 289 | 309 | 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"); |
|---|
| 290 | 335 | } |
|---|
| 291 | 336 | |
|---|
| … | … | |
| 791 | 836 | /*********************************************************************** |
|---|
| 792 | 837 | |
|---|
| 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 | | |
|---|
| 816 | 838 | Iterator with no filtering |
|---|
| 817 | 839 | |
|---|
| … | … | |
| 820 | 842 | private struct Iterator |
|---|
| 821 | 843 | { |
|---|
| 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; |
|---|
| 826 | 849 | |
|---|
| 827 | 850 | /*************************************************************** |
|---|
| … | … | |
| 865 | 888 | k = node.value; |
|---|
| 866 | 889 | r = &node.attribute; |
|---|
| 867 | | node = node.successor; |
|---|
| | 890 | node = bump (node); |
|---|
| 868 | 891 | } |
|---|
| 869 | 892 | return r; |
|---|
| … | … | |
| 884 | 907 | { |
|---|
| 885 | 908 | prior = n; |
|---|
| 886 | | auto next = n.successor; |
|---|
| | 909 | auto next = bump (n); |
|---|
| 887 | 910 | if ((result = dg(n.value, n.attribute)) != 0) |
|---|
| 888 | 911 | break; |
|---|
| … | … | |
| 913 | 936 | return false; |
|---|
| 914 | 937 | } |
|---|
| | 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 | } |
|---|
| 915 | 969 | } |
|---|
| 916 | 970 | } |
|---|
| … | … | |
| 941 | 995 | Stdout.formatln ("{}:{}", key, value); |
|---|
| 942 | 996 | |
|---|
| | 997 | // explicit iteration |
|---|
| | 998 | foreach (key, value; map.iterator("foo", false)) |
|---|
| | 999 | Stdout.formatln ("{}:{}", key, value); |
|---|
| | 1000 | |
|---|
| 943 | 1001 | // generic iteration with optional remove |
|---|
| 944 | 1002 | auto s = map.iterator; |
|---|
| 945 | 1003 | foreach (key, value; s) |
|---|
| 946 | | s.remove; |
|---|
| | 1004 | {} // s.remove; |
|---|
| 947 | 1005 | |
|---|
| 948 | 1006 | // incremental iteration, with optional remove |
|---|
Download in other formats:
|
 |
 |
|
 |
Copyright © 2006-2008 Tango. All Rights Reserved. | Page Width:
Static or
Dynamic