/*
 * @author Ranides Atterwim <ranides@gmail.com>
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira
 */
package net.ranides.assira.functional;

import java.util.function.IntBinaryOperator;
import net.ranides.assira.collection.iterators.IntIterator;

@FunctionalInterface
public interface IntFold extends IntBinaryOperator, Fold<Integer> {
    
    int apply(int a, int b);
    
    @Override
    default Integer apply(Integer a, Integer b) {
        return apply(a.intValue(), b.intValue());
    }
    
    @Override
    default int applyAsInt(int a, int b) {
        return apply(a, b);
    }
    
    default int apply(IntIterator iterator) {
        return apply(iterator, (IntBinaryOperator)this);
    }
    
    default int apply(int[] array) {
        return apply(array, this);
    }
    
    static int apply(IntIterator iterator, IntBinaryOperator operator) {
        int ret = iterator.nextInt();
        while(iterator.hasNext()) {
            ret = operator.applyAsInt(ret, iterator.nextInt());
        }
        return ret;
    }
    
    static int apply(int[] array, IntBinaryOperator operator) {
        int ret = array[0];
        for(int i=1; i<array.length; i++) {
            ret = operator.applyAsInt(ret, array[i]);
        }
        return ret;
    }
}
