001package org.clafer.ir;
002
003import gnu.trove.TIntCollection;
004import gnu.trove.iterator.TIntIterator;
005import java.util.Arrays;
006import org.clafer.collection.ArrayIntIterator;
007import org.clafer.collection.ReverseArrayIntIterator;
008
009/**
010 * A domain over explicitly defined values.
011 *
012 * @author jimmy
013 */
014public class IrEnumDomain implements IrDomain {
015
016    private final int[] values;
017
018    /**
019     * @param values sorted, unique, and immutable integers
020     */
021    public IrEnumDomain(int[] values) {
022        if (values.length == 0) {
023            throw new IllegalArgumentException();
024        }
025        this.values = values;
026    }
027
028    /**
029     * {@inheritDoc}
030     */
031    @Override
032    public boolean isBounded() {
033        // Although technically the domain might be contigious, it is too expensive
034        // to check.
035        return false;
036    }
037
038    /**
039     * {@inheritDoc}
040     */
041    @Override
042    public boolean contains(int value) {
043        return Arrays.binarySearch(values, value) >= 0;
044    }
045
046    /**
047     * {@inheritDoc}
048     */
049    @Override
050    public int getLowBound() {
051        return values[0];
052    }
053
054    /**
055     * {@inheritDoc}
056     */
057    @Override
058    public int getHighBound() {
059        return values[values.length - 1];
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 values.length;
076    }
077
078    /**
079     * {@inheritDoc}
080     */
081    @Override
082    public int[] getValues() {
083        return values;
084    }
085
086    /**
087     * {@inheritDoc}
088     */
089    @Override
090    public TIntIterator iterator() {
091        return new ArrayIntIterator(values);
092    }
093
094    /**
095     * {@inheritDoc}
096     */
097    @Override
098    public TIntIterator iterator(boolean increasing) {
099        return increasing ? new ArrayIntIterator(values) : new ReverseArrayIntIterator(values);
100    }
101
102    /**
103     * {@inheritDoc}
104     */
105    @Override
106    public void transferTo(TIntCollection collection) {
107        collection.addAll(values);
108    }
109
110    /**
111     * {@inheritDoc}
112     */
113    @Override
114    public boolean equals(Object obj) {
115        if (this == obj) {
116            return true;
117        }
118        if (obj instanceof IrDomain) {
119            IrDomain other = (IrDomain) obj;
120            if (size() != other.size()) {
121                return false;
122            }
123            return Arrays.equals(values, other.getValues());
124        }
125        return false;
126    }
127
128    /**
129     * {@inheritDoc}
130     */
131    @Override
132    public int hashCode() {
133        return Arrays.hashCode(values);
134    }
135
136    /**
137     * {@inheritDoc}
138     */
139    @Override
140    public String toString() {
141        StringBuilder result = new StringBuilder();
142        result.append('{');
143        for (int i = 0; i < values.length; i++) {
144            if (i > 0) {
145                result.append(", ");
146            }
147            result.append(values[i]);
148        }
149        result.append('}');
150        return result.toString();
151    }
152}