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