package fj.test; import fj.*; import static fj.Function.curry; import static fj.P.p; import fj.data.*; import static fj.data.Array.array; import static fj.data.Array.iterableArray; import static fj.data.List.fromString; import static fj.data.List.nil; import static fj.test.Variant.variant; import static java.lang.Double.doubleToRawLongBits; import static java.lang.Float.floatToRawIntBits; import java.math.BigDecimal; import java.math.BigInteger; import java.sql.Time; import java.sql.Timestamp; import java.util.ArrayList; import java.util.BitSet; import java.util.Calendar; import java.util.Date; import java.util.EnumMap; import java.util.EnumSet; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; import java.util.IdentityHashMap; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.Map; import java.util.PriorityQueue; import java.util.Properties; import java.util.Stack; import java.util.TreeMap; import java.util.TreeSet; import java.util.Vector; import java.util.WeakHashMap; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.DelayQueue; import java.util.concurrent.Delayed; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.PriorityBlockingQueue; import java.util.concurrent.SynchronousQueue; /** * Transforms a type and a generator to produce a new generator. This function is used to generate * {@link Gen gen} functions. * * @version %build.number% */ public abstract class Cogen<A> { /** * Transforms the given value and generator to a new generator with a high probability of being * independent. * * @param a The value to produce the generator from. * @param g The generator to produce the new generator from. * @return A new generator with a high probability of being independent. */ public abstract <B> Gen<B> cogen(A a, Gen<B> g); /** * A curried version of {@link #cogen(Object, Gen)}. * * @param a The value to produce the generator from. * @return A curried version of {@link #cogen(Object, Gen)}. */ public final <B> F<Gen<B>, Gen<B>> cogen(final A a) { return g -> cogen(a, g); } /** * Composes the given function with this cogen to produce a new cogen. * * @param f The function to compose. * @return A new cogen composed with the given function. */ public final <B> Cogen<B> compose(final F<B, A> f) { return new Cogen<B>() { public <X> Gen<X> cogen(final B b, final Gen<X> g) { return Cogen.this.cogen(f.f(b), g); } }; } /** * Contra-maps this cogen using the given function. * * @param f The function to co-map with. * @return A contra-mapped cogen. */ public final <B> Cogen<B> contramap(final F<B, A> f) { return new Cogen<B>() { public <X> Gen<X> cogen(final B b, final Gen<X> g) { return Cogen.this.cogen(f.f(b), g); } }; } /** * A cogen for a function. * * @param a A gen for the domain of the function. * @param c A cogen for the codomain of the function. * @return A cogen for a function. */ public static <A, B> Cogen<F<A, B>> cogenF(final Gen<A> a, final Cogen<B> c) { return new Cogen<F<A, B>>() { public <X> Gen<X> cogen(final F<A, B> f, final Gen<X> g) { return a.bind(a1 -> c.cogen(f.f(a1), g)); } }; } /** * A cogen for a function-2. * * @param aa A gen for part of the domain of the function. * @param ab A gen for part of the domain of the function. * @param c A cogen for the codomain of the function. * @return A cogen for a function-2. */ public static <A, B, C> Cogen<F2<A, B, C>> cogenF2(final Gen<A> aa, final Gen<B> ab, final Cogen<C> c) { return new Cogen<F2<A, B, C>>() { public <X> Gen<X> cogen(final F2<A, B, C> f, final Gen<X> g) { return cogenF(aa, cogenF(ab, c)).cogen(curry(f), g); } }; } /** * A cogen for a function-3. * * @param aa A gen for part of the domain of the function. * @param ab A gen for part of the domain of the function. * @param ac A gen for part of the domain of the function. * @param c A cogen for the codomain of the function. * @return A cogen for a function-3. */ public static <A, B, C, D> Cogen<F3<A, B, C, D>> cogenF3(final Gen<A> aa, final Gen<B> ab, final Gen<C> ac, final Cogen<D> c) { return new Cogen<F3<A, B, C, D>>() { public <X> Gen<X> cogen(final F3<A, B, C, D> f, final Gen<X> g) { return cogenF(aa, cogenF(ab, cogenF(ac, c))).cogen(curry(f), g); } }; } /** * A cogen for a function-4. * * @param aa A gen for part of the domain of the function. * @param ab A gen for part of the domain of the function. * @param ac A gen for part of the domain of the function. * @param ad A gen for part of the domain of the function. * @param c A cogen for the codomain of the function. * @return A cogen for a function-4. */ public static <A, B, C, D, E> Cogen<F4<A, B, C, D, E>> cogenF4(final Gen<A> aa, final Gen<B> ab, final Gen<C> ac, final Gen<D> ad, final Cogen<E> c) { return new Cogen<F4<A, B, C, D, E>>() { public <X> Gen<X> cogen(final F4<A, B, C, D, E> f, final Gen<X> g) { return cogenF(aa, cogenF(ab, cogenF(ac, cogenF(ad, c)))).cogen(curry(f), g); } }; } /** * A cogen for a function-5. * * @param aa A gen for part of the domain of the function. * @param ab A gen for part of the domain of the function. * @param ac A gen for part of the domain of the function. * @param ad A gen for part of the domain of the function. * @param ae A gen for part of the domain of the function. * @param c A cogen for the codomain of the function. * @return A cogen for a function-5. */ public static <A, B, C, D, E, F$> Cogen<F5<A, B, C, D, E, F$>> cogenF5(final Gen<A> aa, final Gen<B> ab, final Gen<C> ac, final Gen<D> ad, final Gen<E> ae, final Cogen<F$> c) { return new Cogen<F5<A, B, C, D, E, F$>>() { public <X> Gen<X> cogen(final F5<A, B, C, D, E, F$> f, final Gen<X> g) { return cogenF(aa, cogenF(ab, cogenF(ac, cogenF(ad, cogenF(ae, c))))).cogen(curry(f), g); } }; } /** * A cogen for a function-6. * * @param aa A gen for part of the domain of the function. * @param ab A gen for part of the domain of the function. * @param ac A gen for part of the domain of the function. * @param ad A gen for part of the domain of the function. * @param ae A gen for part of the domain of the function. * @param af A gen for part of the domain of the function. * @param c A cogen for the codomain of the function. * @return A cogen for a function-6. */ public static <A, B, C, D, E, F$, G> Cogen<F6<A, B, C, D, E, F$, G>> cogenF6(final Gen<A> aa, final Gen<B> ab, final Gen<C> ac, final Gen<D> ad, final Gen<E> ae, final Gen<F$> af, final Cogen<G> c) { return new Cogen<F6<A, B, C, D, E, F$, G>>() { public <X> Gen<X> cogen(final F6<A, B, C, D, E, F$, G> f, final Gen<X> g) { return cogenF(aa, cogenF(ab, cogenF(ac, cogenF(ad, cogenF(ae, cogenF(af, c)))))).cogen(curry(f), g); } }; } /** * A cogen for a function-7. * * @param aa A gen for part of the domain of the function. * @param ab A gen for part of the domain of the function. * @param ac A gen for part of the domain of the function. * @param ad A gen for part of the domain of the function. * @param ae A gen for part of the domain of the function. * @param af A gen for part of the domain of the function. * @param ag A gen for part of the domain of the function. * @param c A cogen for the codomain of the function. * @return A cogen for a function-7. */ public static <A, B, C, D, E, F$, G, H> Cogen<F7<A, B, C, D, E, F$, G, H>> cogenF7(final Gen<A> aa, final Gen<B> ab, final Gen<C> ac, final Gen<D> ad, final Gen<E> ae, final Gen<F$> af, final Gen<G> ag, final Cogen<H> c) { return new Cogen<F7<A, B, C, D, E, F$, G, H>>() { public <X> Gen<X> cogen(final F7<A, B, C, D, E, F$, G, H> f, final Gen<X> g) { return cogenF(aa, cogenF(ab, cogenF(ac, cogenF(ad, cogenF(ae, cogenF(af, cogenF(ag, c))))))) .cogen(curry(f), g); } }; } /** * A cogen for a function-8. * * @param aa A gen for part of the domain of the function. * @param ab A gen for part of the domain of the function. * @param ac A gen for part of the domain of the function. * @param ad A gen for part of the domain of the function. * @param ae A gen for part of the domain of the function. * @param af A gen for part of the domain of the function. * @param ag A gen for part of the domain of the function. * @param ah A gen for part of the domain of the function. * @param c A cogen for the codomain of the function. * @return A cogen for a function-8. */ public static <A, B, C, D, E, F$, G, H, I> Cogen<F8<A, B, C, D, E, F$, G, H, I>> cogenF8(final Gen<A> aa, final Gen<B> ab, final Gen<C> ac, final Gen<D> ad, final Gen<E> ae, final Gen<F$> af, final Gen<G> ag, final Gen<H> ah, final Cogen<I> c) { return new Cogen<F8<A, B, C, D, E, F$, G, H, I>>() { public <X> Gen<X> cogen(final F8<A, B, C, D, E, F$, G, H, I> f, final Gen<X> g) { return cogenF(aa, cogenF(ab, cogenF(ac, cogenF(ad, cogenF(ae, cogenF(af, cogenF(ag, cogenF(ah, c)))))))) .cogen(curry(f), g); } }; } /** * A cogen for booleans. */ public static final Cogen<Boolean> cogenBoolean = new Cogen<Boolean>() { public <B> Gen<B> cogen(final Boolean b, final Gen<B> g) { return variant(b ? 0 : 1, g); } }; /** * A cogen for integers. */ public static final Cogen<Integer> cogenInteger = new Cogen<Integer>() { public <B> Gen<B> cogen(final Integer i, final Gen<B> g) { return variant(i >= 0 ? 2 * i : -2 * i + 1, g); } }; /** * A cogen for bytes. */ public static final Cogen<Byte> cogenByte = new Cogen<Byte>() { public <B> Gen<B> cogen(final Byte b, final Gen<B> g) { return variant(b >= 0 ? 2 * b : -2 * b + 1, g); } }; /** * A cogen for shorts. */ public static final Cogen<Short> cogenShort = new Cogen<Short>() { public <B> Gen<B> cogen(final Short s, final Gen<B> g) { return variant(s >= 0 ? 2 * s : -2 * s + 1, g); } }; /** * A cogen for longs. */ public static final Cogen<Long> cogenLong = new Cogen<Long>() { public <B> Gen<B> cogen(final Long l, final Gen<B> g) { return variant(l >= 0L ? 2L * l : -2L * l + 1L, g); } }; /** * A cogen for characters. */ public static final Cogen<Character> cogenCharacter = new Cogen<Character>() { public <B> Gen<B> cogen(final Character c, final Gen<B> g) { return variant(c << 1, g); } }; /** * A cogen for floats. */ public static final Cogen<Float> cogenFloat = new Cogen<Float>() { public <B> Gen<B> cogen(final Float f, final Gen<B> g) { return cogenInteger.cogen(floatToRawIntBits(f), g); } }; /** * A cogen for doubles. */ public static final Cogen<Double> cogenDouble = new Cogen<Double>() { public <B> Gen<B> cogen(final Double d, final Gen<B> g) { return cogenLong.cogen(doubleToRawLongBits(d), g); } }; /** * A cogen for the optional value. * * @param ca A cogen for the type of the optional value. * @return A cogen for the optional value. */ public static <A> Cogen<Option<A>> cogenOption(final Cogen<A> ca) { return new Cogen<Option<A>>() { public <B> Gen<B> cogen(final Option<A> o, final Gen<B> g) { return o.isNone() ? variant(0, g) : variant(1, ca.cogen(o.some(), g)); } }; } /** * A cogen for the disjoint union. * * @param ca A cogen for one side of the disjoint union. * @param cb A cogen for one side of the disjoint union. * @return A cogen for the disjoint union. */ public static <A, B> Cogen<Either<A, B>> cogenEither(final Cogen<A> ca, final Cogen<B> cb) { return new Cogen<Either<A, B>>() { public <X> Gen<X> cogen(final Either<A, B> e, final Gen<X> g) { return e.isLeft() ? variant(0, ca.cogen(e.left().value(), g)) : variant(1, cb.cogen(e.right().value(), g)); } }; } /** * A cogen for lists. * * @param ca A cogen for the elements of the list. * @return A cogen for lists. */ public static <A> Cogen<List<A>> cogenList(final Cogen<A> ca) { return new Cogen<List<A>>() { public <B> Gen<B> cogen(final List<A> as, final Gen<B> g) { return as.isEmpty() ? variant(0, g) : variant(1, ca.cogen(as.head(), cogen(as.tail(), g))); } }; } /** * A cogen for strings. */ public static final Cogen<String> cogenString = new Cogen<String>() { public <B> Gen<B> cogen(final String s, final Gen<B> g) { return cogenList(cogenCharacter).cogen(fromString(s), g); } }; /** * A cogen for string buffers. */ public static final Cogen<StringBuffer> cogenStringBuffer = new Cogen<StringBuffer>() { public <B> Gen<B> cogen(final StringBuffer s, final Gen<B> g) { return cogenString.cogen(s.toString(), g); } }; /** * A cogen for string builders. */ public static final Cogen<StringBuilder> cogenStringBuilder = new Cogen<StringBuilder>() { public <B> Gen<B> cogen(final StringBuilder s, final Gen<B> g) { return cogenString.cogen(s.toString(), g); } }; /** * A cogen for streams. * * @param ca A cogen for the elements of the stream. * @return A cogen for streams. */ public static <A> Cogen<Stream<A>> cogenStream(final Cogen<A> ca) { return new Cogen<Stream<A>>() { public <B> Gen<B> cogen(final Stream<A> as, final Gen<B> g) { return as.isEmpty() ? variant(0, g) : variant(1, ca.cogen(as.head(), cogen(as.tail()._1(), g))); } }; } /** * A cogen for the provided LcgRng * @return A cogen for the provided LcgRng. */ public static Cogen<LcgRng> cogenLcgRng() { return new Cogen<LcgRng>() { @Override public <B> Gen<B> cogen(LcgRng rng, Gen<B> g) { long i = rng.getSeed(); return variant(i >= 0 ? 2 * i : -2 * i + 1, g); } }; } /** * A cogen for state. */ public static <S, A> Cogen<State<S, A>> cogenState(Gen<S> as, F2<S, A, Long> f) { return new Cogen<State<S, A>>() { @Override public <B> Gen<B> cogen(State<S, A> s1, Gen<B> g) { return as.bind(r -> { P2<S, A> p = s1.run(r); return variant(f.f(p._1(), p._2()), g); }); } }; } /** * A cogen for arrays. * * @param ca A cogen for the elements of the array. * @return A cogen for arrays. */ public static <A> Cogen<Array<A>> cogenArray(final Cogen<A> ca) { return new Cogen<Array<A>>() { public <B> Gen<B> cogen(final Array<A> as, final Gen<B> g) { return cogenList(ca).cogen(as.toList(), g); } }; } /** * A cogen for throwables. * * @param cs A cogen for the throwable message. * @return A cogen for throwables. */ public static Cogen<Throwable> cogenThrowable(final Cogen<String> cs) { return cs.contramap(new F<Throwable, String>() { public String f(final Throwable t) { return t.getMessage(); } }); } /** * A cogen for throwables. */ public static final Cogen<Throwable> cogenThrowable = cogenThrowable(cogenString); // BEGIN java.util /** * A cogen for array lists. * * @param ca A cogen for the elements of the array list. * @return A cogen for array lists. */ public static <A> Cogen<ArrayList<A>> cogenArrayList(final Cogen<A> ca) { return new Cogen<ArrayList<A>>() { @SuppressWarnings("unchecked") public <B> Gen<B> cogen(final ArrayList<A> as, final Gen<B> g) { return cogenArray(ca).cogen(iterableArray(as), g); } }; } /** * A cogen for bit sets. */ public static final Cogen<BitSet> cogenBitSet = new Cogen<BitSet>() { public <B> Gen<B> cogen(final BitSet s, final Gen<B> g) { List<Boolean> x = nil(); for (int i = 0; i < s.size(); i++) { x = x.snoc(s.get(i)); } return cogenList(cogenBoolean).cogen(x, g); } }; /** * A cogen for calendars. */ public static final Cogen<Calendar> cogenCalendar = new Cogen<Calendar>() { public <B> Gen<B> cogen(final Calendar c, final Gen<B> g) { return cogenLong.cogen(c.getTime().getTime(), g); } }; /** * A cogen for dates. */ public static final Cogen<Date> cogenDate = new Cogen<Date>() { public <B> Gen<B> cogen(final Date d, final Gen<B> g) { return cogenLong.cogen(d.getTime(), g); } }; /** * A cogen for enum maps. * * @param ck A cogen for the map keys. * @param cv A cogen for the map values. * @return A cogen for enum maps. */ public static <K extends Enum<K>, V> Cogen<EnumMap<K, V>> cogenEnumMap(final Cogen<K> ck, final Cogen<V> cv) { return new Cogen<EnumMap<K, V>>() { @SuppressWarnings("UseOfObsoleteCollectionType") public <B> Gen<B> cogen(final EnumMap<K, V> m, final Gen<B> g) { return cogenHashtable(ck, cv).cogen(new Hashtable<>(m), g); } }; } /** * A cogen for enum sets. * * @param c A cogen for the elements of the enum set. * @return A cogen for enum sets. */ public static <A extends Enum<A>> Cogen<EnumSet<A>> cogenEnumSet(final Cogen<A> c) { return new Cogen<EnumSet<A>>() { @SuppressWarnings("unchecked") public <B> Gen<B> cogen(final EnumSet<A> as, final Gen<B> g) { return cogenHashSet(c).cogen(new HashSet<>(as), g); } }; } /** * A cogen for gregorian calendars. */ public static final Cogen<GregorianCalendar> cogenGregorianCalendar = new Cogen<GregorianCalendar>() { public <B> Gen<B> cogen(final GregorianCalendar c, final Gen<B> g) { return cogenLong.cogen(c.getTime().getTime(), g); } }; /** * A cogen for hash maps. * * @param ck A cogen for the map keys. * @param cv A cogen for the map values. * @return A cogen for hash maps. */ public static <K, V> Cogen<HashMap<K, V>> cogenHashMap(final Cogen<K> ck, final Cogen<V> cv) { return new Cogen<HashMap<K, V>>() { @SuppressWarnings("UseOfObsoleteCollectionType") public <B> Gen<B> cogen(final HashMap<K, V> m, final Gen<B> g) { return cogenHashtable(ck, cv).cogen(new Hashtable<>(m), g); } }; } /** * A cogen for hash sets. * * @param c A cogen for the elements of the hash set. * @return A cogen for hash sets. */ public static <A> Cogen<HashSet<A>> cogenHashSet(final Cogen<A> c) { return new Cogen<HashSet<A>>() { @SuppressWarnings("unchecked") public <B> Gen<B> cogen(final HashSet<A> as, final Gen<B> g) { return cogenArray(c).cogen(iterableArray(as), g); } }; } /** * A cogen for hash tables. * * @param ck A cogen for the map keys. * @param cv A cogen for the map values. * @return A cogen for hash tables. */ public static <K, V> Cogen<Hashtable<K, V>> cogenHashtable(final Cogen<K> ck, final Cogen<V> cv) { return new Cogen<Hashtable<K, V>>() { @SuppressWarnings("UseOfObsoleteCollectionType") public <B> Gen<B> cogen(final Hashtable<K, V> h, final Gen<B> g) { List<P2<K, V>> x = nil(); for (final Map.Entry<K, V> entry : h.entrySet()) { x = x.snoc(p(entry.getKey(), entry.getValue())); } return cogenList(cogenP2(ck, cv)).cogen(x, g); } }; } /** * A cogen for identity hash maps. * * @param ck A cogen for the map keys. * @param cv A cogen for the map values. * @return A cogen for identity hash maps. */ public static <K, V> Cogen<IdentityHashMap<K, V>> cogenIdentityHashMap(final Cogen<K> ck, final Cogen<V> cv) { return new Cogen<IdentityHashMap<K, V>>() { @SuppressWarnings("UseOfObsoleteCollectionType") public <B> Gen<B> cogen(final IdentityHashMap<K, V> m, final Gen<B> g) { return cogenHashtable(ck, cv).cogen(new Hashtable<>(m), g); } }; } /** * A cogen for linked hash maps. * * @param ck A cogen for the map keys. * @param cv A cogen for the map values. * @return A cogen for linked hash maps. */ public static <K, V> Cogen<LinkedHashMap<K, V>> cogenLinkedHashMap(final Cogen<K> ck, final Cogen<V> cv) { return new Cogen<LinkedHashMap<K, V>>() { @SuppressWarnings("UseOfObsoleteCollectionType") public <B> Gen<B> cogen(final LinkedHashMap<K, V> m, final Gen<B> g) { return cogenHashtable(ck, cv).cogen(new Hashtable<>(m), g); } }; } /** * A cogen for linked hash sets. * * @param c A cogen for the elements of the linked hash set. * @return A cogen for linked hash sets. */ public static <A> Cogen<LinkedHashSet<A>> cogenLinkedHashSet(final Cogen<A> c) { return new Cogen<LinkedHashSet<A>>() { @SuppressWarnings("unchecked") public <B> Gen<B> cogen(final LinkedHashSet<A> as, final Gen<B> g) { return cogenHashSet(c).cogen(new HashSet<>(as), g); } }; } /** * A cogen for linked lists. * * @param c A cogen for the elements of the linked list. * @return A cogen for linked lists. */ public static <A> Cogen<LinkedList<A>> cogenLinkedList(final Cogen<A> c) { return new Cogen<LinkedList<A>>() { @SuppressWarnings("unchecked") public <B> Gen<B> cogen(final LinkedList<A> as, final Gen<B> g) { return cogenArray(c).cogen(iterableArray(as), g); } }; } /** * A cogen for priority queues. * * @param c A cogen for the elements of the priority queue. * @return A cogen for priority queues. */ public static <A> Cogen<PriorityQueue<A>> cogenPriorityQueue(final Cogen<A> c) { return new Cogen<PriorityQueue<A>>() { @SuppressWarnings("unchecked") public <B> Gen<B> cogen(final PriorityQueue<A> as, final Gen<B> g) { return cogenArray(c).cogen(iterableArray(as), g); } }; } /** * A cogen for properties. */ public static final Cogen<Properties> cogenProperties = new Cogen<Properties>() { @SuppressWarnings("UseOfObsoleteCollectionType") public <B> Gen<B> cogen(final Properties p, final Gen<B> g) { final Hashtable<String, String> t = new Hashtable<>(); for (final Object s : p.keySet()) { t.put((String) s, p.getProperty((String) s)); } return cogenHashtable(cogenString, cogenString).cogen(t, g); } }; /** * A cogen for stacks. * * @param c A cogen for the elements of the stack. * @return A cogen for stacks. */ public static <A> Cogen<Stack<A>> cogenStack(final Cogen<A> c) { return new Cogen<Stack<A>>() { @SuppressWarnings("unchecked") public <B> Gen<B> cogen(final Stack<A> as, final Gen<B> g) { return cogenArray(c).cogen(iterableArray(as), g); } }; } /** * A cogen for tree maps. * * @param ck A cogen for the map keys. * @param cv A cogen for the map values. * @return A cogen for tree maps. */ public static <K, V> Cogen<TreeMap<K, V>> cogenTreeMap(final Cogen<K> ck, final Cogen<V> cv) { return new Cogen<TreeMap<K, V>>() { @SuppressWarnings("UseOfObsoleteCollectionType") public <B> Gen<B> cogen(final TreeMap<K, V> m, final Gen<B> g) { return cogenHashtable(ck, cv).cogen(new Hashtable<>(m), g); } }; } /** * A cogen for tree sets. * * @param c A cogen for the elements of the tree set. * @return A cogen for tree sets. */ public static <A> Cogen<TreeSet<A>> cogenTreeSet(final Cogen<A> c) { return new Cogen<TreeSet<A>>() { @SuppressWarnings("unchecked") public <B> Gen<B> cogen(final TreeSet<A> as, final Gen<B> g) { return cogenHashSet(c).cogen(new HashSet<>(as), g); } }; } /** * A cogen for vectors. * * @param c A cogen for the elements of the vector. * @return A cogen for vectors. */ public static <A> Cogen<Vector<A>> cogenVector(final Cogen<A> c) { return new Cogen<Vector<A>>() { @SuppressWarnings({"unchecked", "UseOfObsoleteCollectionType"}) public <B> Gen<B> cogen(final Vector<A> as, final Gen<B> g) { return cogenArray(c).cogen(iterableArray(as), g); } }; } /** * A cogen for weak hash maps. * * @param ck A cogen for the map keys. * @param cv A cogen for the map values. * @return A cogen for weak hash maps. */ public static <K, V> Cogen<WeakHashMap<K, V>> cogenWeakHashMap(final Cogen<K> ck, final Cogen<V> cv) { return new Cogen<WeakHashMap<K, V>>() { @SuppressWarnings("UseOfObsoleteCollectionType") public <B> Gen<B> cogen(final WeakHashMap<K, V> m, final Gen<B> g) { return cogenHashtable(ck, cv).cogen(new Hashtable<>(m), g); } }; } // END java.util // BEGIN java.util.concurrent /** * A cogen for array blocking queues. * * @param c A cogen for the elements of the array blocking queue. * @return A cogen for array blocking queues. */ public static <A> Cogen<ArrayBlockingQueue<A>> cogenArrayBlockingQueue(final Cogen<A> c) { return new Cogen<ArrayBlockingQueue<A>>() { @SuppressWarnings("unchecked") public <B> Gen<B> cogen(final ArrayBlockingQueue<A> as, final Gen<B> g) { return cogenArray(c).cogen(iterableArray(as), g); } }; } /** * A cogen for concurrent hash maps. * * @param ck A cogen for the map keys. * @param cv A cogen for the map values. * @return A cogen for concurrent hash maps. */ public static <K, V> Cogen<ConcurrentHashMap<K, V>> cogenConcurrentHashMap(final Cogen<K> ck, final Cogen<V> cv) { return new Cogen<ConcurrentHashMap<K, V>>() { @SuppressWarnings("UseOfObsoleteCollectionType") public <B> Gen<B> cogen(final ConcurrentHashMap<K, V> m, final Gen<B> g) { return cogenHashtable(ck, cv).cogen(new Hashtable<>(m), g); } }; } /** * A cogen for concurrent linked queues. * * @param c A cogen for the elements of the concurrent linked queue. * @return A cogen for concurrent linked queues. */ public static <A> Cogen<ConcurrentLinkedQueue<A>> cogenConcurrentLinkedQueue(final Cogen<A> c) { return new Cogen<ConcurrentLinkedQueue<A>>() { @SuppressWarnings("unchecked") public <B> Gen<B> cogen(final ConcurrentLinkedQueue<A> as, final Gen<B> g) { return cogenArray(c).cogen(iterableArray(as), g); } }; } /** * A cogen for copy-on-write array lists. * * @param c A cogen for the elements of the copy-on-write array list. * @return A cogen for copy-on-write array lists. */ public static <A> Cogen<CopyOnWriteArrayList<A>> cogenCopyOnWriteArrayList(final Cogen<A> c) { return new Cogen<CopyOnWriteArrayList<A>>() { @SuppressWarnings("unchecked") public <B> Gen<B> cogen(final CopyOnWriteArrayList<A> as, final Gen<B> g) { return cogenArray(c).cogen(iterableArray(as), g); } }; } /** * A cogen for copy-on-write array sets. * * @param c A cogen for the elements of the copy-on-write array set. * @return A cogen for copy-on-write array sets. */ public static <A> Cogen<CopyOnWriteArraySet<A>> cogenCopyOnWriteArraySet(final Cogen<A> c) { return new Cogen<CopyOnWriteArraySet<A>>() { @SuppressWarnings("unchecked") public <B> Gen<B> cogen(final CopyOnWriteArraySet<A> as, final Gen<B> g) { return cogenArray(c).cogen(iterableArray(as), g); } }; } /** * A cogen for delay queues. * * @param c A cogen for the elements of the delay queue. * @return A cogen for delay queues. */ public static <A extends Delayed> Cogen<DelayQueue<A>> cogenDelayQueue(final Cogen<A> c) { return new Cogen<DelayQueue<A>>() { @SuppressWarnings("unchecked") public <B> Gen<B> cogen(final DelayQueue<A> as, final Gen<B> g) { return cogenArray(c).cogen(iterableArray(as), g); } }; } /** * A cogen for linked blocking queues. * * @param c A cogen for the elements of the linked blocking queue. * @return A cogen for linked blocking queues. */ public static <A> Cogen<LinkedBlockingQueue<A>> cogenLinkedBlockingQueue(final Cogen<A> c) { return new Cogen<LinkedBlockingQueue<A>>() { @SuppressWarnings("unchecked") public <B> Gen<B> cogen(final LinkedBlockingQueue<A> as, final Gen<B> g) { return cogenArray(c).cogen(iterableArray(as), g); } }; } /** * A cogen for priority blocking queues. * * @param c A cogen for the elements of the priority blocking queue. * @return A cogen for priority blocking queues. */ public static <A> Cogen<PriorityBlockingQueue<A>> cogenPriorityBlockingQueue(final Cogen<A> c) { return new Cogen<PriorityBlockingQueue<A>>() { @SuppressWarnings("unchecked") public <B> Gen<B> cogen(final PriorityBlockingQueue<A> as, final Gen<B> g) { return cogenArray(c).cogen(iterableArray(as), g); } }; } /** * A cogen for synchronous queues. * * @param c A cogen for the elements of the synchronous queue. * @return A cogen for synchronous queues. */ public static <A> Cogen<SynchronousQueue<A>> cogenSynchronousQueue(final Cogen<A> c) { return new Cogen<SynchronousQueue<A>>() { @SuppressWarnings("unchecked") public <B> Gen<B> cogen(final SynchronousQueue<A> as, final Gen<B> g) { return cogenArray(c).cogen(iterableArray(as), g); } }; } // END java.util.concurrent // BEGIN java.sql public static final Cogen<java.sql.Date> cogenSQLDate = new Cogen<java.sql.Date>() { public <B> Gen<B> cogen(final java.sql.Date d, final Gen<B> g) { return cogenLong.cogen(d.getTime(), g); } }; public static final Cogen<Timestamp> cogenTimestamp = new Cogen<Timestamp>() { public <B> Gen<B> cogen(final Timestamp t, final Gen<B> g) { return cogenLong.cogen(t.getTime(), g); } }; public static final Cogen<Time> cogenTime = new Cogen<Time>() { public <B> Gen<B> cogen(final Time t, final Gen<B> g) { return cogenLong.cogen(t.getTime(), g); } }; // END java.sql // BEGIN java.math public static final Cogen<BigInteger> cogenBigInteger = new Cogen<BigInteger>() { public <B> Gen<B> cogen(final BigInteger i, final Gen<B> g) { return variant((i.compareTo(BigInteger.ZERO) >= 0 ? i.multiply(BigInteger.valueOf(2L)) : i.multiply(BigInteger.valueOf(-2L).add(BigInteger.ONE))).longValue(), g); } }; public static final Cogen<BigDecimal> cogenBigDecimal = new Cogen<BigDecimal>() { public <B> Gen<B> cogen(final BigDecimal d, final Gen<B> g) { return variant((d.compareTo(BigDecimal.ZERO) >= 0 ? d.multiply(BigDecimal.valueOf(2L)) : d.multiply(BigDecimal.valueOf(-2L).add(BigDecimal.ONE))).longValue(), g); } }; // END java.math /** * A cogen for product-1 values. * * @param ca A cogen for one of the types over which the product-1 is defined. * @return A cogen for product-1 values. */ public static <A> Cogen<P1<A>> cogenP1(final Cogen<A> ca) { return new Cogen<P1<A>>() { public <B> Gen<B> cogen(final P1<A> p, final Gen<B> g) { return ca.cogen(p._1(), g); } }; } /** * A cogen for product-2 values. * * @param ca A cogen for one of the types over which the product-2 is defined. * @param cb A cogen for one of the types over which the product-2 is defined. * @return A cogen for product-2 values. */ public static <A, B> Cogen<P2<A, B>> cogenP2(final Cogen<A> ca, final Cogen<B> cb) { return new Cogen<P2<A, B>>() { public <X> Gen<X> cogen(final P2<A, B> p, final Gen<X> g) { return ca.cogen(p._1(), cb.cogen(p._2(), g)); } }; } /** * A cogen for product-3 values. * * @param ca A cogen for one of the types over which the product-3 is defined. * @param cb A cogen for one of the types over which the product-3 is defined. * @param cc A cogen for one of the types over which the product-3 is defined. * @return A cogen for product-3 values. */ public static <A, B, C> Cogen<P3<A, B, C>> cogenP3(final Cogen<A> ca, final Cogen<B> cb, final Cogen<C> cc) { return new Cogen<P3<A, B, C>>() { public <X> Gen<X> cogen(final P3<A, B, C> p, final Gen<X> g) { return ca.cogen(p._1(), cb.cogen(p._2(), cc.cogen(p._3(), g))); } }; } /** * A cogen for product-4 values. * * @param ca A cogen for one of the types over which the product-4 is defined. * @param cb A cogen for one of the types over which the product-4 is defined. * @param cc A cogen for one of the types over which the product-4 is defined. * @param cd A cogen for one of the types over which the product-4 is defined. * @return A cogen for product-4 values. */ public static <A, B, C, D> Cogen<P4<A, B, C, D>> cogenP4(final Cogen<A> ca, final Cogen<B> cb, final Cogen<C> cc, final Cogen<D> cd) { return new Cogen<P4<A, B, C, D>>() { public <X> Gen<X> cogen(final P4<A, B, C, D> p, final Gen<X> g) { return ca.cogen(p._1(), cb.cogen(p._2(), cc.cogen(p._3(), cd.cogen(p._4(), g)))); } }; } /** * A cogen for product-5 values. * * @param ca A cogen for one of the types over which the product-5 is defined. * @param cb A cogen for one of the types over which the product-5 is defined. * @param cc A cogen for one of the types over which the product-5 is defined. * @param cd A cogen for one of the types over which the product-5 is defined. * @param ce A cogen for one of the types over which the product-5 is defined. * @return A cogen for product-5 values. */ public static <A, B, C, D, E> Cogen<P5<A, B, C, D, E>> cogenP5(final Cogen<A> ca, final Cogen<B> cb, final Cogen<C> cc, final Cogen<D> cd, final Cogen<E> ce) { return new Cogen<P5<A, B, C, D, E>>() { public <X> Gen<X> cogen(final P5<A, B, C, D, E> p, final Gen<X> g) { return ca.cogen(p._1(), cb.cogen(p._2(), cc.cogen(p._3(), cd.cogen(p._4(), ce.cogen(p._5(), g))))); } }; } /** * A cogen for product-6 values. * * @param ca A cogen for one of the types over which the product-6 is defined. * @param cb A cogen for one of the types over which the product-6 is defined. * @param cc A cogen for one of the types over which the product-6 is defined. * @param cd A cogen for one of the types over which the product-6 is defined. * @param ce A cogen for one of the types over which the product-6 is defined. * @param cf A cogen for one of the types over which the product-6 is defined. * @return A cogen for product-6 values. */ public static <A, B, C, D, E, F$> Cogen<P6<A, B, C, D, E, F$>> cogenP6(final Cogen<A> ca, final Cogen<B> cb, final Cogen<C> cc, final Cogen<D> cd, final Cogen<E> ce, final Cogen<F$> cf) { return new Cogen<P6<A, B, C, D, E, F$>>() { public <X> Gen<X> cogen(final P6<A, B, C, D, E, F$> p, final Gen<X> g) { return ca.cogen(p._1(), cb.cogen(p._2(), cc.cogen(p._3(), cd.cogen(p._4(), ce.cogen(p._5(), cf.cogen(p._6(), g)))))); } }; } /** * A cogen for product-7 values. * * @param ca A cogen for one of the types over which the product-7 is defined. * @param cb A cogen for one of the types over which the product-7 is defined. * @param cc A cogen for one of the types over which the product-7 is defined. * @param cd A cogen for one of the types over which the product-7 is defined. * @param ce A cogen for one of the types over which the product-7 is defined. * @param cf A cogen for one of the types over which the product-7 is defined. * @param cg A cogen for one of the types over which the product-7 is defined. * @return A cogen for product-7 values. */ public static <A, B, C, D, E, F$, G> Cogen<P7<A, B, C, D, E, F$, G>> cogenP7(final Cogen<A> ca, final Cogen<B> cb, final Cogen<C> cc, final Cogen<D> cd, final Cogen<E> ce, final Cogen<F$> cf, final Cogen<G> cg) { return new Cogen<P7<A, B, C, D, E, F$, G>>() { public <X> Gen<X> cogen(final P7<A, B, C, D, E, F$, G> p, final Gen<X> g) { return ca.cogen(p._1(), cb.cogen(p._2(), cc.cogen(p._3(), cd.cogen(p._4(), ce.cogen(p._5(), cf.cogen(p._6(), cg.cogen(p._7(), g))))))); } }; } /** * A cogen for product-8 values. * * @param ca A cogen for one of the types over which the product-8 is defined. * @param cb A cogen for one of the types over which the product-8 is defined. * @param cc A cogen for one of the types over which the product-8 is defined. * @param cd A cogen for one of the types over which the product-8 is defined. * @param ce A cogen for one of the types over which the product-8 is defined. * @param cf A cogen for one of the types over which the product-8 is defined. * @param cg A cogen for one of the types over which the product-8 is defined. * @param ch A cogen for one of the types over which the product-8 is defined. * @return A cogen for product-8 values. */ public static <A, B, C, D, E, F$, G, H> Cogen<P8<A, B, C, D, E, F$, G, H>> cogenP8(final Cogen<A> ca, final Cogen<B> cb, final Cogen<C> cc, final Cogen<D> cd, final Cogen<E> ce, final Cogen<F$> cf, final Cogen<G> cg, final Cogen<H> ch) { return new Cogen<P8<A, B, C, D, E, F$, G, H>>() { public <X> Gen<X> cogen(final P8<A, B, C, D, E, F$, G, H> p, final Gen<X> g) { return ca.cogen(p._1(), cb.cogen(p._2(), cc.cogen(p._3(), cd.cogen(p._4(), ce.cogen(p._5(), cf.cogen(p._6(), cg.cogen(p._7(), ch.cogen(p._8(), g)))))))); } }; } }