Browse Source

common.iterable: add several helper classes [with Steffen Maercker]

git-svn-id: https://www.prismmodelchecker.org/svn/prism/prism/trunk@12082 bbc10eb1-c90d-0410-af57-cb519fbb1720
master
Joachim Klein 9 years ago
parent
commit
85281b2f2a
  1. 99
      prism/src/common/iterable/EmptyIterable.java
  2. 111
      prism/src/common/iterable/EmptyIterator.java
  3. 285
      prism/src/common/iterable/FilteringIterator.java
  4. 36
      prism/src/common/iterable/IterableDouble.java
  5. 36
      prism/src/common/iterable/IterableInt.java
  6. 36
      prism/src/common/iterable/IterableLong.java
  7. 87
      prism/src/common/iterable/RangeIntIterable.java
  8. 137
      prism/src/common/iterable/SingletonIterator.java

99
prism/src/common/iterable/EmptyIterable.java

@ -0,0 +1,99 @@
//==============================================================================
//
// Copyright (c) 2016-
// Authors:
// * Steffen Maercker <maercker@tcs.inf.tu-dresden.de> (TU Dresden)
// * Joachim Klein <klein@tcs.inf.tu-dresden.de> (TU Dresden)
//
//------------------------------------------------------------------------------
//
// This file is part of PRISM.
//
// PRISM is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// PRISM is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with PRISM; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//==============================================================================
package common.iterable;
import java.util.Iterator;
/**
* Base class for Iterables returning empty iterators,
* static helpers for common primitive iterators.
*/
public abstract class EmptyIterable<T> implements Iterable<T>
{
private static final Of<?> OF = new Of<>();
private static final OfInt OF_INT = new OfInt();
private static final OfDouble OF_DOUBLE = new OfDouble();
@SuppressWarnings("unchecked")
public static <T> Of<T> Of() {
return (Of<T>) OF;
}
public static OfInt OfInt() {
return OF_INT;
}
public static OfDouble OfDouble() {
return OF_DOUBLE;
}
public static class Of<T> extends EmptyIterable<T>
{
private Of() {};
@Override
public Iterator<T> iterator()
{
return EmptyIterator.Of();
}
}
public static class OfInt extends EmptyIterable<Integer> implements IterableInt
{
private OfInt() {};
@Override
public EmptyIterator.OfInt iterator()
{
return EmptyIterator.OfInt();
}
}
public static class OfLong extends EmptyIterable<Long> implements IterableLong
{
private OfLong() {};
@Override
public EmptyIterator.OfLong iterator()
{
return EmptyIterator.OfLong();
}
}
public static class OfDouble extends EmptyIterable<Double> implements IterableDouble
{
private OfDouble() {};
@Override
public EmptyIterator.OfDouble iterator()
{
return EmptyIterator.OfDouble();
}
}
}

111
prism/src/common/iterable/EmptyIterator.java

@ -0,0 +1,111 @@
//==============================================================================
//
// Copyright (c) 2016-
// Authors:
// * Steffen Maercker <maercker@tcs.inf.tu-dresden.de> (TU Dresden)
// * Joachim Klein <klein@tcs.inf.tu-dresden.de> (TU Dresden)
//
//------------------------------------------------------------------------------
//
// This file is part of PRISM.
//
// PRISM is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// PRISM is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with PRISM; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//==============================================================================
package common.iterable;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.PrimitiveIterator;
/**
* Base class for empty Iterators,
* static helpers for common primitive iterators.
*/
public abstract class EmptyIterator<T> implements Iterator<T>
{
private static final Of<?> OF = new Of<>();
private static final OfInt OF_INT = new OfInt();
private static final OfLong OF_LONG = new OfLong();
private static final OfDouble OF_DOUBLE = new OfDouble();
@SuppressWarnings("unchecked")
public static <T> Of<T> Of() {
return (Of<T>) OF;
}
public static OfInt OfInt() {
return OF_INT;
}
public static OfLong OfLong() {
return OF_LONG;
}
public static OfDouble OfDouble() {
return OF_DOUBLE;
}
@Override
public boolean hasNext()
{
return false;
}
public static class Of<T> extends EmptyIterator<T>
{
private Of() {};
@Override
public T next()
{
throw new NoSuchElementException();
}
}
public static class OfInt extends EmptyIterator<Integer> implements PrimitiveIterator.OfInt
{
private OfInt() {};
@Override
public int nextInt()
{
throw new NoSuchElementException();
}
}
public static class OfLong extends EmptyIterator<Long> implements PrimitiveIterator.OfLong
{
private OfLong() {};
@Override
public long nextLong()
{
throw new NoSuchElementException();
}
}
public static class OfDouble extends EmptyIterator<Double> implements PrimitiveIterator.OfDouble
{
private OfDouble() {};
@Override
public double nextDouble()
{
throw new NoSuchElementException();
}
}
}

