/*
 * @author Ranides Atterwim {@literal <ranides@gmail.com>}
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira
 */
package net.ranides.assira.collection.iterators;

import java.util.Spliterators.AbstractSpliterator;
import java.util.function.Consumer;
import java.util.function.IntFunction;

/**
 * Forwad spliterator is abstract class which can be used to create spliterators of unkown size.
 *
 * Spliterators use "forward convention", so do not require as much boiler-plate code as {@link ForwardIterator}
 *
 * @param <T> T
 * @author Ranides Atterwim {@literal <ranides@gmail.com>}
 */
public abstract class ForwardSpliterator<T> extends AbstractSpliterator<T> {

    /**
     * Creates spliterator with correct characteristics
     */
    public ForwardSpliterator() {
        super(Long.MAX_VALUE, IMMUTABLE);
    }

    /**
     * Creates spliterator which generates natural numbers from specified range.
     *
     * @param begin begin
     * @param end end
     * @param function function
     * @param <T> T
     * @return spliterator
     */
    public static <T> ForwardSpliterator<T> range(int begin, int end, IntFunction<T> function) {
        return new ForwardSpliterator<T>() {
            private int index = begin;

            @Override
            public boolean tryAdvance(Consumer<? super T> action) {
                if(index<end) {
                    action.accept(function.apply(index++));
                    return true;
                }
                return false;
            }
        };
    }

}
