Issue 5236 - [patch] std.format.formattedRead/unformatValue does not support the raw reading of integer types

This commit is contained in:
RazvanN7 2016-11-01 13:58:07 +02:00
parent f6b4e89d64
commit 17d13e2066

View file

@ -4302,7 +4302,7 @@ T unformatValue(T, Range, Char)(ref Range input, ref FormatSpec!Char spec)
import std.conv : parse, text;
if (spec.spec == 's')
{
return parse!T(input);
static if(__traits(compiles, parse!T(input)) ) return parse!T(input);
}
enforce(find(acceptedSpecs!long, spec.spec).length,
text("Wrong unformat specifier '%", spec.spec , "' for ", T.stringof));
@ -4359,43 +4359,11 @@ T unformatValue(T, Range, Char)(ref Range input, ref FormatSpec!Char spec)
enforce(spec.spec == 's',
text("Wrong unformat specifier '%", spec.spec , "' for ", T.stringof));
return parse!T(input);
static if(__traits(compiles, parse!T(input)) ) return parse!T(input);
}
/**
Reads an integral value and returns it.
*/
T unformatValue(T, Range, Char)(ref Range input, ref FormatSpec!Char spec)
if (isInputRange!Range && isIntegral!T && !is(T == enum))
private T rawReadWrapper(T, Range)(ref Range input)
{
import std.algorithm.searching : find;
import std.conv : parse, text;
enforce(find(acceptedSpecs!T, spec.spec).length,
text("Wrong unformat specifier '%", spec.spec , "' for ", T.stringof));
enforce(spec.width == 0, "Parsing integers with a width specification is not implemented"); // TODO
immutable uint base =
spec.spec == 'x' || spec.spec == 'X' ? 16 :
spec.spec == 'o' ? 8 :
spec.spec == 'b' ? 2 :
spec.spec == 's' || spec.spec == 'd' || spec.spec == 'u' ? 10 : 0;
assert(base != 0);
return parse!T(input, base);
}
/**
Reads a floating-point value and returns it.
*/
T unformatValue(T, Range, Char)(ref Range input, ref FormatSpec!Char spec)
if (isFloatingPoint!T && !is(T == enum))
{
import std.algorithm.searching : find;
import std.conv : parse, text;
if (spec.spec == 'r')
{
// raw read
//enforce(input.length >= T.sizeof);
enforce(
isSomeString!Range || ElementType!(Range).sizeof == 1,
"Cannot parse input of type %s".format(Range.stringof)
@ -4420,12 +4388,76 @@ T unformatValue(T, Range, Char)(ref Range input, ref FormatSpec!Char spec)
input.popFront();
}
}
return x.typed;
}
/**
Reads an integral value and returns it.
*/
T unformatValue(T, Range, Char)(ref Range input, ref FormatSpec!Char spec)
if (isInputRange!Range && isIntegral!T && !is(T == enum))
{
import std.algorithm.searching : find;
import std.conv : parse, text;
enforce(find(acceptedSpecs!T, spec.spec).length,
text("Wrong unformat specifier '%", spec.spec , "' for ", T.stringof));
return parse!T(input);
enforce(spec.width == 0, "Parsing integers with a width specification is not implemented"); // TODO
immutable uint base =
spec.spec == 'x' || spec.spec == 'X' ? 16 :
spec.spec == 'o' ? 8 :
spec.spec == 'b' ? 2 :
spec.spec == 's' || spec.spec == 'd' || spec.spec == 'u' ? 10 : 0;
assert(base != 0);
// raw read
//enforce(input.length >= T.sizeof);
if (spec.spec == 'r') return rawReadWrapper!T(input);
enforce(find(acceptedSpecs!T, spec.spec).length,
text("Wrong unformat specifier '%", spec.spec , "' for ", T.stringof));
static if(__traits(compiles, parse!T(input, base)) ) return parse!T(input, base);
}
version(none)unittest
{
union B
{
char[int.sizeof] untyped;
int typed;
}
B b;
b.typed = 5;
char[] input = b.untyped[];
int witness;
formattedRead(input, "%r", &witness);
assert(witness == b.typed);
}
/**
Reads a floating-point value and returns it.
*/
T unformatValue(T, Range, Char)(ref Range input, ref FormatSpec!Char spec)
if (isFloatingPoint!T && !is(T == enum))
{
import std.algorithm.searching : find;
import std.conv : parse, text;
// raw read
//enforce(input.length >= T.sizeof);
if (spec.spec == 'r') return rawReadWrapper!T(input);
enforce(find(acceptedSpecs!T, spec.spec).length,
text("Wrong unformat specifier '%", spec.spec , "' for ", T.stringof));
static if(__traits(compiles, parse!T(input)) ) return parse!T(input);
}
version(none)unittest
@ -4600,7 +4632,7 @@ T unformatValue(T, Range, Char)(ref Range input, ref FormatSpec!Char spec)
enforce(spec.spec == 's',
text("Wrong unformat specifier '%", spec.spec , "' for ", T.stringof));
return parse!T(input);
static if(__traits(compiles, parse!T(input)) ) return parse!T(input);
}
@system pure unittest
@ -4694,7 +4726,7 @@ T unformatValue(T, Range, Char)(ref Range input, ref FormatSpec!Char spec)
enforce(spec.spec == 's',
text("Wrong unformat specifier '%", spec.spec , "' for ", T.stringof));
return parse!T(input);
static if(__traits(compiles, parse!T(input)) ) return parse!T(input);
}
@system pure unittest