// 
// Decompiled by Procyon v0.6.0
// 

package it.unimi.dsi.fastutil.shorts;

import java.io.ObjectStreamException;
import java.io.InvalidObjectException;
import it.unimi.dsi.fastutil.SafeMath;
import java.util.ListIterator;
import java.util.Spliterator;
import java.util.List;
import java.util.Arrays;
import java.util.NoSuchElementException;
import java.util.Iterator;
import java.util.Collection;
import java.io.Serializable;
import java.util.RandomAccess;

public class ShortImmutableList extends ShortLists.ImmutableListBase implements ShortList, RandomAccess, Cloneable, Serializable
{
    private static final long serialVersionUID = 0L;
    static final ShortImmutableList EMPTY;
    private final short[] a;
    
    public ShortImmutableList(final short[] a) {
        this.a = a;
    }
    
    public ShortImmutableList(final Collection<? extends Short> c) {
        this(c.isEmpty() ? ShortArrays.EMPTY_ARRAY : ShortIterators.unwrap(ShortIterators.asShortIterator(c.iterator())));
    }
    
    public ShortImmutableList(final ShortCollection c) {
        this(c.isEmpty() ? ShortArrays.EMPTY_ARRAY : ShortIterators.unwrap(c.iterator()));
    }
    
    public ShortImmutableList(final ShortList l) {
        this(l.isEmpty() ? ShortArrays.EMPTY_ARRAY : new short[l.size()]);
        l.getElements(0, this.a, 0, l.size());
    }
    
    public ShortImmutableList(final short[] a, final int offset, final int length) {
        this((length == 0) ? ShortArrays.EMPTY_ARRAY : new short[length]);
        System.arraycopy(a, offset, this.a, 0, length);
    }
    
    public ShortImmutableList(final ShortIterator i) {
        this(i.hasNext() ? ShortIterators.unwrap(i) : ShortArrays.EMPTY_ARRAY);
    }
    
    public static ShortImmutableList of() {
        return ShortImmutableList.EMPTY;
    }
    
    public static ShortImmutableList of(final short... init) {
        return (init.length == 0) ? of() : new ShortImmutableList(init);
    }
    
    @Override
    public short getShort(final int index) {
        if (index >= this.a.length) {
            throw new IndexOutOfBoundsException("Index (" + index + ") is greater than or equal to list size (" + this.a.length + ")");
        }
        return this.a[index];
    }
    
    @Override
    public int indexOf(final short k) {
        for (int i = 0, size = this.a.length; i < size; ++i) {
            if (k == this.a[i]) {
                return i;
            }
        }
        return -1;
    }
    
    @Override
    public int lastIndexOf(final short k) {
        int i = this.a.length;
        while (i-- != 0) {
            if (k == this.a[i]) {
                return i;
            }
        }
        return -1;
    }
    
    @Override
    public int size() {
        return this.a.length;
    }
    
    @Override
    public boolean isEmpty() {
        return this.a.length == 0;
    }
    
    @Override
    public void getElements(final int from, final short[] a, final int offset, final int length) {
        ShortArrays.ensureOffsetLength(a, offset, length);
        System.arraycopy(this.a, from, a, offset, length);
    }
    
    @Override
    public void forEach(final ShortConsumer action) {
        for (int i = 0; i < this.a.length; ++i) {
            action.accept(this.a[i]);
        }
    }
    
    @Override
    public short[] toShortArray() {
        if (this.a.length == 0) {
            return ShortArrays.EMPTY_ARRAY;
        }
        return this.a.clone();
    }
    
    @Override
    public short[] toArray(short[] a) {
        if (a == null || a.length < this.size()) {
            a = new short[this.a.length];
        }
        System.arraycopy(this.a, 0, a, 0, a.length);
        return a;
    }
    
