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.Boolean;
13 
14 import hunt.text;
15 import std.traits;
16 
17 /**
18  * The Boolean class wraps a value of the primitive type
19  * {@code bool} in an object. An object of type
20  * {@code Boolean} contains a single field whose type is
21  * {@code bool}.
22  * <p>
23  * In addition, this class provides many methods for
24  * converting a {@code bool} to a {@code string} and a
25  * {@code string} to a {@code bool}, as well as other
26  * constants and methods useful when dealing with a
27  * {@code bool}.
28  *
29  * @author  Arthur van Hoff
30  * @since   JDK1.0
31  */
32 class Boolean {
33     /**
34      * The {@code Boolean} object corresponding to the primitive
35      * value {@code true}.
36      */
37     __gshared Boolean TRUE ;
38 
39     /**
40      * The {@code Boolean} object corresponding to the primitive
41      * value {@code false}.
42      */
43     __gshared Boolean FALSE;
44 
45     shared static this() {
46         TRUE = new Boolean(true);
47         FALSE = new Boolean(false);
48     }
49 
50     /**
51      * The Class object representing the primitive type bool.
52      *
53      * @since   JDK1.1
54     //  */
55     // @SuppressWarnings("unchecked")
56     // static  Class<Boolean> TYPE = (Class<Boolean>) Class.getPrimitiveClass("bool");
57 
58     /**
59      * The value of the Boolean.
60      *
61      * @serial
62      */
63     private bool value;
64 
65     /**
66      * Allocates a {@code Boolean} object representing the
67      * {@code value} argument.
68      *
69      * <p><b>Note: It is rarely appropriate to use this constructor.
70      * Unless a <i>new</i> instance is required, the static factory
71      * {@link #valueOf(bool)} is generally a better choice. It is
72      * likely to yield significantly better space and time performance.</b>
73      *
74      * @param   value   the value of the {@code Boolean}.
75      */
76     private void assign(T)(T arg) @safe {
77         static if (is(T : typeof(null))) {
78             value = false;
79         }
80         else static if (is(T : string)) {
81             string t = arg;
82             if (t.length != 0)
83                 value = true;
84             else
85                 value = false;
86         }
87         else static if (is(T : bool)) {
88             value = arg;
89         }
90         else static if (is(T : ulong) && isUnsigned!T) {
91             value = (arg != 0 ? true : false);
92         }
93         else static if (is(T : long)) {
94             value = (arg != 0 ? true : false);
95         }
96         else {
97             static assert(false, text(`unable to convert type "`, T.stringof, `" to Boolean`));
98         }
99     }
100 
101     this(T)(T value) if (!isStaticArray!T) {
102         assign(value);
103     }
104 
105     /// Ditto
106     this(T)(ref T arg) if (isStaticArray!T) {
107         value = arg.booleanValue();
108     }
109     /// Ditto
110     this(T : Boolean)(inout T arg) inout {
111         value = arg.booleanValue();
112     }
113 
114     /**
115      * Allocates a {@code Boolean} object representing the value
116      * {@code true} if the string argument is not {@code null}
117      * and is equal, ignoring case, to the string {@code "true"}.
118      * Otherwise, allocate a {@code Boolean} object representing the
119      * value {@code false}. Examples:<p>
120      * {@code new Boolean("True")} produces a {@code Boolean} object
121      * that represents {@code true}.<br>
122      * {@code new Boolean("yes")} produces a {@code Boolean} object
123      * that represents {@code false}.
124      *
125      * @param   s   the string to be converted to a {@code Boolean}.
126      */
127     this(string s) {
128         this(parseBoolean(s));
129     }
130 
131     /**
132      * Parses the string argument as a bool.  The {@code bool}
133      * returned represents the value {@code true} if the string argument
134      * is not {@code null} and is equal, ignoring case, to the string
135      * {@code "true"}. <p>
136      * Example: {@code Boolean.parseBoolean("True")} returns {@code true}.<br>
137      * Example: {@code Boolean.parseBoolean("yes")} returns {@code false}.
138      *
139      * @param      s   the {@code string} containing the bool
140      *                 representation to be parsed
141      * @return     the bool represented by the string argument
142      * @since 1.5
143      */
144     static bool parseBoolean(string s) {
145         return ((s.length != 0) && equalsIgnoreCase(s, "true"));
146     }
147 
148     /**
149      * Returns the value of this {@code Boolean} object as a bool
150      * primitive.
151      *
152      * @return  the primitive {@code bool} value of this object.
153      */
154     bool booleanValue() {
155         return value;
156     }
157 
158     /**
159      * Returns a {@code Boolean} instance representing the specified
160      * {@code bool} value.  If the specified {@code bool} value
161      * is {@code true}, this method returns {@code Boolean.TRUE};
162      * if it is {@code false}, this method returns {@code Boolean.FALSE}.
163      * If a new {@code Boolean} instance is not required, this method
164      * should generally be used in preference to the constructor
165      * {@link #Boolean(bool)}, as this method is likely to yield
166      * significantly better space and time performance.
167      *
168      * @param  b a bool value.
169      * @return a {@code Boolean} instance representing {@code b}.
170      * @since  1.4
171      */
172     static Boolean valueOf(bool b) {
173         return (b ? TRUE : FALSE);
174     }
175 
176     /**
177      * Returns a {@code Boolean} with a value represented by the
178      * specified string.  The {@code Boolean} returned represents a
179      * true value if the string argument is not {@code null}
180      * and is equal, ignoring case, to the string {@code "true"}.
181      *
182      * @param   s   a string.
183      * @return  the {@code Boolean} value represented by the string.
184      */
185     static Boolean valueOf(string s) {
186         return parseBoolean(s) ? TRUE : FALSE;
187     }
188 
189     /**
190      * Returns a {@code string} object representing the specified
191      * bool.  If the specified bool is {@code true}, then
192      * the string {@code "true"} will be returned, otherwise the
193      * string {@code "false"} will be returned.
194      *
195      * @param b the bool to be converted
196      * @return the string representation of the specified {@code bool}
197      * @since 1.4
198      */
199     static string toString(bool b) {
200         return b ? "true" : "false";
201     }
202 
203     /**
204      * Returns a {@code string} object representing this Boolean's
205      * value.  If this object represents the value {@code true},
206      * a string equal to {@code "true"} is returned. Otherwise, a
207      * string equal to {@code "false"} is returned.
208      *
209      * @return  a string representation of this object.
210      */
211     override string toString() {
212         return value ? "true" : "false";
213     }
214 
215     /**
216      * Returns a hash code for this {@code Boolean} object.
217      *
218      * @return  the integer {@code 1231} if this object represents
219      * {@code true}; returns the integer {@code 1237} if this
220      * object represents {@code false}.
221      */
222     override size_t toHash() @safe nothrow {
223         return value ? 1231 : 1237;
224     }
225 
226     /**
227      * Returns a hash code for a {@code bool} value; compatible with
228      * {@code Boolean.hashCode()}.
229      *
230      * @param value the value to hash
231      * @return a hash code value for a {@code bool} value.
232      * @since 1.8
233      */
234     // static size_t hashCode(bool value) {
235     //     return value ? 1231 : 1237;
236     // }
237 
238     /**
239      * Returns {@code true} if and only if the argument is not
240      * {@code null} and is a {@code Boolean} object that
241      * represents the same {@code bool} value as this object.
242      *
243      * @param   obj   the object to compare with.
244      * @return  {@code true} if the Boolean objects represent the
245      *          same value; {@code false} otherwise.
246      */
247     override bool opEquals(Object obj) {
248         if (cast(Boolean) obj !is null) {
249             return value == (cast(Boolean) obj).booleanValue();
250         }
251         return false;
252     }
253 
254     void opAssign(T)(T arg) if (!isStaticArray!T && !is(T : Boolean)) {
255         assign(arg);
256     }
257 
258     void opAssign(T)(ref T arg) if (isStaticArray!T) {
259         value = arg.booleanValue;
260     }
261 
262     /**
263      * Returns {@code true} if and only if the system property
264      * named by the argument exists and is equal to the string
265      * {@code "true"}. (Beginning with version 1.0.2 of the
266      * Java<small><sup>TM</sup></small> platform, the test of
267      * this string is case insensitive.) A system property is accessible
268      * through {@code getProperty}, a method defined by the
269      * {@code System} class.
270      * <p>
271      * If there is no property with the specified name, or if the specified
272      * name is empty or null, then {@code false} is returned.
273      *
274      * @param   name   the system property name.
275      * @return  the {@code bool} value of the system property.
276      * @throws  SecurityException for the same reasons as
277      *          {@link System#getProperty(string) System.getProperty}
278      * @see     java.lang.System#getProperty(java.lang.string)
279      * @see     java.lang.System#getProperty(java.lang.string, java.lang.string)
280      */
281     // static bool getBoolean(string name) {
282     //     bool result = false;
283     //     try {
284     //         result = parseBoolean(System.getProperty(name));
285     //     } catch (IllegalArgumentException | NullPointerException e) {
286     //     }
287     //     return result;
288     // }
289 
290     /**
291      * Compares this {@code Boolean} instance with another.
292      *
293      * @param   b the {@code Boolean} instance to be compared
294      * @return  zero if this object represents the same bool value as the
295      *          argument; a positive value if this object represents true
296      *          and the argument represents false; and a negative value if
297      *          this object represents false and the argument represents true
298      * @throws  NullPointerException if the argument is {@code null}
299      * @see     Comparable
300      * @since  1.5
301      */
302     int compareTo(Boolean b) {
303         return compare(this.value, b.value);
304     }
305 
306     /**
307      * Compares two {@code bool} values.
308      * The value returned is identical to what would be returned by:
309      * <pre>
310      *    Boolean.valueOf(x).compareTo(Boolean.valueOf(y))
311      * </pre>
312      *
313      * @param  x the first {@code bool} to compare
314      * @param  y the second {@code bool} to compare
315      * @return the value {@code 0} if {@code x == y};
316      *         a value less than {@code 0} if {@code !x && y}; and
317      *         a value greater than {@code 0} if {@code x && !y}
318      * @since 1.7
319      */
320     static int compare(bool x, bool y) {
321         return (x == y) ? 0 : (x ? 1 : -1);
322     }
323 
324     /**
325      * Returns the result of applying the logical AND operator to the
326      * specified {@code bool} operands.
327      *
328      * @param a the first operand
329      * @param b the second operand
330      * @return the logical AND of {@code a} and {@code b}
331      * @see hunt.util.functional.BinaryOperator
332      * @since 1.8
333      */
334     static bool logicalAnd(bool a, bool b) {
335         return a && b;
336     }
337 
338     /**
339      * Returns the result of applying the logical OR operator to the
340      * specified {@code bool} operands.
341      *
342      * @param a the first operand
343      * @param b the second operand
344      * @return the logical OR of {@code a} and {@code b}
345      * @see hunt.util.functional.BinaryOperator
346      * @since 1.8
347      */
348     static bool logicalOr(bool a, bool b) {
349         return a || b;
350     }
351 
352     /**
353      * Returns the result of applying the logical XOR operator to the
354      * specified {@code bool} operands.
355      *
356      * @param a the first operand
357      * @param b the second operand
358      * @return  the logical XOR of {@code a} and {@code b}
359      * @see hunt.util.functional.BinaryOperator
360      * @since 1.8
361      */
362     static bool logicalXor(bool a, bool b) {
363         return a ^ b;
364     }
365 }
366