Package groovy.lang

Source Code of groovy.lang.IntRange$IntRangeIterator

/*
* Copyright 2003-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package groovy.lang;

import org.codehaus.groovy.runtime.IteratorClosureAdapter;

import java.math.BigInteger;
import java.util.AbstractList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

/**
* Represents a list of Integer objects from a specified int up (or down) to and including
* a given to.<p>
* <p/>
* This class is a copy of {@link ObjectRange} optimized for <code>int</code>.  If you make any
* changes to this class, you might consider making parallel changes to {@link ObjectRange}.
*
* @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
* @version $Revision: 6817 $
*/
public class IntRange extends AbstractList implements Range {

    /**
     * Iterates through each number in an <code>IntRange</code>.
     */
    private class IntRangeIterator implements Iterator {
        /**
         * Counts from 0 up to size - 1.
         */
        private int index;

        /**
         * The number of values in the range.
         */
        private int size = size();

        /**
         * The next value to return.
         */
        private int value = reverse ? to : from;

        /**
         * {@inheritDoc}
         */
        public boolean hasNext() {
            return index < size;
        }

        /**
         * {@inheritDoc}
         */
        public Object next() {
            if (index++ > 0) {
                if (index > size) {
                    return null;
                } else {
                    if (reverse) {
                        --value;
                    } else {
                        ++value;
                    }
                }
            }
            return new Integer(value);
        }

        /**
         * Not supported.
         *
         * @throws javax.naming.OperationNotSupportedException always
         */
        public void remove() {
            IntRange.this.remove(index);
        }
    }

    /**
     * The first number in the range.  <code>from </code> is always less than or equal to <code>to</code>.
     */
    private int from;

    /**
     * The last number in the range. <code>to</code> is always greater than or eqaul to <code>from</code>.
     */
    private int to;

    /**
     * If <code>false</code>, counts up from <code>from</code> to <code>to</code>.  Otherwise, counts down
     * from <code>to</code> to <code>from</code>.
     */
    private boolean reverse;

    /**
     * Creates a new <code>IntRange</code>. If <code>from</code> is greater
     * than <code>to</code>, a reverse range is created with
     * <code>from</code> and <code>to</code> swapped.
     *
     * @param from the first number in the range.
     * @param to   the last number in the range.
     * @throws IllegalArgumentException if the range would contain more than
     *                                  {@link Integer#MAX_VALUE} values.
     */
    public IntRange(int from, int to) {
        if (from > to) {
            this.from = to;
            this.to = from;
            this.reverse = true;
        } else {
            this.from = from;
            this.to = to;
        }

        // size() an integer so ranges can have no more than Integer.MAX_VALUE elements
        if (this.to - this.from >= Integer.MAX_VALUE) {
            throw new IllegalArgumentException("range must have no more than " + Integer.MAX_VALUE + " elements");
        }
    }

    /**
     * Creates a new <code>IntRange</code>.
     *
     * @param from    the first value in the range.
     * @param to      the last value in the range.
     * @param reverse <code>true</code> if the range should count from
     *                <code>to</code> to <code>from</code>.
     * @throws IllegalArgumentException if <code>from</code> is greater than <code>to</code>.
     */
    protected IntRange(int from, int to, boolean reverse) {
        if (from > to) {
            throw new IllegalArgumentException("'from' must be less than or equal to 'to'");
        }

        this.from = from;
        this.to = to;
        this.reverse = reverse;
    }

    /**
     * Determines if this object is equal to another object. Delegates to
     * {@link AbstractList#equals(Object)} if <code>that</code> is anthing
     * other than an {@link IntRange}.
     * <p/>
     * <p/>
     * It is not necessary to override <code>hashCode</code>, as
     * {@link AbstractList#hashCode()} provides a suitable hash code.<p>
     * <p/>
     * Note that equals is generally handled by {@link org.codehaus.groovy.runtime.DefaultGroovyMethods#equals(List,List)}
     * instead of this method.
     *
     * @param that the object to compare
     * @return <code>true</code> if the objects are equal
     */
    public boolean equals(Object that) {
        return that instanceof IntRange ? equals((IntRange) that) : super.equals(that);
    }