    @Override
    public ShortListIterator listIterator(final int index) {
        this.ensureIndex(index);
        return new ShortListIterator() {
            int pos = index;
            
            @Override
            public boolean hasNext() {
                return this.pos < ShortImmutableList.this.a.length;
            }
            
            @Override
            public boolean hasPrevious() {
                return this.pos > 0;
            }
            
            @Override
            public short nextShort() {
                if (!this.hasNext()) {
                    throw new NoSuchElementException();
                }
                return ShortImmutableList.this.a[this.pos++];
            }
            
            @Override
            public short previousShort() {
                if (!this.hasPrevious()) {
                    throw new NoSuchElementException();
                }
                final short[] access$000 = ShortImmutableList.this.a;
                final int pos = this.pos - 1;
                this.pos = pos;
                return access$000[pos];
            }
            
            @Override
            public int nextIndex() {
                return this.pos;
            }
            
            @Override
            public int previousIndex() {
                return this.pos - 1;
            }
            
            @Override
            public void forEachRemaining(final ShortConsumer action) {
                while (this.pos < ShortImmutableList.this.a.length) {
                    action.accept(ShortImmutableList.this.a[this.pos++]);
                }
            }
            
            @Override
            public void add(final short k) {
                throw new UnsupportedOperationException();
            }
            
            @Override
            public void set(final short k) {
                throw new UnsupportedOperationException();
            }
            
            @Override
            public void remove() {
                throw new UnsupportedOperationException();
            }
            
            @Override
            public int back(int n) {
                if (n < 0) {
                    throw new IllegalArgumentException("Argument must be nonnegative: " + n);
                }
                final int remaining = ShortImmutableList.this.a.length - this.pos;
                if (n < remaining) {
                    this.pos -= n;
                }
                else {
                    n = remaining;
                    this.pos = 0;
                }
                return n;
            }
            
            @Override
            public int skip(int n) {
                if (n < 0) {
                    throw new IllegalArgumentException("Argument must be nonnegative: " + n);
                }
                final int remaining = ShortImmutableList.this.a.length - this.pos;
                if (n < remaining) {
                    this.pos += n;
                }
                else {
                    n = remaining;
                    this.pos = ShortImmutableList.this.a.length;
                }
                return n;
            }
        };
    }
    
    @Override
    public ShortSpliterator spliterator() {
        return new Spliterator();
    }
    
    @Override
    public ShortList subList(final int from, final int to) {
        if (from == 0 && to == this.size()) {
            return this;
        }
        this.ensureIndex(from);
        this.ensureIndex(to);
        if (from == to) {
            return ShortImmutableList.EMPTY;
        }
        if (from > to) {
            throw new IllegalArgumentException("Start index (" + from + ") is greater than end index (" + to + ")");
        }
        return new ImmutableSubList(this, from, to);
    }
    
    public ShortImmutableList clone() {
        return this;
    }
    
    public boolean equals(final ShortImmutableList l) {
        if (l == this) {
            return true;
        }
        if (this.a == l.a) {
            return true;
        }
        final int s = this.size();
        if (s != l.size()) {
            return false;
        }
        final short[] a1 = this.a;
        final short[] a2 = l.a;
        return Arrays.equals(a1, a2);
    }
    
    @Override
    public boolean equals(final Object o) {
        if (o == this) {
            return true;
        }
        if (o == null) {
            return false;
        }
        if (!(o instanceof List)) {
            return false;
        }
        if (o instanceof ShortImmutableList) {
            return this.equals((ShortImmutableList)o);
        }
        if (o instanceof ImmutableSubList) {
            return ((ImmutableSubList)o).equals(this);
        }
        return super.equals(o);
    }
    
    public int compareTo(final ShortImmutableList l) {
        if (this.a == l.a) {
            return 0;
        }
        final int s1 = this.size();
        final int s2 = l.size();
        final short[] a1 = this.a;
        final short[] a2 = l.a;
        int i;
        for (i = 0; i < s1 && i < s2; ++i) {
            final short e1 = a1[i];
            final short e2 = a2[i];
            final int r;
            if ((r = Short.compare(e1, e2)) != 0) {
                return r;
            }
        }
        return (i < s2) ? -1 : ((i < s1) ? 1 : 0);
    }
    
    @Override
    public int compareTo(final List<? extends Short> l) {
        if (l instanceof ShortImmutableList) {
            return this.compareTo((ShortImmutableList)l);
        }
        if (l instanceof ImmutableSubList) {
            final ImmutableSubList other = (ImmutableSubList)l;
            return -other.compareTo(this);
        }
        return super.compareTo(l);
    }
    
    static {
        EMPTY = new ShortImmutableList(ShortArrays.EMPTY_ARRAY);
    }
    
    private final class Spliterator implements ShortSpliterator
    {
        int pos;
        int max;
        
        public Spliterator(final ShortImmutableList x0) {
            this(x0, 0, x0.a.length);
        }
        
        private Spliterator(final int pos, final int max) {
            assert pos <= max : "pos " + pos + " must be <= max " + max;
            this.pos = pos;
            this.max = max;
        }
        
        @Override
        public int characteristics() {
            return 17744;
        }
        
        @Override
        public long estimateSize() {
            return this.max - this.pos;
        }
        
        @Override
        public boolean tryAdvance(final ShortConsumer action) {
            if (this.pos >= this.max) {
                return false;
            }
            action.accept(ShortImmutableList.this.a[this.pos++]);
            return true;
        }
        
        @Override
        public void forEachRemaining(final ShortConsumer action) {
            while (this.pos < this.max) {
                action.accept(ShortImmutableList.this.a[this.pos]);
                ++this.pos;
            }
        }
        
