1 /** 2 Various functions to determine types at runtime. 3 Originally found in my raijin library and has been backported here. 4 5 Authors: Paul Crane 6 */ 7 8 module typeutils; 9 10 import std.typecons; 11 import std.traits; 12 import std.conv; 13 import std.algorithm : count; 14 15 alias AllowNumericBooleanValues = Flag!"allowNumericBooleanValues"; 16 17 /** 18 Determines if value is a true value 19 20 Params: 21 value = The value to check for a true value 22 allowInteger = Set to allowNumericBooleanValues.yes if a true value can be a numeric 1 23 24 Returns: 25 true if the value is true false otherwise. 26 */ 27 bool isTrue(T)(const T value, const AllowNumericBooleanValues allowInteger = AllowNumericBooleanValues.yes) @trusted 28 { 29 static if(isIntegral!T) 30 { 31 return(value == 1); 32 } 33 else 34 { 35 if(allowInteger) 36 { 37 return(value == "1" || value == "true"); 38 } 39 40 return (value == "true"); 41 } 42 } 43 44 /// 45 unittest 46 { 47 assert(isTrue("true") == true); 48 assert(isTrue("false") == false); 49 assert(isTrue("1") == true); 50 assert(isTrue("0") == false); 51 assert(isTrue("12345") == false); 52 assert(isTrue("trues") == false); 53 54 assert("1".isTrue(AllowNumericBooleanValues.no) == false); 55 } 56 57 /** 58 Determines if value is a false value 59 60 Params: 61 value = The value to check for a false value 62 allowInteger = Set to allowNumericBooleanValues.yes if a false value can be a numeric 0 63 64 Returns: 65 true if the value is false false otherwise. 66 */ 67 bool isFalse(T)(const T value, const AllowNumericBooleanValues allowInteger = AllowNumericBooleanValues.yes) @trusted 68 { 69 static if(isIntegral!T) 70 { 71 return(value == 0); 72 } 73 else 74 { 75 if(allowInteger) 76 { 77 return(value == "0" || value == "false"); 78 } 79 80 return (value == "false"); 81 } 82 } 83 84 /// 85 unittest 86 { 87 assert(isFalse("false") == true); 88 assert(isFalse("true") == false); 89 assert(isFalse("1") == false); 90 assert(isFalse("0") == true); 91 assert(isFalse("12345") == false); 92 assert(isFalse("trues") == false); 93 94 assert("0".isFalse(AllowNumericBooleanValues.no) == false); 95 } 96 97 /** 98 Determines if a value is of type boolean using 0, 1, true and false as qualifiers. 99 100 Params: 101 value = number or boolean string to use. Valid values of 0, 1, "0", "1", "true", "false" 102 allowInteger = Set to allowNumericBooleanValues.yes if a true/false value can be a numeric 0 or 1 103 104 Returns: 105 true if the value is a boolean false otherwise. 106 */ 107 bool isBoolean(T)(const T value, const AllowNumericBooleanValues allowInteger = AllowNumericBooleanValues.yes) @trusted 108 { 109 return(isTrue(value, allowInteger) || isFalse(value, allowInteger)); 110 } 111 112 /// 113 unittest 114 { 115 assert("0".isBoolean == true); 116 assert("1".isBoolean == true); 117 assert("2".isBoolean == false); 118 119 assert("true".isBoolean == true); 120 assert("false".isBoolean == true); 121 assert("trues".isBoolean == false); 122 123 assert("0".isBoolean(AllowNumericBooleanValues.no) == false); 124 assert("1".isBoolean(AllowNumericBooleanValues.no) == false); 125 126 assert(0.isBoolean == true); 127 assert(1.isBoolean == true); 128 assert(2.isBoolean == false); 129 } 130 131 /** 132 Determines if a string is a decimal value 133 134 Params: 135 value = string to use. 136 137 Returns: 138 true if the value is a decimal false otherwise. 139 */ 140 bool isDecimal(const string value) pure @safe 141 { 142 import std.string : isNumeric; 143 return (isNumeric(value) && value.count(".") == 1) ? true : false; 144 } 145 146 /// 147 unittest 148 { 149 assert("13".isDecimal == false); 150 assert("13.333333".isDecimal == true); 151 assert("zzzz".isDecimal == false); 152 } 153 /** 154 Determines if a string is an integer value. 155 156 Params: 157 value = string to use. 158 159 Returns: 160 true if the value is a integer false otherwise. 161 */ 162 bool isInteger(const string value) pure @safe 163 { 164 import std.string : isNumeric; 165 return (isNumeric(value) && value.count(".") == 0) ? true : false; 166 } 167 168 /// 169 unittest 170 { 171 assert("13".isInteger == true); 172 assert("13.333333".isInteger == false); 173 assert("zzzz".isInteger == false); 174 }