001package org.clafer.ir;
002
003import gnu.trove.TIntCollection;
004import gnu.trove.iterator.TIntIterator;
005import org.clafer.collection.BoundIntIterator;
006import org.clafer.collection.ReverseBoundIntIterator;
007
008/**
009 * A contiguous domain between a low and high bound.
010 *
011 * @author jimmy
012 */
013public class IrBoundDomain implements IrDomain {
014
015    private final int low;
016    private final int high;
017
018    /**
019     * @param low lowest value in the domain, inclusive
020     * @param high highest value in the domain, inclusive
021     */
022    public IrBoundDomain(int low, int high) {
023        if (low > high) {
024            throw new IllegalArgumentException(low + ">" + high);
025        }
026        this.low = low;
027        this.high = high;
028    }
029
030    /**
031     * {@inheritDoc}
032     */
033    @Override
034    public boolean isBounded() {
035        return true;
036    }
037
038    /**
039     * {@inheritDoc}
040     */
041    @Override
042    public boolean contains(int value) {
043        return value >= low && value <= high;
044    }
045
046    /**
047     * {@inheritDoc}
048     */
049    @Override
050    public int getLowBound() {
051        return low;
052    }
053
054    /**
055     * {@inheritDoc}
056     */
057    @Override
058    public int getHighBound() {
059        return high;
060    }
061
062    /**
063     * {@inheritDoc}
064     */
065    @Override
066    public boolean isEmpty() {
067        return false;
068    }
069
070    /**
071     * {@inheritDoc}
072     */
073    @Override
074    public int size() {
075        return high + 1 - low;
076    }
077
078    /**
079     * {@inheritDoc}
080     */
081    @Override
082    public int[] getValues() {
083        int[] values = new int[size()];
084        for (int i = 0; i < values.length; i++) {
085            values[i] = low + i;
086        }
087        return values;
088    }
089
090    /**
091     * {@inheritDoc}
092     */
093    @Override
094    public TIntIterator iterator() {
095        return iterator(true);
096    }
097
098    /**
099     * {@inheritDoc}
100     */
101    @Override
102    public TIntIterator iterator(boolean increasing) {
103        return increasing ? new BoundIntIterator(low, high) : new ReverseBoundIntIterator(low, high);
104    }
105
106    /**
107     * {@inheritDoc}
108     */
109    @Override
110    public void transferTo(TIntCollection collection) {
111        for (int i = low; i <= high; i++) {
112            collection.add(i);
113        }
114    }
115
116    /**
117     * {@inheritDoc}
118     */
119    @Override
120    public boolean equals(Object obj) {
121        if (this == obj) {
122            return true;
123        }
124        if (obj instanceof IrDomain) {
125            IrDomain other = (IrDomain) obj;
126            return size() == other.size()
127                    && low == other.getLowBound()
128                    && high == other.getHighBound();
129        }
130        return false;
131    }
132
133    /**
134     * {@inheritDoc}
135     */
136    @Override
137    public int hashCode() {
138        return low ^ high;
139    }
140
141    /**
142     * {@inheritDoc}
143     */
144    @Override
145    public String toString() {
146        return "{" + low + ", ..., " + high + "}";
147    }
148}