Report a bug
If you spot a problem with this page, click here to create a GitHub issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using a local clone.

mir.parse

@nogc and nothrow Parsing Utilities

License:
Authors:
Ilya Yaroshenko
Examples:
mir.conv: to extension.
import mir.conv: to;

assert("123.0".to!double == 123);
assert("123".to!int == 123);
assert("123".to!byte == 123);

import mir.small_string;
alias S = SmallString!32;
assert(S("123.0").to!double == 123);
assert(S("123.").to!double == 123.);
assert(S(".123").to!double == .123);
assert(S("123").to!(immutable int) == 123);
T fromString(T, C)(scope const(C)[] str)
if (isMutable!T);
Performs nothrow and @nogc string to native type conversion.
Returns:
parsed value
Throws:
nogc Exception in case of parse error or non-empty remaining input.

Floating point Mir parsing supports up-to quadruple precision. The conversion error is 0 ULP for normal numbers. Subnormal numbers with an exponent greater than or equal to -512 have upper error bound equal to 1 ULP.

Examples:
assert("123".fromString!int == 123);
static assert("-123".fromString!int == -123);

assert(".5".fromString!float == .5);
assert("12.3".fromString!double == 12.3);
assert("12.3".fromString!float == 12.3f);
assert("12.3".fromString!real == 12.3L);
assert("-12.3e-30".fromString!double == -12.3e-30);
assert("2.9802322387695312E-8".fromString!double == 2.9802322387695312E-8);

// default support of underscores
assert("123_456.789_012".fromString!double == 123_456.789_012);
assert("12_34_56_78_90_12e-6".fromString!double == 123_456.789_012);

// default support of leading zeros
assert("010".fromString!double == 10.0);
assert("000010".fromString!double == 10.0);
assert("0000.10".fromString!double == 0.1);
assert("0000e10".fromString!double == 0);

/// Test CTFE support  
static assert("-12.3e-30".fromString!double == -0x1.f2f280b2414d5p-97);
static assert("+12.3e+30".fromString!double == 0x1.367ee3119d2bap+103);

static assert("1.448997445238699".fromString!double == 0x1.72f17f1f49aadp0);
static if (real.mant_dig >= 64)
    static assert("1.448997445238699".fromString!real == 1.448997445238699L);

static assert("3.518437208883201171875".fromString!float == 0x1.c25c26p+1);
static assert("3.518437208883201171875".fromString!double == 0x1.c25c268497684p+1);
static if (real.mant_dig >= 64)
    static assert("3.518437208883201171875".fromString!real == 0xe.12e13424bb4232fp-2L);    

//  Related DMD Issues:
// https://issues.dlang.org/show_bug.cgi?id=20951
// https://issues.dlang.org/show_bug.cgi?id=20952
// https://issues.dlang.org/show_bug.cgi?id=20953
// https://issues.dlang.org/show_bug.cgi?id=20967
bool fromString(T, C)(scope const(C)[] str, ref T value)
if (isSomeChar!C);
Performs nothrow and @nogc string to native type conversion.
Returns:
true if success and false otherwise.
Examples:
int value;
assert("123".fromString(value) && value == 123);
bool parse(T, Range)(ref scope Range r, ref scope T value)
if (isInputRange!Range && isSomeChar!T);
Single character parsing utilities.
Returns:
true if success and false otherwise.
Examples:
auto s = "str";
char c;
assert(parse(s, c));
assert(c == 's');
assert(s == "tr");
bool parse(T, Range)(ref scope Range r, ref scope T value)
if ((is(T == byte) || is(T == short)) && isInputRange!Range && !__traits(isUnsigned, T));

bool parse(T, Range)(ref scope Range r, ref scope T value)
if (is(T == int) && isInputRange!Range && !__traits(isUnsigned, T));

bool parse(T, Range)(ref scope Range r, ref scope T value)
if (is(T == long) && isInputRange!Range && !__traits(isUnsigned, T));

bool parse(T, Range)(ref scope Range r, ref scope T value)
if ((is(T == ubyte) || is(T == ushort)) && isInputRange!Range && __traits(isUnsigned, T));

bool parse(T, Range)(ref scope Range r, ref scope T value)
if (is(T == uint) && isInputRange!Range && __traits(isUnsigned, T));

bool parse(T, Range)(ref scope Range r, ref scope T value)
if (is(T == ulong) && isInputRange!Range && __traits(isUnsigned, T));
Integer parsing utilities.
Returns:
true if success and false otherwise.
Examples:
import std.meta: AliasSeq;
foreach (T; AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong))
{
    auto str = "123";
    T val;
    assert(parse(str, val));
    assert(val == 123);
    str = "0";
    assert(parse(str, val));
    assert(val == 0);
    str = "9";
    assert(parse(str, val));
    assert(val == 9);
    str = "";
    assert(!parse(str, val));
    assert(val == 0);
    str = "text";
    assert(!parse(str, val));
    assert(val == 0);
}
Examples:
import std.meta: AliasSeq;
foreach (T; AliasSeq!(byte, short, int, long))
{
    auto str = "-123";
    T val;
    assert(parse(str, val));
    assert(val == -123);
    str = "-0";
    assert(parse(str, val));
    assert(val == 0);
    str = "-9text";
    assert(parse(str, val));
    assert(val == -9);
    assert(str == "text");
    enum m = T.min + 0;
    str = m.stringof;
    assert(parse(str, val));
    assert(val == T.min);
}