285
prism/src/common/iterable/FilteringIterator.java

@ -0,0 +1,285 @@
//==============================================================================
//
// Copyright (c) 2016-
// Authors:
// * Steffen Maercker <maercker@tcs.inf.tu-dresden.de> (TU Dresden)
// * Joachim Klein <klein@tcs.inf.tu-dresden.de> (TU Dresden)
//
//------------------------------------------------------------------------------
//
// This file is part of PRISM.
//
// PRISM is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// PRISM is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with PRISM; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//==============================================================================
package common.iterable;
import java.util.HashSet;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.PrimitiveIterator;
import java.util.Set;
import java.util.function.DoublePredicate;
import java.util.function.IntPredicate;
import java.util.function.LongPredicate;
import java.util.function.Predicate;
/**
* Base class for filtering iterators,
* static helpers for common filtering task (deduping).
*/
public abstract class FilteringIterator<T> implements Iterator<T>
{
protected final Iterator<T> iterator;
protected boolean hasNext;
public static <T> Iterator<T> nonNull(Iterable<T> iterable)
{
return nonNull(iterable.iterator());
}
public static <T> Iterator<T> nonNull(Iterator<T> iterator)
{
if (iterator instanceof PrimitiveIterator) {
return iterator;
}
return new FilteringIterator.Of<>(iterator, Objects::nonNull);
}
public FilteringIterator(final Iterable<T> iterable)
{
this(iterable.iterator());
}
public FilteringIterator(final Iterator<T> iterator)
{
this.iterator = iterator;
}
@Override
public boolean hasNext()
{
return hasNext;
}
protected void requireNext()
{
if (!hasNext) {
throw new NoSuchElementException();
}
}
/**
* Obtain filtering iterator for the given iterator,
* filtering duplicate elements (via HashSet, requires
* that {@code equals()} and {@code hashCode()} are properly
* implemented).
*/
public static <T> Iterator<T> dedupe(final Iterator<T> iterator)
{
final Set<T> elements = new HashSet<>();
return new FilteringIterator.Of<>(iterator, (Predicate<T>) elements::add);
}
/**
* Obtain filtering iterator for the given primitive int iterator,
* filtering duplicate elements (via HashSet).
*/
public static OfInt dedupe(final PrimitiveIterator.OfInt iterator)
{
// TODO: use BitSet? Evaluate performance in practice...
final Set<Integer> elements = new HashSet<>();
return new FilteringIterator.OfInt(iterator, (IntPredicate) elements::add);
}
/**
* Obtain filtering iterator for the given primitive long iterator,
* filtering duplicate elements (via HashSet).
*/
public static OfLong dedupe(final PrimitiveIterator.OfLong iterator)
{
final Set<Long> elements = new HashSet<>();
return new FilteringIterator.OfLong(iterator, (LongPredicate) elements::add);
}
/**
* Obtain filtering iterator for the given primitive double iterator,
* filtering duplicate elements (via HashSet).
*/
public static OfDouble dedupe(final PrimitiveIterator.OfDouble iterator)
{
final Set<Double> elements = new HashSet<>();
return new FilteringIterator.OfDouble(iterator, (DoublePredicate) elements::add);
}
public static class Of<T> extends FilteringIterator<T>
{
protected final Predicate<? super T> predicate;
private T next;
public Of(Iterable<T> iterable, Predicate<? super T> predicate)
{
this(iterable.iterator(), predicate);
}
public Of(Iterator<T> iterator, Predicate<? super T> predicate)
{
super(iterator);
this.predicate = predicate;
seekNext();
}
@Override
public T next()
{
requireNext();
T current = next;
seekNext();
return current;
}
private void seekNext()
{
while (iterator.hasNext()) {
next = iterator.next();
if (predicate.test(next)) {
hasNext = true;
return;
}
}
hasNext = false;
next = null;
}
}
public static class OfInt extends FilteringIterator<Integer> implements PrimitiveIterator.OfInt
{
protected final IntPredicate predicate;
private int next;
public OfInt(IterableInt iterable, IntPredicate predicate)
{
this(iterable.iterator(), predicate);
}
public OfInt(PrimitiveIterator.OfInt iterator, IntPredicate predicate)
{
super(iterator);
this.predicate = predicate;
seekNext();
}
@Override
public int nextInt()
{
requireNext();
int current = next;
seekNext();
return current;
}
private void seekNext()
{
while (iterator.hasNext()) {
next = ((PrimitiveIterator.OfInt) iterator).nextInt();
if (predicate.test(next)) {
hasNext = true;
return;
}
}
hasNext = false;
}
}
public static class OfLong extends FilteringIterator<Long> implements PrimitiveIterator.OfLong
{
protected final LongPredicate predicate;
private long next;
public OfLong(IterableLong iterable, LongPredicate predicate)
{
this(iterable.iterator(), predicate);
}
public OfLong(PrimitiveIterator.OfLong iterator, LongPredicate predicate)
{
super(iterator);
this.predicate = predicate;
seekNext();
}
@Override
public long nextLong()
{
requireNext();
long current = next;
seekNext();
return current;
}
private void seekNext()
{
while (iterator.hasNext()) {
next = ((PrimitiveIterator.OfLong) iterator).nextLong();
if (predicate.test(next)) {
hasNext = true;
return;
}
}
hasNext = false;
}
}
public static class OfDouble extends FilteringIterator<Double> implements PrimitiveIterator.OfDouble
{
protected final DoublePredicate predicate;
private double next;
public OfDouble(IterableDouble iterable, DoublePredicate predicate)
{
this(iterable.iterator(), predicate);
}
public OfDouble(PrimitiveIterator.OfDouble iterator, DoublePredicate predicate)
{
super(iterator);
this.predicate = predicate;
seekNext();
}
@Override
public double nextDouble()
{
requireNext();
double current = next;
seekNext();
return current;
}
private void seekNext()
{
while (iterator.hasNext()) {
next = ((PrimitiveIterator.OfDouble) iterator).nextDouble();
if (predicate.test(next)) {
hasNext = true;
return;
}
}
hasNext = false;
}
}
}

