Primitive-Collections/src/builder/resources/speiger/assets/collections/templates/utils/Iterables.template

682 lines
24 KiB
Plaintext

package speiger.src.collections.PACKAGE.utils;
import java.util.Objects;
#if TYPE_BOOLEAN
import java.util.concurrent.atomic.AtomicInteger;
#else if TYPE_OBJECT
import java.util.Comparator;
#endif
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;
#if JDK_FUNCTION
import java.util.function.PREDICATE;
#endif
import speiger.src.collections.PACKAGE.collections.ITERABLE;
import speiger.src.collections.PACKAGE.collections.COLLECTION;
#if !TYPE_OBJECT
import speiger.src.collections.objects.collections.ObjectIterable;
import speiger.src.collections.objects.collections.ObjectIterator;
import speiger.src.collections.PACKAGE.functions.CONSUMER;
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
#else
#if BOOLEAN_COLLECTION_MODULE
import speiger.src.collections.booleans.functions.BooleanConsumer;
import speiger.src.collections.booleans.collections.BooleanIterable;
import speiger.src.collections.booleans.collections.BooleanIterator;
#endif
#iterate
#argument FILTER_TYPE BYTE_COLLECTION_MODULE SHORT_COLLECTION_MODULE INT_COLLECTION_MODULE LONG_COLLECTION_MODULE FLOAT_COLLECTION_MODULE DOUBLE_COLLECTION_MODULE
#argument CONSUMER ByteConsumer ShortConsumer IntConsumer LongConsumer FloatConsumer DoubleConsumer
#argument OUTPUT_ITERABLE ByteIterable ShortIterable IntIterable LongIterable FloatIterable DoubleIterable
#argument OUTPUT_ITERATOR ByteIterator ShortIterator IntIterator LongIterator FloatIterator DoubleIterator
#argument MAPPER ToByteFunction ToShortFunction ToIntFunction ToLongFunction ToFloatFunction ToDoubleFunction
#argument PACKAGE bytes shorts ints longs floats doubles
#if FILTER_TYPE
import speiger.src.collections.PACKAGE.functions.CONSUMER;
import speiger.src.collections.objects.functions.function.MAPPER;
import speiger.src.collections.PACKAGE.collections.OUTPUT_ITERABLE;
import speiger.src.collections.PACKAGE.collections.OUTPUT_ITERATOR;
#endif
#enditerate
#endif
import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.PACKAGE.functions.function.TO_OBJECT_FUNCTION;
#if !JDK_FUNCTION
import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif
import speiger.src.collections.utils.ISizeProvider;
/**
* A Helper class for Iterables
*/
public class ITERABLES
{
/**
* A Helper function that maps a Java-Iterable into a new Type.
* @param iterable the iterable that should be mapped
* @param mapper the function that decides what the result turns into.
* @Type(T)
* @param <E> The return type.
* @return a iterable that is mapped to a new result
*/
public static GENERIC_KEY_SPECIAL_BRACES<E> ObjectIterable<E> map(Iterable<? extends CLASS_TYPE> iterable, TO_OBJECT_FUNCTION KKS_GENERIC_TYPE<E> mapper) {
return new MappedIterable<>(wrap(iterable), mapper);
}
/**
* A Helper function that maps a Iterable into a new Type.
* @param iterable the iterable that should be mapped
* @param mapper the function that decides what the result turns into.
* @Type(T)
* @param <E> The return type.
* @return a iterable that is mapped to a new result
*/
public static GENERIC_KEY_SPECIAL_BRACES<E> ObjectIterable<E> map(ITERABLE KEY_GENERIC_TYPE iterable, TO_OBJECT_FUNCTION KKS_GENERIC_TYPE<E> mapper) {
return new MappedIterable<>(iterable, mapper);
}
#if TYPE_OBJECT
#iterate
#argument MAPPED_TYPE MappedBoolean MappedByte MappedShort MappedInt MappedLong MappedFloat MappedDouble
#argument OUTPUT_ITERABLE BooleanIterable ByteIterable ShortIterable IntIterable LongIterable FloatIterable DoubleIterable
#argument MAPPER Predicate ToByteFunction ToShortFunction ToIntFunction ToLongFunction ToFloatFunction ToDoubleFunction
#argument DATA_TYPE Boolean Byte Short Int Long Float Double
#argument FILTER_TYPE BOOLEAN_COLLECTION_MODULE BYTE_COLLECTION_MODULE SHORT_COLLECTION_MODULE INT_COLLECTION_MODULE LONG_COLLECTION_MODULE FLOAT_COLLECTION_MODULE DOUBLE_COLLECTION_MODULE
#if FILTER_TYPE
/**
* A Helper function that maps a Java-Iterable into a new Type.
* @param iterable the iterable that should be mapped
* @param mapper the function that decides what the result turns into.
* @Type(T)
* @return a iterable that is mapped to a new result
*/
public static <T> OUTPUT_ITERABLE mapToDATA_TYPE(Iterable<? extends CLASS_TYPE> iterable, MAPPER<T> mapper) {
return new MAPPED_TYPEIterable<>(wrap(iterable), mapper);
}
/**
* A Helper function that maps a Iterable into a new Type.
* @param iterable the iterable that should be mapped
* @param mapper the function that decides what the result turns into.
* @Type(T)
* @return a iterable that is mapped to a new result
*/
public static <T> OUTPUT_ITERABLE mapToDATA_TYPE(ITERABLE KEY_GENERIC_TYPE iterable, MAPPER<T> mapper) {
return new MAPPED_TYPEIterable<>(iterable, mapper);
}
#endif
#enditerate
#endif
/**
* A Helper function that flatMaps a Java-Iterable into a new Type.
* @param iterable the iterable that should be flatMapped
* @param mapper the function that decides what the result turns into.
* @Type(T)
* @param <V> The return type supplier.
* @param <E> The return type.
* @return a iterable that is flatMapped to a new result
*/
public static GENERIC_KEY_SPECIAL_BRACES<E, V extends Iterable<E>> ObjectIterable<E> flatMap(Iterable<? extends CLASS_TYPE> iterable, TO_OBJECT_FUNCTION KKS_GENERIC_TYPE<V> mapper) {
return new FlatMappedIterable<>(wrap(iterable), mapper);
}
/**
* A Helper function that flatMaps a Iterable into a new Type.
* @param iterable the iterable that should be flatMapped
* @param mapper the function that decides what the result turns into.
* @Type(T)
* @param <V> The return type supplier.
* @param <E> The return type.
* @return a iterable that is flatMapped to a new result
*/
public static GENERIC_KEY_SPECIAL_BRACES<E, V extends Iterable<E>> ObjectIterable<E> flatMap(ITERABLE KEY_GENERIC_TYPE iterable, TO_OBJECT_FUNCTION KKS_GENERIC_TYPE<V> mapper) {
return new FlatMappedIterable<>(iterable, mapper);
}
/**
* A Helper function that flatMaps a Java-Iterable into a new Type.
* @param iterable the iterable that should be flatMapped
* @param mapper the function that decides what the result turns into.
* @Type(T)
* @param <E> The return type.
* @return a iterable that is flatMapped to a new result
*/
public static GENERIC_KEY_SPECIAL_BRACES<E> ObjectIterable<E> arrayFlatMap(Iterable<? extends CLASS_TYPE> iterable, TO_OBJECT_FUNCTION KKS_GENERIC_TYPE<E[]> mapper) {
return new FlatMappedArrayIterable<>(wrap(iterable), mapper);
}
/**
* A Helper function that flatMaps a Iterable into a new Type.
* @param iterable the iterable that should be flatMapped
* @param mapper the function that decides what the result turns into.
* @Type(T)
* @param <E> The return type.
* @return a iterable that is flatMapped to a new result
*/
public static GENERIC_KEY_SPECIAL_BRACES<E> ObjectIterable<E> arrayFlatMap(ITERABLE KEY_GENERIC_TYPE iterable, TO_OBJECT_FUNCTION KKS_GENERIC_TYPE<E[]> mapper) {
return new FlatMappedArrayIterable<>(iterable, mapper);
}
/**
* A Helper function that filters out all desired elements from a Java-Iterable
* @param iterable that should be filtered.
* @param filter the filter that decides that should be let through
* @Type(T)
* @return a filtered iterable
*/
public static GENERIC_KEY_BRACES ITERABLE KEY_GENERIC_TYPE filter(Iterable<? extends CLASS_TYPE> iterable, PREDICATE KEY_GENERIC_TYPE filter) {
return new FilteredIterableBRACES(wrap(iterable), filter);
}
/**
* A Helper function that filters out all desired elements
* @param iterable that should be filtered.
* @param filter the filter that decides that should be let through
* @Type(T)
* @return a filtered iterable
*/
public static GENERIC_KEY_BRACES ITERABLE KEY_GENERIC_TYPE filter(ITERABLE KEY_GENERIC_TYPE iterable, PREDICATE KEY_GENERIC_TYPE filter) {
return new FilteredIterableBRACES(iterable, filter);
}
/**
* A Helper function that filters out all duplicated elements.
* @param iterable that should be distinct
* @Type(T)
* @return a distinct iterable
*/
public static GENERIC_KEY_BRACES ITERABLE KEY_GENERIC_TYPE distinct(ITERABLE KEY_GENERIC_TYPE iterable) {
return new DistinctIterableBRACES(iterable);
}
/**
* A Helper function that filters out all duplicated elements from a Java Iterable.
* @param iterable that should be distinct
* @Type(T)
* @return a distinct iterable
*/
public static GENERIC_KEY_BRACES ITERABLE KEY_GENERIC_TYPE distinct(Iterable<? extends CLASS_TYPE> iterable) {
return new DistinctIterableBRACES(wrap(iterable));
}
/**
* A Helper function that repeats the Iterable a specific amount of times
* @param iterable that should be repeated
* @param repeats the amount of times the iterable should be repeated
* @Type(T)
* @return a repeating iterable
*/
public static GENERIC_KEY_BRACES ITERABLE KEY_GENERIC_TYPE repeat(ITERABLE KEY_GENERIC_TYPE iterable, int repeats) {
return new RepeatingIterableBRACES(iterable, repeats);
}
/**
* A Helper function that repeats the Iterable a specific amount of times from a Java Iterable
* @param iterable that should be repeated
* @param repeats the amount of times the iterable should be repeated
* @Type(T)
* @return a repeating iterable
*/
public static GENERIC_KEY_BRACES ITERABLE KEY_GENERIC_TYPE repeat(Iterable<? extends CLASS_TYPE> iterable, int repeats) {
return new RepeatingIterableBRACES(wrap(iterable), repeats);
}
/**
* A Helper function that hard limits the Iterable to a specific size
* @param iterable that should be limited
* @param limit the amount of elements it should be limited to
* @Type(T)
* @return a limited iterable
*/
public static GENERIC_KEY_BRACES ITERABLE KEY_GENERIC_TYPE limit(ITERABLE KEY_GENERIC_TYPE iterable, long limit) {
return new LimitedIterableBRACES(iterable, limit);
}
/**
* A Helper function that hard limits the Iterable to a specific size from a Java Iterable
* @param iterable that should be limited
* @param limit the amount of elements it should be limited to
* @Type(T)
* @return a limited iterable
*/
public static GENERIC_KEY_BRACES ITERABLE KEY_GENERIC_TYPE limit(Iterable<? extends CLASS_TYPE> iterable, long limit) {
return new LimitedIterableBRACES(wrap(iterable), limit);
}
/**
* A Helper function that sorts the Iterable.
* This operation is heavily hurting performance because it rebuilds the entire iterator and then sorts it.
* @param iterable that should be sorted
* @param sorter that sorts the iterable. Can be null.
* @Type(T)
* @return a sorted iterable.
*/
public static GENERIC_KEY_BRACES ITERABLE KEY_GENERIC_TYPE sorted(ITERABLE KEY_GENERIC_TYPE iterable, COMPARATOR KEY_GENERIC_TYPE sorter) {
return new SortedIterableBRACES(iterable, sorter);
}
/**
* A Helper function that sorts the Iterable from a Java Iterable
* This operation is heavily hurting performance because it rebuilds the entire iterator and then sorts it.
* @param iterable that should be sorted
* @param sorter that sorts the iterable. Can be null.
* @Type(T)
* @return a sorted iterable.
*/
public static GENERIC_KEY_BRACES ITERABLE KEY_GENERIC_TYPE sorted(Iterable<? extends CLASS_TYPE> iterable, COMPARATOR KEY_GENERIC_TYPE sorter) {
return new SortedIterableBRACES(wrap(iterable), sorter);
}
/**
* A Helper function that allows to preview the result of a Iterable.
* @param iterable that should be peeked at
* @param action callback that receives the value before the iterable returns it
* @Type(T)
* @return a peeked iterable
*/
public static GENERIC_KEY_BRACES ITERABLE KEY_GENERIC_TYPE peek(ITERABLE KEY_GENERIC_TYPE iterable, CONSUMER KEY_GENERIC_TYPE action) {
return new PeekIterableBRACES(iterable, action);
}
/**
* A Helper function that allows to preview the result of a Iterable from a Java Iterable
* @param iterable that should be peeked at
* @param action callback that receives the value before the iterable returns it
* @Type(T)
* @return a peeked iterable
*/
public static GENERIC_KEY_BRACES ITERABLE KEY_GENERIC_TYPE peek(Iterable<? extends CLASS_TYPE> iterable, CONSUMER KEY_GENERIC_TYPE action) {
return new PeekIterableBRACES(wrap(iterable), action);
}
/**
* A Wrapper function that wraps a Java-Iterable into a Type Specific Iterable
* @param iterable that should be wrapped
* @Type(T)
* @return a type specific iterable
*/
public static GENERIC_KEY_BRACES ITERABLE KEY_GENERIC_TYPE wrap(Iterable<? extends CLASS_TYPE> iterable) {
return new WrappedIterableBRACES(iterable);
}
private static class WrappedIterable KEY_GENERIC_TYPE implements ITERABLE KEY_GENERIC_TYPE, ISizeProvider
{
Iterable<? extends CLASS_TYPE> iterable;
public WrappedIterable(Iterable<? extends CLASS_TYPE> iterable) {
this.iterable = iterable;
}
public ITERATOR KEY_GENERIC_TYPE iterator() {
return ITERATORS.wrap(iterable.iterator());
}
@Override
public int size() {
ISizeProvider prov = ISizeProvider.of(iterable);
return prov == null ? -1 : prov.size();
}
#if !TYPE_OBJECT
@Override
public void forEach(CONSUMER action) {
Objects.requireNonNull(action);
iterable.forEach(action);
}
#else
public void forEach(Consumer<? super CLASS_TYPE> action) {
Objects.requireNonNull(action);
iterable.forEach(action);
}
#endif
}
#if TYPE_OBJECT
#iterate
#argument CONSUMER BooleanConsumer ByteConsumer ShortConsumer IntConsumer LongConsumer FloatConsumer DoubleConsumer
#argument MAPPED_TYPE MappedBoolean MappedByte MappedShort MappedInt MappedLong MappedFloat MappedDouble
#argument OUTPUT_ITERABLE BooleanIterable ByteIterable ShortIterable IntIterable LongIterable FloatIterable DoubleIterable
#argument OUTPUT_ITERATOR BooleanIterator ByteIterator ShortIterator IntIterator LongIterator FloatIterator DoubleIterator
#argument MAPPER Predicate ToByteFunction ToShortFunction ToIntFunction ToLongFunction ToFloatFunction ToDoubleFunction
#argument APPLY test applyAsByte applyAsShort applyAsInt applyAsLong applyAsFloat applyAsDouble
#argument DATA_TYPE Boolean Byte Short Int Long Float Double
#argument FILTER_TYPE BOOLEAN_COLLECTION_MODULE BYTE_COLLECTION_MODULE SHORT_COLLECTION_MODULE INT_COLLECTION_MODULE LONG_COLLECTION_MODULE FLOAT_COLLECTION_MODULE DOUBLE_COLLECTION_MODULE
#if FILTER_TYPE
private static class MAPPED_TYPEIterable<E> implements OUTPUT_ITERABLE, ISizeProvider
{
ITERABLE KEY_SPECIAL_GENERIC_TYPE<E> iterable;
MAPPER<E> mapper;
MAPPED_TYPEIterable(ITERABLE<E> iterable, MAPPER<E> mapper) {
this.iterable = iterable;
this.mapper = mapper;
}
public OUTPUT_ITERATOR iterator() {
return ITERATORS.mapToDATA_TYPE(iterable.iterator(), mapper);
}
@Override
public int size() {
ISizeProvider prov = ISizeProvider.of(this);
return prov == null ? -1 : prov.size();
}
@Override
public void forEach(CONSUMER action) {
Objects.requireNonNull(action);
iterable.forEach(E -> action.accept(mapper.APPLY(E)));
}
}
#endif
#enditerate
#endif
private static class MappedIterable KSS_GENERIC_TYPE<E, T> implements ObjectIterable<T>, ISizeProvider
{
ITERABLE KEY_SPECIAL_GENERIC_TYPE<E> iterable;
TO_OBJECT_FUNCTION KSS_GENERIC_TYPE<E, T> mapper;
MappedIterable(ITERABLE KEY_SPECIAL_GENERIC_TYPE<E> iterable, TO_OBJECT_FUNCTION KSS_GENERIC_TYPE<E, T> mapper) {
this.iterable = iterable;
this.mapper = mapper;
}
public ObjectIterator<T> iterator() {
return ITERATORS.map(iterable.iterator(), mapper);
}
@Override
public int size() {
ISizeProvider prov = ISizeProvider.of(this);
return prov == null ? -1 : prov.size();
}
@Override
public void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
iterable.forEach(E -> action.accept(mapper.apply(E)));
}
}
private static class FlatMappedIterable KSS_GENERIC_TYPE<E, T,[SPACE]V extends Iterable<T>> implements ObjectIterable<T>
{
ITERABLE KEY_SPECIAL_GENERIC_TYPE<E> iterable;
TO_OBJECT_FUNCTION KSS_GENERIC_TYPE<E, V> mapper;
FlatMappedIterable(ITERABLE KEY_SPECIAL_GENERIC_TYPE<E> iterable, TO_OBJECT_FUNCTION KSS_GENERIC_TYPE<E, V> mapper) {
this.iterable = iterable;
this.mapper = mapper;
}
@Override
public ObjectIterator<T> iterator() {
return ITERATORS.flatMap(iterable.iterator(), mapper);
}
@Override
public void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
iterable.forEach(E -> mapper.apply(E).forEach(action));
}
}
private static class FlatMappedArrayIterable KSS_GENERIC_TYPE<E, T> implements ObjectIterable<T>
{
ITERABLE KEY_SPECIAL_GENERIC_TYPE<E> iterable;
TO_OBJECT_FUNCTION KSS_GENERIC_TYPE<E, T[]> mapper;
FlatMappedArrayIterable(ITERABLE KEY_SPECIAL_GENERIC_TYPE<E> iterable, TO_OBJECT_FUNCTION KSS_GENERIC_TYPE<E, T[]> mapper) {
this.iterable = iterable;
this.mapper = mapper;
}
@Override
public ObjectIterator<T> iterator() {
return ITERATORS.arrayFlatMap(iterable.iterator(), mapper);
}
@Override
public void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
iterable.forEach(E -> {
T[] array = mapper.apply(E);
for(int i = 0,m=array.length;i<m;action.accept(array[i++]));
});
}
}
private static class RepeatingIterable KEY_GENERIC_TYPE implements ITERABLE KEY_GENERIC_TYPE, ISizeProvider
{
ITERABLE KEY_GENERIC_TYPE iterable;
int repeats;
public RepeatingIterable(ITERABLE KEY_GENERIC_TYPE iterable, int repeats) {
this.iterable = iterable;
this.repeats = repeats;
}
@Override
public ITERATOR KEY_GENERIC_TYPE iterator() {
return ITERATORS.repeat(iterable.iterator(), repeats);
}
@Override
public int size() {
ISizeProvider prov = ISizeProvider.of(iterable);
return prov == null ? -1 : prov.size() * (repeats+1);
}
#if !TYPE_OBJECT
@Override
public void forEach(CONSUMER action) {
Objects.requireNonNull(action);
COLLECTION KEY_GENERIC_TYPE repeater = COLLECTIONS.wrapper();
iterable.forEach(action.andThen(repeater::add));
for(int i = 0;i<repeats;i++)
repeater.forEach(action);
}
#else
@Override
public void forEach(Consumer<? super CLASS_TYPE> action) {
Objects.requireNonNull(action);
COLLECTION KEY_GENERIC_TYPE repeater = COLLECTIONS.wrapper();
iterable.forEach(T -> {action.accept(T); repeater.add(T);});
for(int i = 0;i<repeats;i++)
repeater.forEach(action);
}
#endif
}
private static class FilteredIterable KEY_GENERIC_TYPE implements ITERABLE KEY_GENERIC_TYPE
{
ITERABLE KEY_GENERIC_TYPE iterable;
PREDICATE KEY_GENERIC_TYPE filter;
public FilteredIterable(ITERABLE KEY_GENERIC_TYPE iterable, PREDICATE KEY_GENERIC_TYPE filter) {
this.iterable = iterable;
this.filter = filter;
}
@Override
public ITERATOR KEY_GENERIC_TYPE iterator() {
return ITERATORS.filter(iterable.iterator(), filter);
}
#if !TYPE_OBJECT
@Override
public void forEach(CONSUMER action) {
Objects.requireNonNull(action);
iterable.forEach(T -> { if(!filter.test(T)) action.accept(T); } );
}
#else
public void forEach(Consumer<? super CLASS_TYPE> action) {
Objects.requireNonNull(action);
iterable.forEach(T -> { if(!filter.test(T)) action.accept(T); } );
}
#endif
}
private static class LimitedIterable KEY_GENERIC_TYPE implements ITERABLE KEY_GENERIC_TYPE, ISizeProvider
{
ITERABLE KEY_GENERIC_TYPE iterable;
long limit;
public LimitedIterable(ITERABLE KEY_GENERIC_TYPE iterable, long limit) {
this.iterable = iterable;
this.limit = limit;
}
@Override
public ITERATOR KEY_GENERIC_TYPE iterator() {
return ITERATORS.limit(iterable.iterator(), limit);
}
@Override
public int size() {
ISizeProvider prov = ISizeProvider.of(iterable);
return prov == null ? -1 : (int)Math.min(prov.size(), limit);
}
#if !TYPE_OBJECT
@Override
public void forEach(CONSUMER action) {
Objects.requireNonNull(action);
AtomicLong counter = new AtomicLong();
iterable.forEach(T -> {
if(counter.get() >= limit) return;
counter.incrementAndGet();
action.accept(T);
});
}
#else
public void forEach(Consumer<? super CLASS_TYPE> action) {
Objects.requireNonNull(action);
AtomicLong counter = new AtomicLong();
iterable.forEach(T -> {
if(counter.get() >= limit) return;
counter.incrementAndGet();
action.accept(T);
});
}
#endif
}
private static class SortedIterable KEY_GENERIC_TYPE implements ITERABLE KEY_GENERIC_TYPE, ISizeProvider
{
ITERABLE KEY_GENERIC_TYPE iterable;
COMPARATOR KEY_GENERIC_TYPE sorter;
public SortedIterable(ITERABLE KEY_GENERIC_TYPE iterable, COMPARATOR KEY_GENERIC_TYPE sorter) {
this.iterable = iterable;
this.sorter = sorter;
}
@Override
public ITERATOR KEY_GENERIC_TYPE iterator() {
return ITERATORS.sorted(iterable.iterator(), sorter);
}
@Override
public int size() {
ISizeProvider prov = ISizeProvider.of(iterable);
return prov == null ? -1 : prov.size();
}
#if !TYPE_OBJECT
@Override
public void forEach(CONSUMER action) {
Objects.requireNonNull(action);
COLLECTIONS.CollectionWrapper KEY_GENERIC_TYPE wrapper = COLLECTIONS.wrapper();
iterable.forEach(wrapper::add);
wrapper.unstableSort(sorter);
wrapper.forEach(action);
}
#else
@Override
public void forEach(Consumer<? super CLASS_TYPE> action) {
Objects.requireNonNull(action);
COLLECTIONS.CollectionWrapper KEY_GENERIC_TYPE wrapper = COLLECTIONS.wrapper();
iterable.forEach(wrapper::add);
wrapper.unstableSort(sorter);
wrapper.forEach(action);
}
#endif
}
private static class DistinctIterable KEY_GENERIC_TYPE implements ITERABLE KEY_GENERIC_TYPE
{
ITERABLE KEY_GENERIC_TYPE iterable;
public DistinctIterable(ITERABLE KEY_GENERIC_TYPE iterable) {
this.iterable = iterable;
}
@Override
public ITERATOR KEY_GENERIC_TYPE iterator() {
return ITERATORS.distinct(iterable.iterator());
}
#if !TYPE_OBJECT
@Override
public void forEach(CONSUMER action) {
Objects.requireNonNull(action);
#if TYPE_BOOLEAN
AtomicInteger result = new AtomicInteger();
iterable.forEach(T -> {
if(((result.get() & (T ? 2 : 1)) != 0)) return;
result.getAndAdd(T ? 2 : 1);
action.accept(T);
});
#else
COLLECTION KEY_GENERIC_TYPE filtered = COLLECTIONS.distinctWrapper();
iterable.forEach(T -> { if(filtered.add(T)) action.accept(T); });
#endif
}
#else
public void forEach(Consumer<? super CLASS_TYPE> action) {
Objects.requireNonNull(action);
COLLECTION KEY_GENERIC_TYPE filtered = COLLECTIONS.distinctWrapper();
iterable.forEach(T -> { if(filtered.add(T)) action.accept(T); });
}
#endif
}
private static class PeekIterable KEY_GENERIC_TYPE implements ITERABLE KEY_GENERIC_TYPE, ISizeProvider
{
ITERABLE KEY_GENERIC_TYPE iterable;
CONSUMER KEY_GENERIC_TYPE action;
public PeekIterable(ITERABLE KEY_GENERIC_TYPE iterable, CONSUMER KEY_GENERIC_TYPE action) {
this.iterable = iterable;
this.action = action;
}
@Override
public ITERATOR KEY_GENERIC_TYPE iterator() {
return ITERATORS.peek(iterable.iterator(), action);
}
@Override
public int size() {
ISizeProvider prov = ISizeProvider.of(iterable);
return prov == null ? -1 : prov.size();
}
#if !TYPE_OBJECT
@Override
public void forEach(CONSUMER action) {
Objects.requireNonNull(action);
iterable.forEach(this.action.andThen(action));
}
#else
public void forEach(Consumer<? super CLASS_TYPE> action) {
Objects.requireNonNull(action);
iterable.forEach(this.action.andThen(action));
}
#endif
}
}