    /**
     * Compares an {@link IntRange} to another {@link IntRange}.
     *
     * @return <code>true</code> if the ranges are equal
     * @param that the object to compare for equality
     */
    public boolean equals(IntRange that) {
        return that != null && this.reverse == that.reverse && this.from == that.from && this.to == that.to;
    }

    /**
     * {@inheritDoc}
     */
    public Comparable getFrom() {
        return new Integer(from);
    }

    /**
     * {@inheritDoc}
     */
    public Comparable getTo() {
        return new Integer(to);
    }

    /**
     * Gets the 'from' value as an integer.
     *
     * @return the 'from' value as an integer.
     */
    public int getFromInt() {
        return from;
    }

    /**
     * Gets the 'to' value as an integer.
     *
     * @return the 'to' value as an integer.
     */
    public int getToInt() {
        return to;
    }

    /**
     * {@inheritDoc}
     */
    public boolean isReverse() {
        return reverse;
    }

    public boolean containsWithinBounds(Object o) {
        return contains(o);
    }

    /**
     * {@inheritDoc}
     */
    public Object get(int index) {
        if (index < 0) {
            throw new IndexOutOfBoundsException("Index: " + index + " should not be negative");
        }
        if (index >= size()) {
            throw new IndexOutOfBoundsException("Index: " + index + " too big for range: " + this);
        }
        int value = reverse ? to - index : index + from;
        return new Integer(value);
    }

    /**
     * {@inheritDoc}
     */
    public int size() {
        return to - from + 1;
    }

    /**
     * {@inheritDoc}
     */
    public Iterator iterator() {
        return new IntRangeIterator();
    }

    /**
     * {@inheritDoc}
     */
    public List subList(int fromIndex, int toIndex) {
        if (fromIndex < 0) {
            throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
        }
        if (toIndex > size()) {
            throw new IndexOutOfBoundsException("toIndex = " + toIndex);
        }
        if (fromIndex > toIndex) {
            throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")");
        }

        if (fromIndex == toIndex) {
            return new EmptyRange(new Integer(from));
        }

        return new IntRange(fromIndex + this.from, toIndex + this.from - 1, reverse);
    }

    /**
     * {@inheritDoc}
     */
    public String toString() {
        return reverse ? "" + to + ".." + from : "" + from + ".." + to;
    }

    /**
     * {@inheritDoc}
     */
    public String inspect() {
        return toString();
    }

    /**
     * {@inheritDoc}
     */
    public boolean contains(Object value) {
        if (value instanceof Integer) {
            Integer integer = (Integer) value;
            int i = integer.intValue();
            return i >= from && i <= to;
        }
        if (value instanceof BigInteger) {
            BigInteger bigint = (BigInteger) value;
            return bigint.compareTo(BigInteger.valueOf(from)) >= 0 &&
                    bigint.compareTo(BigInteger.valueOf(to)) <= 0;
        }
        return false;
    }

    /**
     * {@inheritDoc}
     */
    public boolean containsAll(Collection other) {
        if (other instanceof IntRange) {
            final IntRange range = (IntRange) other;
            return this.from <= range.from && range.to <= this.to;
        }
        return super.containsAll(other);
    }

    /**
     * {@inheritDoc}
     */
    public void step(int step, Closure closure) {
        if (reverse) {
            step = -step;
        }
        if (step >= 0) {
            int value = from;
            while (value <= to) {
                closure.call(new Integer(value));
                value = value + step;
            }
        } else {
            int value = to;
            while (value >= from) {
                closure.call(new Integer(value));
                value = value + step;
            }
        }
    }

    /**
     * {@inheritDoc}
     */
    public List step(int step) {
        IteratorClosureAdapter adapter = new IteratorClosureAdapter(this);
        step(step, adapter);
        return adapter.asList();
    }
}
TOP

Related Classes of groovy.lang.IntRange$IntRangeIterator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.