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.ArrayDeque; 13 14 /** 15 * Resizable-array implementation of the {@link Deque} interface. Array 16 * deques have no capacity restrictions; they grow as necessary to support 17 * usage. They are not thread-safe; in the absence of external 18 * synchronization, they do not support concurrent access by multiple threads. 19 * Null elements are prohibited. This class is likely to be faster than 20 * {@link Stack} when used as a stack, and faster than {@link LinkedList} 21 * when used as a queue. 22 * 23 * <p>Most {@code ArrayDeque} operations run in amortized constant time. 24 * Exceptions include {@link #remove(Object) remove}, {@link 25 * #removeFirstOccurrence removeFirstOccurrence}, {@link #removeLastOccurrence 26 * removeLastOccurrence}, {@link #contains contains}, {@link #iterator 27 * iterator.remove()}, and the bulk operations, all of which run in linear 28 * time. 29 * 30 * <p>The iterators returned by this class's {@code iterator} method are 31 * <i>fail-fast</i>: If the deque is modified at any time after the iterator 32 * is created, in any way except through the iterator's own {@code remove} 33 * method, the iterator will generally throw a {@link 34 * ConcurrentModificationException}. Thus, in the face of concurrent 35 * modification, the iterator fails quickly and cleanly, rather than risking 36 * arbitrary, non-deterministic behavior at an undetermined time in the 37 * future. 38 * 39 * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed 40 * as it is, generally speaking, impossible to make any hard guarantees in the 41 * presence of unsynchronized concurrent modification. Fail-fast iterators 42 * throw {@code ConcurrentModificationException} on a best-effort basis. 43 * Therefore, it would be wrong to write a program that depended on this 44 * exception for its correctness: <i>the fail-fast behavior of iterators 45 * should be used only to detect bugs.</i> 46 * 47 * <p>This class and its iterator implement all of the 48 * <em>optional</em> methods of the {@link Collection} and {@link 49 * Iterator} interfaces. 50 * 51 * <p>This class is a member of the 52 * <a href="{@docRoot}/../technotes/guides/collections/index.html"> 53 * Java Collections Framework</a>. 54 * 55 * @author Josh Bloch and Doug Lea 56 * @since 1.6 57 * @param !E the type of elements held in this collection 58 */ 59 // class ArrayDeque(E) : AbstractCollection!E 60 // , Deque!E, Cloneable, Serializable 61 // { 62 // /** 63 // * The array in which the elements of the deque are stored. 64 // * The capacity of the deque is the length of this array, which is 65 // * always a power of two. The array is never allowed to become 66 // * full, except transiently within an addX method where it is 67 // * resized (see doubleCapacity) immediately upon becoming full, 68 // * thus avoiding head and tail wrapping around to equal each 69 // * other. We also guarantee that all array cells not holding 70 // * deque elements are always null. 71 // */ 72 // Object[] elements; // non-private to simplify nested class access 73 74 // /** 75 // * The index of the element at the head of the deque (which is the 76 // * element that would be removed by remove() or pop()); or an 77 // * arbitrary number equal to tail if the deque is empty. 78 // */ 79 // int head; 80 81 // /** 82 // * The index at which the next element would be added to the tail 83 // * of the deque (via addLast(E), add(E), or push(E)). 84 // */ 85 // int tail; 86 87 // /** 88 // * The minimum capacity that we'll use for a newly created deque. 89 // * Must be a power of 2. 90 // */ 91 // private static final int MIN_INITIAL_CAPACITY = 8; 92 93 // // ****** Array allocation and resizing utilities ****** 94 95 // /** 96 // * Allocates empty array to hold the given number of elements. 97 // * 98 // * @param numElements the number of elements to hold 99 // */ 100 // private void allocateElements(int numElements) { 101 // int initialCapacity = MIN_INITIAL_CAPACITY; 102 // // Find the best power of two to hold elements. 103 // // Tests "<=" because arrays aren't kept full. 104 // if (numElements >= initialCapacity) { 105 // initialCapacity = numElements; 106 // initialCapacity |= (initialCapacity >>> 1); 107 // initialCapacity |= (initialCapacity >>> 2); 108 // initialCapacity |= (initialCapacity >>> 4); 109 // initialCapacity |= (initialCapacity >>> 8); 110 // initialCapacity |= (initialCapacity >>> 16); 111 // initialCapacity++; 112 113 // if (initialCapacity < 0) // Too many elements, must back off 114 // initialCapacity >>>= 1;// Good luck allocating 2 ^ 30 elements 115 // } 116 // elements = new Object[initialCapacity]; 117 // } 118 119 // /** 120 // * Doubles the capacity of this deque. Call only when full, i.e., 121 // * when head and tail have wrapped around to become equal. 122 // */ 123 // private void doubleCapacity() { 124 // assert head == tail; 125 // int p = head; 126 // int n = elements.length; 127 // int r = n - p; // number of elements to the right of p 128 // int newCapacity = n << 1; 129 // if (newCapacity < 0) 130 // throw new IllegalStateException("Sorry, deque too big"); 131 // Object[] a = new Object[newCapacity]; 132 // System.arraycopy(elements, p, a, 0, r); 133 // System.arraycopy(elements, 0, a, r, p); 134 // elements = a; 135 // head = 0; 136 // tail = n; 137 // } 138 139 // /** 140 // * Copies the elements from our element array into the specified array, 141 // * in order (from first to last element in the deque). It is assumed 142 // * that the array is large enough to hold all elements in the deque. 143 // * 144 // * @return its argument 145 // */ 146 // private !(T) T[] copyElements(T[] a) { 147 // if (head < tail) { 148 // System.arraycopy(elements, head, a, 0, size()); 149 // } else if (head > tail) { 150 // int headPortionLen = elements.length - head; 151 // System.arraycopy(elements, head, a, 0, headPortionLen); 152 // System.arraycopy(elements, 0, a, headPortionLen, tail); 153 // } 154 // return a; 155 // } 156 157 // /** 158 // * Constructs an empty array deque with an initial capacity 159 // * sufficient to hold 16 elements. 160 // */ 161 // ArrayDeque() { 162 // elements = new Object[16]; 163 // } 164 165 // /** 166 // * Constructs an empty array deque with an initial capacity 167 // * sufficient to hold the specified number of elements. 168 // * 169 // * @param numElements lower bound on initial capacity of the deque 170 // */ 171 // ArrayDeque(int numElements) { 172 // allocateElements(numElements); 173 // } 174 175 // /** 176 // * Constructs a deque containing the elements of the specified 177 // * collection, in the order they are returned by the collection's 178 // * iterator. (The first element returned by the collection's 179 // * iterator becomes the first element, or <i>front</i> of the 180 // * deque.) 181 // * 182 // * @param c the collection whose elements are to be placed into the deque 183 // * @throws NullPointerException if the specified collection is null 184 // */ 185 // ArrayDeque(Collection<E> c) { 186 // allocateElements(c.size()); 187 // addAll(c); 188 // } 189 190 // // The main insertion and extraction methods are addFirst, 191 // // addLast, pollFirst, pollLast. The other methods are defined in 192 // // terms of these. 193 194 // /** 195 // * Inserts the specified element at the front of this deque. 196 // * 197 // * @param e the element to add 198 // * @throws NullPointerException if the specified element is null 199 // */ 200 // void addFirst(E e) { 201 // if (e is null) 202 // throw new NullPointerException(); 203 // elements[head = (head - 1) & (elements.length - 1)] = e; 204 // if (head == tail) 205 // doubleCapacity(); 206 // } 207 208 // /** 209 // * Inserts the specified element at the end of this deque. 210 // * 211 // * <p>This method is equivalent to {@link #add}. 212 // * 213 // * @param e the element to add 214 // * @throws NullPointerException if the specified element is null 215 // */ 216 // void addLast(E e) { 217 // if (e is null) 218 // throw new NullPointerException(); 219 // elements[tail] = e; 220 // if ( (tail = (tail + 1) & (elements.length - 1)) == head) 221 // doubleCapacity(); 222 // } 223 224 // /** 225 // * Inserts the specified element at the front of this deque. 226 // * 227 // * @param e the element to add 228 // * @return {@code true} (as specified by {@link Deque#offerFirst}) 229 // * @throws NullPointerException if the specified element is null 230 // */ 231 // bool offerFirst(E e) { 232 // addFirst(e); 233 // return true; 234 // } 235 236 // /** 237 // * Inserts the specified element at the end of this deque. 238 // * 239 // * @param e the element to add 240 // * @return {@code true} (as specified by {@link Deque#offerLast}) 241 // * @throws NullPointerException if the specified element is null 242 // */ 243 // bool offerLast(E e) { 244 // addLast(e); 245 // return true; 246 // } 247 248 // /** 249 // * @throws NoSuchElementException {@inheritDoc} 250 // */ 251 // E removeFirst() { 252 // E x = pollFirst(); 253 // if (x is null) 254 // throw new NoSuchElementException(); 255 // return x; 256 // } 257 258 // /** 259 // * @throws NoSuchElementException {@inheritDoc} 260 // */ 261 // E removeLast() { 262 // E x = pollLast(); 263 // if (x is null) 264 // throw new NoSuchElementException(); 265 // return x; 266 // } 267 268 // E pollFirst() { 269 // int h = head; 270 // 271 // E result = (E) elements[h]; 272 // // Element is null if deque empty 273 // if (result is null) 274 // return null; 275 // elements[h] = null; // Must null out slot 276 // head = (h + 1) & (elements.length - 1); 277 // return result; 278 // } 279 280 // E pollLast() { 281 // int t = (tail - 1) & (elements.length - 1); 282 // 283 // E result = (E) elements[t]; 284 // if (result is null) 285 // return null; 286 // elements[t] = null; 287 // tail = t; 288 // return result; 289 // } 290 291 // /** 292 // * @throws NoSuchElementException {@inheritDoc} 293 // */ 294 // E getFirst() { 295 // 296 // E result = (E) elements[head]; 297 // if (result is null) 298 // throw new NoSuchElementException(); 299 // return result; 300 // } 301 302 // /** 303 // * @throws NoSuchElementException {@inheritDoc} 304 // */ 305 // E getLast() { 306 // 307 // E result = (E) elements[(tail - 1) & (elements.length - 1)]; 308 // if (result is null) 309 // throw new NoSuchElementException(); 310 // return result; 311 // } 312 313 // 314 // E peekFirst() { 315 // // elements[head] is null if deque empty 316 // return (E) elements[head]; 317 // } 318 319 // 320 // E peekLast() { 321 // return (E) elements[(tail - 1) & (elements.length - 1)]; 322 // } 323 324 // /** 325 // * Removes the first occurrence of the specified element in this 326 // * deque (when traversing the deque from head to tail). 327 // * If the deque does not contain the element, it is unchanged. 328 // * More formally, removes the first element {@code e} such that 329 // * {@code o.equals(e)} (if such an element exists). 330 // * Returns {@code true} if this deque contained the specified element 331 // * (or equivalently, if this deque changed as a result of the call). 332 // * 333 // * @param o element to be removed from this deque, if present 334 // * @return {@code true} if the deque contained the specified element 335 // */ 336 // bool removeFirstOccurrence(Object o) { 337 // if (o is null) 338 // return false; 339 // int mask = elements.length - 1; 340 // int i = head; 341 // Object x; 342 // while ( (x = elements[i]) !is null) { 343 // if (o.equals(x)) { 344 // delete(i); 345 // return true; 346 // } 347 // i = (i + 1) & mask; 348 // } 349 // return false; 350 // } 351 352 // /** 353 // * Removes the last occurrence of the specified element in this 354 // * deque (when traversing the deque from head to tail). 355 // * If the deque does not contain the element, it is unchanged. 356 // * More formally, removes the last element {@code e} such that 357 // * {@code o.equals(e)} (if such an element exists). 358 // * Returns {@code true} if this deque contained the specified element 359 // * (or equivalently, if this deque changed as a result of the call). 360 // * 361 // * @param o element to be removed from this deque, if present 362 // * @return {@code true} if the deque contained the specified element 363 // */ 364 // bool removeLastOccurrence(Object o) { 365 // if (o is null) 366 // return false; 367 // int mask = elements.length - 1; 368 // int i = (tail - 1) & mask; 369 // Object x; 370 // while ( (x = elements[i]) !is null) { 371 // if (o.equals(x)) { 372 // delete(i); 373 // return true; 374 // } 375 // i = (i - 1) & mask; 376 // } 377 // return false; 378 // } 379 380 // // *** Queue methods *** 381 382 // /** 383 // * Inserts the specified element at the end of this deque. 384 // * 385 // * <p>This method is equivalent to {@link #addLast}. 386 // * 387 // * @param e the element to add 388 // * @return {@code true} (as specified by {@link Collection#add}) 389 // * @throws NullPointerException if the specified element is null 390 // */ 391 // bool add(E e) { 392 // addLast(e); 393 // return true; 394 // } 395 396 // /** 397 // * Inserts the specified element at the end of this deque. 398 // * 399 // * <p>This method is equivalent to {@link #offerLast}. 400 // * 401 // * @param e the element to add 402 // * @return {@code true} (as specified by {@link Queue#offer}) 403 // * @throws NullPointerException if the specified element is null 404 // */ 405 // bool offer(E e) { 406 // return offerLast(e); 407 // } 408 409 // /** 410 // * Retrieves and removes the head of the queue represented by this deque. 411 // * 412 // * This method differs from {@link #poll poll} only in that it throws an 413 // * exception if this deque is empty. 414 // * 415 // * <p>This method is equivalent to {@link #removeFirst}. 416 // * 417 // * @return the head of the queue represented by this deque 418 // * @throws NoSuchElementException {@inheritDoc} 419 // */ 420 // E remove() { 421 // return removeFirst(); 422 // } 423 424 // /** 425 // * Retrieves and removes the head of the queue represented by this deque 426 // * (in other words, the first element of this deque), or returns 427 // * {@code null} if this deque is empty. 428 // * 429 // * <p>This method is equivalent to {@link #pollFirst}. 430 // * 431 // * @return the head of the queue represented by this deque, or 432 // * {@code null} if this deque is empty 433 // */ 434 // E poll() { 435 // return pollFirst(); 436 // } 437 438 // /** 439 // * Retrieves, but does not remove, the head of the queue represented by 440 // * this deque. This method differs from {@link #peek peek} only in 441 // * that it throws an exception if this deque is empty. 442 // * 443 // * <p>This method is equivalent to {@link #getFirst}. 444 // * 445 // * @return the head of the queue represented by this deque 446 // * @throws NoSuchElementException {@inheritDoc} 447 // */ 448 // E element() { 449 // return getFirst(); 450 // } 451 452 // /** 453 // * Retrieves, but does not remove, the head of the queue represented by 454 // * this deque, or returns {@code null} if this deque is empty. 455 // * 456 // * <p>This method is equivalent to {@link #peekFirst}. 457 // * 458 // * @return the head of the queue represented by this deque, or 459 // * {@code null} if this deque is empty 460 // */ 461 // E peek() { 462 // return peekFirst(); 463 // } 464 465 // // *** Stack methods *** 466 467 // /** 468 // * Pushes an element onto the stack represented by this deque. In other 469 // * words, inserts the element at the front of this deque. 470 // * 471 // * <p>This method is equivalent to {@link #addFirst}. 472 // * 473 // * @param e the element to push 474 // * @throws NullPointerException if the specified element is null 475 // */ 476 // void push(E e) { 477 // addFirst(e); 478 // } 479 480 // /** 481 // * Pops an element from the stack represented by this deque. In other 482 // * words, removes and returns the first element of this deque. 483 // * 484 // * <p>This method is equivalent to {@link #removeFirst()}. 485 // * 486 // * @return the element at the front of this deque (which is the top 487 // * of the stack represented by this deque) 488 // * @throws NoSuchElementException {@inheritDoc} 489 // */ 490 // E pop() { 491 // return removeFirst(); 492 // } 493 494 // private void checkInvariants() { 495 // assert elements[tail] is null; 496 // assert head == tail ? elements[head] is null : 497 // (elements[head] !is null && 498 // elements[(tail - 1) & (elements.length - 1)] !is null); 499 // assert elements[(head - 1) & (elements.length - 1)] is null; 500 // } 501 502 // /** 503 // * Removes the element at the specified position in the elements array, 504 // * adjusting head and tail as necessary. This can result in motion of 505 // * elements backwards or forwards in the array. 506 // * 507 // * <p>This method is called delete rather than remove to emphasize 508 // * that its semantics differ from those of {@link List#remove(int)}. 509 // * 510 // * @return true if elements moved backwards 511 // */ 512 // private bool delete(int i) { 513 // checkInvariants(); 514 // final Object[] elements = this.elements; 515 // final int mask = elements.length - 1; 516 // final int h = head; 517 // final int t = tail; 518 // final int front = (i - h) & mask; 519 // final int back = (t - i) & mask; 520 521 // // Invariant: head <= i < tail mod circularity 522 // if (front >= ((t - h) & mask)) 523 // throw new ConcurrentModificationException(); 524 525 // // Optimize for least element motion 526 // if (front < back) { 527 // if (h <= i) { 528 // System.arraycopy(elements, h, elements, h + 1, front); 529 // } else { // Wrap around 530 // System.arraycopy(elements, 0, elements, 1, i); 531 // elements[0] = elements[mask]; 532 // System.arraycopy(elements, h, elements, h + 1, mask - h); 533 // } 534 // elements[h] = null; 535 // head = (h + 1) & mask; 536 // return false; 537 // } else { 538 // if (i < t) { // Copy the null tail as well 539 // System.arraycopy(elements, i + 1, elements, i, back); 540 // tail = t - 1; 541 // } else { // Wrap around 542 // System.arraycopy(elements, i + 1, elements, i, mask - i); 543 // elements[mask] = elements[0]; 544 // System.arraycopy(elements, 1, elements, 0, t); 545 // tail = (t - 1) & mask; 546 // } 547 // return true; 548 // } 549 // } 550 551 // // *** Collection Methods *** 552 553 // /** 554 // * Returns the number of elements in this deque. 555 // * 556 // * @return the number of elements in this deque 557 // */ 558 // int size() { 559 // return (tail - head) & (elements.length - 1); 560 // } 561 562 // /** 563 // * Returns {@code true} if this deque contains no elements. 564 // * 565 // * @return {@code true} if this deque contains no elements 566 // */ 567 // bool isEmpty() { 568 // return head == tail; 569 // } 570 571 // /** 572 // * Returns an iterator over the elements in this deque. The elements 573 // * will be ordered from first (head) to last (tail). This is the same 574 // * order that elements would be dequeued (via successive calls to 575 // * {@link #remove} or popped (via successive calls to {@link #pop}). 576 // * 577 // * @return an iterator over the elements in this deque 578 // */ 579 // Iterator!E iterator() { 580 // return new DeqIterator(); 581 // } 582 583 // Iterator!E descendingIterator() { 584 // return new DescendingIterator(); 585 // } 586 587 // private class DeqIterator implements Iterator!E { 588 // /** 589 // * Index of element to be returned by subsequent call to next. 590 // */ 591 // private int cursor = head; 592 593 // /** 594 // * Tail recorded at construction (also in remove), to stop 595 // * iterator and also to check for comodification. 596 // */ 597 // private int fence = tail; 598 599 // /** 600 // * Index of element returned by most recent call to next. 601 // * Reset to -1 if element is deleted by a call to remove. 602 // */ 603 // private int lastRet = -1; 604 605 // bool hasNext() { 606 // return cursor != fence; 607 // } 608 609 // E next() { 610 // if (cursor == fence) 611 // throw new NoSuchElementException(); 612 // 613 // E result = (E) elements[cursor]; 614 // // This check doesn't catch all possible comodifications, 615 // // but does catch the ones that corrupt traversal 616 // if (tail != fence || result is null) 617 // throw new ConcurrentModificationException(); 618 // lastRet = cursor; 619 // cursor = (cursor + 1) & (elements.length - 1); 620 // return result; 621 // } 622 623 // void remove() { 624 // if (lastRet < 0) 625 // throw new IllegalStateException(); 626 // if (delete(lastRet)) { // if left-shifted, undo increment in next() 627 // cursor = (cursor - 1) & (elements.length - 1); 628 // fence = tail; 629 // } 630 // lastRet = -1; 631 // } 632 633 // void forEachRemaining(Consumer<E> action) { 634 // Objects.requireNonNull(action); 635 // Object[] a = elements; 636 // int m = a.length - 1, f = fence, i = cursor; 637 // cursor = f; 638 // while (i != f) { 639 // E e = (E)a[i]; 640 // i = (i + 1) & m; 641 // if (e is null) 642 // throw new ConcurrentModificationException(); 643 // action.accept(e); 644 // } 645 // } 646 // } 647 648 // private class DescendingIterator implements Iterator!E { 649 // /* 650 // * This class is nearly a mirror-image of DeqIterator, using 651 // * tail instead of head for initial cursor, and head instead of 652 // * tail for fence. 653 // */ 654 // private int cursor = tail; 655 // private int fence = head; 656 // private int lastRet = -1; 657 658 // bool hasNext() { 659 // return cursor != fence; 660 // } 661 662 // E next() { 663 // if (cursor == fence) 664 // throw new NoSuchElementException(); 665 // cursor = (cursor - 1) & (elements.length - 1); 666 // 667 // E result = (E) elements[cursor]; 668 // if (head != fence || result is null) 669 // throw new ConcurrentModificationException(); 670 // lastRet = cursor; 671 // return result; 672 // } 673 674 // void remove() { 675 // if (lastRet < 0) 676 // throw new IllegalStateException(); 677 // if (!delete(lastRet)) { 678 // cursor = (cursor + 1) & (elements.length - 1); 679 // fence = head; 680 // } 681 // lastRet = -1; 682 // } 683 // } 684 685 // /** 686 // * Returns {@code true} if this deque contains the specified element. 687 // * More formally, returns {@code true} if and only if this deque contains 688 // * at least one element {@code e} such that {@code o.equals(e)}. 689 // * 690 // * @param o object to be checked for containment in this deque 691 // * @return {@code true} if this deque contains the specified element 692 // */ 693 // bool contains(Object o) { 694 // if (o is null) 695 // return false; 696 // int mask = elements.length - 1; 697 // int i = head; 698 // Object x; 699 // while ( (x = elements[i]) !is null) { 700 // if (o.equals(x)) 701 // return true; 702 // i = (i + 1) & mask; 703 // } 704 // return false; 705 // } 706 707 // /** 708 // * Removes a single instance of the specified element from this deque. 709 // * If the deque does not contain the element, it is unchanged. 710 // * More formally, removes the first element {@code e} such that 711 // * {@code o.equals(e)} (if such an element exists). 712 // * Returns {@code true} if this deque contained the specified element 713 // * (or equivalently, if this deque changed as a result of the call). 714 // * 715 // * <p>This method is equivalent to {@link #removeFirstOccurrence(Object)}. 716 // * 717 // * @param o element to be removed from this deque, if present 718 // * @return {@code true} if this deque contained the specified element 719 // */ 720 // bool remove(Object o) { 721 // return removeFirstOccurrence(o); 722 // } 723 724 // /** 725 // * Removes all of the elements from this deque. 726 // * The deque will be empty after this call returns. 727 // */ 728 // void clear() { 729 // int h = head; 730 // int t = tail; 731 // if (h != t) { // clear all cells 732 // head = tail = 0; 733 // int i = h; 734 // int mask = elements.length - 1; 735 // do { 736 // elements[i] = null; 737 // i = (i + 1) & mask; 738 // } while (i != t); 739 // } 740 // } 741 742 // /** 743 // * Returns an array containing all of the elements in this deque 744 // * in proper sequence (from first to last element). 745 // * 746 // * <p>The returned array will be "safe" in that no references to it are 747 // * maintained by this deque. (In other words, this method must allocate 748 // * a new array). The caller is thus free to modify the returned array. 749 // * 750 // * <p>This method acts as bridge between array-based and collection-based 751 // * APIs. 752 // * 753 // * @return an array containing all of the elements in this deque 754 // */ 755 // Object[] toArray() { 756 // return copyElements(new Object[size()]); 757 // } 758 759 // /** 760 // * Returns an array containing all of the elements in this deque in 761 // * proper sequence (from first to last element); the runtime type of the 762 // * returned array is that of the specified array. If the deque fits in 763 // * the specified array, it is returned therein. Otherwise, a new array 764 // * is allocated with the runtime type of the specified array and the 765 // * size of this deque. 766 // * 767 // * <p>If this deque fits in the specified array with room to spare 768 // * (i.e., the array has more elements than this deque), the element in 769 // * the array immediately following the end of the deque is set to 770 // * {@code null}. 771 // * 772 // * <p>Like the {@link #toArray()} method, this method acts as bridge between 773 // * array-based and collection-based APIs. Further, this method allows 774 // * precise control over the runtime type of the output array, and may, 775 // * under certain circumstances, be used to save allocation costs. 776 // * 777 // * <p>Suppose {@code x} is a deque known to contain only strings. 778 // * The following code can be used to dump the deque into a newly 779 // * allocated array of {@code string}: 780 // * 781 // * <pre> {@code string[] y = x.toArray(new string[0]);}</pre> 782 // * 783 // * Note that {@code toArray(new Object[0])} is identical in function to 784 // * {@code toArray()}. 785 // * 786 // * @param a the array into which the elements of the deque are to 787 // * be stored, if it is big enough; otherwise, a new array of the 788 // * same runtime type is allocated for this purpose 789 // * @return an array containing all of the elements in this deque 790 // * @throws ArrayStoreException if the runtime type of the specified array 791 // * is not a supertype of the runtime type of every element in 792 // * this deque 793 // * @throws NullPointerException if the specified array is null 794 // */ 795 // 796 // !(T) T[] toArray(T[] a) { 797 // int size = size(); 798 // if (a.length < size) 799 // a = (T[])java.lang.reflect.Array.newInstance( 800 // a.getClass().getComponentType(), size); 801 // copyElements(a); 802 // if (a.length > size) 803 // a[size] = null; 804 // return a; 805 // } 806 807 // // *** Object methods *** 808 809 // /** 810 // * Returns a copy of this deque. 811 // * 812 // * @return a copy of this deque 813 // */ 814 // ArrayDeque!E clone() { 815 // try { 816 // 817 // ArrayDeque!E result = (ArrayDeque!E) super.clone(); 818 // result.elements = Arrays.copyOf(elements, elements.length); 819 // return result; 820 // } catch (CloneNotSupportedException e) { 821 // throw new AssertionError(); 822 // } 823 // } 824 825 // private static final long serialVersionUID = 2340985798034038923L; 826 827 // /** 828 // * Saves this deque to a stream (that is, serializes it). 829 // * 830 // * @serialData The current size ({@code int}) of the deque, 831 // * followed by all of its elements (each an object reference) in 832 // * first-to-last order. 833 // */ 834 // private void writeObject(java.io.ObjectOutputStream s) 835 // throws java.io.IOException { 836 // s.defaultWriteObject(); 837 838 // // Write out size 839 // s.writeInt(size()); 840 841 // // Write out elements in order. 842 // int mask = elements.length - 1; 843 // for (int i = head; i != tail; i = (i + 1) & mask) 844 // s.writeObject(elements[i]); 845 // } 846 847 // /** 848 // * Reconstitutes this deque from a stream (that is, deserializes it). 849 // */ 850 // private void readObject(java.io.ObjectInputStream s) 851 // throws java.io.IOException, ClassNotFoundException { 852 // s.defaultReadObject(); 853 854 // // Read in size and allocate array 855 // int size = s.readInt(); 856 // allocateElements(size); 857 // head = 0; 858 // tail = size; 859 860 // // Read in all elements in the proper order. 861 // for (int i = 0; i < size; i++) 862 // elements[i] = s.readObject(); 863 // } 864 865 // /** 866 // * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em> 867 // * and <em>fail-fast</em> {@link Spliterator} over the elements in this 868 // * deque. 869 // * 870 // * <p>The {@code Spliterator} reports {@link Spliterator#SIZED}, 871 // * {@link Spliterator#SUBSIZED}, {@link Spliterator#ORDERED}, and 872 // * {@link Spliterator#NONNULL}. Overriding implementations should document 873 // * the reporting of additional characteristic values. 874 // * 875 // * @return a {@code Spliterator} over the elements in this deque 876 // * @since 1.8 877 // */ 878 // Spliterator!E spliterator() { 879 // return new DeqSpliterator!E(this, -1, -1); 880 // } 881 882 // static final class DeqSpliterator!E implements Spliterator!E { 883 // private final ArrayDeque!E deq; 884 // private int fence; // -1 until first use 885 // private int index; // current index, modified on traverse/split 886 887 // /** Creates new spliterator covering the given array and range */ 888 // DeqSpliterator(ArrayDeque!E deq, int origin, int fence) { 889 // this.deq = deq; 890 // this.index = origin; 891 // this.fence = fence; 892 // } 893 894 // private int getFence() { // force initialization 895 // int t; 896 // if ((t = fence) < 0) { 897 // t = fence = deq.tail; 898 // index = deq.head; 899 // } 900 // return t; 901 // } 902 903 // DeqSpliterator!E trySplit() { 904 // int t = getFence(), h = index, n = deq.elements.length; 905 // if (h != t && ((h + 1) & (n - 1)) != t) { 906 // if (h > t) 907 // t += n; 908 // int m = ((h + t) >>> 1) & (n - 1); 909 // return new DeqSpliterator<>(deq, h, index = m); 910 // } 911 // return null; 912 // } 913 914 // void forEachRemaining(Consumer<E> consumer) { 915 // if (consumer is null) 916 // throw new NullPointerException(); 917 // Object[] a = deq.elements; 918 // int m = a.length - 1, f = getFence(), i = index; 919 // index = f; 920 // while (i != f) { 921 // E e = (E)a[i]; 922 // i = (i + 1) & m; 923 // if (e is null) 924 // throw new ConcurrentModificationException(); 925 // consumer.accept(e); 926 // } 927 // } 928 929 // bool tryAdvance(Consumer<E> consumer) { 930 // if (consumer is null) 931 // throw new NullPointerException(); 932 // Object[] a = deq.elements; 933 // int m = a.length - 1, f = getFence(), i = index; 934 // if (i != fence) { 935 // E e = (E)a[i]; 936 // index = (i + 1) & m; 937 // if (e is null) 938 // throw new ConcurrentModificationException(); 939 // consumer.accept(e); 940 // return true; 941 // } 942 // return false; 943 // } 944 945 // long estimateSize() { 946 // int n = getFence() - index; 947 // if (n < 0) 948 // n += deq.elements.length; 949 // return (long) n; 950 // } 951 952 // override 953 // int characteristics() { 954 // return Spliterator.ORDERED | Spliterator.SIZED | 955 // Spliterator.NONNULL | Spliterator.SUBSIZED; 956 // } 957 // } 958 959 // }