Home | History | Annotate | Download | only in primitives
      1 #!/bin/sh
      2 #
      3 # Usage example: ./generate.sh int Int Integer"
      4 # Args are: primitive type, capitalized primitive type, wrapper type
      5 #
      6 # To make changes to the .java files in this package,
      7 # 1. run this script to generate the templates, move the .gen files
      8 #    somewhere else
      9 # 2. modify the template with your intended changes, then rerun the
     10 #    script
     11 # 3. use any three-way merge tool to edit the checked-in source files,
     12 #    using the before-and-after generated files as the bases.
     13 #
     14 
     15 if [ "$#" -ne "3" ]
     16 then
     17   echo "Usage example: ./generate.sh int Int Integer"
     18   exit 1
     19 fi
     20 
     21 # Note: using the strange strings 'primtyp' and 'WrapperCl' so that they match
     22 # the maximum length of the real strings ('boolean' and 'Character').
     23 
     24 perl -pe "s/primtyp/$1/g; s/PrimTyp/$2/g; s/WrapperCl/$3/g" << "--EOF--" > $2s.java.gen
     25 /*
     26  * Copyright (C) 2008 The Guava Authors
     27  *
     28  * Licensed under the Apache License, Version 2.0 (the "License");
     29  * you may not use this file except in compliance with the License.
     30  * You may obtain a copy of the License at
     31  *
     32  * http://www.apache.org/licenses/LICENSE-2.0
     33  *
     34  * Unless required by applicable law or agreed to in writing, software
     35  * distributed under the License is distributed on an "AS IS" BASIS,
     36  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     37  * See the License for the specific language governing permissions and
     38  * limitations under the License.
     39  */
     40 
     41 package com.google.common.primitives;
     42 
     43 import static com.google.common.base.Preconditions.checkArgument;
     44 import static com.google.common.base.Preconditions.checkElementIndex;
     45 import static com.google.common.base.Preconditions.checkNotNull;
     46 import static com.google.common.base.Preconditions.checkPositionIndexes;
     47 
     48 import com.google.common.annotations.GwtCompatible;
     49 import com.google.common.annotations.GwtIncompatible;
     50 
     51 import java.io.Serializable;
     52 import java.util.AbstractList;
     53 import java.util.Arrays;
     54 import java.util.Collection;
     55 import java.util.Collections;
     56 import java.util.Comparator;
     57 import java.util.List;
     58 import java.util.RandomAccess;
     59 
     60 /**
     61  * Static utility methods pertaining to {@code primtyp} primitives, that are not
     62  * already found in either {@link WrapperCl} or {@link Arrays}.
     63  *
     64  * @author Kevin Bourrillion
     65  * @since 1.0
     66  */
     67 @GwtCompatible
     68 public final class PrimTyps {
     69   private PrimTyps() {}
     70 
     71   /**
     72    * The number of bytes required to represent a primitive {@code primtyp}
     73    * value.
     74    */
     75   public static final int BYTES = WrapperCl.SIZE / Byte.SIZE;
     76 
     77   /**
     78    * Returns a hash code for {@code value}; equal to the result of invoking
     79    * {@code ((WrapperCl) value).hashCode()}.
     80    *
     81    * @param value a primitive {@code primtyp} value
     82    * @return a hash code for the value
     83    */
     84   public static int hashCode(primtyp value) {
     85     return ??
     86   }
     87 
     88   /**
     89    * Returns the {@code primtyp} value that is equal to {@code value}, if
     90    * possible.
     91    *
     92    * @param value any value in the range of the {@code primtyp} type
     93    * @return the {@code primtyp} value that equals {@code value}
     94    * @throws IllegalArgumentException if {@code value} is greater than {@link
     95    *     WrapperCl#MAX_VALUE} or less than {@link WrapperCl#MIN_VALUE}
     96    */
     97   public static primtyp checkedCast(long value) {
     98     primtyp result = (primtyp) value;
     99     checkArgument(result == value, "Out of range: %s", value);
    100     return result;
    101   }
    102 
    103   /**
    104    * Returns the {@code primtyp} nearest in value to {@code value}.
    105    *
    106    * @param value any {@code long} value
    107    * @return the same value cast to {@code primtyp} if it is in the range of the
    108    *     {@code primtyp} type, {@link WrapperCl#MAX_VALUE} if it is too large,
    109    *     or {@link WrapperCl#MIN_VALUE} if it is too small
    110    */
    111   public static primtyp saturatedCast(long value) {
    112     if (value > WrapperCl.MAX_VALUE) {
    113       return WrapperCl.MAX_VALUE;
    114     }
    115     if (value < WrapperCl.MIN_VALUE) {
    116       return WrapperCl.MIN_VALUE;
    117     }
    118     return (primtyp) value;
    119   }
    120 
    121   /**
    122    * Compares the two specified {@code primtyp} values. The sign of the value
    123    * returned is the same as that of {@code ((WrapperCl) a).compareTo(b)}.
    124    *
    125    * @param a the first {@code primtyp} to compare
    126    * @param b the second {@code primtyp} to compare
    127    * @return a negative value if {@code a} is less than {@code b}; a positive
    128    *     value if {@code a} is greater than {@code b}; or zero if they are equal
    129    */
    130   public static int compare(primtyp a, primtyp b) {
    131     return (a < b) ? -1 : ((a > b) ? 1 : 0);
    132   }
    133 
    134   /**
    135    * Returns {@code true} if {@code target} is present as an element anywhere in
    136    * {@code array}.
    137    *
    138    * @param array an array of {@code primtyp} values, possibly empty
    139    * @param target a primitive {@code primtyp} value
    140    * @return {@code true} if {@code array[i] == target} for some value of {@code
    141    *     i}
    142    */
    143   public static boolean contains(primtyp[] array, primtyp target) {
    144     for (primtyp value : array) {
    145       if (value == target) {
    146         return true;
    147       }
    148     }
    149     return false;
    150   }
    151 
    152   /**
    153    * Returns the index of the first appearance of the value {@code target} in
    154    * {@code array}.
    155    *
    156    * @param array an array of {@code primtyp} values, possibly empty
    157    * @param target a primitive {@code primtyp} value
    158    * @return the least index {@code i} for which {@code array[i] == target}, or
    159    *     {@code -1} if no such index exists.
    160    */
    161   public static int indexOf(primtyp[] array, primtyp target) {
    162     return indexOf(array, target, 0, array.length);
    163   }
    164 
    165   // TODO(kevinb): consider making this public
    166   private static int indexOf(
    167       primtyp[] array, primtyp target, int start, int end) {
    168     for (int i = start; i < end; i++) {
    169       if (array[i] == target) {
    170         return i;
    171       }
    172     }
    173     return -1;
    174   }
    175 
    176   /**
    177    * Returns the start position of the first occurrence of the specified {@code
    178    * target} within {@code array}, or {@code -1} if there is no such occurrence.
    179    *
    180    * <p>More formally, returns the lowest index {@code i} such that {@code
    181    * java.util.Arrays.copyOfRange(array, i, i + target.length)} contains exactly
    182    * the same elements as {@code target}.
    183    *
    184    * @param array the array to search for the sequence {@code target}
    185    * @param target the array to search for as a sub-sequence of {@code array}
    186    */
    187   public static int indexOf(primtyp[] array, primtyp[] target) {
    188     checkNotNull(array, "array");
    189     checkNotNull(target, "target");
    190     if (target.length == 0) {
    191       return 0;
    192     }
    193 
    194     outer:
    195     for (int i = 0; i < array.length - target.length + 1; i++) {
    196       for (int j = 0; j < target.length; j++) {
    197         if (array[i + j] != target[j]) {
    198           continue outer;
    199         }
    200       }
    201       return i;
    202     }
    203     return -1;
    204   }
    205 
    206   /**
    207    * Returns the index of the last appearance of the value {@code target} in
    208    * {@code array}.
    209    *
    210    * @param array an array of {@code primtyp} values, possibly empty
    211    * @param target a primitive {@code primtyp} value
    212    * @return the greatest index {@code i} for which {@code array[i] == target},
    213    *     or {@code -1} if no such index exists.
    214    */
    215   public static int lastIndexOf(primtyp[] array, primtyp target) {
    216     return lastIndexOf(array, target, 0, array.length);
    217   }
    218 
    219   // TODO(kevinb): consider making this public
    220   private static int lastIndexOf(
    221       primtyp[] array, primtyp target, int start, int end) {
    222     for (int i = end - 1; i >= start; i--) {
    223       if (array[i] == target) {
    224         return i;
    225       }
    226     }
    227     return -1;
    228   }
    229 
    230   /**
    231    * Returns the least value present in {@code array}.
    232    *
    233    * @param array a <i>nonempty</i> array of {@code primtyp} values
    234    * @return the value present in {@code array} that is less than or equal to
    235    *     every other value in the array
    236    * @throws IllegalArgumentException if {@code array} is empty
    237    */
    238   public static primtyp min(primtyp... array) {
    239     checkArgument(array.length > 0);
    240     primtyp min = array[0];
    241     for (int i = 1; i < array.length; i++) {
    242       if (array[i] < min) {
    243         min = array[i];
    244       }
    245     }
    246     return min;
    247   }
    248 
    249   /**
    250    * Returns the greatest value present in {@code array}.
    251    *
    252    * @param array a <i>nonempty</i> array of {@code primtyp} values
    253    * @return the value present in {@code array} that is greater than or equal to
    254    *     every other value in the array
    255    * @throws IllegalArgumentException if {@code array} is empty
    256    */
    257   public static primtyp max(primtyp... array) {
    258     checkArgument(array.length > 0);
    259     primtyp max = array[0];
    260     for (int i = 1; i < array.length; i++) {
    261       if (array[i] > max) {
    262         max = array[i];
    263       }
    264     }
    265     return max;
    266   }
    267 
    268   /**
    269    * Returns the values from each provided array combined into a single array.
    270    * For example, {@code concat(new primtyp[] {a, b}, new primtyp[] {}, new
    271    * primtyp[] {c}} returns the array {@code {a, b, c}}.
    272    *
    273    * @param arrays zero or more {@code primtyp} arrays
    274    * @return a single array containing all the values from the source arrays, in
    275    *     order
    276    */
    277   public static primtyp[] concat(primtyp[]... arrays) {
    278     int length = 0;
    279     for (primtyp[] array : arrays) {
    280       length += array.length;
    281     }
    282     primtyp[] result = new primtyp[length];
    283     int pos = 0;
    284     for (primtyp[] array : arrays) {
    285       System.arraycopy(array, 0, result, pos, array.length);
    286       pos += array.length;
    287     }
    288     return result;
    289   }
    290 
    291   /**
    292    * Returns a big-endian representation of {@code value} in a ?-element byte
    293    * array; equivalent to {@code
    294    * ByteBuffer.allocate(?).putPrimTyp(value).array()}.  For example, the input
    295    * value {@code ?} would yield the byte array {@code {?}}.
    296    *
    297    * <p>If you need to convert and concatenate several values (possibly even of
    298    * different types), use a shared {@link java.nio.ByteBuffer} instance, or use
    299    * {@link com.google.common.io.ByteStreams#newDataOutput()} to get a growable
    300    * buffer.
    301    */
    302   @GwtIncompatible("doesn't work")
    303   public static byte[] toByteArray(primtyp value) {
    304     return new byte[] {
    305       ?
    306     };
    307   }
    308 
    309   /**
    310    * Returns the {@code primtyp} value whose big-endian representation is
    311    * stored in the first ? bytes of {@code bytes}; equivalent to {@code
    312    * ByteBuffer.wrap(bytes).getPrimTyp()}. For example, the input byte array
    313    * {@code {?}} would yield the {@code primtyp} value {@code ?}.
    314    *
    315    * <p>Arguably, it's preferable to use {@link java.nio.ByteBuffer}; that
    316    * library exposes much more flexibility at little cost in readability.
    317    *
    318    * @throws IllegalArgumentException if {@code bytes} has fewer than ?
    319    *     elements
    320    */
    321   @GwtIncompatible("doesn't work")
    322   public static primtyp fromByteArray(byte[] bytes) {
    323     checkArgument(bytes.length >= BYTES,
    324         "array too small: %s < %s", bytes.length, BYTES);
    325     return fromBytes(bytes[0], bytes[1], bytes[2], bytes[3]);
    326   }
    327 
    328   /**
    329    * Returns the {@code primtyp} value whose byte representation is the given ?
    330    * bytes, in big-endian order; equivalent to {@code
    331    * PrimTyps.fromByteArray(new byte[] { ? })}.
    332    *
    333    * @since 7.0
    334    */
    335   @GwtIncompatible("doesn't work")
    336   public static primtyp fromBytes(byte b1, byte b2, byte b3, byte b4) {
    337     return ?
    338   }
    339 
    340   /**
    341    * Returns an array containing the same values as {@code array}, but
    342    * guaranteed to be of a specified minimum length. If {@code array} already
    343    * has a length of at least {@code minLength}, it is returned directly.
    344    * Otherwise, a new array of size {@code minLength + padding} is returned,
    345    * containing the values of {@code array}, and zeroes in the remaining places.
    346    *
    347    * @param array the source array
    348    * @param minLength the minimum length the returned array must guarantee
    349    * @param padding an extra amount to "grow" the array by if growth is
    350    *     necessary
    351    * @throws IllegalArgumentException if {@code minLength} or {@code padding} is
    352    *     negative
    353    * @return an array containing the values of {@code array}, with guaranteed
    354    *     minimum length {@code minLength}
    355    */
    356   public static primtyp[] ensureCapacity(
    357       primtyp[] array, int minLength, int padding) {
    358     checkArgument(minLength >= 0, "Invalid minLength: %s", minLength);
    359     checkArgument(padding >= 0, "Invalid padding: %s", padding);
    360     return (array.length < minLength)
    361         ? copyOf(array, minLength + padding)
    362         : array;
    363   }
    364 
    365   // Arrays.copyOf() requires Java 6
    366   private static primtyp[] copyOf(primtyp[] original, int length) {
    367     primtyp[] copy = new primtyp[length];
    368     System.arraycopy(original, 0, copy, 0, Math.min(original.length, length));
    369     return copy;
    370   }
    371 
    372   /**
    373    * Returns a string containing the supplied {@code primtyp} values separated
    374    * by {@code separator}. For example, {@code join("-", 1?, 2?, 3?)} returns
    375    * the string {@code "1-2-3"}.
    376    *
    377    * @param separator the text that should appear between consecutive values in
    378    *     the resulting string (but not at the start or end)
    379    * @param array an array of {@code primtyp} values, possibly empty
    380    */
    381   public static String join(String separator, primtyp... array) {
    382     checkNotNull(separator);
    383     if (array.length == 0) {
    384       return "";
    385     }
    386 
    387     // For pre-sizing a builder, just get the right order of magnitude
    388     StringBuilder builder = new StringBuilder(array.length * ??);
    389     builder.append(array[0]);
    390     for (int i = 1; i < array.length; i++) {
    391       builder.append(separator).append(array[i]);
    392     }
    393     return builder.toString();
    394   }
    395 
    396   /**
    397    * Returns a comparator that compares two {@code primtyp} arrays
    398    * lexicographically. That is, it compares, using {@link
    399    * #compare(primtyp, primtyp)}), the first pair of values that follow any
    400    * common prefix, or when one array is a prefix of the other, treats the
    401    * shorter array as the lesser. For example, {@code [] < [1] < [1, 2] < [2]}.
    402    *
    403    * <p>The returned comparator is inconsistent with {@link
    404    * Object#equals(Object)} (since arrays support only identity equality), but
    405    * it is consistent with {@link Arrays#equals(primtyp[], primtyp[])}.
    406    *
    407    * @see <a href="http://en.wikipedia.org/wiki/Lexicographical_order">
    408    *     Lexicographical order article at Wikipedia</a>
    409    * @since 2.0
    410    */
    411   public static Comparator<primtyp[]> lexicographicalComparator() {
    412     return LexicographicalComparator.INSTANCE;
    413   }
    414 
    415   private enum LexicographicalComparator implements Comparator<primtyp[]> {
    416     INSTANCE;
    417 
    418     @Override
    419     public int compare(primtyp[] left, primtyp[] right) {
    420       int minLength = Math.min(left.length, right.length);
    421       for (int i = 0; i < minLength; i++) {
    422         int result = PrimTyps.compare(left[i], right[i]);
    423         if (result != 0) {
    424           return result;
    425         }
    426       }
    427       return left.length - right.length;
    428     }
    429   }
    430 
    431   /**
    432    * Copies a collection of {@code WrapperCl} instances into a new array of
    433    * primitive {@code primtyp} values.
    434    *
    435    * <p>Elements are copied from the argument collection as if by {@code
    436    * collection.toArray()}.  Calling this method is as thread-safe as calling
    437    * that method.
    438    *
    439    * @param collection a collection of {@code WrapperCl} objects
    440    * @return an array containing the same values as {@code collection}, in the
    441    *     same order, converted to primitives
    442    * @throws NullPointerException if {@code collection} or any of its elements
    443    *     is null
    444    */
    445   public static primtyp[] toArray(Collection<WrapperCl> collection) {
    446     if (collection instanceof PrimTypArrayAsList) {
    447       return ((PrimTypArrayAsList) collection).toPrimTypArray();
    448     }
    449 
    450     Object[] boxedArray = collection.toArray();
    451     int len = boxedArray.length;
    452     primtyp[] array = new primtyp[len];
    453     for (int i = 0; i < len; i++) {
    454       // checkNotNull for GWT (do not optimize)
    455       array[i] = (WrapperCl) checkNotNull(boxedArray[i]);
    456     }
    457     return array;
    458   }
    459 
    460   /**
    461    * Returns a fixed-size list backed by the specified array, similar to {@link
    462    * Arrays#asList(Object[])}. The list supports {@link List#set(int, Object)},
    463    * but any attempt to set a value to {@code null} will result in a {@link
    464    * NullPointerException}.
    465    *
    466    * <p>The returned list maintains the values, but not the identities, of
    467    * {@code WrapperCl} objects written to or read from it.  For example, whether
    468    * {@code list.get(0) == list.get(0)} is true for the returned list is
    469    * unspecified.
    470    *
    471    * @param backingArray the array to back the list
    472    * @return a list view of the array
    473    */
    474   public static List<WrapperCl> asList(primtyp... backingArray) {
    475     if (backingArray.length == 0) {
    476       return Collections.emptyList();
    477     }
    478     return new PrimTypArrayAsList(backingArray);
    479   }
    480 
    481   @GwtCompatible
    482   private static class PrimTypArrayAsList extends AbstractList<WrapperCl>
    483       implements RandomAccess, Serializable {
    484     final primtyp[] array;
    485     final int start;
    486     final int end;
    487 
    488     PrimTypArrayAsList(primtyp[] array) {
    489       this(array, 0, array.length);
    490     }
    491 
    492     PrimTypArrayAsList(primtyp[] array, int start, int end) {
    493       this.array = array;
    494       this.start = start;
    495       this.end = end;
    496     }
    497 
    498     @Override public int size() {
    499       return end - start;
    500     }
    501 
    502     @Override public boolean isEmpty() {
    503       return false;
    504     }
    505 
    506     @Override public WrapperCl get(int index) {
    507       checkElementIndex(index, size());
    508       return array[start + index];
    509     }
    510 
    511     @Override public boolean contains(Object target) {
    512       // Overridden to prevent a ton of boxing
    513       return (target instanceof WrapperCl)
    514           && PrimTyps.indexOf(array, (WrapperCl) target, start, end) != -1;
    515     }
    516 
    517     @Override public int indexOf(Object target) {
    518       // Overridden to prevent a ton of boxing
    519       if (target instanceof WrapperCl) {
    520         int i = PrimTyps.indexOf(array, (WrapperCl) target, start, end);
    521         if (i >= 0) {
    522           return i - start;
    523         }
    524       }
    525       return -1;
    526     }
    527 
    528     @Override public int lastIndexOf(Object target) {
    529       // Overridden to prevent a ton of boxing
    530       if (target instanceof WrapperCl) {
    531         int i = PrimTyps.lastIndexOf(array, (WrapperCl) target, start, end);
    532         if (i >= 0) {
    533           return i - start;
    534         }
    535       }
    536       return -1;
    537     }
    538 
    539     @Override public WrapperCl set(int index, WrapperCl element) {
    540       checkElementIndex(index, size());
    541       primtyp oldValue = array[start + index];
    542       array[start + index] = checkNotNull(element);  // checkNotNull for GWT (do not optimize)
    543       return oldValue;
    544     }
    545 
    546     @Override public List<WrapperCl> subList(int fromIndex, int toIndex) {
    547       int size = size();
    548       checkPositionIndexes(fromIndex, toIndex, size);
    549       if (fromIndex == toIndex) {
    550         return Collections.emptyList();
    551       }
    552       return new PrimTypArrayAsList(array, start + fromIndex, start + toIndex);
    553     }
    554 
    555     @Override public boolean equals(Object object) {
    556       if (object == this) {
    557         return true;
    558       }
    559       if (object instanceof PrimTypArrayAsList) {
    560         PrimTypArrayAsList that = (PrimTypArrayAsList) object;
    561         int size = size();
    562         if (that.size() != size) {
    563           return false;
    564         }
    565         for (int i = 0; i < size; i++) {
    566           if (array[start + i] != that.array[that.start + i]) {
    567             return false;
    568           }
    569         }
    570         return true;
    571       }
    572       return super.equals(object);
    573     }
    574 
    575     @Override public int hashCode() {
    576       int result = 1;
    577       for (int i = start; i < end; i++) {
    578         result = 31 * result + PrimTyps.hashCode(array[i]);
    579       }
    580       return result;
    581     }
    582 
    583     @Override public String toString() {
    584       StringBuilder builder = new StringBuilder(size() * ??);
    585       builder.append('[').append(array[start]);
    586       for (int i = start + 1; i < end; i++) {
    587         builder.append(", ").append(array[i]);
    588       }
    589       return builder.append(']').toString();
    590     }
    591 
    592     primtyp[] toPrimTypArray() {
    593       // Arrays.copyOfRange() requires Java 6
    594       int size = size();
    595       primtyp[] result = new primtyp[size];
    596       System.arraycopy(array, start, result, 0, size);
    597       return result;
    598     }
    599 
    600     private static final long serialVersionUID = 0;
    601   }
    602 }
    603 --EOF--
    604 
    605