1 /** 2 * Parsing from string to standard types. 3 */ 4 module bc..string.conv; 5 6 import bc.string.ascii; 7 import bc.core.intrinsics; 8 import std.traits; 9 10 alias cstring = const(char)[]; 11 12 //TODO: check for owerloads? 13 //TODO: use parseToken to fast check length of input number 14 15 ParseResult!T parse(T)(cstring str) if (isIntegral!T && !is(T == enum)) 16 { 17 pragma(inline, true); 18 if (!str.length) return ParseResult!T.init; 19 20 size_t count; 21 static if (isSigned!T) { 22 ptrdiff_t res; 23 bool sign; 24 if (str[0] == '-') { 25 sign = true; 26 count++; 27 } else if (str[0] == '+') 28 count++; 29 } else size_t res; 30 31 for (; count < str.length; ++count) 32 { 33 if (_expect(!str[count].isDigit, false)) return ParseResult!T.init; 34 res = res*10 + (str[count]-'0'); 35 } 36 37 if (_expect(res > T.max, false)) return ParseResult!T.init; 38 39 static if (isSigned!T) { 40 if (sign) res = -res; 41 } 42 return ParseResult!T(cast(T)res, count); 43 } 44 45 @safe unittest 46 { 47 assert("42".parse!int == ParseResult!int(42, 2)); 48 assert("42".parse!uint == ParseResult!uint(42, 2)); 49 assert("-42".parse!int == ParseResult!int(-42, 3)); 50 assert("+42".parse!int == ParseResult!int(42, 3)); 51 } 52 53 /// Result of the parse functions 54 struct ParseResult(T) 55 { 56 T data; /// parsed value 57 size_t count; /// Number of characters consumed while parsing (0 means that input couldn't be parsed into specified type) 58 59 /// Checks if some data was actually parsed from the input 60 bool opCast(T)() const if(is(T == bool)) { return count > 0; } 61 // alias data this; 62 }