SquirrelJME/SquirrelJME

View on GitHub
modules/cldc-compact/src/main/java/java/util/__LinkedListListIterator__.java

Summary

Maintainability
A
0 mins
Test Coverage
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the Mozilla Public License Version 2.0.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package java.util;

/**
 * The list iterator for this linked list.
 *
 * @param <E> The types of values to store.
 * @since 2018/10/29
 */
final class __LinkedListListIterator__<E>
    implements ListIterator<E>
{
    /** The owning linked list. */
    protected final LinkedList<E> list;
    
    /** The virtualized index for the list (estimated). */
    private int _vdx;
    
    /** Last virtualized index. */
    private int _lastvdx;
    
    /** The current link the list is at. */
    private __Link__<E> _next;
    
    /** The last element, for removal or setting */
    private __Link__<E> _last;
    
    /** The current modification count, to detect modifications. */
    private int _atmod;
    
    /**
     * Initializes the iterator starting at the given index.
     *
     * @param __list The linked list this interfaces with.
     * @param __i The index to start at.
     * @throws IndexOutOfBoundsException If the index is outside of the
     * list bounds.
     * @throws NullPointerException On null arguments.
     * @since 2018/10/29
     */
    __LinkedListListIterator__(LinkedList<E> __list, int __i)
        throws IndexOutOfBoundsException, NullPointerException
    {
        if (__list == null)
            throw new NullPointerException("NARG");
        
        int size = __list._size;
        if (__i < 0 || __i > size)
            throw new IndexOutOfBoundsException("IOOB");
        
        // Closer to the start of the list
        __Link__<E> rover;
        if (__i < (size >> 1))
        {
            rover = __list._head;
            
            for (int i = -1; i < __i; i++)
                rover = rover._next;
        }
        
        // Closer to the end of the list
        else
        {
            rover = __list._tail;
            
            for (int i = size; i > __i; i--)
                rover = rover._prev;
        }
        
        // Store start information
        this.list = __list;
        this._next = rover;
        this._vdx = __i;
        this._atmod = __list.modCount;
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/10/29
     */
    @Override
    public final void add(E __v)
    {
        // Check modification
        this.__checkConcurrent();
        
        // These will both be adjusted
        int vdx = this._vdx;
        __Link__<E> next = this._next;
        
        // The documentation specifies that the object is inserted
        // before the implicit cursor, which means the next call to
        // previous will return the new element. Next would just return
        // the same element no matter how many elements are added.
        // So it is inserted between the previous and our current next
        new __Link__<E>(next._prev, __v, next);
        
        // Since we inserted an item, vdx goes up
        this._vdx++;
        
        // Size also goes up
        this.list._size++;
        
        // Set list as being modified and update our count to match
        this._atmod = ++this.list.modCount;
        
        // Cannot remove or set
        this._last = null;
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/10/29
     */
    @Override
    public final boolean hasNext()
    {
        // Check modification
        this.__checkConcurrent();
        
        // There is a next as long as the current element is before the
        // size
        return this._vdx < this.list._size;
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/10/29
     */
    @Override
    public final boolean hasPrevious()
    {
        // Check modification
        this.__checkConcurrent();
        
        // There is a previous as long as this is not the first element
        return this._vdx > 0;
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/10/28
     */
    @Override
    public final E next()
        throws NoSuchElementException
    {
        // Check modification
        this.__checkConcurrent();
        
        // We are at the tail node, do nothing
        __Link__<E> next = this._next;
        if (next == this.list._tail)
            throw new NoSuchElementException("NSEE");
        
        // Removal and set can be done on this
        this._last = next;
        
        // Iterate and record for the next element
        this._lastvdx = this._vdx++;
        this._next = next._next;
        
        // Return the current value
        return next._value;
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/10/29
     */
    @Override
    public final int nextIndex()
    {
        // Check modification
        this.__checkConcurrent();
        
        // Virtual index should match this one
        return this._vdx;
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/10/29
     */
    @Override
    public final E previous()
    {
        // Check modification
        this.__checkConcurrent();
        
        // We are at the head node, do nothing
        __Link__<E> next = this._next;
        if (next._prev == this.list._head)
            throw new NoSuchElementException("NSEE");
        
        // Move to previous
        __Link__<E> prev = next._prev;
        
        // Removal is done on this
        this._last = prev;
        
        // Move index back
        this._lastvdx = --this._vdx;
        this._next = prev;
        
        // Use previous value
        return prev._value;
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/10/29
     */
    @Override
    public final int previousIndex()
    {
        // Check modification
        this.__checkConcurrent();
        
        // Should be the previous virtual index
        return this._vdx - 1;
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/10/29
     */
    @Override
    public final void remove()
        throws IllegalStateException
    {
        // Check modification
        this.__checkConcurrent();
        
        /* {@squirreljme.error ZZ2u Cannot remove the element from the
        linked list because there was no previous call to next or
        previous, or add was called.} */
        __Link__<E> last = this._last;
        if (last == null)
            throw new IllegalStateException("ZZ2u");
        
        // Only removed once
        this._last = null;
        
        // Just link the previous and next entries to the others and
        // drop this link
        last._prev._next = last._next;
        last._next._prev = last._prev;
        
        // If the next entry is after this point then it will needs its
        // index dropped
        int vdx = this._vdx,
            lastvdx = this._lastvdx;
        if (vdx > lastvdx)
            this._vdx = vdx - 1;
        
        // Set list as being modified and update our count to match
        this._atmod = ++this.list.modCount;
        
        // Size goes down
        this.list._size--;
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/10/29
     */
    @Override
    public final void set(E __v)
        throws IllegalStateException
    {
        // Check modification
        this.__checkConcurrent();
        
        /* {@squirreljme.error ZZ2v Cannot set the element from the
        linked list because there was no previous call to next or
        previous, or add was called.} */
        __Link__<E> last = this._last;
        if (last == null)
            throw new IllegalStateException("ZZ2v");
        
        // Just set it
        last._value = __v;
    }
    
    /**
     * Checks if the list was concurrently modified.
     *
     * @throws ConcurrentModificationException If it was modified.
     * @since 2018/10/29
     */
    private void __checkConcurrent()
        throws ConcurrentModificationException
    {
        /* {@squirreljme.error ZZ2w List has been concurrently modified.} */
        if (this._atmod != this.list.modCount)
        {
            // Just empty these out so they are never used again
            this._next = null;
            this._last = null;
            
            // Fail
            throw new ConcurrentModificationException("ZZ2w");
        }
    }
}