        @Override
        public long skip(long n) {
            if (n < 0L) {
                throw new IllegalArgumentException("Argument must be nonnegative: " + n);
            }
            if (this.pos >= this.max) {
                return 0L;
            }
            final int remaining = this.max - this.pos;
            if (n < remaining) {
                this.pos = SafeMath.safeLongToInt(this.pos + n);
                return n;
            }
            n = remaining;
            this.pos = this.max;
            return n;
        }
        
        @Override
        public ShortSpliterator trySplit() {
            final int retLen = this.max - this.pos >> 1;
            if (retLen <= 1) {
                return null;
            }
            final int retMax;
            final int myNewPos = retMax = this.pos + retLen;
            final int oldPos = this.pos;
            this.pos = myNewPos;
            return new Spliterator(oldPos, retMax);
        }
    }
    
    private static final class ImmutableSubList extends ShortLists.ImmutableListBase implements RandomAccess, Serializable
    {
        private static final long serialVersionUID = 7054639518438982401L;
        final ShortImmutableList innerList;
        final int from;
        final int to;
        final transient short[] a;
        
        ImmutableSubList(final ShortImmutableList innerList, final int from, final int to) {
            this.innerList = innerList;
            this.from = from;
            this.to = to;
            this.a = innerList.a;
        }
        
        @Override
        public short getShort(final int index) {
            this.ensureRestrictedIndex(index);
            return this.a[index + this.from];
        }
        
        @Override
        public int indexOf(final short k) {
            for (int i = this.from; i < this.to; ++i) {
                if (k == this.a[i]) {
                    return i - this.from;
                }
            }
            return -1;
        }
        
        @Override
        public int lastIndexOf(final short k) {
            int i = this.to;
            while (i-- != this.from) {
                if (k == this.a[i]) {
                    return i - this.from;
                }
            }
            return -1;
        }
        
        @Override
        public int size() {
            return this.to - this.from;
        }
        
        @Override
        public boolean isEmpty() {
            return this.to <= this.from;
        }
        
        @Override
        public void getElements(final int fromSublistIndex, final short[] a, final int offset, final int length) {
            ShortArrays.ensureOffsetLength(a, offset, length);
            this.ensureRestrictedIndex(fromSublistIndex);
            if (this.from + length > this.to) {
                throw new IndexOutOfBoundsException("Final index " + (this.from + length) + " (startingIndex: " + this.from + " + length: " + length + ") is greater then list length " + this.size());
            }
            System.arraycopy(this.a, fromSublistIndex + this.from, a, offset, length);
        }
        
        @Override
        public void forEach(final ShortConsumer action) {
            for (int i = this.from; i < this.to; ++i) {
                action.accept(this.a[i]);
            }
        }
        
        @Override
        public short[] toShortArray() {
            return Arrays.copyOfRange(this.a, this.from, this.to);
        }
        
        @Override
        public short[] toArray(short[] a) {
            if (a == null || a.length < this.size()) {
                a = new short[this.size()];
            }
            System.arraycopy(this.a, this.from, a, 0, this.size());
            return a;
        }
        
        @Override
        public ShortListIterator listIterator(final int index) {
            this.ensureIndex(index);
            return new ShortListIterator() {
                int pos = index;
                
                @Override
                public boolean hasNext() {
                    return this.pos < ImmutableSubList.this.to;
                }
                
                @Override
                public boolean hasPrevious() {
                    return this.pos > ImmutableSubList.this.from;
                }
                
                @Override
                public short nextShort() {
                    if (!this.hasNext()) {
                        throw new NoSuchElementException();
                    }
                    return ImmutableSubList.this.a[this.pos++ + ImmutableSubList.this.from];
                }
                
                @Override
                public short previousShort() {
                    if (!this.hasPrevious()) {
                        throw new NoSuchElementException();
                    }
                    final short[] a = ImmutableSubList.this.a;
                    final int pos = this.pos - 1;
                    this.pos = pos;
                    return a[pos + ImmutableSubList.this.from];
                }
                
                @Override
                public int nextIndex() {
                    return this.pos;
                }
                
                @Override
                public int previousIndex() {
                    return this.pos - 1;
                }
                
                @Override
                public void forEachRemaining(final ShortConsumer action) {
                    while (this.pos < ImmutableSubList.this.to) {
                        action.accept(ImmutableSubList.this.a[this.pos++ + ImmutableSubList.this.from]);
                    }
                }
                
                @Override
                public void add(final short k) {
                    throw new UnsupportedOperationException();
                }
                
                @Override
                public void set(final short k) {
                    throw new UnsupportedOperationException();
                }
                
                @Override
                public void remove() {
                    throw new UnsupportedOperationException();
                }
                
                @Override
                public int back(int n) {
                    if (n < 0) {
                        throw new IllegalArgumentException("Argument must be nonnegative: " + n);
                    }
                    final int remaining = ImmutableSubList.this.to - this.pos;
                    if (n < remaining) {
                        this.pos -= n;
                    }
                    else {
                        n = remaining;
                        this.pos = 0;
                    }
                    return n;
                }
                
                @Override
                public int skip(int n) {
                    if (n < 0) {
                        throw new IllegalArgumentException("Argument must be nonnegative: " + n);
                    }
                    final int remaining = ImmutableSubList.this.to - this.pos;
                    if (n < remaining) {
                        this.pos += n;
                    }
                    else {
                        n = remaining;
                        this.pos = ImmutableSubList.this.to;
                    }
                    return n;
                }
            };
        }
        
