001/*
002 * $Id$
003 */
004
005package edu.jas.util;
006
007
008import java.util.Iterator;
009import java.util.NoSuchElementException;
010
011
012/**
013 * Iterable for Long.
014 * @author Heinz Kredel
015 */
016public class LongIterable implements Iterable<Long> {
017
018
019    private boolean nonNegative = true;
020
021
022    private long upperBound = Long.MAX_VALUE;
023
024
025    /**
026     * Constructor.
027     */
028    public LongIterable() {
029    }
030
031
032    /**
033     * Constructor.
034     */
035    public LongIterable(long ub) {
036        upperBound = ub;
037    }
038
039
040    /**
041     * Set the upper bound for the iterator.
042     * @param ub an upper bound for the iterator elements.
043     */
044    public void setUpperBound(long ub) {
045        upperBound = ub;
046    }
047
048
049    /**
050     * Get the upper bound for the iterator.
051     * @return the upper bound for the iterator elements.
052     */
053    public long getUpperBound() {
054        return upperBound;
055    }
056
057
058    /**
059     * Set the iteration algorithm to all elements.
060     */
061    public void setAllIterator() {
062        nonNegative = false;
063    }
064
065
066    /**
067     * Set the iteration algorithm to non-negative elements.
068     */
069    public void setNonNegativeIterator() {
070        nonNegative = true;
071    }
072
073
074    /**
075     * Get an iterator over Long.
076     * @return an iterator.
077     */
078    public Iterator<Long> iterator() {
079        return new LongIterator(nonNegative, upperBound);
080    }
081
082}
083
084
085/**
086 * Long iterator.
087 * @author Heinz Kredel
088 */
089class LongIterator implements Iterator<Long> {
090
091
092    /**
093     * data structure.
094     */
095    long current;
096
097
098    boolean empty;
099
100
101    final boolean nonNegative;
102
103
104    protected long upperBound;
105
106
107    /**
108     * Set the upper bound for the iterator.
109     * @param ub an upper bound for the iterator elements.
110     */
111    public void setUpperBound(long ub) {
112        upperBound = ub;
113    }
114
115
116    /**
117     * Get the upper bound for the iterator.
118     * @return the upper bound for the iterator elements.
119     */
120    public long getUpperBound() {
121        return upperBound;
122    }
123
124
125    /**
126     * Long iterator constructor.
127     */
128    public LongIterator() {
129        this(false, Long.MAX_VALUE);
130    }
131
132
133    /**
134     * Long iterator constructor.
135     * @param nn true for an iterator over non-negative longs, false for all
136     *            elements iterator.
137     * @param ub an upper bound for the entries.
138     */
139    public LongIterator(boolean nn, long ub) {
140        current = 0L;
141        //System.out.println("current = " + current);
142        empty = false;
143        nonNegative = nn;
144        upperBound = ub;
145        //System.out.println("upperBound = " + upperBound);
146    }
147
148
149    /**
150     * Test for availability of a next long.
151     * @return true if the iteration has more Longs, else false.
152     */
153    public synchronized boolean hasNext() {
154        return !empty;
155    }
156
157
158    /**
159     * Get next Long.
160     * @return next Long.
161     */
162    public synchronized Long next() {
163        if (empty) {
164            throw new NoSuchElementException("invalid call of next()");
165        }
166        Long res = Long.valueOf(current);
167        if (nonNegative) {
168            current++;
169        } else if (current > 0L) {
170            current = -current;
171        } else {
172            current = -current;
173            current++;
174        }
175        if (current > upperBound) {
176            empty = true;
177        }
178        return res;
179    }
180
181
182    /**
183     * Remove a tuple if allowed.
184     */
185    public void remove() {
186        throw new UnsupportedOperationException("cannot remove elements");
187    }
188
189}