001: /*
002: $Id: IntRange.java 4098 2006-10-10 16:09:48Z blackdrag $
003:
004: Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
005:
006: Redistribution and use of this software and associated documentation
007: ("Software"), with or without modification, are permitted provided
008: that the following conditions are met:
009:
010: 1. Redistributions of source code must retain copyright
011: statements and notices. Redistributions must also contain a
012: copy of this document.
013:
014: 2. Redistributions in binary form must reproduce the
015: above copyright notice, this list of conditions and the
016: following disclaimer in the documentation and/or other
017: materials provided with the distribution.
018:
019: 3. The name "groovy" must not be used to endorse or promote
020: products derived from this Software without prior written
021: permission of The Codehaus. For written permission,
022: please contact info@codehaus.org.
023:
024: 4. Products derived from this Software may not be called "groovy"
025: nor may "groovy" appear in their names without prior written
026: permission of The Codehaus. "groovy" is a registered
027: trademark of The Codehaus.
028:
029: 5. Due credit should be given to The Codehaus -
030: http://groovy.codehaus.org/
031:
032: THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
033: ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
034: NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
035: FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
036: THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
037: INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
038: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
039: SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
040: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
041: STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
042: ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
043: OF THE POSSIBILITY OF SUCH DAMAGE.
044:
045: */
046: package groovy.lang;
047:
048: import java.util.AbstractList;
049: import java.util.Iterator;
050: import java.util.List;
051:
052: import org.codehaus.groovy.runtime.IteratorClosureAdapter;
053: import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
054:
055: /**
056: * Represents a list of Integer objects from a specified int up to and including
057: * a given and to.
058: *
059: * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
060: * @version $Revision: 4098 $
061: */
062: public class IntRange extends AbstractList implements Range {
063:
064: private int from;
065: private int to;
066: private boolean reverse;
067:
068: public IntRange(int from, int to) {
069: if (from > to) {
070: this .from = to;
071: this .to = from;
072: this .reverse = true;
073: } else {
074: this .from = from;
075: this .to = to;
076: }
077: }
078:
079: protected IntRange(int from, int to, boolean reverse) {
080: this .from = from;
081: this .to = to;
082: this .reverse = reverse;
083: }
084:
085: public boolean equals(Object that) {
086: if (that instanceof IntRange) {
087: return equals((IntRange) that);
088: } else if (that instanceof List) {
089: return equals((List) that);
090: }
091: return false;
092: }
093:
094: public boolean equals(List that) {
095: int size = size();
096: if (that.size() == size) {
097: for (int i = 0; i < size; i++) {
098: if (!DefaultTypeTransformation.compareEqual(get(i),
099: that.get(i))) {
100: return false;
101: }
102: }
103: return true;
104: }
105: return false;
106: }
107:
108: public boolean equals(IntRange that) {
109: return this .reverse == that.reverse && this .from == that.from
110: && this .to == that.to;
111: }
112:
113: public Comparable getFrom() {
114: return new Integer(from);
115: }
116:
117: public Comparable getTo() {
118: return new Integer(to);
119: }
120:
121: public int getFromInt() {
122: return from;
123: }
124:
125: public int getToInt() {
126: return to;
127: }
128:
129: public boolean isReverse() {
130: return reverse;
131: }
132:
133: public Object get(int index) {
134: if (index < 0) {
135: throw new IndexOutOfBoundsException("Index: " + index
136: + " should not be negative");
137: }
138: if (index >= size()) {
139: throw new IndexOutOfBoundsException("Index: " + index
140: + " too big for range: " + this );
141: }
142: int value = (reverse) ? to - index : index + from;
143: return new Integer(value);
144: }
145:
146: public int size() {
147: return to - from + 1;
148: }
149:
150: public int hashCode() {
151: return from ^ to + (reverse ? 1 : 0);
152: }
153:
154: public Iterator iterator() {
155: return new Iterator() {
156: int index = 0;
157: int size = size();
158: int value = (reverse) ? to : from;
159:
160: public boolean hasNext() {
161: return index < size;
162: }
163:
164: public Object next() {
165: if (index++ > 0) {
166: if (index > size) {
167: return null;
168: } else {
169: if (reverse) {
170: --value;
171: } else {
172: ++value;
173: }
174: }
175: }
176: return new Integer(value);
177: }
178:
179: public void remove() {
180: IntRange.this .remove(index);
181: }
182: };
183: }
184:
185: public List subList(int fromIndex, int toIndex) {
186: if (fromIndex < 0) {
187: throw new IndexOutOfBoundsException("fromIndex = "
188: + fromIndex);
189: }
190: if (toIndex > size()) {
191: throw new IndexOutOfBoundsException("toIndex = " + toIndex);
192: }
193: if (fromIndex > toIndex) {
194: throw new IllegalArgumentException("fromIndex(" + fromIndex
195: + ") > toIndex(" + toIndex + ")");
196: }
197: return new IntRange(fromIndex + this .from, toIndex + this .from
198: - 1, reverse);
199: }
200:
201: public String toString() {
202: return (reverse) ? "" + to + ".." + from : "" + from + ".."
203: + to;
204: }
205:
206: public String inspect() {
207: return toString();
208: }
209:
210: public boolean contains(Object value) {
211: if (value instanceof Integer) {
212: Integer integer = (Integer) value;
213: int i = integer.intValue();
214: return i >= from && i <= to;
215: } else if (value instanceof IntRange) {
216: IntRange range = (IntRange) value;
217: return from <= range.from && range.to <= to;
218: }
219: return false;
220: }
221:
222: public void step(int step, Closure closure) {
223: if (reverse) {
224: step = -step;
225: }
226: if (step >= 0) {
227: int value = from;
228: while (value <= to) {
229: closure.call(new Integer(value));
230: value = value + step;
231: }
232: } else {
233: int value = to;
234: while (value >= from) {
235: closure.call(new Integer(value));
236: value = value + step;
237: }
238: }
239: }
240:
241: public List step(int step) {
242: IteratorClosureAdapter adapter = new IteratorClosureAdapter(
243: this);
244: step(step, adapter);
245: return adapter.asList();
246: }
247: }
|