package net.minecraft.util; import com.google.common.base.Function; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.UnmodifiableIterator; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; public class Cartesian { private static final String __OBFID = "CL_00002327"; /** * Create the cartesian product. This method returns an Iterable of arrays of type clazz. * * @param sets the Sets to combine. This is an Iterable of Iterables of type clazz */ public static Iterable cartesianProduct(Class clazz, Iterable sets) { return new Cartesian.Product(clazz, (Iterable[])toArray(Iterable.class, sets), null); } /** * Like cartesianProduct(Class, Iterable) but returns an Iterable of Lists instead. */ public static Iterable cartesianProduct(Iterable sets) { return arraysAsLists(cartesianProduct(Object.class, sets)); } /** * Convert an Iterable of Arrays (Object[]) to an Iterable of Lists */ private static Iterable arraysAsLists(Iterable arrays) { return Iterables.transform(arrays, new Cartesian.GetList(null)); } /** * Create a new Array of type clazz with the contents of the given Iterable */ private static Object[] toArray(Class clazz, Iterable it) { ArrayList var2 = Lists.newArrayList(); Iterator var3 = it.iterator(); while (var3.hasNext()) { Object var4 = var3.next(); var2.add(var4); } return (Object[])var2.toArray(createArray(clazz, var2.size())); } private static Object[] createArray(Class p_179319_0_, int p_179319_1_) { return (Object[])((Object[])Array.newInstance(p_179319_0_, p_179319_1_)); } static class GetList implements Function { private static final String __OBFID = "CL_00002325"; private GetList() {} public List apply(Object[] array) { return Arrays.asList((Object[])array); } public Object apply(Object p_apply_1_) { return this.apply((Object[])p_apply_1_); } GetList(Object p_i46022_1_) { this(); } } static class Product implements Iterable { private final Class clazz; private final Iterable[] iterables; private static final String __OBFID = "CL_00002324"; private Product(Class clazz, Iterable[] iterables) { this.clazz = clazz; this.iterables = iterables; } public Iterator iterator() { return (Iterator)(this.iterables.length <= 0 ? Collections.singletonList((Object[])Cartesian.createArray(this.clazz, 0)).iterator() : new Cartesian.Product.ProductIterator(this.clazz, this.iterables, null)); } Product(Class p_i46021_1_, Iterable[] p_i46021_2_, Object p_i46021_3_) { this(p_i46021_1_, p_i46021_2_); } static class ProductIterator extends UnmodifiableIterator { private int index; private final Iterable[] iterables; private final Iterator[] iterators; private final Object[] results; private static final String __OBFID = "CL_00002323"; private ProductIterator(Class clazz, Iterable[] iterables) { this.index = -2; this.iterables = iterables; this.iterators = (Iterator[])Cartesian.createArray(Iterator.class, this.iterables.length); for (int var3 = 0; var3 < this.iterables.length; ++var3) { this.iterators[var3] = iterables[var3].iterator(); } this.results = Cartesian.createArray(clazz, this.iterators.length); } private void endOfData() { this.index = -1; Arrays.fill(this.iterators, (Object)null); Arrays.fill(this.results, (Object)null); } public boolean hasNext() { if (this.index == -2) { this.index = 0; Iterator[] var5 = this.iterators; int var2 = var5.length; for (int var3 = 0; var3 < var2; ++var3) { Iterator var4 = var5[var3]; if (!var4.hasNext()) { this.endOfData(); break; } } return true; } else { if (this.index >= this.iterators.length) { for (this.index = this.iterators.length - 1; this.index >= 0; --this.index) { Iterator var1 = this.iterators[this.index]; if (var1.hasNext()) { break; } if (this.index == 0) { this.endOfData(); break; } var1 = this.iterables[this.index].iterator(); this.iterators[this.index] = var1; if (!var1.hasNext()) { this.endOfData(); break; } } } return this.index >= 0; } } public Object[] next0() { if (!this.hasNext()) { throw new NoSuchElementException(); } else { while (this.index < this.iterators.length) { this.results[this.index] = this.iterators[this.index].next(); ++this.index; } return (Object[])this.results.clone(); } } public Object next() { return this.next0(); } ProductIterator(Class p_i46019_1_, Iterable[] p_i46019_2_, Object p_i46019_3_) { this(p_i46019_1_, p_i46019_2_); } } } }