View Javadoc

    1   /*
    2    $Id: IntRange.java 4098 2006-10-10 16:09:48Z blackdrag $
    3
    4    Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
    5
    6    Redistribution and use of this software and associated documentation
    7    ("Software"), with or without modification, are permitted provided
    8    that the following conditions are met:
    9
    10   1. Redistributions of source code must retain copyright
    11      statements and notices.  Redistributions must also contain a
    12      copy of this document.
    13
    14   2. Redistributions in binary form must reproduce the
    15      above copyright notice, this list of conditions and the
    16      following disclaimer in the documentation and/or other
    17      materials provided with the distribution.
    18
    19   3. The name "groovy" must not be used to endorse or promote
    20      products derived from this Software without prior written
    21      permission of The Codehaus.  For written permission,
    22      please contact info@codehaus.org.
    23
    24   4. Products derived from this Software may not be called "groovy"
    25      nor may "groovy" appear in their names without prior written
    26      permission of The Codehaus. "groovy" is a registered
    27      trademark of The Codehaus.
    28
    29   5. Due credit should be given to The Codehaus -
    30      http://groovy.codehaus.org/
    31
    32   THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
    33   ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
    34   NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
    35   FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
    36   THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
    37   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    38   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    39   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    40   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
    41   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    42   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
    43   OF THE POSSIBILITY OF SUCH DAMAGE.
    44
    45   */
    46  package groovy.lang;
    47
    48  import java.util.AbstractList;
    49  import java.util.Iterator;
    50  import java.util.List;
    51
    52  import org.codehaus.groovy.runtime.IteratorClosureAdapter;
    53  import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
    54
    55  /***
    56   * Represents a list of Integer objects from a specified int up to and including
    57   * a given and to.
    58   *
    59   * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
    60   * @version $Revision: 4098 $
    61   */
    62  public class IntRange extends AbstractList implements Range {
    63
    64      private int from;
    65      private int to;
    66      private boolean reverse;
    67
    68      public IntRange(int from, int to) {
    69          if (from > to) {
    70              this.from = to;
    71              this.to = from;
    72              this.reverse = true;
    73          }
    74          else {
    75              this.from = from;
    76              this.to = to;
    77          }
    78      }
    79
    80      protected IntRange(int from, int to, boolean reverse) {
    81          this.from = from;
    82          this.to = to;
    83          this.reverse = reverse;
    84      }
    85
    86      public boolean equals(Object that) {
    87          if (that instanceof IntRange) {
    88              return equals((IntRange) that);
    89          }
    90          else if (that instanceof List) {
    91              return equals((List) that);
    92          }
    93          return false;
    94      }
    95
    96      public boolean equals(List that) {
    97          int size = size();
    98          if (that.size() == size) {
    99              for (int i = 0; i < size; i++) {
    100                 if (!DefaultTypeTransformation.compareEqual(get(i), that.get(i))) {
    101                     return false;
    102                 }
    103             }
    104             return true;
    105         }
    106         return false;
    107     }
    108
    109     public boolean equals(IntRange that) {
    110         return this.reverse == that.reverse && this.from == that.from && 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 + " should not be negative");
    136         }
    137         if (index >= size()) {
    138             throw new IndexOutOfBoundsException("Index: " + index + " too big for range: " + this);
    139         }
    140         int value = (reverse) ? to - index : index + from;
    141         return new Integer(value);
    142     }
    143
    144     public int size() {
    145         return to - from + 1;
    146     }
    147
    148     public int hashCode() {
    149         return from ^ to + (reverse ? 1 : 0);
    150     }
    151
    152     public Iterator iterator() {
    153         return new Iterator() {
    154             int index = 0;
    155             int size = size();
    156             int value = (reverse) ? to : from;
    157
    158             public boolean hasNext() {
    159                 return index < size;
    160             }
    161
    162             public Object next() {
    163                 if (index++ > 0) {
    164                     if (index > size) {
    165                         return null;
    166                     }
    167                     else {
    168                         if (reverse) {
    169                             --value;
    170                         }
    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 = " + fromIndex);
    188         }
    189         if (toIndex > size()) {
    190             throw new IndexOutOfBoundsException("toIndex = " + toIndex);
    191         }
    192         if (fromIndex > toIndex) {
    193             throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")");
    194         }
    195         return new IntRange(fromIndex + this.from, toIndex + this.from - 1, reverse);
    196     }
    197
    198     public String toString() {
    199         return (reverse) ? "" + to + ".." + from : "" + from + ".." + to;
    200     }
    201
    202     public String inspect() {
    203         return toString();
    204     }
    205
    206     public boolean contains(Object value) {
    207         if (value instanceof Integer) {
    208             Integer integer = (Integer) value;
    209             int i = integer.intValue();
    210             return i >= from && i <= to;
    211         } else if (value instanceof IntRange) {
    212             IntRange range = (IntRange) value;
    213             return from<=range.from && range.to<=to;
    214         }
    215         return false;
    216     }
    217
    218     public void step(int step, Closure closure) {
    219         if (reverse) {
    220             step = -step;
    221         }
    222         if (step >= 0) {
    223             int value = from;
    224             while (value <= to) {
    225                 closure.call(new Integer(value));
    226                 value = value + step;
    227             }
    228         }
    229         else {
    230             int value = to;
    231             while (value >= from) {
    232                 closure.call(new Integer(value));
    233                 value = value + step;
    234             }
    235         }
    236     }
    237
    238     public List step(int step) {
    239         IteratorClosureAdapter adapter = new IteratorClosureAdapter(this);
    240         step(step, adapter);
    241         return adapter.asList();
    242     }
    243 }