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&trade; 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 }