/*
 * @author Ranides Atterwim <ranides@gmail.com>
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira
 */
package net.ranides.assira.collection.iterators;

import java.util.Iterator;

public interface IntIterator extends Iterator<Integer> {

    int nextInt();

    @Override
    default Integer next() {
        return nextInt();
    }

    @Override
    default void remove() {
        throw new UnsupportedOperationException();
    }

    /**
     * Wraps a standard iterator into a type-specific iterator.
     *
     * <P>This method wraps a standard iterator into a type-specific one which
     * will handle the type conversions for you. Of course, any attempt to wrap
     * an iterator returning the instances of the wrong class will generate a
     * {@link ClassCastException}. The returned iterator is backed by
     * <code>iterator</code>: changes to one of the iterators will affect the other,
     * too.
     *
     * <P>If <code>iterator</code> is already type-specific, it will returned and no new
     * object will be generated.
     *
     * @param iterator an iterator.
     * @return a type-specific iterator backed by <code>iterator</code>.
     */
    @SuppressWarnings("unchecked")
    static IntIterator wrap(Iterator<? extends Integer> iterator) {
        if (iterator instanceof IntIterator) {
            return (IntIterator) iterator;
        }
        return new IntIterator(){
            @Override
            public boolean hasNext() {
                return iterator.hasNext();
            }

            @Override
            public void remove() {
                iterator.remove();
            }

            @Override
            public int nextInt() {
                return iterator.next();
            }
        };
    }
    
    @SuppressWarnings("unchecked")
    static IntIterator $wrap(Iterator<?> comparator) {
        return wrap((Iterator)comparator);
    }
    
}
