001/*
002 *  This file is part of the Jikes RVM project (http://jikesrvm.org).
003 *
004 *  This file is licensed to You under the Eclipse Public License (EPL);
005 *  You may not use this file except in compliance with the License. You
006 *  may obtain a copy of the License at
007 *
008 *      http://www.opensource.org/licenses/eclipse-1.0.php
009 *
010 *  See the COPYRIGHT.txt file distributed with this work for information
011 *  regarding copyright ownership.
012 */
013package org.jikesrvm.util;
014
015import java.util.ListIterator;
016import java.util.NoSuchElementException;
017import org.jikesrvm.VM;
018
019public final class LinkedListIteratorRVM<T> implements ListIterator<T> {
020  boolean canRemove = false;
021
022  /** The list we are iterating over */
023  final LinkedListRVM<T> l;
024
025  /** Pointer to the current (most recently returned) element. */
026  private LinkedListRVM.Element<T> cursor = null;
027
028  /**
029   * Constructor
030   *
031   * @param l The list to iterate over.
032   */
033  LinkedListIteratorRVM(LinkedListRVM<T> l) {
034    this.l = l;
035  }
036
037  @Override
038  public void add(T arg0) {
039    l.insertAfter(cursor, arg0);
040    cursor = cursor.next;
041  }
042
043  @Override
044  public boolean hasNext() {
045    return cursor != l.tail;
046  }
047
048  @Override
049  public boolean hasPrevious() {
050    return cursor != null && cursor != l.head;
051  }
052
053  @Override
054  public T next() {
055    if (cursor == null) {
056      cursor = l.head;
057    } else {
058      if (cursor.next == null) {
059        throw new NoSuchElementException();
060      }
061      cursor = cursor.next;
062    }
063    canRemove = true;
064    return cursor.entry;
065  }
066
067  @Override
068  public void remove() {
069    if (canRemove) {
070      l.removeInternal(cursor);
071      canRemove = false;
072    } else {
073      throw new IllegalStateException();
074    }
075  }
076
077  /* ---------------------------------------------------------------------- */
078  /*                      Methods below unimplemented                       */
079  /* ---------------------------------------------------------------------- */
080
081  @Override
082  public int nextIndex() {
083    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);
084    return 0;
085  }
086
087  @Override
088  public T previous() {
089    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);
090    return null;
091  }
092
093  @Override
094  public int previousIndex() {
095    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);
096    return 0;
097  }
098
099  @Override
100  public void set(Object arg0) {
101    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);
102  }
103
104}