36
prism/src/common/iterable/IterableDouble.java

@ -0,0 +1,36 @@
//==============================================================================
//
// Copyright (c) 2016-
// Authors:
// * Steffen Maercker <maercker@tcs.inf.tu-dresden.de> (TU Dresden)
//
//------------------------------------------------------------------------------
//
// This file is part of PRISM.
//
// PRISM is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// PRISM is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with PRISM; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//==============================================================================
package common.iterable;
import java.util.PrimitiveIterator.OfDouble;
/** Iterable for a PrimitiveIterator.OfDouble */
public interface IterableDouble extends Iterable<Double>
{
@Override
public OfDouble iterator();
}

36
prism/src/common/iterable/IterableInt.java

@ -0,0 +1,36 @@
//==============================================================================
//
// Copyright (c) 2016-
// Authors:
// * Steffen Maercker <maercker@tcs.inf.tu-dresden.de> (TU Dresden)
//
//------------------------------------------------------------------------------
//
// This file is part of PRISM.
//
// PRISM is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// PRISM is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with PRISM; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//==============================================================================
package common.iterable;
import java.util.PrimitiveIterator.OfInt;
/** Iterable for a PrimitiveIterator.OfInt */
public interface IterableInt extends Iterable<Integer>
{
@Override
public OfInt iterator();
}

36
prism/src/common/iterable/IterableLong.java

