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