444 public static final IntVector single(Species<Integer> s, int e) { 445 return zero(s).with(0, e); 446 } 447 448 /** 449 * Returns a vector where each lane element is set to a randomly 450 * generated primitive value. 451 * 452 * The semantics are equivalent to calling 453 * {@link ThreadLocalRandom#nextInt()} 454 * 455 * @param s species of the desired vector 456 * @return a vector where each lane elements is set to a randomly 457 * generated primitive value 458 */ 459 public static IntVector random(Species<Integer> s) { 460 ThreadLocalRandom r = ThreadLocalRandom.current(); 461 return ((IntSpecies)s).op(i -> r.nextInt()); 462 } 463 464 /** 465 * Returns a mask where each lane is set or unset according to given 466 * {@code boolean} values 467 * <p> 468 * For each mask lane, where {@code N} is the mask lane index, 469 * if the given {@code boolean} value at index {@code N} is {@code true} 470 * then the mask lane at index {@code N} is set, otherwise it is unset. 471 * 472 * @param species mask species 473 * @param bits the given {@code boolean} values 474 * @return a mask where each lane is set or unset according to the given {@code boolean} value 475 * @throws IndexOutOfBoundsException if {@code bits.length < species.length()} 476 */ 477 @ForceInline 478 public static Mask<Integer> maskFromValues(Species<Integer> species, boolean... bits) { 479 if (species.boxType() == IntMaxVector.class) 480 return new IntMaxVector.IntMaxMask(bits); 481 switch (species.bitSize()) { 482 case 64: return new Int64Vector.Int64Mask(bits); 483 case 128: return new Int128Vector.Int128Mask(bits); 484 case 256: return new Int256Vector.Int256Mask(bits); 485 case 512: return new Int512Vector.Int512Mask(bits); 486 default: throw new IllegalArgumentException(Integer.toString(species.bitSize())); 487 } 488 } 489 490 // @@@ This is a bad implementation -- makes lambdas capturing -- fix this 491 static Mask<Integer> trueMask(Species<Integer> species) { 492 if (species.boxType() == IntMaxVector.class) 493 return IntMaxVector.IntMaxMask.TRUE_MASK; 494 switch (species.bitSize()) { 495 case 64: return Int64Vector.Int64Mask.TRUE_MASK; 496 case 128: return Int128Vector.Int128Mask.TRUE_MASK; 497 case 256: return Int256Vector.Int256Mask.TRUE_MASK; 498 case 512: return Int512Vector.Int512Mask.TRUE_MASK; 499 default: throw new IllegalArgumentException(Integer.toString(species.bitSize())); 500 } 501 } 502 503 static Mask<Integer> falseMask(Species<Integer> species) { 504 if (species.boxType() == IntMaxVector.class) 505 return IntMaxVector.IntMaxMask.FALSE_MASK; 506 switch (species.bitSize()) { 507 case 64: return Int64Vector.Int64Mask.FALSE_MASK; 508 case 128: return Int128Vector.Int128Mask.FALSE_MASK; 509 case 256: return Int256Vector.Int256Mask.FALSE_MASK; 510 case 512: return Int512Vector.Int512Mask.FALSE_MASK; 511 default: throw new IllegalArgumentException(Integer.toString(species.bitSize())); 512 } 513 } 514 515 /** 516 * Loads a mask from a {@code boolean} array starting at an offset. 517 * <p> 518 * For each mask lane, where {@code N} is the mask lane index, 519 * if the array element at index {@code ix + N} is {@code true} then the 520 * mask lane at index {@code N} is set, otherwise it is unset. 521 * 522 * @param species mask species 523 * @param bits the {@code boolean} array 524 * @param ix the offset into the array 525 * @return the mask loaded from a {@code boolean} array 526 * @throws IndexOutOfBoundsException if {@code ix < 0}, or 527 * {@code ix > bits.length - species.length()} 528 */ 529 @ForceInline 530 @SuppressWarnings("unchecked") 531 public static Mask<Integer> maskFromArray(Species<Integer> species, boolean[] bits, int ix) { 532 Objects.requireNonNull(bits); 533 ix = VectorIntrinsics.checkIndex(ix, bits.length, species.length()); 534 return VectorIntrinsics.load((Class<Mask<Integer>>) species.maskType(), int.class, species.length(), 535 bits, (((long) ix) << ARRAY_SHIFT) + Unsafe.ARRAY_BOOLEAN_BASE_OFFSET, 536 bits, ix, species, 537 (c, idx, s) -> (Mask<Integer>) ((IntSpecies)s).opm(n -> c[idx + n])); 538 } 539 540 /** 541 * Returns a mask where all lanes are set. 542 * 543 * @param species mask species 544 * @return a mask where all lanes are set 545 */ 546 @ForceInline 547 @SuppressWarnings("unchecked") 548 public static Mask<Integer> maskAllTrue(Species<Integer> species) { 549 return VectorIntrinsics.broadcastCoerced((Class<Mask<Integer>>) species.maskType(), int.class, species.length(), 550 (int)-1, species, 551 ((z, s) -> trueMask(s))); 552 } 553 554 /** 555 * Returns a mask where all lanes are unset. 556 * 557 * @param species mask species 558 * @return a mask where all lanes are unset 559 */ 560 @ForceInline 561 @SuppressWarnings("unchecked") 562 public static Mask<Integer> maskAllFalse(Species<Integer> species) { 563 return VectorIntrinsics.broadcastCoerced((Class<Mask<Integer>>) species.maskType(), int.class, species.length(), 564 0, species, 565 ((z, s) -> falseMask(s))); 566 } 567 568 /** 569 * Returns a shuffle of mapped indexes where each lane element is 570 * the result of applying a mapping function to the corresponding lane 571 * index. 572 * <p> 573 * Care should be taken to ensure Shuffle values produced from this 574 * method are consumed as constants to ensure optimal generation of 575 * code. For example, values held in static final fields or values 576 * held in loop constant local variables. 577 * <p> 578 * This method behaves as if a shuffle is created from an array of 579 * mapped indexes as follows: 580 * <pre>{@code 581 * int[] a = new int[species.length()]; 582 * for (int i = 0; i < a.length; i++) { 583 * a[i] = f.applyAsInt(i); 584 * } 585 * return this.shuffleFromValues(a); 586 * }</pre> 587 * 588 * @param species shuffle species 589 * @param f the lane index mapping function 590 * @return a shuffle of mapped indexes 591 */ 592 @ForceInline 593 public static Shuffle<Integer> shuffle(Species<Integer> species, IntUnaryOperator f) { 594 if (species.boxType() == IntMaxVector.class) 595 return new IntMaxVector.IntMaxShuffle(f); 596 switch (species.bitSize()) { 597 case 64: return new Int64Vector.Int64Shuffle(f); 598 case 128: return new Int128Vector.Int128Shuffle(f); 599 case 256: return new Int256Vector.Int256Shuffle(f); 600 case 512: return new Int512Vector.Int512Shuffle(f); 601 default: throw new IllegalArgumentException(Integer.toString(species.bitSize())); 602 } 603 } 604 605 /** 606 * Returns a shuffle where each lane element is the value of its 607 * corresponding lane index. 608 * <p> 609 * This method behaves as if a shuffle is created from an identity 610 * index mapping function as follows: 611 * <pre>{@code 612 * return this.shuffle(i -> i); 613 * }</pre> 614 * 615 * @param species shuffle species 616 * @return a shuffle of lane indexes 617 */ 618 @ForceInline 619 public static Shuffle<Integer> shuffleIota(Species<Integer> species) { 620 if (species.boxType() == IntMaxVector.class) 621 return new IntMaxVector.IntMaxShuffle(AbstractShuffle.IDENTITY); 622 switch (species.bitSize()) { 623 case 64: return new Int64Vector.Int64Shuffle(AbstractShuffle.IDENTITY); 624 case 128: return new Int128Vector.Int128Shuffle(AbstractShuffle.IDENTITY); 625 case 256: return new Int256Vector.Int256Shuffle(AbstractShuffle.IDENTITY); 626 case 512: return new Int512Vector.Int512Shuffle(AbstractShuffle.IDENTITY); 627 default: throw new IllegalArgumentException(Integer.toString(species.bitSize())); 628 } 629 } 630 631 /** 632 * Returns a shuffle where each lane element is set to a given 633 * {@code int} value logically AND'ed by the species length minus one. 634 * <p> 635 * For each shuffle lane, where {@code N} is the shuffle lane index, the 636 * the {@code int} value at index {@code N} logically AND'ed by 637 * {@code species.length() - 1} is placed into the resulting shuffle at 638 * lane index {@code N}. 639 * 640 * @param species shuffle species 641 * @param ixs the given {@code int} values 642 * @return a shuffle where each lane element is set to a given 643 * {@code int} value 644 * @throws IndexOutOfBoundsException if the number of int values is 645 * {@code < species.length()} 646 */ 647 @ForceInline 648 public static Shuffle<Integer> shuffleFromValues(Species<Integer> species, int... ixs) { 649 if (species.boxType() == IntMaxVector.class) 650 return new IntMaxVector.IntMaxShuffle(ixs); 651 switch (species.bitSize()) { 652 case 64: return new Int64Vector.Int64Shuffle(ixs); 653 case 128: return new Int128Vector.Int128Shuffle(ixs); 654 case 256: return new Int256Vector.Int256Shuffle(ixs); 655 case 512: return new Int512Vector.Int512Shuffle(ixs); 656 default: throw new IllegalArgumentException(Integer.toString(species.bitSize())); 657 } 658 } 659 660 /** 661 * Loads a shuffle from an {@code int} array starting at an offset. 662 * <p> 663 * For each shuffle lane, where {@code N} is the shuffle lane index, the 664 * array element at index {@code i + N} logically AND'ed by 665 * {@code species.length() - 1} is placed into the resulting shuffle at lane 666 * index {@code N}. 667 * 668 * @param species shuffle species 669 * @param ixs the {@code int} array 670 * @param i the offset into the array 671 * @return a shuffle loaded from the {@code int} array 672 * @throws IndexOutOfBoundsException if {@code i < 0}, or 673 * {@code i > a.length - species.length()} 674 */ 675 @ForceInline 676 public static Shuffle<Integer> shuffleFromArray(Species<Integer> species, int[] ixs, int i) { 677 if (species.boxType() == IntMaxVector.class) 678 return new IntMaxVector.IntMaxShuffle(ixs, i); 679 switch (species.bitSize()) { 680 case 64: return new Int64Vector.Int64Shuffle(ixs, i); 681 case 128: return new Int128Vector.Int128Shuffle(ixs, i); 682 case 256: return new Int256Vector.Int256Shuffle(ixs, i); 683 case 512: return new Int512Vector.Int512Shuffle(ixs, i); 684 default: throw new IllegalArgumentException(Integer.toString(species.bitSize())); 685 } 686 } 687 688 // Ops 689 690 @Override 691 public abstract IntVector add(Vector<Integer> v); 692 693 /** 694 * Adds this vector to the broadcast of an input scalar. 695 * <p> 696 * This is a vector binary operation where the primitive addition operation 697 * ({@code +}) is applied to lane elements. 698 * 699 * @param s the input scalar 700 * @return the result of adding this vector to the broadcast of an input 701 * scalar 702 */ 703 public abstract IntVector add(int s); 704 705 @Override 706 public abstract IntVector add(Vector<Integer> v, Mask<Integer> m); 707 1682 * @param a the array 1683 * @param i the offset into the array, may be negative if relative 1684 * indexes in the index map compensate to produce a value within the 1685 * array bounds 1686 * @param m the mask 1687 * @param indexMap the index map 1688 * @param j the offset into the index map 1689 * @throws IndexOutOfBoundsException if {@code j < 0}, or 1690 * {@code j > indexMap.length - this.length()}, 1691 * or for any vector lane index {@code N} where the mask at lane 1692 * {@code N} is set the result of {@code i + indexMap[j + N]} is 1693 * {@code < 0} or {@code >= a.length} 1694 */ 1695 public abstract void intoArray(int[] a, int i, Mask<Integer> m, int[] indexMap, int j); 1696 // Species 1697 1698 @Override 1699 public abstract Species<Integer> species(); 1700 1701 /** 1702 * Class representing {@link IntVector}'s of the same {@link Vector.Shape Shape}. 1703 */ 1704 static final class IntSpecies extends Vector.AbstractSpecies<Integer> { 1705 final Function<int[], IntVector> vectorFactory; 1706 final Function<boolean[], Vector.Mask<Integer>> maskFactory; 1707 1708 private IntSpecies(Vector.Shape shape, 1709 Class<?> boxType, 1710 Class<?> maskType, 1711 Function<int[], IntVector> vectorFactory, 1712 Function<boolean[], Vector.Mask<Integer>> maskFactory) { 1713 super(shape, int.class, Integer.SIZE, boxType, maskType); 1714 this.vectorFactory = vectorFactory; 1715 this.maskFactory = maskFactory; 1716 } 1717 1718 interface FOp { 1719 int apply(int i); 1720 } 1721 1722 interface FOpm { 1723 boolean apply(int i); 1724 } 1725 1726 IntVector op(FOp f) { 1727 int[] res = new int[length()]; 1728 for (int i = 0; i < length(); i++) { 1729 res[i] = f.apply(i); 1730 } 1731 return vectorFactory.apply(res); 1732 } 1733 1734 IntVector op(Vector.Mask<Integer> o, FOp f) { 1735 int[] res = new int[length()]; 1736 boolean[] mbits = ((AbstractMask<Integer>)o).getBits(); 1737 for (int i = 0; i < length(); i++) { 1738 if (mbits[i]) { 1739 res[i] = f.apply(i); 1740 } 1741 } 1742 return vectorFactory.apply(res); 1743 } 1744 1745 Vector.Mask<Integer> opm(IntVector.IntSpecies.FOpm f) { 1746 boolean[] res = new boolean[length()]; 1747 for (int i = 0; i < length(); i++) { 1748 res[i] = (boolean)f.apply(i); 1749 } 1750 return maskFactory.apply(res); 1751 } 1752 } 1753 1754 /** 1755 * Finds the preferred species for an element type of {@code int}. 1756 * <p> 1757 * A preferred species is a species chosen by the platform that has a 1758 * shape of maximal bit size. A preferred species for different element 1759 * types will have the same shape, and therefore vectors, masks, and 1760 * shuffles created from such species will be shape compatible. 1761 * 1762 * @return the preferred species for an element type of {@code int} 1763 */ 1764 private static IntSpecies preferredSpecies() { 1765 return (IntSpecies) Species.ofPreferred(int.class); 1766 } 1767 1768 /** 1769 * Finds a species for an element type of {@code int} and shape. 1770 * 1771 * @param s the shape 1772 * @return a species for an element type of {@code int} and shape 1773 * @throws IllegalArgumentException if no such species exists for the shape 1774 */ 1775 static IntSpecies species(Vector.Shape s) { 1776 Objects.requireNonNull(s); 1777 switch (s) { 1778 case S_64_BIT: return (IntSpecies) SPECIES_64; 1779 case S_128_BIT: return (IntSpecies) SPECIES_128; 1780 case S_256_BIT: return (IntSpecies) SPECIES_256; 1781 case S_512_BIT: return (IntSpecies) SPECIES_512; 1782 case S_Max_BIT: return (IntSpecies) SPECIES_MAX; 1783 default: throw new IllegalArgumentException("Bad shape: " + s); 1784 } 1785 } 1786 1787 /** Species representing {@link IntVector}s of {@link Vector.Shape#S_64_BIT Shape.S_64_BIT}. */ 1788 public static final Species<Integer> SPECIES_64 = new IntSpecies(Shape.S_64_BIT, Int64Vector.class, Int64Vector.Int64Mask.class, 1789 Int64Vector::new, Int64Vector.Int64Mask::new); 1790 1791 /** Species representing {@link IntVector}s of {@link Vector.Shape#S_128_BIT Shape.S_128_BIT}. */ 1792 public static final Species<Integer> SPECIES_128 = new IntSpecies(Shape.S_128_BIT, Int128Vector.class, Int128Vector.Int128Mask.class, 1793 Int128Vector::new, Int128Vector.Int128Mask::new); 1794 1795 /** Species representing {@link IntVector}s of {@link Vector.Shape#S_256_BIT Shape.S_256_BIT}. */ 1796 public static final Species<Integer> SPECIES_256 = new IntSpecies(Shape.S_256_BIT, Int256Vector.class, Int256Vector.Int256Mask.class, 1797 Int256Vector::new, Int256Vector.Int256Mask::new); 1798 1799 /** Species representing {@link IntVector}s of {@link Vector.Shape#S_512_BIT Shape.S_512_BIT}. */ 1800 public static final Species<Integer> SPECIES_512 = new IntSpecies(Shape.S_512_BIT, Int512Vector.class, Int512Vector.Int512Mask.class, 1801 Int512Vector::new, Int512Vector.Int512Mask::new); 1802 1803 /** Species representing {@link IntVector}s of {@link Vector.Shape#S_Max_BIT Shape.S_Max_BIT}. */ 1804 public static final Species<Integer> SPECIES_MAX = new IntSpecies(Shape.S_Max_BIT, IntMaxVector.class, IntMaxVector.IntMaxMask.class, 1805 IntMaxVector::new, IntMaxVector.IntMaxMask::new); 1806 1807 /** 1808 * Preferred species for {@link IntVector}s. 1809 * A preferred species is a species of maximal bit size for the platform. 1810 */ 1811 public static final Species<Integer> SPECIES_PREFERRED = (Species<Integer>) preferredSpecies(); 1812 } | 444 public static final IntVector single(Species<Integer> s, int e) { 445 return zero(s).with(0, e); 446 } 447 448 /** 449 * Returns a vector where each lane element is set to a randomly 450 * generated primitive value. 451 * 452 * The semantics are equivalent to calling 453 * {@link ThreadLocalRandom#nextInt()} 454 * 455 * @param s species of the desired vector 456 * @return a vector where each lane elements is set to a randomly 457 * generated primitive value 458 */ 459 public static IntVector random(Species<Integer> s) { 460 ThreadLocalRandom r = ThreadLocalRandom.current(); 461 return ((IntSpecies)s).op(i -> r.nextInt()); 462 } 463 464 // Ops 465 466 @Override 467 public abstract IntVector add(Vector<Integer> v); 468 469 /** 470 * Adds this vector to the broadcast of an input scalar. 471 * <p> 472 * This is a vector binary operation where the primitive addition operation 473 * ({@code +}) is applied to lane elements. 474 * 475 * @param s the input scalar 476 * @return the result of adding this vector to the broadcast of an input 477 * scalar 478 */ 479 public abstract IntVector add(int s); 480 481 @Override 482 public abstract IntVector add(Vector<Integer> v, Mask<Integer> m); 483 1458 * @param a the array 1459 * @param i the offset into the array, may be negative if relative 1460 * indexes in the index map compensate to produce a value within the 1461 * array bounds 1462 * @param m the mask 1463 * @param indexMap the index map 1464 * @param j the offset into the index map 1465 * @throws IndexOutOfBoundsException if {@code j < 0}, or 1466 * {@code j > indexMap.length - this.length()}, 1467 * or for any vector lane index {@code N} where the mask at lane 1468 * {@code N} is set the result of {@code i + indexMap[j + N]} is 1469 * {@code < 0} or {@code >= a.length} 1470 */ 1471 public abstract void intoArray(int[] a, int i, Mask<Integer> m, int[] indexMap, int j); 1472 // Species 1473 1474 @Override 1475 public abstract Species<Integer> species(); 1476 1477 /** 1478 * Class representing {@link IntVector}'s of the same {@link Shape Shape}. 1479 */ 1480 static final class IntSpecies extends AbstractSpecies<Integer> { 1481 final Function<int[], IntVector> vectorFactory; 1482 1483 private IntSpecies(Shape shape, 1484 Class<?> boxType, 1485 Class<?> maskType, 1486 Function<int[], IntVector> vectorFactory, 1487 Function<boolean[], Mask<Integer>> maskFactory, 1488 Function<IntUnaryOperator, Shuffle<Integer>> shuffleFromArrayFactory, 1489 fShuffleFromArray<Integer> shuffleFromOpFactory) { 1490 super(shape, int.class, Integer.SIZE, boxType, maskType, maskFactory, 1491 shuffleFromArrayFactory, shuffleFromOpFactory); 1492 this.vectorFactory = vectorFactory; 1493 } 1494 1495 interface FOp { 1496 int apply(int i); 1497 } 1498 1499 interface FOpm { 1500 boolean apply(int i); 1501 } 1502 1503 IntVector op(FOp f) { 1504 int[] res = new int[length()]; 1505 for (int i = 0; i < length(); i++) { 1506 res[i] = f.apply(i); 1507 } 1508 return vectorFactory.apply(res); 1509 } 1510 1511 IntVector op(Mask<Integer> o, FOp f) { 1512 int[] res = new int[length()]; 1513 boolean[] mbits = ((AbstractMask<Integer>)o).getBits(); 1514 for (int i = 0; i < length(); i++) { 1515 if (mbits[i]) { 1516 res[i] = f.apply(i); 1517 } 1518 } 1519 return vectorFactory.apply(res); 1520 } 1521 } 1522 1523 /** 1524 * Finds the preferred species for an element type of {@code int}. 1525 * <p> 1526 * A preferred species is a species chosen by the platform that has a 1527 * shape of maximal bit size. A preferred species for different element 1528 * types will have the same shape, and therefore vectors, masks, and 1529 * shuffles created from such species will be shape compatible. 1530 * 1531 * @return the preferred species for an element type of {@code int} 1532 */ 1533 private static IntSpecies preferredSpecies() { 1534 return (IntSpecies) Species.ofPreferred(int.class); 1535 } 1536 1537 /** 1538 * Finds a species for an element type of {@code int} and shape. 1539 * 1540 * @param s the shape 1541 * @return a species for an element type of {@code int} and shape 1542 * @throws IllegalArgumentException if no such species exists for the shape 1543 */ 1544 static IntSpecies species(Shape s) { 1545 Objects.requireNonNull(s); 1546 switch (s) { 1547 case S_64_BIT: return (IntSpecies) SPECIES_64; 1548 case S_128_BIT: return (IntSpecies) SPECIES_128; 1549 case S_256_BIT: return (IntSpecies) SPECIES_256; 1550 case S_512_BIT: return (IntSpecies) SPECIES_512; 1551 case S_Max_BIT: return (IntSpecies) SPECIES_MAX; 1552 default: throw new IllegalArgumentException("Bad shape: " + s); 1553 } 1554 } 1555 1556 /** Species representing {@link IntVector}s of {@link Shape#S_64_BIT Shape.S_64_BIT}. */ 1557 public static final Species<Integer> SPECIES_64 = new IntSpecies(Shape.S_64_BIT, Int64Vector.class, Int64Vector.Int64Mask.class, 1558 Int64Vector::new, Int64Vector.Int64Mask::new, 1559 Int64Vector.Int64Shuffle::new, Int64Vector.Int64Shuffle::new); 1560 1561 /** Species representing {@link IntVector}s of {@link Shape#S_128_BIT Shape.S_128_BIT}. */ 1562 public static final Species<Integer> SPECIES_128 = new IntSpecies(Shape.S_128_BIT, Int128Vector.class, Int128Vector.Int128Mask.class, 1563 Int128Vector::new, Int128Vector.Int128Mask::new, 1564 Int128Vector.Int128Shuffle::new, Int128Vector.Int128Shuffle::new); 1565 1566 /** Species representing {@link IntVector}s of {@link Shape#S_256_BIT Shape.S_256_BIT}. */ 1567 public static final Species<Integer> SPECIES_256 = new IntSpecies(Shape.S_256_BIT, Int256Vector.class, Int256Vector.Int256Mask.class, 1568 Int256Vector::new, Int256Vector.Int256Mask::new, 1569 Int256Vector.Int256Shuffle::new, Int256Vector.Int256Shuffle::new); 1570 1571 /** Species representing {@link IntVector}s of {@link Shape#S_512_BIT Shape.S_512_BIT}. */ 1572 public static final Species<Integer> SPECIES_512 = new IntSpecies(Shape.S_512_BIT, Int512Vector.class, Int512Vector.Int512Mask.class, 1573 Int512Vector::new, Int512Vector.Int512Mask::new, 1574 Int512Vector.Int512Shuffle::new, Int512Vector.Int512Shuffle::new); 1575 1576 /** Species representing {@link IntVector}s of {@link Shape#S_Max_BIT Shape.S_Max_BIT}. */ 1577 public static final Species<Integer> SPECIES_MAX = new IntSpecies(Shape.S_Max_BIT, IntMaxVector.class, IntMaxVector.IntMaxMask.class, 1578 IntMaxVector::new, IntMaxVector.IntMaxMask::new, 1579 IntMaxVector.IntMaxShuffle::new, IntMaxVector.IntMaxShuffle::new); 1580 1581 /** 1582 * Preferred species for {@link IntVector}s. 1583 * A preferred species is a species of maximal bit size for the platform. 1584 */ 1585 public static final Species<Integer> SPECIES_PREFERRED = (Species<Integer>) preferredSpecies(); 1586 } |