001/*
002 * $Id$
003 */
004
005package edu.jas.poly;
006
007import java.util.Map;
008import java.util.SortedMap;
009import java.util.Comparator;
010import java.util.Iterator;
011import java.util.Spliterator;
012import java.util.Spliterators;
013import java.util.function.Consumer;
014
015import edu.jas.structure.RingElem;
016
017import edu.jas.poly.ExpVector;
018
019
020/**
021 * Spliterator over monomials of a polynomial. 
022 * Adaptor for val.entrySet().spliterator().
023 * @author Heinz Kredel
024 */
025
026public class PolySpliterator<C extends RingElem<C> > 
027    implements Spliterator< Monomial<C> > {
028
029
030    /** 
031     * Internal spliterator over polynomial map.
032     */
033    protected Spliterator< Map.Entry<ExpVector,C> > ms;
034
035
036    /** 
037     * Polynomial sorted map.
038     */
039    protected SortedMap<ExpVector,C> sm;
040
041    
042    /** 
043     * Constructor of polynomial spliterator.
044     * @param m SortedMap of a polynomial.
045     */
046    public PolySpliterator( SortedMap<ExpVector,C> m ) {
047        //this(Spliterators.spliterator(m.entrySet(), Spliterator.NONNULL), m);
048        this(m.entrySet().spliterator(), m);
049    }
050
051
052    /** 
053     * Constructor of polynomial spliterator.
054     * @param mse Spliterator a polynomial.
055     * @param m SortedMap of a polynomial.
056     */
057    protected PolySpliterator( Spliterator<Map.Entry<ExpVector,C>> mse, SortedMap<ExpVector,C> m ) {
058        sm = m;
059        ms = mse;
060    }
061
062    
063    /**
064     * String representation of PolySpliterator.
065     * @see java.lang.Object#toString()
066     */
067    @Override
068    public String toString() {
069        return "PolySpliterator(" + estimateSize() + ", " + characteristics() + ")";
070    }
071
072    
073    /** 
074     * Returns a set of characteristics of this Spliterator and its
075     * elements.
076     * @return ORed value of the characteristics.
077     */
078    public int characteristics() {
079        return ms.characteristics();
080    }
081
082    
083    /** 
084     * Returns an estimate of the number of elements of this Spliterator.
085     * @return size of the sorted map.
086     */
087    public long estimateSize() {
088        return ms.estimateSize();
089    }
090
091    
092    /** 
093     * Get the monomial comparator.
094     * @return monomial comparator.
095     */
096    public Comparator<Monomial<C>> getComparator() {
097        return new Comparator<Monomial<C>>() {
098            @Override
099            public int compare(Monomial<C> a, Monomial<C> b) {
100                if (sm == null) {
101                    throw new RuntimeException("sm == null");
102                }
103                int s = sm.comparator().compare(a.e, b.e);
104                if (s != 0) { // always true
105                    return s;
106                }
107                return a.c.compareTo(b.c);
108            }
109        };
110    }
111
112
113    /** 
114     * Try to split this spliterator.
115     * @return polynomial spliterator or null.
116     */
117    public PolySpliterator<C> trySplit() {
118        Spliterator< Map.Entry<ExpVector,C> > part = ms.trySplit();
119        //System.out.println("PolySplit(" + part.characteristics() + ")");
120        return new PolySpliterator<C>(part, sm);
121    }
122
123
124    /** 
125     * If a remaining element exists perform the action on it.
126     * @return true if the polynomial spliterator could be advanced, else false.
127     */
128    public boolean tryAdvance(Consumer<? super Monomial<C>> action) {
129        Consumer<Map.Entry<ExpVector,C>> mact =
130            new Consumer<Map.Entry<ExpVector,C>>() {
131                public void accept(Map.Entry<ExpVector,C> me) {
132                    action.accept( new Monomial<C>(me.getKey(), me.getValue()) );
133                }
134            };
135        return ms.tryAdvance(mact);
136    }
137
138}