1 /* 2 * Hunt - A refined core library for D programming language. 3 * 4 * Copyright (C) 2018-2019 HuntLabs 5 * 6 * Website: https://www.huntlabs.net/ 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module hunt.collection.TreeMap; 13 14 import hunt.collection.AbstractCollection; 15 import hunt.collection.AbstractMap; 16 import hunt.collection.AbstractSet; 17 import hunt.collection.Collection; 18 import hunt.collection.Iterator; 19 import hunt.collection.Map; 20 import hunt.collection.NavigableMap; 21 import hunt.collection.NavigableSet; 22 import hunt.collection.Set; 23 import hunt.collection.SortedMap; 24 import hunt.collection.SortedSet; 25 26 import hunt.Exceptions; 27 import hunt.Functions; 28 import hunt.Object; 29 import hunt.util.Comparator; 30 import hunt.util.Spliterator; 31 32 import std.algorithm; 33 import std.conv; 34 // import std.concurrency : initOnce; 35 import std.exception; 36 import std.math; 37 import std.range; 38 import std.traits; 39 40 41 version (HUNT_DEBUG) import hunt.logging; 42 43 // Red-black mechanics 44 45 private enum bool RED = false; 46 private enum bool BLACK = true; 47 48 49 /** 50 * A Red-Black tree based {@link NavigableMap} implementation. 51 * The map is sorted according to the {@linkplain Comparable natural 52 * ordering} of its keys, or by a {@link Comparator} provided at map 53 * creation time, depending on which constructor is used. 54 * 55 * <p>This implementation provides guaranteed log(n) time cost for the 56 * {@code containsKey}, {@code get}, {@code put} and {@code remove} 57 * operations. Algorithms are adaptations of those in Cormen, Leiserson, and 58 * Rivest's <em>Introduction to Algorithms</em>. 59 * 60 * <p>Note that the ordering maintained by a tree map, like any sorted map, and 61 * whether or not an explicit comparator is provided, must be <em>consistent 62 * with {@code equals}</em> if this sorted map is to correctly implement the 63 * {@code Map} interface. (See {@code Comparable} or {@code Comparator} for a 64 * precise definition of <em>consistent with equals</em>.) This is so because 65 * the {@code Map} interface is defined in terms of the {@code equals} 66 * operation, but a sorted map performs all key comparisons using its {@code 67 * compareTo} (or {@code compare}) method, so two keys that are deemed equal by 68 * this method are, from the standpoint of the sorted map, equal. The behavior 69 * of a sorted map <em>is</em> well-defined even if its ordering is 70 * inconsistent with {@code equals}; it just fails to obey the general contract 71 * of the {@code Map} interface. 72 * 73 * <p><strong>Note that this implementation is not synchronized.</strong> 74 * If multiple threads access a map concurrently, and at least one of the 75 * threads modifies the map structurally, it <em>must</em> be synchronized 76 * externally. (A structural modification is any operation that adds or 77 * deletes one or more mappings; merely changing the value associated 78 * with an existing key is not a structural modification.) This is 79 * typically accomplished by synchronizing on some object that naturally 80 * encapsulates the map. 81 * If no such object exists, the map should be "wrapped" using the 82 * {@link Collections#synchronizedSortedMap Collections.synchronizedSortedMap} 83 * method. This is best done at creation time, to prevent accidental 84 * unsynchronized access to the map: <pre> 85 * SortedMap m = Collections.synchronizedSortedMap(new TreeMap(...));</pre> 86 * 87 * <p>The iterators returned by the {@code iterator} method of the collections 88 * returned by all of this class's "collection view methods" are 89 * <em>fail-fast</em>: if the map is structurally modified at any time after 90 * the iterator is created, in any way except through the iterator's own 91 * {@code remove} method, the iterator will throw a {@link 92 * ConcurrentModificationException}. Thus, in the face of concurrent 93 * modification, the iterator fails quickly and cleanly, rather than risking 94 * arbitrary, non-deterministic behavior at an undetermined time in the future. 95 * 96 * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed 97 * as it is, generally speaking, impossible to make any hard guarantees in the 98 * presence of unsynchronized concurrent modification. Fail-fast iterators 99 * throw {@code ConcurrentModificationException} on a best-effort basis. 100 * Therefore, it would be wrong to write a program that depended on this 101 * exception for its correctness: <em>the fail-fast behavior of iterators 102 * should be used only to detect bugs.</em> 103 * 104 * <p>All {@code MapEntry} pairs returned by methods in this class 105 * and its views represent snapshots of mappings at the time they were 106 * produced. They do <strong>not</strong> support the {@code Entry.setValue} 107 * method. (Note however that it is possible to change mappings in the 108 * associated map using {@code put}.) 109 * 110 * <p>This class is a member of the 111 * <a href="{@docRoot}/../technotes/guides/collections/index.html"> 112 * Java Collections Framework</a>. 113 * 114 * @param !K the type of keys maintained by this map 115 * @param !V the type of mapped values 116 * 117 * @author Josh Bloch and Doug Lea 118 * @see Map 119 * @see HashMap 120 * @see Hashtable 121 * @see Comparable 122 * @see Comparator 123 * @see Collection 124 */ 125 126 class TreeMap(K,V) : AbstractMap!(K,V), NavigableMap!(K,V) 127 if(isOrderingComparable!K) { //, Cloneable 128 129 /** 130 * The comparator used to maintain order in this tree map, or 131 * null if it uses the natural ordering of its keys. 132 * 133 * @serial 134 */ 135 private Comparator!K _comparator; 136 137 private TreeMapEntry!(K,V) root; 138 139 /** 140 * The number of entries in the tree 141 */ 142 // private int _size = 0; 143 144 /** 145 * The number of structural modifications to the tree. 146 */ 147 private int modCount = 0; 148 149 /** 150 * Constructs a new, empty tree map, using the natural ordering of its 151 * keys. All keys inserted into the map must implement the {@link 152 * Comparable} interface. Furthermore, all such keys must be 153 * <em>mutually comparable</em>: {@code k1.compareTo(k2)} must not throw 154 * a {@code ClassCastException} for any keys {@code k1} and 155 * {@code k2} in the map. If the user attempts to put a key into the 156 * map that violates this constraint (for example, the user attempts to 157 * put a string key into a map whose keys are integers), the 158 * {@code put(Object key, Object value)} call will throw a 159 * {@code ClassCastException}. 160 */ 161 this() { 162 _comparator = null; 163 } 164 165 /** 166 * Constructs a new, empty tree map, ordered according to the given 167 * comparator. All keys inserted into the map must be <em>mutually 168 * comparable</em> by the given comparator: {@code comparator.compare(k1, 169 * k2)} must not throw a {@code ClassCastException} for any keys 170 * {@code k1} and {@code k2} in the map. If the user attempts to put 171 * a key into the map that violates this constraint, the {@code put(Object 172 * key, Object value)} call will throw a 173 * {@code ClassCastException}. 174 * 175 * @param comparator the comparator that will be used to order this map. 176 * If {@code null}, the {@linkplain Comparable natural 177 * ordering} of the keys will be used. 178 */ 179 this(Comparator!K comparator) { 180 this._comparator = comparator; 181 } 182 183 /** 184 * Constructs a new tree map containing the same mappings as the given 185 * map, ordered according to the <em>natural ordering</em> of its keys. 186 * All keys inserted into the new map must implement the {@link 187 * Comparable} interface. Furthermore, all such keys must be 188 * <em>mutually comparable</em>: {@code k1.compareTo(k2)} must not throw 189 * a {@code ClassCastException} for any keys {@code k1} and 190 * {@code k2} in the map. This method runs in n*log(n) time. 191 * 192 * @param m the map whose mappings are to be placed in this map 193 * @throws ClassCastException if the keys in m are not {@link Comparable}, 194 * or are not mutually comparable 195 * @throws NullPointerException if the specified map is null 196 */ 197 this(Map!(K, V) m) { 198 _comparator = null; 199 putAll(m); 200 } 201 202 /** 203 * Constructs a new tree map containing the same mappings and 204 * using the same ordering as the specified sorted map. This 205 * method runs in linear time. 206 * 207 * @param m the sorted map whose mappings are to be placed in this map, 208 * and whose comparator is to be used to sort this map 209 * @throws NullPointerException if the specified map is null 210 */ 211 // this(SortedMap!(K, V) m) { 212 // _comparator = m.comparator(); 213 // try { 214 // buildFromSorted(m.size(), m.entrySet().iterator(), null, null); 215 // } catch (IOException cannotHappen) { 216 // } catch (ClassNotFoundException cannotHappen) { 217 // } 218 // } 219 220 221 // Query Operations 222 223 /** 224 * Returns the number of key-value mappings in this map. 225 * 226 * @return the number of key-value mappings in this map 227 */ 228 // override int size() { 229 // return _size; 230 // } 231 232 /** 233 * Returns {@code true} if this map contains a mapping for the specified 234 * key. 235 * 236 * @param key key whose presence in this map is to be tested 237 * @return {@code true} if this map contains a mapping for the 238 * specified key 239 * @throws ClassCastException if the specified key cannot be compared 240 * with the keys currently in the map 241 * @throws NullPointerException if the specified key is null 242 * and this map uses natural ordering, or its comparator 243 * does not permit null keys 244 */ 245 override bool containsKey(K key) { 246 return getEntry(key) !is null; 247 } 248 249 /** 250 * Returns {@code true} if this map maps one or more keys to the 251 * specified value. More formally, returns {@code true} if and only if 252 * this map contains at least one mapping to a value {@code v} such 253 * that {@code (value is null ? v is null : value.equals(v))}. This 254 * operation will probably require time linear in the map size for 255 * most implementations. 256 * 257 * @param value value whose presence in this map is to be tested 258 * @return {@code true} if a mapping to {@code value} exists; 259 * {@code false} otherwise 260 */ 261 override bool containsValue(V value) { 262 for (TreeMapEntry!(K,V) e = getFirstEntry(); e !is null; e = successor(e)) 263 if (valEquals(value, e.value)) 264 return true; 265 return false; 266 } 267 268 /** 269 * Returns the value to which the specified key is mapped, 270 * or {@code null} if this map contains no mapping for the key. 271 * 272 * <p>More formally, if this map contains a mapping from a key 273 * {@code k} to a value {@code v} such that {@code key} compares 274 * equal to {@code k} according to the map's ordering, then this 275 * method returns {@code v}; otherwise it returns {@code null}. 276 * (There can be at most one such mapping.) 277 * 278 * <p>A return value of {@code null} does not <em>necessarily</em> 279 * indicate that the map contains no mapping for the key; it's also 280 * possible that the map explicitly maps the key to {@code null}. 281 * The {@link #containsKey containsKey} operation may be used to 282 * distinguish these two cases. 283 * 284 * @throws ClassCastException if the specified key cannot be compared 285 * with the keys currently in the map 286 * @throws NullPointerException if the specified key is null 287 * and this map uses natural ordering, or its comparator 288 * does not permit null keys 289 */ 290 override V get(K key) { 291 TreeMapEntry!(K,V) p = getEntry(key); 292 return (p is null ? null : p.value); 293 } 294 295 Comparator!K comparator() { 296 return _comparator; 297 } 298 299 /** 300 * @throws NoSuchElementException {@inheritDoc} 301 */ 302 K firstKey() { 303 return key(getFirstEntry()); 304 } 305 306 /** 307 * @throws NoSuchElementException {@inheritDoc} 308 */ 309 K lastKey() { 310 return key(getLastEntry()); 311 } 312 313 /** 314 * Copies all of the mappings from the specified map to this map. 315 * These mappings replace any mappings that this map had for any 316 * of the keys currently in the specified map. 317 * 318 * @param map mappings to be stored in this map 319 * @throws ClassCastException if the class of a key or value in 320 * the specified map prevents it from being stored in this map 321 * @throws NullPointerException if the specified map is null or 322 * the specified map contains a null key and this map does not 323 * permit null keys 324 */ 325 override void putAll(Map!(K, V) map) { 326 int mapSize = map.size(); 327 SortedMap!(K, V) sortedMap = cast(SortedMap!(K, V)) map; 328 if (_size==0 && mapSize !is 0 && sortedMap !is null) { 329 Comparator!K c = sortedMap.comparator(); 330 if (c == _comparator) { 331 ++modCount; 332 implementationMissing(false); 333 // try { 334 // buildFromSorted(mapSize, map, //.entrySet().iterator(), 335 // null, null); 336 // } catch (IOException cannotHappen) { 337 // } 338 // catch (ClassNotFoundException cannotHappen) { 339 // } 340 return; 341 } 342 } 343 super.putAll(map); 344 } 345 346 /** 347 * Returns this map's entry for the given key, or {@code null} if the map 348 * does not contain an entry for the key. 349 * 350 * @return this map's entry for the given key, or {@code null} if the map 351 * does not contain an entry for the key 352 * @throws ClassCastException if the specified key cannot be compared 353 * with the keys currently in the map 354 * @throws NullPointerException if the specified key is null 355 * and this map uses natural ordering, or its comparator 356 * does not permit null keys 357 */ 358 final TreeMapEntry!(K,V) getEntry(K key) { 359 // Offload comparator-based version for sake of performance 360 if (_comparator !is null) 361 return getEntryUsingComparator(key); 362 static if(is(T == class)) 363 { 364 if (key is null) 365 throw new NullPointerException(); 366 } 367 K k = key; 368 TreeMapEntry!(K,V) p = root; 369 while (p !is null) { 370 // static if(isNumeric!(K)) 371 // int cp = std.math.cmp(cast(float)k, cast(float)p.key); 372 // else 373 // int cp = std.algorithm.cmp(k, p.key); 374 int cp = compare(k, p.key); 375 376 if (cp < 0) 377 p = p.left; 378 else if (cp > 0) 379 p = p.right; 380 else 381 return p; 382 } 383 return null; 384 } 385 386 /** 387 * Version of getEntry using comparator. Split off from getEntry 388 * for performance. (This is not worth doing for most methods, 389 * that are less dependent on comparator performance, but is 390 * worthwhile here.) 391 */ 392 final TreeMapEntry!(K,V) getEntryUsingComparator(K key) { 393 K k = key; 394 Comparator!K cpr = _comparator; 395 if (cpr !is null) { 396 TreeMapEntry!(K,V) p = root; 397 while (p !is null) { 398 int cmp = cpr.compare(k, p.key); 399 if (cmp < 0) 400 p = p.left; 401 else if (cmp > 0) 402 p = p.right; 403 else 404 return p; 405 } 406 } 407 return null; 408 } 409 410 /** 411 * Gets the entry corresponding to the specified key; if no such entry 412 * exists, returns the entry for the least key greater than the specified 413 * key; if no such entry exists (i.e., the greatest key in the Tree is less 414 * than the specified key), returns {@code null}. 415 */ 416 final TreeMapEntry!(K,V) getCeilingEntry(K key) { 417 TreeMapEntry!(K,V) p = root; 418 while (p !is null) { 419 int cmp = compare(key, p.key); 420 if (cmp < 0) { 421 if (p.left !is null) 422 p = p.left; 423 else 424 return p; 425 } else if (cmp > 0) { 426 if (p.right !is null) { 427 p = p.right; 428 } else { 429 TreeMapEntry!(K,V) parent = p.parent; 430 TreeMapEntry!(K,V) ch = p; 431 while (parent !is null && ch == parent.right) { 432 ch = parent; 433 parent = parent.parent; 434 } 435 return parent; 436 } 437 } else 438 return p; 439 } 440 return null; 441 } 442 443 /** 444 * Gets the entry corresponding to the specified key; if no such entry 445 * exists, returns the entry for the greatest key less than the specified 446 * key; if no such entry exists, returns {@code null}. 447 */ 448 final TreeMapEntry!(K,V) getFloorEntry(K key) { 449 TreeMapEntry!(K,V) p = root; 450 while (p !is null) { 451 int cmp = compare(key, p.key); 452 if (cmp > 0) { 453 if (p.right !is null) 454 p = p.right; 455 else 456 return p; 457 } else if (cmp < 0) { 458 if (p.left !is null) { 459 p = p.left; 460 } else { 461 TreeMapEntry!(K,V) parent = p.parent; 462 TreeMapEntry!(K,V) ch = p; 463 while (parent !is null && ch == parent.left) { 464 ch = parent; 465 parent = parent.parent; 466 } 467 return parent; 468 } 469 } else 470 return p; 471 472 } 473 return null; 474 } 475 476 /** 477 * Gets the entry for the least key greater than the specified 478 * key; if no such entry exists, returns the entry for the least 479 * key greater than the specified key; if no such entry exists 480 * returns {@code null}. 481 */ 482 final TreeMapEntry!(K,V) getHigherEntry(K key) { 483 TreeMapEntry!(K,V) p = root; 484 while (p !is null) { 485 int cmp = compare(key, p.key); 486 if (cmp < 0) { 487 if (p.left !is null) 488 p = p.left; 489 else 490 return p; 491 } else { 492 if (p.right !is null) { 493 p = p.right; 494 } else { 495 TreeMapEntry!(K,V) parent = p.parent; 496 TreeMapEntry!(K,V) ch = p; 497 while (parent !is null && ch == parent.right) { 498 ch = parent; 499 parent = parent.parent; 500 } 501 return parent; 502 } 503 } 504 } 505 return null; 506 } 507 508 /** 509 * Returns the entry for the greatest key less than the specified key; if 510 * no such entry exists (i.e., the least key in the Tree is greater than 511 * the specified key), returns {@code null}. 512 */ 513 final TreeMapEntry!(K,V) getLowerEntry(K key) { 514 TreeMapEntry!(K,V) p = root; 515 while (p !is null) { 516 int cmp = compare(key, p.key); 517 if (cmp > 0) { 518 if (p.right !is null) 519 p = p.right; 520 else 521 return p; 522 } else { 523 if (p.left !is null) { 524 p = p.left; 525 } else { 526 TreeMapEntry!(K,V) parent = p.parent; 527 TreeMapEntry!(K,V) ch = p; 528 while (parent !is null && ch == parent.left) { 529 ch = parent; 530 parent = parent.parent; 531 } 532 return parent; 533 } 534 } 535 } 536 return null; 537 } 538 539 /** 540 * Associates the specified value with the specified key in this map. 541 * If the map previously contained a mapping for the key, the old 542 * value is replaced. 543 * 544 * @param key key with which the specified value is to be associated 545 * @param value value to be associated with the specified key 546 * 547 * @return the previous value associated with {@code key}, or 548 * {@code null} if there was no mapping for {@code key}. 549 * (A {@code null} return can also indicate that the map 550 * previously associated {@code null} with {@code key}.) 551 * @throws ClassCastException if the specified key cannot be compared 552 * with the keys currently in the map 553 * @throws NullPointerException if the specified key is null 554 * and this map uses natural ordering, or its comparator 555 * does not permit null keys 556 */ 557 override V put(K key, V value) { 558 TreeMapEntry!(K,V) t = root; 559 if (t is null) { 560 // compare(key, key); // type (and possibly null) check 561 562 root = new TreeMapEntry!(K,V)(key, value, null); 563 _size = 1; 564 modCount++; 565 return null; 566 } 567 int _cmp; 568 TreeMapEntry!(K,V) parent; 569 // split comparator and comparable paths 570 Comparator!K cpr = _comparator; 571 if (cpr !is null) { 572 do { 573 parent = t; 574 _cmp = cpr.compare(key, t.key); 575 if (_cmp < 0) 576 t = t.left; 577 else if (_cmp > 0) 578 t = t.right; 579 else 580 return t.setValue(value); 581 } while (t !is null); 582 } 583 else { 584 // if (key is null) 585 // throw new NullPointerException(); 586 // Comparable!K k = cast(Comparable!K) key; 587 K k = key; 588 do { 589 parent = t; 590 _cmp = hunt.util.Comparator.compare(k, t.key); 591 592 if (_cmp < 0) 593 t = t.left; 594 else if (_cmp > 0) 595 t = t.right; 596 else 597 return t.setValue(value); 598 } while (t !is null); 599 } 600 TreeMapEntry!(K,V) e = new TreeMapEntry!(K,V)(key, value, parent); 601 if (_cmp < 0) 602 parent.left = e; 603 else 604 parent.right = e; 605 fixAfterInsertion(e); 606 _size++; 607 modCount++; 608 return null; 609 } 610 611 /** 612 * Removes the mapping for this key from this TreeMap if present. 613 * 614 * @param key key for which mapping should be removed 615 * @return the previous value associated with {@code key}, or 616 * {@code null} if there was no mapping for {@code key}. 617 * (A {@code null} return can also indicate that the map 618 * previously associated {@code null} with {@code key}.) 619 * @throws ClassCastException if the specified key cannot be compared 620 * with the keys currently in the map 621 * @throws NullPointerException if the specified key is null 622 * and this map uses natural ordering, or its comparator 623 * does not permit null keys 624 */ 625 override V remove(K key) { 626 TreeMapEntry!(K,V) p = getEntry(key); 627 if (p is null) 628 return null; 629 630 V oldValue = p.value; 631 deleteEntry(p); 632 return oldValue; 633 } 634 635 /** 636 * Removes all of the mappings from this map. 637 * The map will be empty after this call returns. 638 */ 639 override void clear() { 640 modCount++; 641 _size = 0; 642 root = null; 643 } 644 645 /** 646 * Returns a shallow copy of this {@code TreeMap} instance. (The keys and 647 * values themselves are not cloned.) 648 * 649 * @return a shallow copy of this map 650 */ 651 // Object clone() { 652 // TreeMap<?,?> clone; 653 // try { 654 // clone = (TreeMap<?,?>) super.clone(); 655 // } catch (CloneNotSupportedException e) { 656 // throw new InternalError(e); 657 // } 658 659 // // Put clone into "virgin" state (except for comparator) 660 // clone.root = null; 661 // clone.size = 0; 662 // clone.modCount = 0; 663 // clone.entrySet = null; 664 // clone._navigableKeySet = null; 665 // clone._descendingMap = null; 666 667 // // Initialize clone with our mappings 668 // try { 669 // clone.buildFromSorted(size, entrySet().iterator(), null, null); 670 // } catch (java.io.IOException cannotHappen) { 671 // } catch (ClassNotFoundException cannotHappen) { 672 // } 673 674 // return clone; 675 // } 676 677 // NavigableMap API methods 678 679 /** 680 */ 681 MapEntry!(K,V) firstEntry() { 682 return exportEntry!(K,V)(getFirstEntry()); 683 } 684 685 /** 686 */ 687 MapEntry!(K,V) lastEntry() { 688 return exportEntry!(K,V)(getLastEntry()); 689 } 690 691 /** 692 */ 693 MapEntry!(K,V) pollFirstEntry() { 694 TreeMapEntry!(K,V) p = getFirstEntry(); 695 MapEntry!(K,V) result = exportEntry!(K,V)(p); 696 if (p !is null) 697 deleteEntry(p); 698 return result; 699 } 700 701 /** 702 */ 703 MapEntry!(K,V) pollLastEntry() { 704 TreeMapEntry!(K,V) p = getLastEntry(); 705 MapEntry!(K,V) result = exportEntry!(K,V)(p); 706 if (p !is null) 707 deleteEntry(p); 708 return result; 709 } 710 711 /** 712 * @throws ClassCastException {@inheritDoc} 713 * @throws NullPointerException if the specified key is null 714 * and this map uses natural ordering, or its comparator 715 * does not permit null keys 716 */ 717 MapEntry!(K,V) lowerEntry(K key) { 718 return exportEntry!(K,V)(getLowerEntry(key)); 719 } 720 721 /** 722 * @throws ClassCastException {@inheritDoc} 723 * @throws NullPointerException if the specified key is null 724 * and this map uses natural ordering, or its comparator 725 * does not permit null keys 726 */ 727 K lowerKey(K key) { 728 return keyOrNull(getLowerEntry(key)); 729 } 730 731 /** 732 * @throws ClassCastException {@inheritDoc} 733 * @throws NullPointerException if the specified key is null 734 * and this map uses natural ordering, or its comparator 735 * does not permit null keys 736 */ 737 MapEntry!(K,V) floorEntry(K key) { 738 return exportEntry!(K,V)(getFloorEntry(key)); 739 } 740 741 /** 742 * @throws ClassCastException {@inheritDoc} 743 * @throws NullPointerException if the specified key is null 744 * and this map uses natural ordering, or its comparator 745 * does not permit null keys 746 */ 747 K floorKey(K key) { 748 return keyOrNull(getFloorEntry(key)); 749 } 750 751 /** 752 * @throws ClassCastException {@inheritDoc} 753 * @throws NullPointerException if the specified key is null 754 * and this map uses natural ordering, or its comparator 755 * does not permit null keys 756 */ 757 MapEntry!(K,V) ceilingEntry(K key) { 758 return exportEntry!(K,V)(getCeilingEntry(key)); 759 } 760 761 /** 762 * @throws ClassCastException {@inheritDoc} 763 * @throws NullPointerException if the specified key is null 764 * and this map uses natural ordering, or its comparator 765 * does not permit null keys 766 */ 767 K ceilingKey(K key) { 768 return keyOrNull(getCeilingEntry(key)); 769 } 770 771 /** 772 * @throws ClassCastException {@inheritDoc} 773 * @throws NullPointerException if the specified key is null 774 * and this map uses natural ordering, or its comparator 775 * does not permit null keys 776 */ 777 MapEntry!(K,V) higherEntry(K key) { 778 return exportEntry!(K,V)(getHigherEntry(key)); 779 } 780 781 /** 782 * @throws ClassCastException {@inheritDoc} 783 * @throws NullPointerException if the specified key is null 784 * and this map uses natural ordering, or its comparator 785 * does not permit null keys 786 */ 787 K higherKey(K key) { 788 return keyOrNull(getHigherEntry(key)); 789 } 790 791 // Views 792 793 /** 794 * Fields initialized to contain an instance of the entry set view 795 * the first time this view is requested. Views are stateless, so 796 * there's no reason to create more than one. 797 */ 798 // private EntrySet _entrySet; 799 // private KeySet!(K,V) _navigableKeySet; 800 private NavigableMap!(K,V) _descendingMap; 801 802 /** 803 * Returns a {@link Set} view of the keys contained in this map. 804 * 805 * <p>The set's iterator returns the keys in ascending order. 806 * The set's spliterator is 807 * <em><a href="Spliterator.html#binding">late-binding</a></em>, 808 * <em>fail-fast</em>, and additionally reports {@link Spliterator#SORTED} 809 * and {@link Spliterator#ORDERED} with an encounter order that is ascending 810 * key order. The spliterator's comparator (see 811 * {@link java.util.Spliterator#getComparator()}) is {@code null} if 812 * the tree map's comparator (see {@link #comparator()}) is {@code null}. 813 * Otherwise, the spliterator's comparator is the same as or imposes the 814 * same total ordering as the tree map's comparator. 815 * 816 * <p>The set is backed by the map, so changes to the map are 817 * reflected in the set, and vice-versa. If the map is modified 818 * while an iteration over the set is in progress (except through 819 * the iterator's own {@code remove} operation), the results of 820 * the iteration are undefined. The set supports element removal, 821 * which removes the corresponding mapping from the map, via the 822 * {@code Iterator.remove}, {@code Set.remove}, 823 * {@code removeAll}, {@code retainAll}, and {@code clear} 824 * operations. It does not support the {@code add} or {@code addAll} 825 * operations. 826 */ 827 // Set!K keySet() { 828 // return navigableKeySet(); 829 // } 830 831 /** 832 */ 833 // NavigableSet!K navigableKeySet() { 834 // KeySet!(K, V) nks = _navigableKeySet; 835 // return (nks !is null) ? nks : (_navigableKeySet = new KeySet!(K, V)(this)); 836 // } 837 838 /** 839 */ 840 // NavigableSet!K descendingKeySet() { 841 // return descendingMap().navigableKeySet(); 842 // } 843 844 /** 845 * Returns a {@link Collection} view of the values contained in this map. 846 * 847 * <p>The collection's iterator returns the values in ascending order 848 * of the corresponding keys. The collection's spliterator is 849 * <em><a href="Spliterator.html#binding">late-binding</a></em>, 850 * <em>fail-fast</em>, and additionally reports {@link Spliterator#ORDERED} 851 * with an encounter order that is ascending order of the corresponding 852 * keys. 853 * 854 * <p>The collection is backed by the map, so changes to the map are 855 * reflected in the collection, and vice-versa. If the map is 856 * modified while an iteration over the collection is in progress 857 * (except through the iterator's own {@code remove} operation), 858 * the results of the iteration are undefined. The collection 859 * supports element removal, which removes the corresponding 860 * mapping from the map, via the {@code Iterator.remove}, 861 * {@code Collection.remove}, {@code removeAll}, 862 * {@code retainAll} and {@code clear} operations. It does not 863 * support the {@code add} or {@code addAll} operations. 864 */ 865 // Collection!V values() { 866 // Collection!V vs = values; 867 // if (vs is null) { 868 // vs = new Values(); 869 // values = vs; 870 // } 871 // return vs; 872 // } 873 874 /** 875 * Returns a {@link Set} view of the mappings contained in this map. 876 * 877 * <p>The set's iterator returns the entries in ascending key order. The 878 * sets's spliterator is 879 * <em><a href="Spliterator.html#binding">late-binding</a></em>, 880 * <em>fail-fast</em>, and additionally reports {@link Spliterator#SORTED} and 881 * {@link Spliterator#ORDERED} with an encounter order that is ascending key 882 * order. 883 * 884 * <p>The set is backed by the map, so changes to the map are 885 * reflected in the set, and vice-versa. If the map is modified 886 * while an iteration over the set is in progress (except through 887 * the iterator's own {@code remove} operation, or through the 888 * {@code setValue} operation on a map entry returned by the 889 * iterator) the results of the iteration are undefined. The set 890 * supports element removal, which removes the corresponding 891 * mapping from the map, via the {@code Iterator.remove}, 892 * {@code Set.remove}, {@code removeAll}, {@code retainAll} and 893 * {@code clear} operations. It does not support the 894 * {@code add} or {@code addAll} operations. 895 */ 896 // Set!(MapEntry!(K,V)) entrySet() { 897 // EntrySet es = _entrySet; 898 // return (es !is null) ? es : (_entrySet = new EntrySet()); 899 // } 900 901 /** 902 */ 903 // NavigableMap!(K, V) descendingMap() { 904 // NavigableMap!(K, V) km = _descendingMap; 905 // return (km !is null) ? km : 906 // (_descendingMap = new DescendingSubMap!(K, V)(this, 907 // true, K.init, true, 908 // true, K.init, true)); 909 // } 910 911 /** 912 * @throws ClassCastException {@inheritDoc} 913 * @throws NullPointerException if {@code fromKey} or {@code toKey} is 914 * null and this map uses natural ordering, or its comparator 915 * does not permit null keys 916 * @throws IllegalArgumentException {@inheritDoc} 917 */ 918 NavigableMap!(K,V) subMap(K fromKey, bool fromInclusive, 919 K toKey, bool toInclusive) { 920 return new AscendingSubMap!(K, V)(this, 921 false, fromKey, fromInclusive, 922 false, toKey, toInclusive); 923 } 924 925 /** 926 * @throws ClassCastException {@inheritDoc} 927 * @throws NullPointerException if {@code toKey} is null 928 * and this map uses natural ordering, or its comparator 929 * does not permit null keys 930 * @throws IllegalArgumentException {@inheritDoc} 931 */ 932 NavigableMap!(K,V) headMap(K toKey, bool inclusive) { 933 return new AscendingSubMap!(K, V)(this, 934 true, K.init, true, 935 false, toKey, inclusive); 936 } 937 938 /** 939 * @throws ClassCastException {@inheritDoc} 940 * @throws NullPointerException if {@code fromKey} is null 941 * and this map uses natural ordering, or its comparator 942 * does not permit null keys 943 * @throws IllegalArgumentException {@inheritDoc} 944 */ 945 NavigableMap!(K,V) tailMap(K fromKey, bool inclusive) { 946 return new AscendingSubMap!(K, V)(this, 947 false, fromKey, inclusive, 948 true, K.init, true); 949 } 950 951 /** 952 * @throws ClassCastException {@inheritDoc} 953 * @throws NullPointerException if {@code fromKey} or {@code toKey} is 954 * null and this map uses natural ordering, or its comparator 955 * does not permit null keys 956 * @throws IllegalArgumentException {@inheritDoc} 957 */ 958 SortedMap!(K,V) subMap(K fromKey, K toKey) { 959 return subMap(fromKey, true, toKey, false); 960 } 961 962 /** 963 * @throws ClassCastException {@inheritDoc} 964 * @throws NullPointerException if {@code toKey} is null 965 * and this map uses natural ordering, or its comparator 966 * does not permit null keys 967 * @throws IllegalArgumentException {@inheritDoc} 968 */ 969 SortedMap!(K,V) headMap(K toKey) { 970 return headMap(toKey, false); 971 } 972 973 /** 974 * @throws ClassCastException {@inheritDoc} 975 * @throws NullPointerException if {@code fromKey} is null 976 * and this map uses natural ordering, or its comparator 977 * does not permit null keys 978 * @throws IllegalArgumentException {@inheritDoc} 979 */ 980 SortedMap!(K,V) tailMap(K fromKey) { 981 return tailMap(fromKey, true); 982 } 983 984 override 985 bool replace(K key, V oldValue, V newValue) { 986 TreeMapEntry!(K,V) p = getEntry(key); 987 if (p !is null && oldValue == p.value) { 988 p.value = newValue; 989 return true; 990 } 991 return false; 992 } 993 994 override 995 V replace(K key, V value) { 996 TreeMapEntry!(K,V) p = getEntry(key); 997 if (p !is null) { 998 V oldValue = p.value; 999 p.value = value; 1000 return oldValue; 1001 } 1002 return null; 1003 } 1004 1005 // override 1006 // void replaceAll(BiFunction<K, V, ? : V> function) { 1007 // Objects.requireNonNull(function); 1008 // int expectedModCount = modCount; 1009 1010 // for (TreeMapEntry!(K, V) e = getFirstEntry(); e !is null; e = successor(e)) { 1011 // e.value = function.apply(e.key, e.value); 1012 1013 // if (expectedModCount !is modCount) { 1014 // throw new ConcurrentModificationException(); 1015 // } 1016 // } 1017 // } 1018 1019 1020 // View class support 1021 1022 override int opApply(scope int delegate(ref K, ref V) dg) { 1023 if(dg is null) 1024 throw new NullPointerException(); 1025 1026 int result = 0; 1027 int expectedModCount = modCount; 1028 for (TreeMapEntry!(K, V) e = getFirstEntry(); e !is null; e = successor(e)) { 1029 result = dg(e.key, e.value); 1030 if(result != 0) return result; 1031 } 1032 1033 if (expectedModCount !is modCount) 1034 throw new ConcurrentModificationException(); 1035 1036 return result; 1037 } 1038 1039 1040 override int opApply(scope int delegate(MapEntry!(K, V) entry) dg) { 1041 if(dg is null) 1042 throw new NullPointerException(); 1043 1044 int result = 0; 1045 int expectedModCount = modCount; 1046 for (TreeMapEntry!(K, V) e = getFirstEntry(); e !is null; e = successor(e)) { 1047 result = dg(e); 1048 if(result != 0) return result; 1049 } 1050 1051 if (expectedModCount !is modCount) 1052 throw new ConcurrentModificationException(); 1053 1054 return result; 1055 } 1056 1057 override InputRange!K byKey() 1058 { 1059 return new KeyInputRange(); 1060 // throw new NotImplementedException(); 1061 } 1062 1063 override InputRange!V byValue() 1064 { 1065 return new ValueInputRange(); 1066 // throw new NotImplementedException(); 1067 } 1068 1069 1070 // class Values : AbstractCollection!V { 1071 // Iterator!V iterator() { 1072 // return new ValueIterator(getFirstEntry()); 1073 // } 1074 1075 // override int size() { 1076 // return this.outer.size(); 1077 // } 1078 1079 // override bool contains(V o) { 1080 // return this.outer.containsValue(o); 1081 // } 1082 1083 // bool remove(V o) { 1084 // for (TreeMapEntry!(K,V) e = getFirstEntry(); e !is null; e = successor(e)) { 1085 // if (valEquals(e.getValue(), o)) { 1086 // deleteEntry(e); 1087 // return true; 1088 // } 1089 // } 1090 // return false; 1091 // } 1092 1093 // override void clear() { 1094 // this.outer.clear(); 1095 // } 1096 1097 // // Spliterator!V spliterator() { 1098 // // return new ValueSpliterator!(K,V)(TreeMap.this, null, null, 0, -1, 0); 1099 // // } 1100 // } 1101 1102 // class EntrySet : AbstractSet!(MapEntry!(K,V)) { 1103 1104 // Iterator!(MapEntry!(K,V)) iterator() { 1105 // return new EntryIterator(getFirstEntry()); 1106 // } 1107 1108 // override bool contains(MapEntry!(K,V) entry) { 1109 // // if (!(o instanceof MapEntry)) 1110 // // return false; 1111 // // MapEntry<?,?> entry = (MapEntry<?,?>) o; 1112 // V value = entry.getValue(); 1113 // TreeMapEntry!(K,V) p = getEntry(entry.getKey()); 1114 // return p !is null && valEquals(p.getValue(), value); 1115 // } 1116 1117 // bool remove(MapEntry!(K,V) entry) { 1118 // // if (!(o instanceof MapEntry)) 1119 // // return false; 1120 // // MapEntry<?,?> entry = (MapEntry<?,?>) o; 1121 // V value = entry.getValue(); 1122 // TreeMapEntry!(K,V) p = getEntry(entry.getKey()); 1123 // if (p !is null && valEquals(p.getValue(), value)) { 1124 // deleteEntry(p); 1125 // return true; 1126 // } 1127 // return false; 1128 // } 1129 1130 // override int size() { 1131 // return this.outer.size(); 1132 // } 1133 1134 // override void clear() { 1135 // this.outer.clear(); 1136 // } 1137 1138 // // Spliterator!(MapEntry!(K,V)) spliterator() { 1139 // // return new EntrySpliterator!(K,V)(this.outer, null, null, 0, -1, 0); 1140 // // } 1141 // } 1142 1143 /* 1144 * Unlike Values and EntrySet, the KeySet class is static, 1145 * delegating to a NavigableMap to allow use by SubMaps, which 1146 * outweighs the ugliness of needing type-tests for the following 1147 * Iterator methods that are defined appropriately in main versus 1148 * submap classes. 1149 */ 1150 1151 // Iterator!K keyIterator() { 1152 // return new KeyIterator(getFirstEntry()); 1153 // } 1154 1155 // Iterator!K descendingKeyIterator() { 1156 // return new DescendingKeyIterator(getLastEntry()); 1157 // } 1158 1159 // static final class KeySet(E, V) : AbstractSet!E , NavigableSet!E { 1160 // private NavigableMap!(E, V) m; 1161 1162 // this(NavigableMap!(E, V) map) { m = map; } 1163 1164 // Iterator!E iterator() { 1165 // TreeMap!(E, V) mm = cast(TreeMap!(E, V))m; 1166 // if (mm !is null) 1167 // return mm.keyIterator(); 1168 // else 1169 // return (cast(TreeMap.NavigableSubMap!(E, V))m).keyIterator(); 1170 // } 1171 1172 // Iterator!E descendingIterator() { 1173 // TreeMap!(E, V) mm = cast(TreeMap!(E, V))m; 1174 // if (mm !is null) 1175 // return mm.descendingKeyIterator(); 1176 // else 1177 // return (cast(TreeMap.NavigableSubMap!(E, V))m).descendingKeyIterator(); 1178 // } 1179 1180 // override int size() { return m.size(); } 1181 // override bool isEmpty() { return m.isEmpty(); } 1182 // override bool contains(K o) { return m.containsKey(o); } 1183 // override void clear() { m.clear(); } 1184 // E lower(E e) { return m.lowerKey(e); } 1185 // E floor(E e) { return m.floorKey(e); } 1186 // E ceiling(E e) { return m.ceilingKey(e); } 1187 // E higher(E e) { return m.higherKey(e); } 1188 // E first() { return m.firstKey(); } 1189 // E last() { return m.lastKey(); } 1190 // // Comparator!E comparator() { return m.comparator(); } 1191 // E pollFirst() { 1192 // MapEntry!(E, V) e = m.pollFirstEntry(); 1193 // return (e is null) ? E.init : e.getKey(); 1194 // } 1195 // E pollLast() { 1196 // MapEntry!(E, V) e = m.pollLastEntry(); 1197 // return (e is null) ? E.init : e.getKey(); 1198 // } 1199 // bool remove(E o) { 1200 // int oldSize = size(); 1201 // m.remove(o); 1202 // return size() !is oldSize; 1203 // } 1204 // NavigableSet!E subSet(E fromElement, bool fromInclusive, 1205 // E toElement, bool toInclusive) { 1206 // return new KeySet!(E, V)(m.subMap(fromElement, fromInclusive, 1207 // toElement, toInclusive)); 1208 // } 1209 // NavigableSet!E headSet(E toElement, bool inclusive) { 1210 // return new KeySet!(E, V)(m.headMap(toElement, inclusive)); 1211 // } 1212 // NavigableSet!E tailSet(E fromElement, bool inclusive) { 1213 // return new KeySet!(E, V)(m.tailMap(fromElement, inclusive)); 1214 // } 1215 // SortedSet!E subSet(E fromElement, E toElement) { 1216 // return subSet(fromElement, true, toElement, false); 1217 // } 1218 // SortedSet!E headSet(E toElement) { 1219 // return headSet(toElement, false); 1220 // } 1221 // SortedSet!E tailSet(E fromElement) { 1222 // return tailSet(fromElement, true); 1223 // } 1224 // NavigableSet!E descendingSet() { 1225 // return new KeySet!(E, V)(m.descendingMap()); 1226 // } 1227 1228 // // Spliterator!E spliterator() { 1229 // // return keySpliteratorFor(m); 1230 // // } 1231 // } 1232 1233 /** 1234 * Base class for TreeMap Iterators 1235 */ 1236 1237 mixin template TreeMapIterator() { 1238 TreeMapEntry!(K,V) next; 1239 TreeMapEntry!(K,V) lastReturned; 1240 int expectedModCount; 1241 1242 this() { 1243 expectedModCount = modCount; 1244 lastReturned = null; 1245 next = getFirstEntry(); 1246 } 1247 1248 final bool empty() { 1249 return next is null; 1250 } 1251 1252 final void popFront() { 1253 TreeMapEntry!(K,V) e = next; 1254 if (e is null) 1255 throw new NoSuchElementException(); 1256 if (modCount !is expectedModCount) 1257 throw new ConcurrentModificationException(); 1258 next = successor(e); 1259 lastReturned = e; 1260 // return e; 1261 } 1262 1263 // final TreeMapEntry!(K,V) prevEntry() { 1264 // TreeMapEntry!(K,V) e = next; 1265 // if (e is null) 1266 // throw new NoSuchElementException(); 1267 // if (modCount !is expectedModCount) 1268 // throw new ConcurrentModificationException(); 1269 // next = predecessor(e); 1270 // lastReturned = e; 1271 // return e; 1272 // } 1273 } 1274 1275 final class KeyInputRange : InputRange!K { 1276 mixin TreeMapIterator; 1277 1278 final K front() @property { return next.key; } 1279 1280 // https://forum.dlang.org/thread/amzthhonuozlobghqqgk@forum.dlang.org?page=1 1281 // https://issues.dlang.org/show_bug.cgi?id=18036 1282 final K moveFront() @property { throw new NotSupportedException(); } 1283 1284 int opApply(scope int delegate(K) dg) { 1285 if(dg is null) 1286 throw new NullPointerException(); 1287 1288 int result = 0; 1289 int expectedModCount = modCount; 1290 for (TreeMapEntry!(K, V) e = getFirstEntry(); e !is null; e = successor(e)) { 1291 result = dg(e.key); 1292 if(result != 0) return result; 1293 } 1294 1295 if (expectedModCount !is modCount) 1296 throw new ConcurrentModificationException(); 1297 1298 return result; 1299 } 1300 1301 int opApply(scope int delegate(size_t, K) dg) { 1302 if(dg is null) 1303 throw new NullPointerException(); 1304 1305 int result = 0; 1306 int mc = modCount; 1307 size_t index = 0; 1308 for (TreeMapEntry!(K, V) e = getFirstEntry(); e !is null; e = successor(e)) { 1309 result = dg(index++, e.key); 1310 if(result != 0) return result; 1311 } 1312 1313 if(modCount != mc) 1314 throw new ConcurrentModificationException(); 1315 1316 return result; 1317 } 1318 } 1319 1320 final class ValueInputRange : InputRange!V { 1321 mixin TreeMapIterator; 1322 1323 final V front() @property { return next.value; } 1324 1325 final V moveFront() @property { throw new NotSupportedException(); } 1326 1327 int opApply(scope int delegate(V) dg) { 1328 if(dg is null) 1329 throw new NullPointerException(); 1330 1331 int result = 0; 1332 int mc = modCount; 1333 for (TreeMapEntry!(K, V) e = getFirstEntry(); e !is null; e = successor(e)) { 1334 result = dg(e.value); 1335 if(result != 0) return result; 1336 } 1337 1338 if(modCount != mc) 1339 throw new ConcurrentModificationException(); 1340 1341 return result; 1342 } 1343 1344 int opApply(scope int delegate(size_t, V) dg) { 1345 if(dg is null) 1346 throw new NullPointerException(); 1347 1348 int result = 0; 1349 int mc = modCount; 1350 size_t index = 0; 1351 for (TreeMapEntry!(K, V) e = getFirstEntry(); e !is null; e = successor(e)) { 1352 result = dg(index++, e.value); 1353 if(result != 0) return result; 1354 } 1355 1356 if(modCount != mc) 1357 throw new ConcurrentModificationException(); 1358 1359 return result; 1360 } 1361 } 1362 1363 // abstract class PrivateEntryIterator(T) : Iterator!T { 1364 // TreeMapEntry!(K,V) next; 1365 // TreeMapEntry!(K,V) lastReturned; 1366 // int expectedModCount; 1367 1368 // this(TreeMapEntry!(K,V) first) { 1369 // expectedModCount = modCount; 1370 // lastReturned = null; 1371 // next = first; 1372 // } 1373 1374 // final bool hasNext() { 1375 // return next !is null; 1376 // } 1377 1378 // final TreeMapEntry!(K,V) nextEntry() { 1379 // TreeMapEntry!(K,V) e = next; 1380 // if (e is null) 1381 // throw new NoSuchElementException(); 1382 // if (modCount !is expectedModCount) 1383 // throw new ConcurrentModificationException(); 1384 // next = successor(e); 1385 // lastReturned = e; 1386 // return e; 1387 // } 1388 1389 // final TreeMapEntry!(K,V) prevEntry() { 1390 // TreeMapEntry!(K,V) e = next; 1391 // if (e is null) 1392 // throw new NoSuchElementException(); 1393 // if (modCount !is expectedModCount) 1394 // throw new ConcurrentModificationException(); 1395 // next = predecessor(e); 1396 // lastReturned = e; 1397 // return e; 1398 // } 1399 1400 // void remove() { 1401 // if (lastReturned is null) 1402 // throw new IllegalStateException(); 1403 // if (modCount !is expectedModCount) 1404 // throw new ConcurrentModificationException(); 1405 // // deleted entries are replaced by their successors 1406 // if (lastReturned.left !is null && lastReturned.right !is null) 1407 // next = lastReturned; 1408 // deleteEntry(lastReturned); 1409 // expectedModCount = modCount; 1410 // lastReturned = null; 1411 // } 1412 // } 1413 1414 // final class EntryIterator : PrivateEntryIterator!(MapEntry!(K,V)) { 1415 // this(TreeMapEntry!(K,V) first) { 1416 // super(first); 1417 // } 1418 // MapEntry!(K,V) next() { 1419 // return nextEntry(); 1420 // } 1421 // } 1422 1423 // final class ValueIterator : PrivateEntryIterator!V { 1424 // this(TreeMapEntry!(K,V) first) { 1425 // super(first); 1426 // } 1427 // V next() { 1428 // return nextEntry().value; 1429 // } 1430 // } 1431 1432 // final class KeyIterator : PrivateEntryIterator!K { 1433 // this(TreeMapEntry!(K,V) first) { 1434 // super(first); 1435 // } 1436 // K next() { 1437 // return nextEntry().key; 1438 // } 1439 // } 1440 1441 // final class DescendingKeyIterator : PrivateEntryIterator!K { 1442 // this(TreeMapEntry!(K,V) first) { 1443 // super(first); 1444 // } 1445 // K next() { 1446 // return prevEntry().key; 1447 // } 1448 1449 // override void remove() { 1450 // if (lastReturned is null) 1451 // throw new IllegalStateException(); 1452 // if (modCount !is expectedModCount) 1453 // throw new ConcurrentModificationException(); 1454 // deleteEntry(lastReturned); 1455 // lastReturned = null; 1456 // expectedModCount = modCount; 1457 // } 1458 // } 1459 1460 /** 1461 * Compares two keys using the correct comparison method for this TreeMap. 1462 */ 1463 // final private int compare(K k1, K k2) { 1464 // if(k1 == k2) return 0; 1465 // else if(k1 > k2) return 1; 1466 // else return -1; 1467 // } 1468 1469 1470 // SubMaps 1471 1472 /** 1473 * Dummy value serving as unmatchable fence key for unbounded 1474 * SubMapIterators 1475 */ 1476 // private __gshared Object UNBOUNDED; 1477 1478 // shared static this() 1479 // { 1480 // UNBOUNDED = new Object(); 1481 // } 1482 1483 /** 1484 * This class exists solely for the sake of serialization 1485 * compatibility with previous releases of TreeMap that did not 1486 * support NavigableMap. It translates an old-version SubMap into 1487 * a new-version AscendingSubMap. This class is never otherwise 1488 * used. 1489 */ 1490 private class SubMap : AbstractMap!(K,V), SortedMap!(K,V) { 1491 1492 private bool fromStart = false, toEnd = false; 1493 private K fromKey, toKey; 1494 // private Object readResolve() { 1495 // return new AscendingSubMap<>(TreeMap.this, 1496 // fromStart, fromKey, true, 1497 // toEnd, toKey, false); 1498 // } 1499 Set!(MapEntry!(K,V)) entrySet() { throw new InternalError(); } 1500 K lastKey() { throw new InternalError(); } 1501 K firstKey() { throw new InternalError(); } 1502 SortedMap!(K,V) subMap(K fromKey, K toKey) { throw new InternalError(); } 1503 SortedMap!(K,V) headMap(K toKey) { throw new InternalError(); } 1504 SortedMap!(K,V) tailMap(K fromKey) { throw new InternalError(); } 1505 Comparator!K comparator() { throw new InternalError(); } 1506 1507 1508 override bool opEquals(IObject o) { 1509 return opEquals(cast(Object) o); 1510 } 1511 1512 override bool opEquals(Object o) { 1513 return super.opEquals(o); 1514 } 1515 1516 override size_t toHash() @trusted nothrow { 1517 return super.toHash(); 1518 } 1519 1520 override string toString() { 1521 return super.toString(); 1522 } 1523 1524 override K[] keySet() { 1525 return super.keySet(); 1526 } 1527 1528 override V[] values() { 1529 return super.values; 1530 } 1531 1532 override Object clone() { 1533 return super.clone(); 1534 } 1535 } 1536 1537 1538 /** 1539 * Returns the first Entry in the TreeMap (according to the TreeMap's 1540 * key-sort function). Returns null if the TreeMap is empty. 1541 */ 1542 final TreeMapEntry!(K,V) getFirstEntry() { 1543 TreeMapEntry!(K,V) p = root; 1544 if (p !is null) 1545 while (p.left !is null) 1546 p = p.left; 1547 return p; 1548 } 1549 1550 /** 1551 * Returns the last Entry in the TreeMap (according to the TreeMap's 1552 * key-sort function). Returns null if the TreeMap is empty. 1553 */ 1554 final TreeMapEntry!(K,V) getLastEntry() { 1555 TreeMapEntry!(K,V) p = root; 1556 if (p !is null) 1557 while (p.right !is null) 1558 p = p.right; 1559 return p; 1560 } 1561 1562 1563 1564 /** 1565 * Balancing operations. 1566 * 1567 * Implementations of rebalancings during insertion and deletion are 1568 * slightly different than the CLR version. Rather than using dummy 1569 * nilnodes, we use a set of accessors that deal properly with null. They 1570 * are used to avoid messiness surrounding nullness checks in the main 1571 * algorithms. 1572 */ 1573 1574 private static bool colorOf(K,V)(TreeMapEntry!(K,V) p) { 1575 return (p is null ? BLACK : p.color); 1576 } 1577 1578 private static TreeMapEntry!(K,V) parentOf(K,V)(TreeMapEntry!(K,V) p) { 1579 return (p is null ? null: p.parent); 1580 } 1581 1582 private static void setColor(K,V)(TreeMapEntry!(K,V) p, bool c) { 1583 if (p !is null) 1584 p.color = c; 1585 } 1586 1587 private static TreeMapEntry!(K,V) leftOf(K,V)(TreeMapEntry!(K,V) p) { 1588 return (p is null) ? null: p.left; 1589 } 1590 1591 private static TreeMapEntry!(K,V) rightOf(K,V)(TreeMapEntry!(K,V) p) { 1592 return (p is null) ? null: p.right; 1593 } 1594 1595 /** From CLR */ 1596 private void rotateLeft(TreeMapEntry!(K,V) p) { 1597 if (p !is null) { 1598 TreeMapEntry!(K,V) r = p.right; 1599 p.right = r.left; 1600 if (r.left !is null) 1601 r.left.parent = p; 1602 r.parent = p.parent; 1603 if (p.parent is null) 1604 root = r; 1605 else if (p.parent.left == p) 1606 p.parent.left = r; 1607 else 1608 p.parent.right = r; 1609 r.left = p; 1610 p.parent = r; 1611 } 1612 } 1613 1614 /** From CLR */ 1615 private void rotateRight(TreeMapEntry!(K,V) p) { 1616 if (p !is null) { 1617 TreeMapEntry!(K,V) l = p.left; 1618 p.left = l.right; 1619 if (l.right !is null) l.right.parent = p; 1620 l.parent = p.parent; 1621 if (p.parent is null) 1622 root = l; 1623 else if (p.parent.right == p) 1624 p.parent.right = l; 1625 else p.parent.left = l; 1626 l.right = p; 1627 p.parent = l; 1628 } 1629 } 1630 1631 /** From CLR */ 1632 private void fixAfterInsertion(TreeMapEntry!(K,V) x) { 1633 x.color = RED; 1634 1635 while (x !is null && x !is root && x.parent.color == RED) { 1636 if (parentOf(x) == leftOf(parentOf(parentOf(x)))) { 1637 TreeMapEntry!(K,V) y = rightOf(parentOf(parentOf(x))); 1638 if (colorOf(y) == RED) { 1639 setColor(parentOf(x), BLACK); 1640 setColor(y, BLACK); 1641 setColor(parentOf(parentOf(x)), RED); 1642 x = parentOf(parentOf(x)); 1643 } else { 1644 if (x == rightOf(parentOf(x))) { 1645 x = parentOf(x); 1646 rotateLeft(x); 1647 } 1648 setColor(parentOf(x), BLACK); 1649 setColor(parentOf(parentOf(x)), RED); 1650 rotateRight(parentOf(parentOf(x))); 1651 } 1652 } else { 1653 TreeMapEntry!(K,V) y = leftOf(parentOf(parentOf(x))); 1654 if (colorOf(y) == RED) { 1655 setColor(parentOf(x), BLACK); 1656 setColor(y, BLACK); 1657 setColor(parentOf(parentOf(x)), RED); 1658 x = parentOf(parentOf(x)); 1659 } else { 1660 if (x == leftOf(parentOf(x))) { 1661 x = parentOf(x); 1662 rotateRight(x); 1663 } 1664 setColor(parentOf(x), BLACK); 1665 setColor(parentOf(parentOf(x)), RED); 1666 rotateLeft(parentOf(parentOf(x))); 1667 } 1668 } 1669 } 1670 root.color = BLACK; 1671 } 1672 1673 /** 1674 * Delete node p, and then rebalance the tree. 1675 */ 1676 private void deleteEntry(TreeMapEntry!(K,V) p) { 1677 modCount++; 1678 _size--; 1679 1680 // If strictly internal, copy successor's element to p and then make p 1681 // point to successor. 1682 if (p.left !is null && p.right !is null) { 1683 TreeMapEntry!(K,V) s = successor(p); 1684 p.key = s.key; 1685 p.value = s.value; 1686 p = s; 1687 } // p has 2 children 1688 1689 // Start fixup at replacement node, if it exists. 1690 TreeMapEntry!(K,V) replacement = (p.left !is null ? p.left : p.right); 1691 1692 if (replacement !is null) { 1693 // Link replacement to parent 1694 replacement.parent = p.parent; 1695 if (p.parent is null) 1696 root = replacement; 1697 else if (p == p.parent.left) 1698 p.parent.left = replacement; 1699 else 1700 p.parent.right = replacement; 1701 1702 // Null out links so they are OK to use by fixAfterDeletion. 1703 p.left = p.right = p.parent = null; 1704 1705 // Fix replacement 1706 if (p.color == BLACK) 1707 fixAfterDeletion(replacement); 1708 } else if (p.parent is null) { // return if we are the only node. 1709 root = null; 1710 } else { // No children. Use self as phantom replacement and unlink. 1711 if (p.color == BLACK) 1712 fixAfterDeletion(p); 1713 1714 if (p.parent !is null) { 1715 if (p == p.parent.left) 1716 p.parent.left = null; 1717 else if (p == p.parent.right) 1718 p.parent.right = null; 1719 p.parent = null; 1720 } 1721 } 1722 } 1723 1724 /** From CLR */ 1725 private void fixAfterDeletion(TreeMapEntry!(K,V) x) { 1726 while (x !is root && colorOf(x) == BLACK) { 1727 if (x == leftOf(parentOf(x))) { 1728 TreeMapEntry!(K,V) sib = rightOf(parentOf(x)); 1729 1730 if (colorOf(sib) == RED) { 1731 setColor(sib, BLACK); 1732 setColor(parentOf(x), RED); 1733 rotateLeft(parentOf(x)); 1734 sib = rightOf(parentOf(x)); 1735 } 1736 1737 if (colorOf(leftOf(sib)) == BLACK && 1738 colorOf(rightOf(sib)) == BLACK) { 1739 setColor(sib, RED); 1740 x = parentOf(x); 1741 } else { 1742 if (colorOf(rightOf(sib)) == BLACK) { 1743 setColor(leftOf(sib), BLACK); 1744 setColor(sib, RED); 1745 rotateRight(sib); 1746 sib = rightOf(parentOf(x)); 1747 } 1748 setColor(sib, colorOf(parentOf(x))); 1749 setColor(parentOf(x), BLACK); 1750 setColor(rightOf(sib), BLACK); 1751 rotateLeft(parentOf(x)); 1752 x = root; 1753 } 1754 } else { // symmetric 1755 TreeMapEntry!(K,V) sib = leftOf(parentOf(x)); 1756 1757 if (colorOf(sib) == RED) { 1758 setColor(sib, BLACK); 1759 setColor(parentOf(x), RED); 1760 rotateRight(parentOf(x)); 1761 sib = leftOf(parentOf(x)); 1762 } 1763 1764 if (colorOf(rightOf(sib)) == BLACK && 1765 colorOf(leftOf(sib)) == BLACK) { 1766 setColor(sib, RED); 1767 x = parentOf(x); 1768 } else { 1769 if (colorOf(leftOf(sib)) == BLACK) { 1770 setColor(rightOf(sib), BLACK); 1771 setColor(sib, RED); 1772 rotateLeft(sib); 1773 sib = leftOf(parentOf(x)); 1774 } 1775 setColor(sib, colorOf(parentOf(x))); 1776 setColor(parentOf(x), BLACK); 1777 setColor(leftOf(sib), BLACK); 1778 rotateRight(parentOf(x)); 1779 x = root; 1780 } 1781 } 1782 } 1783 1784 setColor(x, BLACK); 1785 } 1786 1787 // private static final long serialVersionUID = 919286545866124006L; 1788 1789 /** 1790 * Save the state of the {@code TreeMap} instance to a stream (i.e., 1791 * serialize it). 1792 * 1793 * @serialData The <em>size</em> of the TreeMap (the number of key-value 1794 * mappings) is emitted (int), followed by the key (Object) 1795 * and value (Object) for each key-value mapping represented 1796 * by the TreeMap. The key-value mappings are emitted in 1797 * key-order (as determined by the TreeMap's Comparator, 1798 * or by the keys' natural ordering if the TreeMap has no 1799 * Comparator). 1800 */ 1801 // private void writeObject(java.io.ObjectOutputStream s) 1802 // throws java.io.IOException { 1803 // // Write out the Comparator and any hidden stuff 1804 // s.defaultWriteObject(); 1805 1806 // // Write out size (number of Mappings) 1807 // s.writeInt(size); 1808 1809 // // Write out keys and values (alternating) 1810 // for (Iterator!(MapEntry!(K,V)) i = entrySet().iterator(); i.hasNext(); ) { 1811 // MapEntry!(K,V) e = i.next(); 1812 // s.writeObject(e.getKey()); 1813 // s.writeObject(e.getValue()); 1814 // } 1815 // } 1816 1817 /** 1818 * Reconstitute the {@code TreeMap} instance from a stream (i.e., 1819 * deserialize it). 1820 */ 1821 // private void readObject(final java.io.ObjectInputStream s) 1822 // throws java.io.IOException, ClassNotFoundException { 1823 // // Read in the Comparator and any hidden stuff 1824 // s.defaultReadObject(); 1825 1826 // // Read in size 1827 // int size = s.readInt(); 1828 1829 // buildFromSorted(size, null, s, null); 1830 // } 1831 1832 /** Intended to be called only from TreeSet.readObject */ 1833 // void readTreeSet(int size, java.io.ObjectInputStream s, V defaultVal) { 1834 // buildFromSorted(size, null, s, defaultVal); 1835 // } 1836 1837 /** Intended to be called only from TreeSet.addAll */ 1838 // void addAllForTreeSet(SortedSet!K set, V defaultVal) { 1839 // try { 1840 // buildFromSorted(set.size(), set.iterator(), null, defaultVal); 1841 // } catch (IOException cannotHappen) { 1842 // } catch (ClassNotFoundException cannotHappen) { 1843 // } 1844 // } 1845 1846 1847 /** 1848 * Linear time tree building algorithm from sorted data. Can accept keys 1849 * and/or values from iterator or stream. This leads to too many 1850 * parameters, but seems better than alternatives. The four formats 1851 * that this method accepts are: 1852 * 1853 * 1) An iterator of Map.Entries. (it !is null, defaultVal is null). 1854 * 2) An iterator of keys. (it !is null, defaultVal !is null). 1855 * 3) A stream of alternating serialized keys and values. 1856 * (it is null, defaultVal is null). 1857 * 4) A stream of serialized keys. (it is null, defaultVal !is null). 1858 * 1859 * It is assumed that the comparator of the TreeMap is already set prior 1860 * to calling this method. 1861 * 1862 * @param size the number of keys (or key-value pairs) to be read from 1863 * the iterator or stream 1864 * @param it If non-null, new entries are created from entries 1865 * or keys read from this iterator. 1866 * @param str If non-null, new entries are created from keys and 1867 * possibly values read from this stream in serialized form. 1868 * Exactly one of it and str should be non-null. 1869 * @param defaultVal if non-null, this default value is used for 1870 * each value in the map. If null, each value is read from 1871 * iterator or stream, as described above. 1872 * @throws java.io.IOException propagated from stream reads. This cannot 1873 * occur if str is null. 1874 * @throws ClassNotFoundException propagated from readObject. 1875 * This cannot occur if str is null. 1876 */ 1877 // private void buildFromSorted(int size, Iterator<?> it, 1878 // // java.io.ObjectInputStream str, 1879 // V defaultVal) { 1880 // this._size = size; 1881 // root = buildFromSorted(0, 0, size-1, computeRedLevel(size), 1882 // it, defaultVal); 1883 // } 1884 1885 /** 1886 * Recursive "helper method" that does the real work of the 1887 * previous method. Identically named parameters have 1888 * identical definitions. Additional parameters are documented below. 1889 * It is assumed that the comparator and size fields of the TreeMap are 1890 * already set prior to calling this method. (It ignores both fields.) 1891 * 1892 * @param level the current level of tree. Initial call should be 0. 1893 * @param lo the first element index of this subtree. Initial should be 0. 1894 * @param hi the last element index of this subtree. Initial should be 1895 * size-1. 1896 * @param redLevel the level at which nodes should be red. 1897 * Must be equal to computeRedLevel for tree of this size. 1898 */ 1899 // private final TreeMapEntry!(K,V) buildFromSorted(int level, int lo, int hi, 1900 // int redLevel, 1901 // Iterator<?> it, 1902 // // java.io.ObjectInputStream str, 1903 // V defaultVal) { 1904 // /* 1905 // * Strategy: The root is the middlemost element. To get to it, we 1906 // * have to first recursively construct the entire left subtree, 1907 // * so as to grab all of its elements. We can then proceed with right 1908 // * subtree. 1909 // * 1910 // * The lo and hi arguments are the minimum and maximum 1911 // * indices to pull out of the iterator or stream for current subtree. 1912 // * They are not actually indexed, we just proceed sequentially, 1913 // * ensuring that items are extracted in corresponding order. 1914 // */ 1915 1916 // if (hi < lo) return null; 1917 1918 // int mid = (lo + hi) >>> 1; 1919 1920 // TreeMapEntry!(K,V) left = null; 1921 // if (lo < mid) 1922 // left = buildFromSorted(level+1, lo, mid - 1, redLevel, 1923 // it, str, defaultVal); 1924 1925 // // extract key and/or value from iterator or stream 1926 // K key; 1927 // V value; 1928 // if (it !is null) { 1929 // if (defaultVal is null) { 1930 // MapEntry<?,?> entry = (MapEntry<?,?>)it.next(); 1931 // key = (K)entry.getKey(); 1932 // value = (V)entry.getValue(); 1933 // } else { 1934 // key = (K)it.next(); 1935 // value = defaultVal; 1936 // } 1937 // } else { // use stream 1938 // key = (K) str.readObject(); 1939 // value = (defaultVal !is null ? defaultVal : (V) str.readObject()); 1940 // } 1941 1942 // TreeMapEntry!(K,V) middle = new Entry<>(key, value, null); 1943 1944 // // color nodes in non-full bottommost level red 1945 // if (level == redLevel) 1946 // middle.color = RED; 1947 1948 // if (left !is null) { 1949 // middle.left = left; 1950 // left.parent = middle; 1951 // } 1952 1953 // if (mid < hi) { 1954 // TreeMapEntry!(K,V) right = buildFromSorted(level+1, mid+1, hi, redLevel, 1955 // it, str, defaultVal); 1956 // middle.right = right; 1957 // right.parent = middle; 1958 // } 1959 1960 // return middle; 1961 // } 1962 1963 /** 1964 * Find the level down to which to assign all nodes BLACK. This is the 1965 * last `full' level of the complete binary tree produced by 1966 * buildTree. The remaining nodes are colored RED. (This makes a `nice' 1967 * set of color assignments wrt future insertions.) This level number is 1968 * computed by finding the number of splits needed to reach the zeroeth 1969 * node. (The answer is ~lg(N), but in any case must be computed by same 1970 * quick O(lg(N)) loop.) 1971 */ 1972 private static int computeRedLevel(int sz) { 1973 int level = 0; 1974 for (int m = sz - 1; m >= 0; m = m / 2 - 1) 1975 level++; 1976 return level; 1977 } 1978 1979 /** 1980 * Currently, we support Spliterator-based versions only for the 1981 * full map, in either plain of descending form, otherwise relying 1982 * on defaults because size estimation for submaps would dominate 1983 * costs. The type tests needed to check these for key views are 1984 * not very nice but avoid disrupting existing class 1985 * structures. Callers must use plain default spliterators if this 1986 * returns null. 1987 */ 1988 // static !K Spliterator!K keySpliteratorFor(NavigableMap<K,?> m) { 1989 // if (m instanceof TreeMap) { 1990 // TreeMap<K,Object> t = 1991 // (TreeMap<K,Object>) m; 1992 // return t.keySpliterator(); 1993 // } 1994 // if (m instanceof DescendingSubMap) { 1995 // DescendingSubMap<K,?> dm = 1996 // (DescendingSubMap<K,?>) m; 1997 // TreeMap<K,?> tm = dm.m; 1998 // if (dm == tm.descendingMap) { 1999 // TreeMap<K,Object> t = 2000 // (TreeMap<K,Object>) tm; 2001 // return t.descendingKeySpliterator(); 2002 // } 2003 // } 2004 // NavigableSubMap<K,?> sm = 2005 // (NavigableSubMap<K,?>) m; 2006 // return sm.keySpliterator(); 2007 // } 2008 2009 // final Spliterator!K keySpliterator() { 2010 // return new KeySpliterator!(K,V)(this, null, null, 0, -1, 0); 2011 // } 2012 2013 // final Spliterator!K descendingKeySpliterator() { 2014 // return new DescendingKeySpliterator!(K,V)(this, null, null, 0, -2, 0); 2015 // } 2016 2017 /** 2018 * Base class for spliterators. Iteration starts at a given 2019 * origin and continues up to but not including a given fence (or 2020 * null for end). At top-level, for ascending cases, the first 2021 * split uses the root as left-fence/right-origin. From there, 2022 * right-hand splits replace the current fence with its left 2023 * child, also serving as origin for the split-off spliterator. 2024 * Left-hands are symmetric. Descending versions place the origin 2025 * at the end and invert ascending split rules. This base class 2026 * is non-commital about directionality, or whether the top-level 2027 * spliterator covers the whole tree. This means that the actual 2028 * split mechanics are located in subclasses. Some of the subclass 2029 * trySplit methods are identical (except for return types), but 2030 * not nicely factorable. 2031 * 2032 * Currently, subclass versions exist only for the full map 2033 * (including descending keys via its descendingMap). Others are 2034 * possible but currently not worthwhile because submaps require 2035 * O(n) computations to determine size, which substantially limits 2036 * potential speed-ups of using custom Spliterators versus default 2037 * mechanics. 2038 * 2039 * To boostrap initialization, external constructors use 2040 * negative size estimates: -1 for ascend, -2 for descend. 2041 */ 2042 // static class TreeMapSpliterator!(K,V) { 2043 // final TreeMap!(K,V) tree; 2044 // TreeMapEntry!(K,V) current; // traverser; initially first node in range 2045 // TreeMapEntry!(K,V) fence; // one past last, or null 2046 // int side; // 0: top, -1: is a left split, +1: right 2047 // int est; // size estimate (exact only for top-level) 2048 // int expectedModCount; // for CME checks 2049 2050 // TreeMapSpliterator(TreeMap!(K,V) tree, 2051 // TreeMapEntry!(K,V) origin, TreeMapEntry!(K,V) fence, 2052 // int side, int est, int expectedModCount) { 2053 // this.tree = tree; 2054 // this.current = origin; 2055 // this.fence = fence; 2056 // this.side = side; 2057 // this.est = est; 2058 // this.expectedModCount = expectedModCount; 2059 // } 2060 2061 // final int getEstimate() { // force initialization 2062 // int s; TreeMap!(K,V) t; 2063 // if ((s = est) < 0) { 2064 // if ((t = tree) !is null) { 2065 // current = (s == -1) ? t.getFirstEntry() : t.getLastEntry(); 2066 // s = est = t.size; 2067 // expectedModCount = t.modCount; 2068 // } 2069 // else 2070 // s = est = 0; 2071 // } 2072 // return s; 2073 // } 2074 2075 // final long estimateSize() { 2076 // return (long)getEstimate(); 2077 // } 2078 // } 2079 2080 // static final class KeySpliterator!(K,V) 2081 // : TreeMapSpliterator!(K,V) 2082 // , Spliterator!K { 2083 // KeySpliterator(TreeMap!(K,V) tree, 2084 // TreeMapEntry!(K,V) origin, TreeMapEntry!(K,V) fence, 2085 // int side, int est, int expectedModCount) { 2086 // super(tree, origin, fence, side, est, expectedModCount); 2087 // } 2088 2089 // KeySpliterator!(K,V) trySplit() { 2090 // if (est < 0) 2091 // getEstimate(); // force initialization 2092 // int d = side; 2093 // TreeMapEntry!(K,V) e = current, f = fence, 2094 // s = ((e is null || e == f) ? null : // empty 2095 // (d == 0) ? tree.root : // was top 2096 // (d > 0) ? e.right : // was right 2097 // (d < 0 && f !is null) ? f.left : // was left 2098 // null); 2099 // if (s !is null && s !is e && s !is f && 2100 // tree.compare(e.key, s.key) < 0) { // e not already past s 2101 // side = 1; 2102 // return new KeySpliterator<> 2103 // (tree, e, current = s, -1, est >>>= 1, expectedModCount); 2104 // } 2105 // return null; 2106 // } 2107 2108 // void forEachRemaining(Consumer!K action) { 2109 // if (action is null) 2110 // throw new NullPointerException(); 2111 // if (est < 0) 2112 // getEstimate(); // force initialization 2113 // TreeMapEntry!(K,V) f = fence, e, p, pl; 2114 // if ((e = current) !is null && e !is f) { 2115 // current = f; // exhaust 2116 // do { 2117 // action.accept(e.key); 2118 // if ((p = e.right) !is null) { 2119 // while ((pl = p.left) !is null) 2120 // p = pl; 2121 // } 2122 // else { 2123 // while ((p = e.parent) !is null && e == p.right) 2124 // e = p; 2125 // } 2126 // } while ((e = p) !is null && e !is f); 2127 // if (tree.modCount !is expectedModCount) 2128 // throw new ConcurrentModificationException(); 2129 // } 2130 // } 2131 2132 // bool tryAdvance(Consumer!K action) { 2133 // TreeMapEntry!(K,V) e; 2134 // if (action is null) 2135 // throw new NullPointerException(); 2136 // if (est < 0) 2137 // getEstimate(); // force initialization 2138 // if ((e = current) is null || e == fence) 2139 // return false; 2140 // current = successor(e); 2141 // action.accept(e.key); 2142 // if (tree.modCount !is expectedModCount) 2143 // throw new ConcurrentModificationException(); 2144 // return true; 2145 // } 2146 2147 // int characteristics() { 2148 // return (side == 0 ? Spliterator.SIZED : 0) | 2149 // Spliterator.DISTINCT | Spliterator.SORTED | Spliterator.ORDERED; 2150 // } 2151 2152 // final Comparator!K getComparator() { 2153 // return tree.comparator; 2154 // } 2155 2156 // } 2157 2158 // static final class DescendingKeySpliterator!(K,V) 2159 // : TreeMapSpliterator!(K,V) 2160 // , Spliterator!K { 2161 // DescendingKeySpliterator(TreeMap!(K,V) tree, 2162 // TreeMapEntry!(K,V) origin, TreeMapEntry!(K,V) fence, 2163 // int side, int est, int expectedModCount) { 2164 // super(tree, origin, fence, side, est, expectedModCount); 2165 // } 2166 2167 // DescendingKeySpliterator!(K,V) trySplit() { 2168 // if (est < 0) 2169 // getEstimate(); // force initialization 2170 // int d = side; 2171 // TreeMapEntry!(K,V) e = current, f = fence, 2172 // s = ((e is null || e == f) ? null : // empty 2173 // (d == 0) ? tree.root : // was top 2174 // (d < 0) ? e.left : // was left 2175 // (d > 0 && f !is null) ? f.right : // was right 2176 // null); 2177 // if (s !is null && s !is e && s !is f && 2178 // tree.compare(e.key, s.key) > 0) { // e not already past s 2179 // side = 1; 2180 // return new DescendingKeySpliterator<> 2181 // (tree, e, current = s, -1, est >>>= 1, expectedModCount); 2182 // } 2183 // return null; 2184 // } 2185 2186 // void forEachRemaining(Consumer!K action) { 2187 // if (action is null) 2188 // throw new NullPointerException(); 2189 // if (est < 0) 2190 // getEstimate(); // force initialization 2191 // TreeMapEntry!(K,V) f = fence, e, p, pr; 2192 // if ((e = current) !is null && e !is f) { 2193 // current = f; // exhaust 2194 // do { 2195 // action.accept(e.key); 2196 // if ((p = e.left) !is null) { 2197 // while ((pr = p.right) !is null) 2198 // p = pr; 2199 // } 2200 // else { 2201 // while ((p = e.parent) !is null && e == p.left) 2202 // e = p; 2203 // } 2204 // } while ((e = p) !is null && e !is f); 2205 // if (tree.modCount !is expectedModCount) 2206 // throw new ConcurrentModificationException(); 2207 // } 2208 // } 2209 2210 // bool tryAdvance(Consumer!K action) { 2211 // TreeMapEntry!(K,V) e; 2212 // if (action is null) 2213 // throw new NullPointerException(); 2214 // if (est < 0) 2215 // getEstimate(); // force initialization 2216 // if ((e = current) is null || e == fence) 2217 // return false; 2218 // current = predecessor(e); 2219 // action.accept(e.key); 2220 // if (tree.modCount !is expectedModCount) 2221 // throw new ConcurrentModificationException(); 2222 // return true; 2223 // } 2224 2225 // int characteristics() { 2226 // return (side == 0 ? Spliterator.SIZED : 0) | 2227 // Spliterator.DISTINCT | Spliterator.ORDERED; 2228 // } 2229 // } 2230 2231 // static final class ValueSpliterator!(K,V) 2232 // : TreeMapSpliterator!(K,V) 2233 // , Spliterator!V { 2234 // ValueSpliterator(TreeMap!(K,V) tree, 2235 // TreeMapEntry!(K,V) origin, TreeMapEntry!(K,V) fence, 2236 // int side, int est, int expectedModCount) { 2237 // super(tree, origin, fence, side, est, expectedModCount); 2238 // } 2239 2240 // ValueSpliterator!(K,V) trySplit() { 2241 // if (est < 0) 2242 // getEstimate(); // force initialization 2243 // int d = side; 2244 // TreeMapEntry!(K,V) e = current, f = fence, 2245 // s = ((e is null || e == f) ? null : // empty 2246 // (d == 0) ? tree.root : // was top 2247 // (d > 0) ? e.right : // was right 2248 // (d < 0 && f !is null) ? f.left : // was left 2249 // null); 2250 // if (s !is null && s !is e && s !is f && 2251 // tree.compare(e.key, s.key) < 0) { // e not already past s 2252 // side = 1; 2253 // return new ValueSpliterator<> 2254 // (tree, e, current = s, -1, est >>>= 1, expectedModCount); 2255 // } 2256 // return null; 2257 // } 2258 2259 // void forEachRemaining(Consumer<V> action) { 2260 // if (action is null) 2261 // throw new NullPointerException(); 2262 // if (est < 0) 2263 // getEstimate(); // force initialization 2264 // TreeMapEntry!(K,V) f = fence, e, p, pl; 2265 // if ((e = current) !is null && e !is f) { 2266 // current = f; // exhaust 2267 // do { 2268 // action.accept(e.value); 2269 // if ((p = e.right) !is null) { 2270 // while ((pl = p.left) !is null) 2271 // p = pl; 2272 // } 2273 // else { 2274 // while ((p = e.parent) !is null && e == p.right) 2275 // e = p; 2276 // } 2277 // } while ((e = p) !is null && e !is f); 2278 // if (tree.modCount !is expectedModCount) 2279 // throw new ConcurrentModificationException(); 2280 // } 2281 // } 2282 2283 // bool tryAdvance(Consumer<V> action) { 2284 // TreeMapEntry!(K,V) e; 2285 // if (action is null) 2286 // throw new NullPointerException(); 2287 // if (est < 0) 2288 // getEstimate(); // force initialization 2289 // if ((e = current) is null || e == fence) 2290 // return false; 2291 // current = successor(e); 2292 // action.accept(e.value); 2293 // if (tree.modCount !is expectedModCount) 2294 // throw new ConcurrentModificationException(); 2295 // return true; 2296 // } 2297 2298 // int characteristics() { 2299 // return (side == 0 ? Spliterator.SIZED : 0) | Spliterator.ORDERED; 2300 // } 2301 // } 2302 2303 // static final class EntrySpliterator!(K,V) 2304 // : TreeMapSpliterator!(K,V) 2305 // , Spliterator!(MapEntry!(K,V)) { 2306 // EntrySpliterator(TreeMap!(K,V) tree, 2307 // TreeMapEntry!(K,V) origin, TreeMapEntry!(K,V) fence, 2308 // int side, int est, int expectedModCount) { 2309 // super(tree, origin, fence, side, est, expectedModCount); 2310 // } 2311 2312 // EntrySpliterator!(K,V) trySplit() { 2313 // if (est < 0) 2314 // getEstimate(); // force initialization 2315 // int d = side; 2316 // TreeMapEntry!(K,V) e = current, f = fence, 2317 // s = ((e is null || e == f) ? null : // empty 2318 // (d == 0) ? tree.root : // was top 2319 // (d > 0) ? e.right : // was right 2320 // (d < 0 && f !is null) ? f.left : // was left 2321 // null); 2322 // if (s !is null && s !is e && s !is f && 2323 // tree.compare(e.key, s.key) < 0) { // e not already past s 2324 // side = 1; 2325 // return new EntrySpliterator<> 2326 // (tree, e, current = s, -1, est >>>= 1, expectedModCount); 2327 // } 2328 // return null; 2329 // } 2330 2331 // void forEachRemaining(Consumer<MapEntry!(K, V)> action) { 2332 // if (action is null) 2333 // throw new NullPointerException(); 2334 // if (est < 0) 2335 // getEstimate(); // force initialization 2336 // TreeMapEntry!(K,V) f = fence, e, p, pl; 2337 // if ((e = current) !is null && e !is f) { 2338 // current = f; // exhaust 2339 // do { 2340 // action.accept(e); 2341 // if ((p = e.right) !is null) { 2342 // while ((pl = p.left) !is null) 2343 // p = pl; 2344 // } 2345 // else { 2346 // while ((p = e.parent) !is null && e == p.right) 2347 // e = p; 2348 // } 2349 // } while ((e = p) !is null && e !is f); 2350 // if (tree.modCount !is expectedModCount) 2351 // throw new ConcurrentModificationException(); 2352 // } 2353 // } 2354 2355 // bool tryAdvance(Consumer<MapEntry!(K,V)> action) { 2356 // TreeMapEntry!(K,V) e; 2357 // if (action is null) 2358 // throw new NullPointerException(); 2359 // if (est < 0) 2360 // getEstimate(); // force initialization 2361 // if ((e = current) is null || e == fence) 2362 // return false; 2363 // current = successor(e); 2364 // action.accept(e); 2365 // if (tree.modCount !is expectedModCount) 2366 // throw new ConcurrentModificationException(); 2367 // return true; 2368 // } 2369 2370 // int characteristics() { 2371 // return (side == 0 ? Spliterator.SIZED : 0) | 2372 // Spliterator.DISTINCT | Spliterator.SORTED | Spliterator.ORDERED; 2373 // } 2374 2375 // override 2376 // Comparator<MapEntry!(K, V)> getComparator() { 2377 // // Adapt or create a key-based comparator 2378 // if (tree.comparator !is null) { 2379 // return MapEntry.comparingByKey(tree.comparator); 2380 // } 2381 // else { 2382 // return (Comparator<MapEntry!(K, V)> & Serializable) (e1, e2) -> { 2383 // 2384 // Comparable!K k1 = (Comparable!K) e1.getKey(); 2385 // return k1.compareTo(e2.getKey()); 2386 // }; 2387 // } 2388 // } 2389 // } 2390 2391 override bool opEquals(IObject o) { 2392 return opEquals(cast(Object) o); 2393 } 2394 2395 override bool opEquals(Object o) { 2396 return super.opEquals(o); 2397 } 2398 2399 override size_t toHash() @trusted nothrow { 2400 return super.toHash(); 2401 } 2402 2403 override string toString() { 2404 return super.toString(); 2405 } 2406 2407 override Object clone() { 2408 return super.clone(); 2409 } 2410 } 2411 2412 2413 /** 2414 * Node in the Tree. Doubles as a means to pass key-value pairs back to 2415 * user (see MapEntry). 2416 */ 2417 final class TreeMapEntry(K,V) : AbstractMapEntry!(K,V) { 2418 TreeMapEntry!(K,V) left; 2419 TreeMapEntry!(K,V) right; 2420 TreeMapEntry!(K,V) parent; 2421 bool color = BLACK; 2422 2423 /** 2424 * Make a new cell with given key, value, and parent, and with 2425 * {@code null} child links, and BLACK color. 2426 */ 2427 this(K key, V value, TreeMapEntry!(K,V) parent) { 2428 super(key, value); 2429 this.parent = parent; 2430 } 2431 2432 override size_t toHash() @trusted nothrow { 2433 // int keyHash = (key is null ? 0 : key.hashCode()); 2434 // int valueHash = (value is null ? 0 : value.hashCode()); 2435 // return keyHash ^ valueHash; 2436 static if(is(K == class)) { 2437 size_t kHash = 0; 2438 if(key !is null) kHash = key.toHash(); 2439 } 2440 else { 2441 size_t kHash = hashOf(key); 2442 } 2443 2444 static if(is(V == class)) { 2445 size_t vHash = 0; 2446 if(value !is null) vHash = value.toHash(); 2447 } 2448 else { 2449 size_t vHash = hashOf(value); 2450 } 2451 2452 return kHash ^ vHash; 2453 } 2454 2455 } 2456 2457 2458 /** 2459 * @serial include 2460 */ 2461 abstract static class NavigableSubMap(K,V) : AbstractMap!(K,V) , NavigableMap!(K,V) { 2462 /** 2463 * The backing map. 2464 */ 2465 protected TreeMap!(K,V) m; 2466 2467 /** 2468 * Endpoints are represented as triples (fromStart, lo, 2469 * loInclusive) and (toEnd, hi, hiInclusive). If fromStart is 2470 * true, then the low (absolute) bound is the start of the 2471 * backing map, and the other values are ignored. Otherwise, 2472 * if loInclusive is true, lo is the inclusive bound, else lo 2473 * is the exclusive bound. Similarly for the upper bound. 2474 */ 2475 K lo, hi; 2476 bool fromStart, toEnd; 2477 bool loInclusive, hiInclusive; 2478 2479 int sizeModCount = 0; 2480 2481 this(TreeMap!(K,V) m, 2482 bool fromStart, K lo, bool loInclusive, 2483 bool toEnd, K hi, bool hiInclusive) { 2484 if (!fromStart && !toEnd) { 2485 if (compare(lo, hi) > 0) 2486 throw new IllegalArgumentException("fromKey > toKey"); 2487 } else { 2488 // if (!fromStart) // type check 2489 // compare(lo, lo); 2490 // if (!toEnd) 2491 // compare(hi, hi); 2492 } 2493 2494 this.m = m; 2495 this.fromStart = fromStart; 2496 this.lo = lo; 2497 this.loInclusive = loInclusive; 2498 this.toEnd = toEnd; 2499 this.hi = hi; 2500 this.hiInclusive = hiInclusive; 2501 2502 this._size = -1; 2503 // if(fromStart && toEnd) 2504 // this._size = m.size(); 2505 // else 2506 // updateSize(); 2507 } 2508 2509 // internal utilities 2510 2511 final bool tooLow(K key) { 2512 if (!fromStart) { 2513 int c = compare(key, lo); 2514 if (c < 0 || (c == 0 && !loInclusive)) 2515 return true; 2516 } 2517 return false; 2518 } 2519 2520 final bool tooHigh(K key) { 2521 if (!toEnd) { 2522 int c = compare(key, hi); 2523 if (c > 0 || (c == 0 && !hiInclusive)) 2524 return true; 2525 } 2526 return false; 2527 } 2528 2529 final bool inRange(K key) { 2530 return !tooLow(key) && !tooHigh(key); 2531 } 2532 2533 final bool inClosedRange(K key) { 2534 return (fromStart || compare(key, lo) >= 0) 2535 && (toEnd || compare(hi, key) >= 0); 2536 } 2537 2538 final bool inRange(K key, bool inclusive) { 2539 return inclusive ? inRange(key) : inClosedRange(key); 2540 } 2541 2542 /* 2543 * Absolute versions of relation operations. 2544 * Subclasses map to these using like-named "sub" 2545 * versions that invert senses for descending maps 2546 */ 2547 2548 final TreeMapEntry!(K,V) absLowest() { 2549 TreeMapEntry!(K,V) e = 2550 (fromStart ? m.getFirstEntry() : 2551 (loInclusive ? m.getCeilingEntry(lo) : 2552 m.getHigherEntry(lo))); 2553 return (e is null || tooHigh(e.key)) ? null : e; 2554 } 2555 2556 final TreeMapEntry!(K,V) absHighest() { 2557 TreeMapEntry!(K,V) e = 2558 (toEnd ? m.getLastEntry() : 2559 (hiInclusive ? m.getFloorEntry(hi) : 2560 m.getLowerEntry(hi))); 2561 return (e is null || tooLow(e.key)) ? null : e; 2562 } 2563 2564 final TreeMapEntry!(K,V) absCeiling(K key) { 2565 if (tooLow(key)) 2566 return absLowest(); 2567 TreeMapEntry!(K,V) e = m.getCeilingEntry(key); 2568 return (e is null || tooHigh(e.key)) ? null : e; 2569 } 2570 2571 final TreeMapEntry!(K,V) absHigher(K key) { 2572 if (tooLow(key)) 2573 return absLowest(); 2574 TreeMapEntry!(K,V) e = m.getHigherEntry(key); 2575 return (e is null || tooHigh(e.key)) ? null : e; 2576 } 2577 2578 final TreeMapEntry!(K,V) absFloor(K key) { 2579 if (tooHigh(key)) 2580 return absHighest(); 2581 TreeMapEntry!(K,V) e = m.getFloorEntry(key); 2582 return (e is null || tooLow(e.key)) ? null : e; 2583 } 2584 2585 final TreeMapEntry!(K,V) absLower(K key) { 2586 if (tooHigh(key)) 2587 return absHighest(); 2588 TreeMapEntry!(K,V) e = m.getLowerEntry(key); 2589 return (e is null || tooLow(e.key)) ? null : e; 2590 } 2591 2592 /** Returns the absolute high fence for ascending traversal */ 2593 final TreeMapEntry!(K,V) absHighFence() { 2594 return (toEnd ? null : (hiInclusive ? 2595 m.getHigherEntry(hi) : 2596 m.getCeilingEntry(hi))); 2597 } 2598 2599 /** Return the absolute low fence for descending traversal */ 2600 final TreeMapEntry!(K,V) absLowFence() { 2601 return (fromStart ? null : (loInclusive ? 2602 m.getLowerEntry(lo) : 2603 m.getFloorEntry(lo))); 2604 } 2605 2606 // Abstract methods defined in ascending vs descending classes 2607 // These relay to the appropriate absolute versions 2608 2609 abstract TreeMapEntry!(K,V) subLowest(); 2610 abstract TreeMapEntry!(K,V) subHighest(); 2611 abstract TreeMapEntry!(K,V) subCeiling(K key); 2612 abstract TreeMapEntry!(K,V) subHigher(K key); 2613 abstract TreeMapEntry!(K,V) subFloor(K key); 2614 abstract TreeMapEntry!(K,V) subLower(K key); 2615 2616 /** Returns ascending iterator from the perspective of this submap */ 2617 // abstract Iterator!K keyIterator(); 2618 2619 // abstract Spliterator!K keySpliterator(); 2620 2621 /** Returns descending iterator from the perspective of this submap */ 2622 // abstract Iterator!K descendingKeyIterator(); 2623 2624 2625 // methods 2626 override bool opEquals(IObject o) { 2627 return opEquals(cast(Object) o); 2628 } 2629 2630 override bool opEquals(Object o) { 2631 return super.opEquals(o); 2632 } 2633 2634 override size_t toHash() @trusted nothrow { 2635 return super.toHash(); 2636 } 2637 2638 override string toString() { 2639 return super.toString(); 2640 } 2641 2642 override Object clone() { 2643 return super.clone(); 2644 } 2645 2646 override bool isEmpty() { 2647 if(fromStart && toEnd) 2648 return m.isEmpty(); 2649 else { 2650 TreeMapEntry!(K,V) n = absLowest(); 2651 return n is null || tooHigh(n.key); 2652 } 2653 } 2654 2655 override int size() { 2656 if(fromStart && toEnd) 2657 return m.size(); 2658 if(_size == -1 || sizeModCount != m.modCount) 2659 updateSize(); 2660 return _size; 2661 } 2662 2663 private void updateSize() { 2664 int s = 0; 2665 foreach(item; this) { 2666 s++; 2667 } 2668 _size = s; 2669 } 2670 2671 final override bool containsKey(K key) { 2672 return inRange(key) && m.containsKey(key); 2673 } 2674 2675 final override V put(K key, V value) { 2676 if (!inRange(key)) 2677 throw new IllegalArgumentException("key out of range"); 2678 // _size++; 2679 return m.put(key, value); 2680 } 2681 2682 final override V get(K key) { 2683 return !inRange(key) ? null : m.get(key); 2684 } 2685 2686 final override V remove(K key) { 2687 // _size--; 2688 return !inRange(key) ? null : m.remove(key); 2689 } 2690 2691 final MapEntry!(K,V) ceilingEntry(K key) { 2692 return exportEntry!(K,V)(subCeiling(key)); 2693 } 2694 2695 final K ceilingKey(K key) { 2696 return keyOrNull(subCeiling(key)); 2697 } 2698 2699 final MapEntry!(K,V) higherEntry(K key) { 2700 return exportEntry!(K,V)(subHigher(key)); 2701 } 2702 2703 final K higherKey(K key) { 2704 return keyOrNull(subHigher(key)); 2705 } 2706 2707 final MapEntry!(K,V) floorEntry(K key) { 2708 return exportEntry!(K,V)(subFloor(key)); 2709 } 2710 2711 final K floorKey(K key) { 2712 return keyOrNull(subFloor(key)); 2713 } 2714 2715 final MapEntry!(K,V) lowerEntry(K key) { 2716 return exportEntry!(K,V)(subLower(key)); 2717 } 2718 2719 final K lowerKey(K key) { 2720 return keyOrNull(subLower(key)); 2721 } 2722 2723 final K firstKey() { 2724 return key(subLowest()); 2725 } 2726 2727 final K lastKey() { 2728 return key(subHighest()); 2729 } 2730 2731 final MapEntry!(K,V) firstEntry() { 2732 return exportEntry!(K,V)(subLowest()); 2733 } 2734 2735 final MapEntry!(K,V) lastEntry() { 2736 return exportEntry!(K,V)(subHighest()); 2737 } 2738 2739 final MapEntry!(K,V) pollFirstEntry() { 2740 TreeMapEntry!(K,V) e = subLowest(); 2741 MapEntry!(K,V) result = exportEntry!(K,V)(e); 2742 if (e !is null) 2743 m.deleteEntry(e); 2744 return result; 2745 } 2746 2747 final MapEntry!(K,V) pollLastEntry() { 2748 TreeMapEntry!(K,V) e = subHighest(); 2749 MapEntry!(K,V) result = exportEntry!(K,V)(e); 2750 if (e !is null) 2751 m.deleteEntry(e); 2752 return result; 2753 } 2754 2755 // Views 2756 // NavigableMap!(K,V) descendingMapView; 2757 // EntrySetView entrySetView; 2758 // KeySet!(K, V) navigableKeySetView; 2759 2760 // final NavigableSet!K navigableKeySet() { 2761 // KeySet!(K, V) nksv = navigableKeySetView; 2762 // return (nksv !is null) ? nksv : 2763 // (navigableKeySetView = new TreeMap.KeySet!(K, V)(this)); 2764 // } 2765 2766 // final Set!K keySet() { 2767 // return navigableKeySet(); 2768 // } 2769 2770 // NavigableSet!K descendingKeySet() { 2771 // return descendingMap().navigableKeySet(); 2772 // } 2773 2774 alias subMap = NavigableMap!(K,V).subMap; 2775 alias headMap = NavigableMap!(K,V).headMap; 2776 alias tailMap = NavigableMap!(K,V).tailMap; 2777 2778 final SortedMap!(K,V) subMap(K fromKey, K toKey) { 2779 return subMap(fromKey, true, toKey, false); 2780 } 2781 2782 final SortedMap!(K,V) headMap(K toKey) { 2783 return headMap(toKey, false); 2784 } 2785 2786 final SortedMap!(K,V) tailMap(K fromKey) { 2787 return tailMap(fromKey, true); 2788 } 2789 2790 // View classes 2791 2792 // abstract class EntrySetView : AbstractSet!(MapEntry!(K,V)) { 2793 // private int _size = -1, sizeModCount; 2794 2795 // override int size() { 2796 // if (fromStart && toEnd) 2797 // return m.size(); 2798 // // if (_size == -1 || sizeModCount !is m.modCount) { 2799 // // sizeModCount = m.modCount; 2800 // // _size = 0; 2801 // // Iterator!K i = iterator(); 2802 // // while (i.hasNext()) { 2803 // // _size++; 2804 // // i.next(); 2805 // // } 2806 // // } 2807 // implementationMissing(); 2808 // return _size; 2809 // } 2810 2811 // override bool isEmpty() { 2812 // TreeMapEntry!(K,V) n = absLowest(); 2813 // return n is null || tooHigh(n.key); 2814 // } 2815 2816 // override bool contains(MapEntry!(K,V) entry) { 2817 // // MapEntry!(K,V) entry = cast(MapEntry!(K,V)) o; 2818 // // if (!(o instanceof MapEntry)) 2819 // // return false; 2820 // K key = entry.getKey(); 2821 // if (!inRange(key)) 2822 // return false; 2823 // TreeMapEntry!(K,V) node = m.getEntry(key); 2824 // return node !is null && 2825 // valEquals(node.getValue(), entry.getValue()); 2826 // } 2827 2828 // bool remove(MapEntry!(K,V) entry) { 2829 // // if (!(o instanceof MapEntry)) 2830 // // return false; 2831 // // MapEntry<?,?> entry = (MapEntry<?,?>) o; 2832 // K key = entry.getKey(); 2833 // if (!inRange(key)) 2834 // return false; 2835 // TreeMapEntry!(K,V) node = m.getEntry(key); 2836 // if (node !is null && valEquals(node.getValue(), 2837 // entry.getValue())) { 2838 // m.deleteEntry(node); 2839 // return true; 2840 // } 2841 // return false; 2842 // } 2843 // } 2844 2845 2846 /** 2847 * Iterators for SubMaps 2848 */ 2849 2850 // see also: SubMapIterator 2851 mixin template SubMapInputRange() { 2852 TreeMapEntry!(K,V) lastReturned; 2853 TreeMapEntry!(K,V) next; 2854 // K fenceKey; 2855 TreeMapEntry!(K,V) _fence; 2856 int expectedModCount; 2857 2858 this(TreeMapEntry!(K,V) first, 2859 TreeMapEntry!(K,V) fence) { 2860 expectedModCount = m.modCount; 2861 lastReturned = null; 2862 next = first; 2863 // fenceKey = fence is null ? K.init : fence.key; 2864 _fence = fence; 2865 } 2866 2867 final bool empty() { 2868 return next is null || (_fence !is null && next.key == _fence.key); 2869 } 2870 2871 final void popFront() { 2872 TreeMapEntry!(K,V) e = next; 2873 if (e is null || (_fence !is null && e.key == _fence.key)) { 2874 throw new NoSuchElementException(); 2875 } 2876 2877 next = successor(e); 2878 lastReturned = e; 2879 // return e; 2880 } 2881 } 2882 2883 final class KeyInputRange : InputRange!K { 2884 mixin SubMapInputRange; 2885 2886 final K front() @property { return next.key; } 2887 2888 final K moveFront() @property { throw new NotSupportedException(); } 2889 2890 int opApply(scope int delegate(K) dg) { 2891 if(dg is null) 2892 throw new NullPointerException(); 2893 2894 int result = 0; 2895 while(!empty()) { 2896 result = dg(next.key); 2897 // popFront(); 2898 if(result != 0) return result; 2899 next = successor(next); 2900 } 2901 2902 if (m.modCount != expectedModCount) 2903 throw new ConcurrentModificationException(); 2904 return result; 2905 } 2906 2907 int opApply(scope int delegate(size_t, K) dg) { 2908 if(dg is null) 2909 throw new NullPointerException(); 2910 2911 int result = 0; 2912 size_t index = 0; 2913 while(!empty()) { 2914 result = dg(index++, next.key); 2915 if(result != 0) return result; 2916 next = successor(next); 2917 } 2918 2919 if (m.modCount != expectedModCount) 2920 throw new ConcurrentModificationException(); 2921 2922 return result; 2923 } 2924 } 2925 2926 final class ValueInputRange : InputRange!V { 2927 mixin SubMapInputRange; 2928 2929 final V front() @property { return next.value; } 2930 2931 final V moveFront() @property { throw new NotSupportedException(); } 2932 2933 int opApply(scope int delegate(V) dg) { 2934 if(dg is null) 2935 throw new NullPointerException(); 2936 2937 int result = 0; 2938 while(!empty()) { 2939 result = dg(next.value); 2940 if(result != 0) return result; 2941 next = successor(next); 2942 } 2943 2944 if (m.modCount != expectedModCount) 2945 throw new ConcurrentModificationException(); 2946 return result; 2947 } 2948 2949 int opApply(scope int delegate(size_t, V) dg) { 2950 if(dg is null) 2951 throw new NullPointerException(); 2952 2953 int result = 0; 2954 size_t index = 0; 2955 while(!empty()) { 2956 result = dg(index++, next.value); 2957 if(result != 0) return result; 2958 next = successor(next); 2959 } 2960 2961 if (m.modCount != expectedModCount) 2962 throw new ConcurrentModificationException(); 2963 2964 return result; 2965 } 2966 } 2967 2968 2969 abstract class SubMapIterator(T) : Iterator!T { 2970 TreeMapEntry!(K,V) lastReturned; 2971 TreeMapEntry!(K,V) _next; 2972 // K fenceKey; 2973 TreeMapEntry!(K,V) _fence; 2974 int expectedModCount; 2975 2976 this(TreeMapEntry!(K,V) first, 2977 TreeMapEntry!(K,V) fence) { 2978 expectedModCount = m.modCount; 2979 lastReturned = null; 2980 _next = first; 2981 _fence = fence; 2982 } 2983 2984 final bool hasNext() { 2985 if(_fence is null) { 2986 return _next !is null; 2987 } else { 2988 return _next !is null && _next.key != _fence.key; 2989 } 2990 } 2991 2992 final TreeMapEntry!(K,V) nextEntry() { 2993 TreeMapEntry!(K,V) e = _next; 2994 if (e is null || ( _fence !is null && _next.key == _fence.key)) 2995 throw new NoSuchElementException(); 2996 2997 if (m.modCount != expectedModCount) 2998 throw new ConcurrentModificationException(); 2999 _next = successor(e); 3000 lastReturned = e; 3001 return e; 3002 } 3003 3004 final TreeMapEntry!(K,V) prevEntry() { 3005 TreeMapEntry!(K,V) e = _next; 3006 if (e is null || ( _fence !is null && _next.key == _fence.key)) 3007 throw new NoSuchElementException(); 3008 if (m.modCount != expectedModCount) 3009 throw new ConcurrentModificationException(); 3010 _next = predecessor(e); 3011 lastReturned = e; 3012 return e; 3013 } 3014 3015 final void removeAscending() { 3016 if (lastReturned is null) 3017 throw new IllegalStateException(); 3018 if (m.modCount !is expectedModCount) 3019 throw new ConcurrentModificationException(); 3020 // deleted entries are replaced by their successors 3021 if (lastReturned.left !is null && lastReturned.right !is null) 3022 _next = lastReturned; 3023 m.deleteEntry(lastReturned); 3024 lastReturned = null; 3025 expectedModCount = m.modCount; 3026 } 3027 3028 final void removeDescending() { 3029 if (lastReturned is null) 3030 throw new IllegalStateException(); 3031 if (m.modCount !is expectedModCount) 3032 throw new ConcurrentModificationException(); 3033 m.deleteEntry(lastReturned); 3034 lastReturned = null; 3035 expectedModCount = m.modCount; 3036 } 3037 3038 } 3039 3040 final class SubMapEntryIterator : SubMapIterator!(MapEntry!(K,V)) { 3041 this(TreeMapEntry!(K,V) first, 3042 TreeMapEntry!(K,V) fence) { 3043 super(first, fence); 3044 } 3045 MapEntry!(K,V) next() { 3046 return nextEntry(); 3047 } 3048 void remove() { 3049 removeAscending(); 3050 } 3051 } 3052 3053 final class DescendingSubMapEntryIterator : SubMapIterator!(MapEntry!(K,V)) { 3054 this(TreeMapEntry!(K,V) last, TreeMapEntry!(K,V) fence) { 3055 super(last, fence); 3056 } 3057 3058 MapEntry!(K,V) next() { 3059 return prevEntry(); 3060 } 3061 void remove() { 3062 removeDescending(); 3063 } 3064 } 3065 3066 // Implement minimal Spliterator as KeySpliterator backup 3067 final class SubMapKeyIterator : SubMapIterator!K { // , Spliterator!K 3068 this(TreeMapEntry!(K,V) first, 3069 TreeMapEntry!(K,V) fence) { 3070 super(first, fence); 3071 } 3072 K next() { 3073 return nextEntry().key; 3074 } 3075 void remove() { 3076 removeAscending(); 3077 } 3078 Spliterator!K trySplit() { 3079 return null; 3080 } 3081 void forEachRemaining(Consumer!K action) { 3082 while (hasNext()) 3083 action(next()); 3084 } 3085 bool tryAdvance(Consumer!K action) { 3086 if (hasNext()) { 3087 action(next()); 3088 return true; 3089 } 3090 return false; 3091 } 3092 long estimateSize() { 3093 return long.max; 3094 } 3095 int characteristics() { 3096 return SpliteratorCharacteristic.DISTINCT | SpliteratorCharacteristic.ORDERED | 3097 SpliteratorCharacteristic.SORTED; 3098 } 3099 final Comparator!K getComparator() { 3100 return this.outer.comparator(); 3101 } 3102 } 3103 3104 final class DescendingSubMapKeyIterator : SubMapIterator!K { // , Spliterator!K 3105 this(TreeMapEntry!(K,V) last, 3106 TreeMapEntry!(K,V) fence) { 3107 super(last, fence); 3108 } 3109 K next() { 3110 return prevEntry().key; 3111 } 3112 void remove() { 3113 removeDescending(); 3114 } 3115 Spliterator!K trySplit() { 3116 return null; 3117 } 3118 void forEachRemaining(Consumer!K action) { 3119 while (hasNext()) 3120 action(next()); 3121 } 3122 bool tryAdvance(Consumer!K action) { 3123 if (hasNext()) { 3124 action(next()); 3125 return true; 3126 } 3127 return false; 3128 } 3129 long estimateSize() { 3130 return long.max; 3131 } 3132 // int characteristics() { 3133 // return Spliterator.DISTINCT | Spliterator.ORDERED; 3134 // } 3135 } 3136 3137 3138 } 3139 3140 /** 3141 * @serial include 3142 */ 3143 final class AscendingSubMap(K,V) : NavigableSubMap!(K,V) { 3144 3145 this(TreeMap!(K,V) m, 3146 bool fromStart, K lo, bool loInclusive, 3147 bool toEnd, K hi, bool hiInclusive) { 3148 super(m, fromStart, lo, loInclusive, toEnd, hi, hiInclusive); 3149 } 3150 3151 Comparator!K comparator() { 3152 return m.comparator(); 3153 } 3154 3155 NavigableMap!(K,V) subMap(K fromKey, bool fromInclusive, 3156 K toKey, bool toInclusive) { 3157 if (!inRange(fromKey, fromInclusive)) 3158 throw new IllegalArgumentException("fromKey out of range"); 3159 if (!inRange(toKey, toInclusive)) 3160 throw new IllegalArgumentException("toKey out of range"); 3161 return new AscendingSubMap!(K,V)(m, 3162 false, fromKey, fromInclusive, 3163 false, toKey, toInclusive); 3164 } 3165 3166 NavigableMap!(K,V) headMap(K toKey, bool inclusive) { 3167 if (!inRange(toKey, inclusive)) 3168 throw new IllegalArgumentException("toKey out of range"); 3169 return new AscendingSubMap!(K,V)(m, 3170 fromStart, lo, loInclusive, 3171 false, toKey, inclusive); 3172 } 3173 3174 NavigableMap!(K,V) tailMap(K fromKey, bool inclusive) { 3175 if (!inRange(fromKey, inclusive)) 3176 throw new IllegalArgumentException("fromKey out of range"); 3177 return new AscendingSubMap!(K,V)(m, 3178 false, fromKey, inclusive, 3179 toEnd, hi, hiInclusive); 3180 } 3181 3182 // NavigableMap!(K,V) descendingMap() { 3183 // NavigableMap!(K,V) mv = descendingMapView; 3184 // return (mv !is null) ? mv : 3185 // (descendingMapView = 3186 // new DescendingSubMap!(K,V)(m, 3187 // fromStart, lo, loInclusive, 3188 // toEnd, hi, hiInclusive)); 3189 // } 3190 3191 override InputRange!K byKey() { 3192 return new KeyInputRange(absLowest(), absHighFence()); 3193 } 3194 3195 override InputRange!V byValue() { 3196 return new ValueInputRange(absLowest(), absHighFence()); 3197 } 3198 // override Iterator!K keyIterator() { 3199 // return new SubMapKeyIterator(absLowest(), absHighFence()); 3200 // } 3201 3202 // Spliterator!K keySpliterator() { 3203 // return new SubMapKeyIterator(absLowest(), absHighFence()); 3204 // } 3205 3206 // override Iterator!K descendingKeyIterator() { 3207 // return new DescendingSubMapKeyIterator(absHighest(), absLowFence()); 3208 // } 3209 3210 3211 override int opApply(scope int delegate(ref K, ref V) dg) { 3212 if(dg is null) 3213 throw new NullPointerException(); 3214 3215 int result = 0; 3216 Iterator!(MapEntry!(K,V)) iterator = new SubMapEntryIterator(absLowest(), absHighFence()); 3217 while(iterator.hasNext()) { 3218 TreeMapEntry!(K,V) e = cast(TreeMapEntry!(K,V)) iterator.next(); 3219 result = dg(e.key, e.value); 3220 if(result != 0) return result; 3221 } 3222 3223 return result; 3224 } 3225 3226 override int opApply(scope int delegate(MapEntry!(K, V) entry) dg) { 3227 if(dg is null) 3228 throw new NullPointerException(); 3229 3230 int result = 0; 3231 Iterator!(MapEntry!(K,V)) iterator = new SubMapEntryIterator(absLowest(), absHighFence()); 3232 while(iterator.hasNext()) { 3233 result = dg(iterator.next()); 3234 if(result != 0) return result; 3235 } 3236 3237 return result; 3238 } 3239 3240 // final class AscendingEntrySetView : EntrySetView { 3241 // Iterator!(MapEntry!(K,V)) iterator() { 3242 // return new SubMapEntryIterator(absLowest(), absHighFence()); 3243 // } 3244 // } 3245 3246 // Set!(MapEntry!(K,V)) entrySet() { 3247 // EntrySetView es = entrySetView; 3248 // return (es !is null) ? es : (entrySetView = new AscendingEntrySetView()); 3249 // } 3250 3251 override TreeMapEntry!(K,V) subLowest() { return absLowest(); } 3252 override TreeMapEntry!(K,V) subHighest() { return absHighest(); } 3253 override TreeMapEntry!(K,V) subCeiling(K key) { return absCeiling(key); } 3254 override TreeMapEntry!(K,V) subHigher(K key) { return absHigher(key); } 3255 override TreeMapEntry!(K,V) subFloor(K key) { return absFloor(key); } 3256 override TreeMapEntry!(K,V) subLower(K key) { return absLower(key); } 3257 } 3258 3259 /** 3260 * @serial include 3261 */ 3262 final class DescendingSubMap(K,V) : NavigableSubMap!(K,V) { 3263 // private static final long serialVersionUID = 912986545866120460L; 3264 this(TreeMap!(K,V) m, 3265 bool fromStart, K lo, bool loInclusive, 3266 bool toEnd, K hi, bool hiInclusive) { 3267 super(m, fromStart, lo, loInclusive, toEnd, hi, hiInclusive); 3268 3269 // reverseComparator = Collections.reverseOrder(m._comparator); 3270 } 3271 3272 private Comparator!K reverseComparator; 3273 3274 Comparator!K comparator() { 3275 implementationMissing(); 3276 return reverseComparator; 3277 } 3278 3279 NavigableMap!(K,V) subMap(K fromKey, bool fromInclusive, 3280 K toKey, bool toInclusive) { 3281 if (!inRange(fromKey, fromInclusive)) 3282 throw new IllegalArgumentException("fromKey out of range"); 3283 if (!inRange(toKey, toInclusive)) 3284 throw new IllegalArgumentException("toKey out of range"); 3285 return new DescendingSubMap!(K,V)(m, 3286 false, toKey, toInclusive, 3287 false, fromKey, fromInclusive); 3288 } 3289 3290 NavigableMap!(K,V) headMap(K toKey, bool inclusive) { 3291 if (!inRange(toKey, inclusive)) 3292 throw new IllegalArgumentException("toKey out of range"); 3293 return new DescendingSubMap!(K,V)(m, 3294 false, toKey, inclusive, 3295 toEnd, hi, hiInclusive); 3296 } 3297 3298 NavigableMap!(K,V) tailMap(K fromKey, bool inclusive) { 3299 if (!inRange(fromKey, inclusive)) 3300 throw new IllegalArgumentException("fromKey out of range"); 3301 return new DescendingSubMap!(K,V)(m, 3302 fromStart, lo, loInclusive, 3303 false, fromKey, inclusive); 3304 } 3305 3306 // NavigableMap!(K,V) descendingMap() { 3307 // NavigableMap!(K,V) mv = descendingMapView; 3308 // return (mv !is null) ? mv : 3309 // (descendingMapView = 3310 // new AscendingSubMap!(K,V)(m, 3311 // fromStart, lo, loInclusive, 3312 // toEnd, hi, hiInclusive)); 3313 // } 3314 3315 // override Iterator!K keyIterator() { 3316 // return new DescendingSubMapKeyIterator(absHighest(), absLowFence()); 3317 // } 3318 3319 // override Spliterator!K keySpliterator() { 3320 // return new DescendingSubMapKeyIterator(absHighest(), absLowFence()); 3321 // } 3322 3323 // override Iterator!K descendingKeyIterator() { 3324 // return new SubMapKeyIterator(absLowest(), absHighFence()); 3325 // } 3326 3327 // final class DescendingEntrySetView : EntrySetView { 3328 // Iterator!(MapEntry!(K,V)) iterator() { 3329 // return new DescendingSubMapEntryIterator(absHighest(), absLowFence()); 3330 // } 3331 // } 3332 3333 // Set!(MapEntry!(K,V)) entrySet() { 3334 // EntrySetView es = entrySetView; 3335 // return (es !is null) ? es : (entrySetView = new DescendingEntrySetView()); 3336 // } 3337 3338 override TreeMapEntry!(K,V) subLowest() { return absHighest(); } 3339 override TreeMapEntry!(K,V) subHighest() { return absLowest(); } 3340 override TreeMapEntry!(K,V) subCeiling(K key) { return absFloor(key); } 3341 override TreeMapEntry!(K,V) subHigher(K key) { return absLower(key); } 3342 override TreeMapEntry!(K,V) subFloor(K key) { return absCeiling(key); } 3343 override TreeMapEntry!(K,V) subLower(K key) { return absHigher(key); } 3344 } 3345 3346 3347 // Little utilities 3348 3349 /** 3350 * Returns the successor of the specified Entry, or null if no such. 3351 */ 3352 private TreeMapEntry!(K,V) successor(K,V)(TreeMapEntry!(K,V) t) { 3353 if (t is null) 3354 return null; 3355 else if (t.right !is null) { 3356 TreeMapEntry!(K,V) p = t.right; 3357 while (p.left !is null) 3358 p = p.left; 3359 return p; 3360 } else { 3361 TreeMapEntry!(K,V) p = t.parent; 3362 TreeMapEntry!(K,V) ch = t; 3363 while (p !is null && ch == p.right) { 3364 ch = p; 3365 p = p.parent; 3366 } 3367 return p; 3368 } 3369 } 3370 3371 /** 3372 * Returns the predecessor of the specified Entry, or null if no such. 3373 */ 3374 private TreeMapEntry!(K,V) predecessor(K,V)(TreeMapEntry!(K,V) t) { 3375 if (t is null) 3376 return null; 3377 else if (t.left !is null) { 3378 TreeMapEntry!(K,V) p = t.left; 3379 while (p.right !is null) 3380 p = p.right; 3381 return p; 3382 } else { 3383 TreeMapEntry!(K,V) p = t.parent; 3384 TreeMapEntry!(K,V) ch = t; 3385 while (p !is null && ch == p.left) { 3386 ch = p; 3387 p = p.parent; 3388 } 3389 return p; 3390 } 3391 } 3392 3393 3394 /** 3395 * Test two values for equality. Differs from o1.equals(o2) only in 3396 * that it copes with {@code null} o1 properly. 3397 */ 3398 private bool valEquals(V)(V o1, V o2) { 3399 // return (o1 is null ? o2 is null : o1.equals(o2)); 3400 return o1 == o2; 3401 } 3402 3403 /** 3404 * Return SimpleImmutableEntry for entry, or null if null 3405 */ 3406 private MapEntry!(K,V) exportEntry(K,V)(TreeMapEntry!(K,V) e) { 3407 return (e is null) ? null : 3408 new SimpleImmutableEntry!(K,V)(e); 3409 } 3410 3411 /** 3412 * Return key for entry, or null if null 3413 */ 3414 private K keyOrNull(K,V)(TreeMapEntry!(K,V) e) { 3415 return (e is null) ? K.init : e.key; 3416 } 3417 3418 /** 3419 * Returns the key corresponding to the specified Entry. 3420 * @throws NoSuchElementException if the Entry is null 3421 */ 3422 private K key(K, V)(TreeMapEntry!(K,V) e) { 3423 if (e is null) 3424 throw new NoSuchElementException(); 3425 return e.key; 3426 }