001/*
002 *  Copyright 2001-2010 Stephen Colebourne
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.joda.primitives.list.impl;
017
018import java.util.Collection;
019import java.util.ConcurrentModificationException;
020import java.util.Iterator;
021import java.util.List;
022import java.util.NoSuchElementException;
023
024import org.joda.primitives.DoubleUtils;
025import org.joda.primitives.collection.impl.AbstractDoubleCollection;
026import org.joda.primitives.iterator.DoubleIterator;
027import org.joda.primitives.list.DoubleList;
028import org.joda.primitives.listiterator.DoubleListIterator;
029
030/**
031 * Abstract base class for lists of primitive <code>double</code> elements.
032 * <p>
033 * This class implements {@link java.util.Collection Collection} allowing
034 * seamless integration with other APIs.
035 * <p>
036 * The <code>get(int)</code> and <code>size()</code> methods must be
037 * implemented by subclases.
038 * To make the subclass modifiable, the <code>add(int, double)</code>,
039 * <code>removeIndex(int)</code> and set(int, double) must also be implemented.
040 * Subclasses may override other methods to increase efficiency.
041 *
042 * @author Stephen Colebourne
043 * @author Rodney Waldhoff
044 * @author Jason Tiscione
045 * @version CODE GENERATED
046 * @since 1.0
047 */
048public abstract class AbstractDoubleList extends AbstractDoubleCollection implements DoubleList {
049    // This file is CODE GENERATED. Do not change manually.
050
051    /**
052     * Constructor.
053     */
054    protected AbstractDoubleList() {
055        super();
056    }
057
058    // DoubleList methods
059    //-----------------------------------------------------------------------
060    /**
061     * Gets an iterator over this list.
062     *
063     * @return an iterator over this list, not null
064     */
065    public DoubleListIterator iterator() {
066        return listIterator(0);
067    }
068
069    /**
070     * Gets a list iterator over this list.
071     * <p>
072     * This implementation uses <code>doubleListIterator(int)</code>.
073     *
074     * @return an iterator over this list, not null
075     */
076    public DoubleListIterator listIterator() {
077        return listIterator(0);
078    }
079
080    /**
081     * Gets a list iterator over this list from a start index.
082     *
083     * @param index  the index to start from
084     * @return an iterator over this list, not null
085     * @throws IndexOutOfBoundsException if the index is invalid
086     */
087    public DoubleListIterator listIterator(int index) {
088        checkIndex(index);
089        return new PListIterator(this, index);
090    }
091
092    /**
093     * Gets the first primitive value.
094     *
095     * @return value at index zero
096     * @throws IndexOutOfBoundsException if the size is zero
097     */
098    public double firstDouble() {
099        return getDouble(0);
100    }
101
102    /**
103     * Gets the last primitive value.
104     *
105     * @return value at index <code>size() - 1</code>
106     * @throws IndexOutOfBoundsException if the size is zero
107     */
108    public double lastDouble() {
109        return getDouble(size() - 1);
110    }
111
112    /**
113     * Checks whether this collection contains a specified primitive value.
114     * <p>
115     * This implementation uses <code>getDouble(int)</code>.
116     *
117     * @param value  the value to search for
118     * @return <code>true</code> if the value is found
119     */
120    public boolean contains(double value) {
121        for (int i = 0, isize = size(); i < isize; i++) {
122            if (getDouble(i) == value) {
123                return true;
124            }
125        }
126        return false;
127    }
128
129    /**
130     * Gets the first index of the specified primitive value.
131     * <p>
132     * This implementation uses <code>indexof(double, int)</code>.
133     *
134     * @param value  the value to search for
135     * @return the zero-based index, or <code>-1</code> if not found
136     */
137    public int indexOf(double value) {
138        return indexOf(value, 0);
139    }
140
141    /**
142     * Gets the first index of the specified primitive value from an index.
143     * <p>
144     * This method follows the conventions of <code>String</code> in that a
145     * negative index is treated as zero, and an index greater than the list
146     * size will simply return <code>-1</code>.
147     * <p>
148     * This implementation uses <code>get(int)</code>.
149     *
150     * @param value  the value to search for
151     * @param fromIndexInclusive  the index to start searching from, inclusive
152     * @return the zero-based index, or <code>-1</code> if not found
153     */
154    public int indexOf(double value, int fromIndexInclusive) {
155        if (fromIndexInclusive < 0) {
156            fromIndexInclusive = 0;
157        }
158        for (int i = fromIndexInclusive, isize = size(); i < isize; i++) {
159            if (getDouble(i) == value) {
160                return i;
161            }
162        }
163        return -1;
164    }
165
166    /**
167     * Gets the last index of the specified primitive value.
168     * <p>
169     * This implementation uses <code>lastIndexof(double, int)</code>.
170     *
171     * @param value  the value to search for
172     * @return the zero-based index, or <code>-1</code> if not found
173     */
174    public int lastIndexOf(double value) {
175        return lastIndexOf(value, size());
176    }
177
178    /**
179     * Gets the first index of the specified primitive value from an index.
180     * <p>
181     * This method follows the conventions of <code>String</code> in that an
182     * index greater than the list size will start searching at the list size,
183     * and a negative index simply returns <code>-1</code>.
184     * <p>
185     * This implementation uses <code>get(int)</code>.
186     *
187     * @param value  the value to search for
188     * @param fromIndexInclusive  the index to start searching from, inclusive
189     * @return the zero-based index, or <code>-1</code> if not found
190     */
191    public int lastIndexOf(double value, int fromIndexInclusive) {
192        if (fromIndexInclusive >= size()) {
193            fromIndexInclusive = size() - 1;
194        }
195        for (int i = fromIndexInclusive; i >= 0; i--) {
196            if (getDouble(i) == value) {
197                return i;
198            }
199        }
200        return -1;
201    }
202
203    /**
204     * Gets a range of elements as an array.
205     *
206     * @param fromIndexInclusive  the index to start from, inclusive
207     * @param toIndexExclusive  the index to end at, exclusive
208     * @return a new array containing a copy of the range of elements, not null
209     * @throws IndexOutOfBoundsException if either index is invalid
210     */
211    public double[] toDoubleArray(int fromIndexInclusive, int toIndexExclusive) {
212        checkRange(fromIndexInclusive, toIndexExclusive);
213        
214        if (fromIndexInclusive == toIndexExclusive) {
215            return DoubleUtils.EMPTY_DOUBLE_ARRAY;
216        }
217        int size = toIndexExclusive - fromIndexInclusive;
218        double[] result = new double[size];
219        arrayCopy(fromIndexInclusive, result, 0, size);
220        return result;
221    }
222
223    /**
224     * Gets a range view of part of this list.
225     * <p>
226     * This method allows operations to work on a range within the greater list.
227     * Changes made to the either object will affect the other.
228     *
229     * @param fromIndexInclusive  the index to start from, inclusive
230     * @param toIndexExclusive  the index to end at, exclusive
231     * @return a new DoubleList for the subList, not null
232     * @throws IndexOutOfBoundsException if either index is invalid
233     */
234    public DoubleList subList(int fromIndexInclusive, int toIndexExclusive) {
235        return null; // TODO
236    }
237
238    /**
239     * Clears the listof all elements (optional operation).
240     * <p>
241     * This implementation uses <code>removeRange(int, int)</code>.
242     *
243     * @throws UnsupportedOperationException if method not supported by this collection
244     */
245    public void clear() {
246        removeRange(0, size());
247    }
248
249    /**
250     * Adds a primitive value to this collection (optional operation).
251     * <p>
252     * This implementation uses <code>add(int, double)</code>.
253     *
254     * @param value  the value to add to this collection
255     * @return <code>true</code> if this collection was modified by this method call
256     * @throws IllegalArgumentException if value is rejected by this collection
257     * @throws UnsupportedOperationException if not supported by this collection
258     */
259    public boolean add(double value) {
260        checkAddModifiable();
261        return add(size(), value);
262    }
263
264    /**
265     * Adds a primitive value to this list at an index (optional operation).
266     * <p>
267     * This implementation throws UnsupportedOperationException.
268     *
269     * @param index  the index to add at
270     * @param value  the value to add to this collection
271     * @return <code>true</code> if this list was modified by this method call
272     * @throws IndexOutOfBoundsException if the index is invalid
273     * @throws IllegalArgumentException if value is rejected by this collection
274     * @throws UnsupportedOperationException if not supported by this collection
275     */
276    public boolean add(int index, double value) {
277        throw new UnsupportedOperationException("List does not support add");
278    }
279
280    /**
281     * Adds an array of primitive values to this list at an index (optional operation).
282     * <p>
283     * This implementation uses <code>addAll(int, double)</code>.
284     *
285     * @param values  the values to add to this collection, null treated as empty array
286     * @return <code>true</code> if this list was modified by this method call
287     * @throws IndexOutOfBoundsException if the index is invalid
288     * @throws IllegalArgumentException if value is rejected by this collection
289     * @throws UnsupportedOperationException if not supported by this collection
290     */
291    public boolean addAll(double[] values) {
292        checkAddModifiable();
293        return addAll(size(), values);
294    }
295
296    /**
297     * Adds an array of primitive values to this list at an index (optional operation).
298     * <p>
299     * This method is optional, throwing an UnsupportedOperationException if the
300     * collection cannot be added to.
301     *
302     * @param index  the index to add at
303     * @param values  the values to add to this collection, null treated as empty array
304     * @return <code>true</code> if this list was modified by this method call
305     * @throws IndexOutOfBoundsException if the index is invalid
306     * @throws IllegalArgumentException if value is rejected by this collection
307     * @throws UnsupportedOperationException if not supported by this collection
308     */
309    public boolean addAll(int index, double[] values) {
310        checkAddModifiable();
311        checkIndex(index);
312        boolean changed = false;
313        if (values != null) {
314            for (int i = 0; i < values.length; i++) {
315                changed |= add(index + i, values[i]);
316            }
317        }
318        return changed;
319    }
320
321    /**
322     * Removes a primitive value by index from the list (optional operation).
323     * <p>
324     * This implementation throws UnsupportedOperationException.
325     *
326     * @param index  the index to remove from
327     * @return the primitive value previously at this index
328     * @throws IndexOutOfBoundsException if the index is invalid
329     * @throws UnsupportedOperationException if not supported by this collection
330     */
331    public double removeDoubleAt(int index) {
332        throw new UnsupportedOperationException("List does not support remove");
333    }
334
335    /**
336     * Removes the first occurrence of a primitive value from the list (optional operation).
337     * <p>
338     * This implementation uses <code>get(int)</code> and <code>removeDoubleAt(int)</code>.
339     *
340     * @param value  the value to remove
341     * @return the primitive value previously at this index
342     * @throws UnsupportedOperationException if not supported by this collection
343     */
344    public boolean removeDouble(double value) {
345        checkRemoveModifiable();
346        for (int i = 0, isize = size(); i < isize; i++) {
347            if (getDouble(i) == value) {
348                removeDoubleAt(i);
349                return true;
350            }
351        }
352        return false;
353    }
354
355    /**
356     * Removes a range of values from the list (optional operation).
357     * <p>
358     * This implementation uses <code>removeDoubleAt(int)</code>.
359     *
360     * @param fromIndexInclusive  the start of the range to remove, inclusive
361     * @param toIndexExclusive  the end of the range to remove, exclusive
362     * @return <code>true</code> if the collection was modified
363     * @throws IndexOutOfBoundsException if the index is invalid
364     * @throws UnsupportedOperationException if remove is not supported
365     */
366    public boolean removeRange(int fromIndexInclusive, int toIndexExclusive) {
367        checkRemoveModifiable();
368        checkRange(fromIndexInclusive, toIndexExclusive);
369        if (fromIndexInclusive == toIndexExclusive) {
370            return false;
371        }
372        for (int i = size() - 1; i >= 0; i--) {
373            removeDoubleAt(i);
374        }
375        return true;
376    }
377
378    /**
379     * Sets the primitive value at a specified index.
380     * <p>
381     * This implementation throws UnsupportedOperationException.
382     *
383     * @param index  the index to set
384     * @param value  the value to store
385     * @return the previous value at the index
386     * @throws IndexOutOfBoundsException if the index is invalid
387     * @throws IllegalArgumentException if value is rejected by this collection
388     * @throws UnsupportedOperationException if not supported by this collection
389     */
390    public double set(int index, double value) {
391        throw new UnsupportedOperationException("List does not support set");
392    }
393
394    // List methods
395    //-----------------------------------------------------------------------
396    /**
397     * Gets the <code>Double</code> value at the specified index.
398     *
399     * @param index  the index to get from
400     * @return value at the index
401     * @throws IndexOutOfBoundsException if the index is invalid
402     */
403    public Double get(int index) {
404        return DoubleUtils.toObject(getDouble(index));
405    }
406
407    /**
408     * Gets the first <code>Double</code> value.
409     *
410     * @return value at index zero or null if the size is zero
411     */
412    public Double first() {
413        if (size() == 0) {
414            return null;
415        }
416        return get(0);
417    }
418
419    /**
420     * Gets the last <code>Double</code> value.
421     *
422     * @return value at index <code>size() - 1</code> or null if the size is zero
423     */
424    public Double last() {
425        if (size() == 0) {
426            return null;
427        }
428        return get(size() - 1);
429    }
430
431    /**
432     * Gets the first index of the specified <code>Double</code> value.
433     *
434     * @param value  the value to search for
435     * @return the zero-based index, or <code>-1</code> if not found
436     * @throws NullPointerException if the value if null
437     * @throws ClassCastException if the object is not <code>Double</code>
438     */
439    public int indexOf(Object value) {
440        return indexOf(DoubleUtils.toPrimitive(value));
441    }
442
443    /**
444     * Gets the first index of the specified <code>Double</code> value from an index.
445     * <p>
446     * This method follows the conventions of <code>String</code> in that a
447     * negative index is treated as zero, and an index greater than the list
448     * size will simply return <code>-1</code>.
449     *
450     * @param value  the value to search for
451     * @param fromIndexInclusive  the index to start searching from, inclusive
452     * @return the zero-based index, or <code>-1</code> if not found
453     * @throws NullPointerException if the value if null
454     * @throws ClassCastException if the object is not <code>Double</code>
455     */
456    public int indexOf(Object value, int fromIndexInclusive) {
457        return indexOf(DoubleUtils.toPrimitive(value), fromIndexInclusive);
458    }
459
460    /**
461     * Gets the last index of the specified <code>Double</code> value.
462     *
463     * @param value  the value to search for
464     * @return the zero-based index, or <code>-1</code> if not found
465     * @throws NullPointerException if the value if null
466     * @throws ClassCastException if the object is not <code>Double</code>
467     */
468    public int lastIndexOf(Object value) {
469        return lastIndexOf(DoubleUtils.toPrimitive(value));
470    }
471
472    /**
473     * Gets the first index of the specified <code>Double</code> value from an index.
474     * <p>
475     * This method follows the conventions of <code>String</code> in that an
476     * index greater than the list size will start searching at the list size,
477     * and a negative index simply returns <code>-1</code>.
478     *
479     * @param value  the value to search for
480     * @param fromIndexInclusive  the index to start searching from, inclusive
481     * @return the zero-based index, or <code>-1</code> if not found
482     * @throws NullPointerException if the value if null
483     * @throws ClassCastException if the object is not <code>Double</code>
484     */
485    public int lastIndexOf(Object value, int fromIndexInclusive) {
486        return lastIndexOf(DoubleUtils.toPrimitive(value), fromIndexInclusive);
487    }
488
489    /**
490     * Adds the <code>Double</code> value to this collection (optional operation).
491     * <p>
492     * This method is optional, throwing an UnsupportedOperationException if the
493     * collection cannot be added to.
494     *
495     * @param value  the value to add to this collection
496     * @return <code>true</code> if this collection was modified by this method call
497     * @throws IllegalArgumentException if value is rejected by this collection
498     * @throws UnsupportedOperationException if not supported by this collection
499     */
500    public boolean add(Double value) {
501        checkAddModifiable();
502        return add(size(), DoubleUtils.toPrimitive(value));
503    }
504
505    /**
506     * Adds the <code>Double</code> value to this list at an index (optional operation).
507     * <p>
508     * This method is optional, throwing an UnsupportedOperationException if the
509     * collection cannot be added to.
510     *
511     * @param index  the index to add at
512     * @param value  the value to add to this collection
513     * @throws IndexOutOfBoundsException if the index is invalid
514     * @throws ClassCastException if the object is not <code>Double</code>
515     * @throws IllegalArgumentException if value is rejected by this collection
516     * @throws UnsupportedOperationException if not supported by this collection
517     */
518    public void add(int index, Double value) {
519        checkAddModifiable();
520        checkIndex(index);
521        add(index, DoubleUtils.toPrimitive(value));
522    }
523
524    /**
525     * Adds an array of <code>Double</code> values to this list at an index (optional operation).
526     * <p>
527     * This method is optional, throwing an UnsupportedOperationException if the
528     * collection cannot be added to.
529     *
530     * @param index  the index to add at
531     * @param coll  the values to add to this collection
532     * @return <code>true</code> if this list was modified by this method call
533     * @throws IndexOutOfBoundsException if the index is invalid
534     * @throws ClassCastException if any object is not <code>Double</code>
535     * @throws IllegalArgumentException if value is rejected by this collection
536     * @throws UnsupportedOperationException if not supported by this collection
537     */
538    public boolean addAll(int index, Collection<? extends Double> coll) {
539        checkAddModifiable();
540        checkIndex(index);
541        return addAll(index, DoubleUtils.toPrimitiveArray(coll));
542    }
543
544    /**
545     * Removes a primitive value by index from the list (optional operation).
546     * <p>
547     * This implementation uses <code>removeDoubleAt(int)</code>.
548     *
549     * @deprecated This method should only be used when working with List and
550     *  not when working with DoubleList - use <code>removeDoubleAt(int)</code>
551     * @param index  the index to remove from
552     * @return the primitive value previously at this index
553     * @throws IndexOutOfBoundsException if the index is invalid
554     * @throws UnsupportedOperationException if not supported by this collection
555     */
556    public Double remove(int index) {
557        checkRemoveModifiable();
558        return DoubleUtils.toObject(removeDoubleAt(index));
559    }
560
561    /**
562     * Sets the <code>Double</code> value at a specified index.
563     * <p>
564     * This implementation uses <code>set(int, double)</code>.
565     *
566     * @param index  the index to set
567     * @param value  the value to store
568     * @return the previous value at the index
569     * @throws IndexOutOfBoundsException if the index is invalid
570     * @throws IllegalArgumentException if value is rejected by this collection
571     * @throws UnsupportedOperationException if not supported by this collection
572     */
573    public Double set(int index, Double value) {
574        checkSetModifiable();
575        checkIndexExists(index);
576        return DoubleUtils.toObject(set(index, DoubleUtils.toPrimitive(value)));
577    }
578
579    //-----------------------------------------------------------------------
580    /**
581     * Compares this list to another as per the contract of <code>List</code>.
582     *
583     * @param obj  the object to compare to
584     * @return <code>true</code> if the lists are equal
585     */
586    public boolean equals(Object obj) {
587        if (obj == this) {
588            return true;
589        }
590        if (obj instanceof DoubleList) {
591            DoubleList other = (DoubleList) obj;
592            if (size() != other.size()) {
593                return false;
594            }
595            DoubleIterator it1 = listIterator();
596            DoubleIterator it2 = other.listIterator();
597            while (it1.hasNext() && it2.hasNext()) {
598                if (it1.nextDouble() != it2.nextDouble()) {
599                    return false;
600                }
601            }
602            return true;
603        } else if (obj instanceof List<?>) {
604            List<?> other = (List<?>) obj;
605            if (size() != other.size()) {
606                return false;
607            }
608            DoubleIterator it1 = listIterator();
609            Iterator<?> it2 = other.listIterator();
610            while (it1.hasNext() && it2.hasNext()) {
611                Object next = it2.next();
612                if (isToPrimitivePossible(next) == false) {
613                    return false;
614                }
615                if (it1.nextDouble() != toPrimitive(next)) {
616                    return false;
617                }
618            }
619            return true;
620        } else {
621            return false;
622        }
623    }
624
625    /**
626     * Gets the hashCode of this list as per the contract of <code>List</code>.
627     *
628     * @return the hash code for this list
629     */
630    public int hashCode() {
631        int hashCode = 1;
632        Iterator<Double> it = iterator();
633        while (it.hasNext()) {
634            Object obj = it.next();
635            hashCode = 31 * hashCode + (obj == null ? 0 : obj.hashCode());
636        }
637        return hashCode;
638    }
639
640    //-----------------------------------------------------------------------
641    /**
642     * Copies data from this collection into the specified array.
643     * This method is pre-validated.
644     * 
645     * @param fromIndex  the index to start from
646     * @param dest  the destination array
647     * @param destIndex  the destination start index
648     * @param size  the number of items to copy
649     */
650    protected void arrayCopy(int fromIndex, double[] dest, int destIndex, int size) {
651        for (int i = 0; i < size; i++) {
652            dest[i + destIndex] = getDouble(i + fromIndex);
653        }
654    }
655
656    /**
657     * Are the set methods supported.
658     * <p>
659     * This implementation returns false.
660     *
661     * @return true if supported
662     */
663    protected boolean isSetModifiable() {
664        return false;
665    }
666
667    /**
668     * Is the collection modifiable in any way.
669     *
670     * @return true if supported
671     */
672    public boolean isModifiable() {
673        return isAddModifiable() || isRemoveModifiable() || isSetModifiable();
674    }
675
676    /**
677     * Check whether add is suported and throw an exception.
678     */
679    protected void checkSetModifiable() {
680        if (isSetModifiable() == false) {
681            throw new UnsupportedOperationException("Collection does not support set");
682        }
683    }
684
685    /**
686     * Checks whether an index is valid or not.
687     * 
688     * @param index  the index to check
689     * @throws IndexOutOfBoundsException if either index is invalid
690     */
691    protected void checkIndexExists(int index) {
692        if (index < 0) {
693            throw new ArrayIndexOutOfBoundsException(
694                "Index less than zero: " + index + " < 0");
695        }
696        if (index >= size()) {
697            throw new ArrayIndexOutOfBoundsException(
698                "Index greater than/equal to size(): " + index + " >= " + size());
699        }
700    }
701
702    /**
703     * Checks whether an index is valid or not.
704     * 
705     * @param index  the index to check
706     * @throws IndexOutOfBoundsException if either index is invalid
707     */
708    protected void checkIndex(int index) {
709        if (index < 0) {
710            throw new ArrayIndexOutOfBoundsException(
711                "Index less than zero: " + index + " < 0");
712        }
713        if (index > size()) {
714            throw new ArrayIndexOutOfBoundsException(
715                "Index greater than size(): " + index + " > " + size());
716        }
717    }
718
719    /**
720     * Checks whether a range is valid or not.
721     * 
722     * @param fromIndexInclusive  the index to start from, inclusive
723     * @param toIndexExclusive  the index to end at, exclusive
724     * @throws IndexOutOfBoundsException if either index is invalid
725     */
726    protected void checkRange(int fromIndexInclusive, int toIndexExclusive) {
727        if (fromIndexInclusive < 0) {
728            throw new ArrayIndexOutOfBoundsException(
729                "From index less than zero: " + fromIndexInclusive + " < 0");
730        }
731        if (toIndexExclusive > size()) {
732            throw new ArrayIndexOutOfBoundsException(
733                "To index greater than size(): " + toIndexExclusive + " > " + size());
734        }
735        if (fromIndexInclusive > toIndexExclusive) {
736            throw new ArrayIndexOutOfBoundsException(
737                "To index greater than from index: " + fromIndexInclusive + " > " + toIndexExclusive);
738        }
739    }
740
741    //-----------------------------------------------------------------------
742    /**
743     * List iterator.
744     */
745    protected static class PListIterator implements DoubleListIterator {
746
747        private final AbstractDoubleList iList;
748        private final int iStart;
749        private int iCursor = 0;
750        private int iLastIndex = -1;
751        
752        protected PListIterator(AbstractDoubleList list, int start) {
753            super();
754            this.iList = list;
755            this.iStart = start;
756            this.iCursor = start;
757        }
758
759        //-----------------------------------------------------------------------
760        public boolean hasNext() {
761            return (iCursor < iList.size());
762        }
763
764        public double nextDouble() {
765            if (hasNext() == false) {
766                throw new NoSuchElementException("No more elements available");
767            }
768            iLastIndex = iCursor;
769            return iList.getDouble(iCursor++);
770        }
771
772        public Double next() {
773            return iList.toObject(nextDouble());
774        }
775
776        public int nextIndex() {
777            return iCursor;
778        }
779
780        //-----------------------------------------------------------------------
781        public boolean hasPrevious() {
782            return (iCursor > 0);
783        }
784
785        public double previousDouble() {
786            if (hasPrevious() == false) {
787                throw new NoSuchElementException("No more elements available");
788            }
789            iLastIndex = --iCursor;
790            return iList.getDouble(iCursor);
791        }
792
793        public Double previous() {
794            return iList.toObject(previousDouble());
795        }
796
797        public int previousIndex() {
798            return iCursor - 1;
799        }
800
801        //-----------------------------------------------------------------------
802        public void remove() {
803            iList.checkRemoveModifiable();
804            if (iLastIndex == -1) {
805                throw new IllegalStateException("Element cannot be removed");
806            }
807            iList.removeDoubleAt(iLastIndex);
808            iCursor = iLastIndex;
809            iLastIndex = -1;
810        }
811
812        public void add(double value) {
813            iList.checkAddModifiable();
814            try {
815                iList.add(iCursor++, value);
816                iLastIndex = -1;
817            } catch (IndexOutOfBoundsException ex) {
818                throw new ConcurrentModificationException("The underlying list was modified");
819            }
820        }
821
822        public void add(Double obj) {
823            iList.checkAddModifiable();
824            add(iList.toPrimitive(obj));
825        }
826        
827        public void set(double value) {
828            iList.checkSetModifiable();
829            if (iLastIndex == -1) {
830                throw new IllegalStateException("Element cannot be set");
831            }
832            try {
833                iList.set(iLastIndex, value);
834            } catch (IndexOutOfBoundsException ex) {
835                throw new ConcurrentModificationException("The underlying list was modified");
836            }
837        }
838
839        public void set(Double obj) {
840            iList.checkSetModifiable();
841            set(iList.toPrimitive(obj));
842        }
843
844        //-----------------------------------------------------------------------
845        public boolean isModifiable() {
846            return iList.isModifiable();
847        }
848
849        public boolean isResettable() {
850            return true;
851        }
852
853        public void reset() {
854            iCursor = iStart;
855        }
856
857    }
858
859}
860