|
39 | 39 | import static fj.data.Stream.nil; |
40 | 40 |
|
41 | 41 | import static java.lang.System.arraycopy; |
| 42 | +import static java.math.BigInteger.ZERO; |
| 43 | + |
42 | 44 | import java.math.BigDecimal; |
43 | 45 | import java.math.BigInteger; |
44 | 46 | import java.sql.Time; |
@@ -354,7 +356,7 @@ public static <A> Shrink<ArrayList<A>> shrinkArrayList(final Shrink<A> sa) { |
354 | 356 | * A shrink strategy for enum maps. |
355 | 357 | * |
356 | 358 | * @param sk The shrink strategy for keys. |
357 | | - * @param sv The shrink stratgey for values. |
| 359 | + * @param sv The shrink strategy for values. |
358 | 360 | * @return A shrink strategy for enum maps. |
359 | 361 | */ |
360 | 362 | public static <K extends Enum<K>, V> Shrink<EnumMap<K, V>> shrinkEnumMap(final Shrink<K> sk, final Shrink<V> sv) { |
@@ -385,7 +387,7 @@ public static <A extends Enum<A>> Shrink<EnumSet<A>> shrinkEnumSet(final Shrink< |
385 | 387 | * A shrink strategy for hash maps. |
386 | 388 | * |
387 | 389 | * @param sk The shrink strategy for keys. |
388 | | - * @param sv The shrink stratgey for values. |
| 390 | + * @param sv The shrink strategy for values. |
389 | 391 | * @return A shrink strategy for hash maps. |
390 | 392 | */ |
391 | 393 | public static <K, V> Shrink<HashMap<K, V>> shrinkHashMap(final Shrink<K> sk, final Shrink<V> sv) { |
@@ -406,7 +408,7 @@ public static <A> Shrink<HashSet<A>> shrinkHashSet(final Shrink<A> sa) { |
406 | 408 | * A shrink strategy for hash tables. |
407 | 409 | * |
408 | 410 | * @param sk The shrink strategy for keys. |
409 | | - * @param sv The shrink stratgey for values. |
| 411 | + * @param sv The shrink strategy for values. |
410 | 412 | * @return A shrink strategy for hash tables. |
411 | 413 | */ |
412 | 414 | @SuppressWarnings("UseOfObsoleteCollectionType") |
@@ -430,7 +432,7 @@ public static <K, V> Shrink<Hashtable<K, V>> shrinkHashtable(final Shrink<K> sk, |
430 | 432 | * A shrink strategy for identity hash maps. |
431 | 433 | * |
432 | 434 | * @param sk The shrink strategy for keys. |
433 | | - * @param sv The shrink stratgey for values. |
| 435 | + * @param sv The shrink strategy for values. |
434 | 436 | * @return A shrink strategy for identity hash maps. |
435 | 437 | */ |
436 | 438 | public static <K, V> Shrink<IdentityHashMap<K, V>> shrinkIdentityHashMap(final Shrink<K> sk, final Shrink<V> sv) { |
@@ -441,7 +443,7 @@ public static <K, V> Shrink<IdentityHashMap<K, V>> shrinkIdentityHashMap(final S |
441 | 443 | * A shrink strategy for linked hash maps. |
442 | 444 | * |
443 | 445 | * @param sk The shrink strategy for keys. |
444 | | - * @param sv The shrink stratgey for values. |
| 446 | + * @param sv The shrink strategy for values. |
445 | 447 | * @return A shrink strategy for linked hash maps. |
446 | 448 | */ |
447 | 449 | public static <K, V> Shrink<LinkedHashMap<K, V>> shrinkLinkedHashMap(final Shrink<K> sk, final Shrink<V> sv) { |
@@ -514,7 +516,7 @@ public static <A> Shrink<Stack<A>> shrinkStack(final Shrink<A> sa) { |
514 | 516 | * A shrink strategy for tree maps. |
515 | 517 | * |
516 | 518 | * @param sk The shrink strategy for keys. |
517 | | - * @param sv The shrink stratgey for values. |
| 519 | + * @param sv The shrink strategy for values. |
518 | 520 | * @return A shrink strategy for tree maps. |
519 | 521 | */ |
520 | 522 | public static <K, V> Shrink<TreeMap<K, V>> shrinkTreeMap(final Shrink<K> sk, final Shrink<V> sv) { |
@@ -545,7 +547,7 @@ public static <A> Shrink<Vector<A>> shrinkVector(final Shrink<A> sa) { |
545 | 547 | * A shrink strategy for weak hash maps. |
546 | 548 | * |
547 | 549 | * @param sk The shrink strategy for keys. |
548 | | - * @param sv The shrink stratgey for values. |
| 550 | + * @param sv The shrink strategy for values. |
549 | 551 | * @return A shrink strategy for weak hash maps. |
550 | 552 | */ |
551 | 553 | public static <K, V> Shrink<WeakHashMap<K, V>> shrinkWeakHashMap(final Shrink<K> sk, final Shrink<V> sv) { |
@@ -570,7 +572,7 @@ public static <A> Shrink<ArrayBlockingQueue<A>> shrinkArrayBlockingQueue(final S |
570 | 572 | * A shrink strategy for concurrent hash maps. |
571 | 573 | * |
572 | 574 | * @param sk The shrink strategy for keys. |
573 | | - * @param sv The shrink stratgey for values. |
| 575 | + * @param sv The shrink strategy for values. |
574 | 576 | * @return A shrink strategy for concurrent hash maps. |
575 | 577 | */ |
576 | 578 | public static <K, V> Shrink<ConcurrentHashMap<K, V>> shrinkConcurrentHashMap(final Shrink<K> sk, final Shrink<V> sv) { |
@@ -676,23 +678,20 @@ public static <A> Shrink<SynchronousQueue<A>> shrinkSynchronousQueue(final Shrin |
676 | 678 | /** |
677 | 679 | * A shrink strategy for big integers. |
678 | 680 | */ |
679 | | - public static final Shrink<BigInteger> shrinkBigInteger = |
680 | | - shrinkP2(shrinkByte, shrinkArray(shrinkByte)).map(bs -> { |
681 | | - final byte[] x = new byte[bs._2().length() + 1]; |
682 | | - |
683 | | - for (int i = 0; i < bs._2().array().length; i++) { |
684 | | - x[i] = bs._2().get(i); |
685 | | - } |
686 | | - |
687 | | - x[bs._2().length()] = bs._1(); |
| 681 | + public static final Shrink<BigInteger> shrinkBigInteger = shrink(i -> { |
| 682 | + final Equal<BigInteger> eq = Equal.bigintEqual; |
| 683 | + final BigInteger two = BigInteger.valueOf(2L); |
| 684 | + if (eq.eq(i, ZERO)) { |
| 685 | + return nil(); |
| 686 | + } else { |
| 687 | + final Stream<BigInteger> is = cons(ZERO, |
| 688 | + () -> iterate(x -> x.divide(two), i) |
| 689 | + .takeWhile(x2 -> eq.notEq(x2, ZERO)) |
| 690 | + .map(i::subtract)); |
688 | 691 |
|
689 | | - return new BigInteger(x); |
690 | | - }, i -> { |
691 | | - final byte[] b = i.toByteArray(); |
692 | | - final Byte[] x = new Byte[b.length - 1]; |
693 | | - arraycopy(b, 0, x, 0, b.length - 1); |
694 | | - return p(b[0], array(x)); |
695 | | - }); |
| 692 | + return Ord.bigintOrd.isLessThan(i, ZERO) ? cons(i.negate(), () -> is) : is; |
| 693 | + } |
| 694 | + }); |
696 | 695 |
|
697 | 696 | /** |
698 | 697 | * A shrink strategy for big decimals. |
|