1 /* 2 * Hunt - A refined core library for D programming language. 3 * 4 * Copyright (C) 2018-2019 HuntLabs 5 * 6 * Website: https://www.huntlabs.net/ 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module hunt.Short; 13 14 import hunt.Byte; 15 import hunt.Nullable; 16 import hunt.Number; 17 import std.conv; 18 /** 19 * The {@code Short} class wraps a value of primitive type {@code 20 * short} in an object. An object of type {@code Short} contains a 21 * single field whose type is {@code short}. 22 * 23 * <p>In addition, this class provides several methods for converting 24 * a {@code short} to a {@code string} and a {@code string} to a 25 * {@code short}, as well as other constants and methods useful when 26 * dealing with a {@code short}. 27 * 28 * @author Nakul Saraiya 29 * @author Joseph D. Darcy 30 * @see java.lang.Number 31 * @since JDK1.1 32 */ 33 class Short : AbstractNumber!short /*implements Comparable<Short> */{ 34 35 /** 36 * A constant holding the minimum value a {@code short} can 37 * have, -2<sup>15</sup>. 38 */ 39 enum short MIN_VALUE = -32768; 40 41 /** 42 * A constant holding the maximum value a {@code short} can 43 * have, 2<sup>15</sup>-1. 44 */ 45 enum short MAX_VALUE = 32767; 46 47 /** 48 * The {@code Class} instance representing the primitive type 49 * {@code short}. 50 */ 51 // @SuppressWarnings("unchecked") 52 // static Class<Short> TYPE = (Class<Short>) Class.getPrimitiveClass("short"); 53 54 /** 55 * Returns a new {@code string} object representing the 56 * specified {@code short}. The radix is assumed to be 10. 57 * 58 * @param s the {@code short} to be converted 59 * @return the string representation of the specified {@code short} 60 * @see java.lang.Integer#toString(int) 61 */ 62 static string toString(short s) { 63 return to!string(s); 64 } 65 66 /** 67 * Parses the string argument as a signed {@code short} in the 68 * radix specified by the second argument. The characters in the 69 * string must all be digits, of the specified radix (as 70 * determined by whether {@link java.lang.Character#digit(char, 71 * int)} returns a nonnegative value) except that the first 72 * character may be an ASCII minus sign {@code '-'} 73 * ({@code '\u005Cu002D'}) to indicate a negative value or an 74 * ASCII plus sign {@code '+'} ({@code '\u005Cu002B'}) to 75 * indicate a positive value. The resulting {@code short} value 76 * is returned. 77 * 78 * <p>An exception of type {@code NumberFormatException} is 79 * thrown if any of the following situations occurs: 80 * <ul> 81 * <li> The first argument is {@code null} or is a string of 82 * length zero. 83 * 84 * <li> The radix is either smaller than {@link 85 * java.lang.Character#MIN_RADIX} or larger than {@link 86 * java.lang.Character#MAX_RADIX}. 87 * 88 * <li> Any character of the string is not a digit of the 89 * specified radix, except that the first character may be a minus 90 * sign {@code '-'} ({@code '\u005Cu002D'}) or plus sign 91 * {@code '+'} ({@code '\u005Cu002B'}) provided that the 92 * string is longer than length 1. 93 * 94 * <li> The value represented by the string is not a value of type 95 * {@code short}. 96 * </ul> 97 * 98 * @param s the {@code string} containing the 99 * {@code short} representation to be parsed 100 * @param radix the radix to be used while parsing {@code s} 101 * @return the {@code short} represented by the string 102 * argument in the specified radix. 103 * @throws NumberFormatException If the {@code string} 104 * does not contain a parsable {@code short}. 105 */ 106 // static short parseShort(string s, int radix) 107 // throws NumberFormatException { 108 // int i = Integer.parseInt(s, radix); 109 // if (i < MIN_VALUE || i > MAX_VALUE) 110 // throw new NumberFormatException( 111 // "Value out of range. Value:\"" ~ s ~ "\" Radix:" ~ radix); 112 // return (short)i; 113 // } 114 115 /** 116 * Parses the string argument as a signed decimal {@code 117 * short}. The characters in the string must all be decimal 118 * digits, except that the first character may be an ASCII minus 119 * sign {@code '-'} ({@code '\u005Cu002D'}) to indicate a 120 * negative value or an ASCII plus sign {@code '+'} 121 * ({@code '\u005Cu002B'}) to indicate a positive value. The 122 * resulting {@code short} value is returned, exactly as if the 123 * argument and the radix 10 were given as arguments to the {@link 124 * #parseShort(java.lang.string, int)} method. 125 * 126 * @param s a {@code string} containing the {@code short} 127 * representation to be parsed 128 * @return the {@code short} value represented by the 129 * argument in decimal. 130 * @throws NumberFormatException If the string does not 131 * contain a parsable {@code short}. 132 */ 133 // static short parseShort(string s) throws NumberFormatException { 134 // return parseShort(s, 10); 135 // } 136 137 /** 138 * Returns a {@code Short} object holding the value 139 * extracted from the specified {@code string} when parsed 140 * with the radix given by the second argument. The first argument 141 * is interpreted as representing a signed {@code short} in 142 * the radix specified by the second argument, exactly as if the 143 * argument were given to the {@link #parseShort(java.lang.string, 144 * int)} method. The result is a {@code Short} object that 145 * represents the {@code short} value specified by the string. 146 * 147 * <p>In other words, this method returns a {@code Short} object 148 * equal to the value of: 149 * 150 * <blockquote> 151 * {@code new Short(Short.parseShort(s, radix))} 152 * </blockquote> 153 * 154 * @param s the string to be parsed 155 * @param radix the radix to be used in interpreting {@code s} 156 * @return a {@code Short} object holding the value 157 * represented by the string argument in the 158 * specified radix. 159 * @throws NumberFormatException If the {@code string} does 160 * not contain a parsable {@code short}. 161 */ 162 // static Short valueOf(string s, int radix) 163 // throws NumberFormatException { 164 // return valueOf(parseShort(s, radix)); 165 // } 166 167 /** 168 * Returns a {@code Short} object holding the 169 * value given by the specified {@code string}. The argument 170 * is interpreted as representing a signed decimal 171 * {@code short}, exactly as if the argument were given to 172 * the {@link #parseShort(java.lang.string)} method. The result is 173 * a {@code Short} object that represents the 174 * {@code short} value specified by the string. 175 * 176 * <p>In other words, this method returns a {@code Short} object 177 * equal to the value of: 178 * 179 * <blockquote> 180 * {@code new Short(Short.parseShort(s))} 181 * </blockquote> 182 * 183 * @param s the string to be parsed 184 * @return a {@code Short} object holding the value 185 * represented by the string argument 186 * @throws NumberFormatException If the {@code string} does 187 * not contain a parsable {@code short}. 188 */ 189 // static Short valueOf(string s) throws NumberFormatException { 190 // return valueOf(s, 10); 191 // } 192 193 // private static class ShortCache { 194 // private ShortCache(){} 195 196 // static Short cache[] = new Short[-(-128) + 127 + 1]; 197 198 // static { 199 // for(int i = 0; i < cache.length; i++) 200 // cache[i] = new Short((short)(i - 128)); 201 // } 202 // } 203 204 /** 205 * Returns a {@code Short} instance representing the specified 206 * {@code short} value. 207 * If a new {@code Short} instance is not required, this method 208 * should generally be used in preference to the constructor 209 * {@link #Short(short)}, as this method is likely to yield 210 * significantly better space and time performance by caching 211 * frequently requested values. 212 * 213 * This method will always cache values in the range -128 to 127, 214 * inclusive, and may cache other values outside of this range. 215 * 216 * @param s a short value. 217 * @return a {@code Short} instance representing {@code s}. 218 * @since 1.5 219 */ 220 // static Short valueOf(short s) { 221 // int offset = 128; 222 // int sAsInt = s; 223 // if (sAsInt >= -128 && sAsInt <= 127) { // must cache 224 // return ShortCache.cache[sAsInt + offset]; 225 // } 226 // return new Short(s); 227 // } 228 229 /** 230 * Decodes a {@code string} into a {@code Short}. 231 * Accepts decimal, hexadecimal, and octal numbers given by 232 * the following grammar: 233 * 234 * <blockquote> 235 * <dl> 236 * <dt><i>DecodableString:</i> 237 * <dd><i>Sign<sub>opt</sub> DecimalNumeral</i> 238 * <dd><i>Sign<sub>opt</sub></i> {@code 0x} <i>HexDigits</i> 239 * <dd><i>Sign<sub>opt</sub></i> {@code 0X} <i>HexDigits</i> 240 * <dd><i>Sign<sub>opt</sub></i> {@code #} <i>HexDigits</i> 241 * <dd><i>Sign<sub>opt</sub></i> {@code 0} <i>OctalDigits</i> 242 * 243 * <dt><i>Sign:</i> 244 * <dd>{@code -} 245 * <dd>{@code +} 246 * </dl> 247 * </blockquote> 248 * 249 * <i>DecimalNumeral</i>, <i>HexDigits</i>, and <i>OctalDigits</i> 250 * are as defined in section 3.10.1 of 251 * <cite>The Java™ Language Specification</cite>, 252 * except that underscores are not accepted between digits. 253 * 254 * <p>The sequence of characters following an optional 255 * sign and/or radix specifier ("{@code 0x}", "{@code 0X}", 256 * "{@code #}", or leading zero) is parsed as by the {@code 257 * Short.parseShort} method with the indicated radix (10, 16, or 258 * 8). This sequence of characters must represent a positive 259 * value or a {@link NumberFormatException} will be thrown. The 260 * result is negated if first character of the specified {@code 261 * string} is the minus sign. No whitespace characters are 262 * permitted in the {@code string}. 263 * 264 * @param nm the {@code string} to decode. 265 * @return a {@code Short} object holding the {@code short} 266 * value represented by {@code nm} 267 * @throws NumberFormatException if the {@code string} does not 268 * contain a parsable {@code short}. 269 * @see java.lang.Short#parseShort(java.lang.string, int) 270 */ 271 // static Short decode(string nm) throws NumberFormatException { 272 // int i = Integer.decode(nm); 273 // if (i < MIN_VALUE || i > MAX_VALUE) 274 // throw new NumberFormatException( 275 // "Value " ~ i ~ " out of range from input " ~ nm); 276 // return valueOf((short)i); 277 // } 278 279 /** 280 * The value of the {@code Short}. 281 * 282 * @serial 283 */ 284 // private short value; 285 286 /** 287 * Constructs a newly allocated {@code Short} object that 288 * represents the specified {@code short} value. 289 * 290 * @param value the value to be represented by the 291 * {@code Short}. 292 */ 293 this(short value) { 294 super(value); 295 } 296 297 this(int value) { 298 super(cast(short)value); 299 } 300 301 /** 302 * Constructs a newly allocated {@code Short} object that 303 * represents the {@code short} value indicated by the 304 * {@code string} parameter. The string is converted to a 305 * {@code short} value in exactly the manner used by the 306 * {@code parseShort} method for radix 10. 307 * 308 * @param s the {@code string} to be converted to a 309 * {@code Short} 310 * @throws NumberFormatException If the {@code string} 311 * does not contain a parsable {@code short}. 312 * @see java.lang.Short#parseShort(java.lang.string, int) 313 */ 314 // Short(string s) throws NumberFormatException { 315 // this.value = parseShort(s, 10); 316 // } 317 318 319 /** 320 * Returns a hash code for this {@code Short}; equal to the result 321 * of invoking {@code intValue()}. 322 * 323 * @return a hash code value for this {@code Short} 324 */ 325 override 326 size_t toHash() @trusted nothrow { 327 return cast(int)(value); 328 } 329 330 331 /** 332 * The number of bits used to represent a {@code short} value in two's 333 * complement binary form. 334 * @since 1.5 335 */ 336 static const int SIZE = 16; 337 338 /** 339 * The number of bytes used to represent a {@code short} value in two's 340 * complement binary form. 341 * 342 * @since 1.8 343 */ 344 static int BYTES = SIZE / Byte.SIZE; 345 346 /** 347 * Returns the value obtained by reversing the order of the bytes in the 348 * two's complement representation of the specified {@code short} value. 349 * 350 * @param i the value whose bytes are to be reversed 351 * @return the value obtained by reversing (or, equivalently, swapping) 352 * the bytes in the specified {@code short} value. 353 * @since 1.5 354 */ 355 static short reverseBytes(short i) { 356 return cast(short) (((i & 0xFF00) >> 8) | (i << 8)); 357 } 358 359 360 /** 361 * Converts the argument to an {@code int} by an unsigned 362 * conversion. In an unsigned conversion to an {@code int}, the 363 * high-order 16 bits of the {@code int} are zero and the 364 * low-order 16 bits are equal to the bits of the {@code short} argument. 365 * 366 * Consequently, zero and positive {@code short} values are mapped 367 * to a numerically equal {@code int} value and negative {@code 368 * short} values are mapped to an {@code int} value equal to the 369 * input plus 2<sup>16</sup>. 370 * 371 * @param x the value to convert to an unsigned {@code int} 372 * @return the argument converted to {@code int} by an unsigned 373 * conversion 374 * @since 1.8 375 */ 376 static int toUnsignedInt(short x) { 377 return (cast(int) x) & 0xffff; 378 } 379 380 /** 381 * Converts the argument to a {@code long} by an unsigned 382 * conversion. In an unsigned conversion to a {@code long}, the 383 * high-order 48 bits of the {@code long} are zero and the 384 * low-order 16 bits are equal to the bits of the {@code short} argument. 385 * 386 * Consequently, zero and positive {@code short} values are mapped 387 * to a numerically equal {@code long} value and negative {@code 388 * short} values are mapped to a {@code long} value equal to the 389 * input plus 2<sup>16</sup>. 390 * 391 * @param x the value to convert to an unsigned {@code long} 392 * @return the argument converted to {@code long} by an unsigned 393 * conversion 394 * @since 1.8 395 */ 396 static long toUnsignedLong(short x) { 397 return (cast(long) x) & 0xffffL; 398 } 399 400 /** use serialVersionUID from JDK 1.1. for interoperability */ 401 private static long serialVersionUID = 7515723908773894738L; 402 403 static short parseShort(string s) { 404 auto i = to!int(s); 405 if (i < MIN_VALUE || i > MAX_VALUE) 406 { 407 throw new Exception( 408 "Value " ~s ~ " out of range from input "); 409 } 410 411 return cast(short)i; 412 } 413 }