        @Override
        public ShortSpliterator spliterator() {
            return new SubListSpliterator();
        }
        
        boolean contentsEquals(final short[] otherA, final int otherAFrom, final int otherATo) {
            if (this.a == otherA && this.from == otherAFrom && this.to == otherATo) {
                return true;
            }
            if (otherATo - otherAFrom != this.size()) {
                return false;
            }
            int pos = this.from;
            int otherPos = otherAFrom;
            while (pos < this.to) {
                if (this.a[pos++] != otherA[otherPos++]) {
                    return false;
                }
            }
            return true;
        }
        
        @Override
        public boolean equals(final Object o) {
            if (o == this) {
                return true;
            }
            if (o == null) {
                return false;
            }
            if (!(o instanceof List)) {
                return false;
            }
            if (o instanceof ShortImmutableList) {
                final ShortImmutableList other = (ShortImmutableList)o;
                return this.contentsEquals(other.a, 0, other.size());
            }
            if (o instanceof ImmutableSubList) {
                final ImmutableSubList other2 = (ImmutableSubList)o;
                return this.contentsEquals(other2.a, other2.from, other2.to);
            }
            return super.equals(o);
        }
        
        int contentsCompareTo(final short[] otherA, final int otherAFrom, final int otherATo) {
            if (this.a == otherA && this.from == otherAFrom && this.to == otherATo) {
                return 0;
            }
            int i = this.from;
            for (int j = otherAFrom; i < this.to && i < otherATo; ++i, ++j) {
                final short e1 = this.a[i];
                final short e2 = otherA[j];
                final int r;
                if ((r = Short.compare(e1, e2)) != 0) {
                    return r;
                }
            }
            return (i < otherATo) ? -1 : ((i < this.to) ? 1 : 0);
        }
        
        @Override
        public int compareTo(final List<? extends Short> l) {
            if (l instanceof ShortImmutableList) {
                final ShortImmutableList other = (ShortImmutableList)l;
                return this.contentsCompareTo(other.a, 0, other.size());
            }
            if (l instanceof ImmutableSubList) {
                final ImmutableSubList other2 = (ImmutableSubList)l;
                return this.contentsCompareTo(other2.a, other2.from, other2.to);
            }
            return super.compareTo(l);
        }
        
        private Object readResolve() throws ObjectStreamException {
            try {
                return this.innerList.subList(this.from, this.to);
            }
            catch (final IllegalArgumentException | IndexOutOfBoundsException ex) {
                throw (InvalidObjectException)new InvalidObjectException(ex.getMessage()).initCause(ex);
            }
        }
        
        @Override
        public ShortList subList(final int from, final int to) {
            this.ensureIndex(from);
            this.ensureIndex(to);
            if (from == to) {
                return ShortImmutableList.EMPTY;
            }
            if (from > to) {
                throw new IllegalArgumentException("Start index (" + from + ") is greater than end index (" + to + ")");
            }
            return new ImmutableSubList(this.innerList, from + this.from, to + this.from);
        }
        
        private final class SubListSpliterator extends ShortSpliterators.EarlyBindingSizeIndexBasedSpliterator
        {
            SubListSpliterator() {
                super(ImmutableSubList.this.from, ImmutableSubList.this.to);
            }
            
            private SubListSpliterator(final int pos, final int maxPos) {
                super(pos, maxPos);
            }
            
            @Override
            protected final short get(final int i) {
                return ImmutableSubList.this.a[i];
            }
            
            @Override
            protected final SubListSpliterator makeForSplit(final int pos, final int maxPos) {
                return new SubListSpliterator(pos, maxPos);
            }
            
            @Override
            public boolean tryAdvance(final ShortConsumer action) {
                if (this.pos >= this.maxPos) {
                    return false;
                }
                action.accept(ImmutableSubList.this.a[this.pos++]);
                return true;
            }
            
            @Override
            public void forEachRemaining(final ShortConsumer action) {
                final int max = this.maxPos;
                while (this.pos < max) {
                    action.accept(ImmutableSubList.this.a[this.pos++]);
                }
            }
            
            @Override
            public int characteristics() {
                return 17744;
            }
        }
    }
}