@ -0,0 +1,36 @@
//==============================================================================
//
// Copyright (c) 2016-
// Authors:
// * Steffen Maercker <maercker@tcs.inf.tu-dresden.de> (TU Dresden)
//
//------------------------------------------------------------------------------
//
// This file is part of PRISM.
//
// PRISM is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// PRISM is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with PRISM; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//==============================================================================
package common.iterable;
import java.util.PrimitiveIterator.OfLong;
/** Iterable for a PrimitiveIterator.OfLong */
public interface IterableLong extends Iterable<Long>
{
@Override
public OfLong iterator();
}

87
prism/src/common/iterable/RangeIntIterable.java

@ -0,0 +1,87 @@
//==============================================================================
//
// Copyright (c) 2016-
// Authors:
// * Joachim Klein <klein@tcs.inf.tu-dresden.de> (TU Dresden)
//
//------------------------------------------------------------------------------
//
// This file is part of PRISM.
//
// PRISM is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// PRISM is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with PRISM; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//==============================================================================
package common.iterable;
import java.util.PrimitiveIterator;
/**
* An Iterable that returns a Primitive.OfInt iterator for all the integers
* between two values, first and last (inclusive).
* If first > last, then the sequence is descending (first, first-1, ..., last+1, last),
* otherwise it is ascending (first, first+1, ..., last-1, last).
*/
public class RangeIntIterable implements IterableInt
{
/** The first integer of the sequence */
final private int first;
/** The last integer of the sequence */
final private int last;
/** Are we ascending? */
final private boolean ascending;
/**
* Constructor
* @param first the first integer in the sequence
* @param last the last integer in the sequence
*/
public RangeIntIterable(int first, int last)
{
this.first = first;
this.last = last;
ascending = (first <= last);
}
@Override
public PrimitiveIterator.OfInt iterator()
{
return new PrimitiveIterator.OfInt()
{
int current = first;
@Override
public boolean hasNext()
{
if (ascending) {
return current <= last;
} else {
return current >= last;
}
}
@Override
public int nextInt()
{
if (ascending) {
return current++;
} else {
return current--;
}
}
};
}
}

137
prism/src/common/iterable/SingletonIterator.java

@ -0,0 +1,137 @@
//==============================================================================
//
// Copyright (c) 2016-
// Authors:
// * Steffen Maercker <maercker@tcs.inf.tu-dresden.de> (TU Dresden)
//
//------------------------------------------------------------------------------
//
// This file is part of PRISM.
//
// PRISM is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// PRISM is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with PRISM; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//==============================================================================
package common.iterable;
import java.util.Iterator;
import java.util.Optional;
import java.util.OptionalDouble;
import java.util.OptionalInt;
import java.util.OptionalLong;
import java.util.PrimitiveIterator;
/**
* Base class for an iterator that ranges over a single element,
* static helpers for common primitive iterators.
*/
public abstract class SingletonIterator<T> implements Iterator<T>
{
public static class Of<T> extends SingletonIterator<T>
{
private Optional<T> element;
public Of(T element)
{
this.element = Optional.of(element);
}
@Override
public boolean hasNext()
{
return element.isPresent();
}
@Override
public T next()
{
Optional<T> result = element;
element = Optional.empty();
return result.get();
}
}
public static class OfInt extends SingletonIterator<Integer> implements PrimitiveIterator.OfInt
{
private OptionalInt element;
public OfInt(int element)
{
this.element = OptionalInt.of(element);
}
@Override
public boolean hasNext()
{
return element.isPresent();
}
@Override
public int nextInt()
{
OptionalInt result = element;
element = OptionalInt.empty();
return result.getAsInt();
}
}
public static class OfLong extends SingletonIterator<Long> implements PrimitiveIterator.OfLong
{
private OptionalLong element;
public OfLong(Long element)
{
this.element = OptionalLong.of(element);
}
@Override
public boolean hasNext()
{
return element.isPresent();
}
@Override
public long nextLong()
{
OptionalLong result = element;
element = OptionalLong.empty();
return result.getAsLong();
}
}
public static class OfDouble extends SingletonIterator<Double> implements PrimitiveIterator.OfDouble
{
private OptionalDouble element;
public OfDouble(double element)
{
this.element = OptionalDouble.of(element);
}
@Override
public boolean hasNext()
{
return element.isPresent();
}
@Override
public double nextDouble()
{
OptionalDouble result = element;
element = OptionalDouble.empty();
return result.getAsDouble();
}
}
}
Loading…
Cancel
Save