package jetbrains.mps.internal.collections.runtime.impl; /*Generated by MPS */ import jetbrains.mps.internal.collections.runtime.Sequence; import jetbrains.mps.internal.collections.runtime.AbstractSequence; import java.util.Comparator; import java.util.Iterator; import java.util.List; import jetbrains.mps.internal.collections.runtime.ISequence; import jetbrains.mps.baseLanguage.closures.runtime._FunctionTypes; import jetbrains.mps.internal.collections.runtime.SelectComparator; import java.util.ArrayList; import java.util.Arrays; import java.util.ListIterator; public class SortingSequence<U> extends Sequence<U> implements Iterable<U> { private final AbstractSequence<U> input; private final Comparator<? super U> comparator; public SortingSequence(AbstractSequence<U> input, Comparator<? super U> comparator, boolean ascending) { if (input == null || comparator == null) { throw new NullPointerException(); } this.input = input; if (ascending) { this.comparator = comparator; } else { this.comparator = new SortingSequence.InversedComparator<U>(comparator); } } public SortingSequence(AbstractSequence<U> input, Comparator<U> comparator) { if (input == null || comparator == null) { throw new NullPointerException(); } this.input = input; this.comparator = comparator; } @Override public Iterator<U> iterator() { List<U> sortedInput = inputSortedWithSelector(); return new SortingSequence.UnmodifiableIterator<U>(sortedInput.listIterator()); } @Override public ISequence<U> alsoSort(_FunctionTypes._return_P1_E0<? extends Comparable<?>, ? super U> selector, boolean ascending) { SelectComparator<U> selectComparator = new SelectComparator<U>(selector); return new SortingSequence<U>(input, new SortingSequence.CompoundComparator<U>(comparator, (ascending ? selectComparator : new SortingSequence.InversedComparator<U>(selectComparator)))); } @SuppressWarnings(value = "unchecked") private List<U> inputSortedWithSelector() { ArrayList<U> cache = new ArrayList<U>(); for (U u : input) { cache.add(u); } U[] array = (U[]) cache.toArray(); Arrays.sort(array, comparator); return Arrays.asList(array); } private static class UnmodifiableIterator<U> implements Iterator<U> { private final ListIterator<U> source; public UnmodifiableIterator(ListIterator<U> source) { this.source = source; } @Override public boolean hasNext() { return source.hasNext(); } @Override public U next() { return source.next(); } @Override public void remove() { throw new UnsupportedOperationException(); } } private static class InversedComparator<T> implements Comparator<T> { private final Comparator<? super T> primary; public InversedComparator(Comparator<? super T> primary) { this.primary = primary; } @Override public int compare(T a, T b) { return -primary.compare(a, b); } } private static class CompoundComparator<T> implements Comparator<T> { private final Comparator<? super T> secondary; private final Comparator<? super T> primary; public CompoundComparator(Comparator<? super T> primary, Comparator<? super T> secondary) { this.primary = primary; this.secondary = secondary; } @Override public int compare(T a, T b) { int c = primary.compare(a, b); return (c == 0 ? secondary.compare(a, b) : c); } } }