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