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

package it.unimi.dsi.fastutil.shorts;

import java.util.Spliterator;

public final class ShortBigSpliterators
{
    public abstract static class AbstractIndexBasedSpliterator extends AbstractShortSpliterator
    {
        protected long pos;
        
        protected AbstractIndexBasedSpliterator(final long initialPos) {
            this.pos = initialPos;
        }
        
        protected abstract short get(final long p0);
        
        protected abstract long getMaxPos();
        
        protected abstract ShortSpliterator makeForSplit(final long p0, final long p1);
        
        protected long computeSplitPoint() {
            return this.pos + (this.getMaxPos() - this.pos) / 2L;
        }
        
        private void splitPointCheck(final long splitPoint, final long observedMax) {
            if (splitPoint < this.pos || splitPoint > observedMax) {
                throw new IndexOutOfBoundsException("splitPoint " + splitPoint + " outside of range of current position " + this.pos + " and range end " + observedMax);
            }
        }
        
        @Override
        public int characteristics() {
            return 16720;
        }
        
        @Override
        public long estimateSize() {
            return this.getMaxPos() - this.pos;
        }
        
        @Override
        public boolean tryAdvance(final ShortConsumer action) {
            if (this.pos >= this.getMaxPos()) {
                return false;
            }
            action.accept(this.get(this.pos++));
            return true;
        }
        
        @Override
        public void forEachRemaining(final ShortConsumer action) {
            final long max = this.getMaxPos();
            while (this.pos < max) {
                action.accept(this.get(this.pos));
                ++this.pos;
            }
        }
        
        @Override
        public long skip(long n) {
            if (n < 0L) {
                throw new IllegalArgumentException("Argument must be nonnegative: " + n);
            }
            final long max = this.getMaxPos();
            if (this.pos >= max) {
                return 0L;
            }
            final long remaining = max - this.pos;
            if (n < remaining) {
                this.pos += n;
                return n;
            }
            n = remaining;
            this.pos = max;
            return n;
        }
        
        @Override
        public ShortSpliterator trySplit() {
            final long max = this.getMaxPos();
            final long splitPoint = this.computeSplitPoint();
            if (splitPoint == this.pos || splitPoint == max) {
                return null;
            }
            this.splitPointCheck(splitPoint, max);
            final long oldPos = this.pos;
            final ShortSpliterator maybeSplit = this.makeForSplit(oldPos, splitPoint);
            if (maybeSplit != null) {
                this.pos = splitPoint;
            }
            return maybeSplit;
        }
    }
    
    public abstract static class EarlyBindingSizeIndexBasedSpliterator extends AbstractIndexBasedSpliterator
    {
        protected final long maxPos;
        
        protected EarlyBindingSizeIndexBasedSpliterator(final long initialPos, final long maxPos) {
            super(initialPos);
            this.maxPos = maxPos;
        }
        
        @Override
        protected final long getMaxPos() {
            return this.maxPos;
        }
    }
    
    public abstract static class LateBindingSizeIndexBasedSpliterator extends AbstractIndexBasedSpliterator
    {
        protected long maxPos;
        private boolean maxPosFixed;
        
        protected LateBindingSizeIndexBasedSpliterator(final long initialPos) {
            super(initialPos);
            this.maxPos = -1L;
            this.maxPosFixed = false;
        }
        
        protected LateBindingSizeIndexBasedSpliterator(final long initialPos, final long fixedMaxPos) {
            super(initialPos);
            this.maxPos = -1L;
            this.maxPos = fixedMaxPos;
            this.maxPosFixed = true;
        }
        
        protected abstract long getMaxPosFromBackingStore();
        
        @Override
        protected final long getMaxPos() {
            return this.maxPosFixed ? this.maxPos : this.getMaxPosFromBackingStore();
        }
        
        @Override
        public ShortSpliterator trySplit() {
            final ShortSpliterator maybeSplit = super.trySplit();
            if (!this.maxPosFixed && maybeSplit != null) {
                this.maxPos = this.getMaxPosFromBackingStore();
                this.maxPosFixed = true;
            }
            return maybeSplit;
        }
    }
}
