mirror of
https://github.com/dlang/phobos.git
synced 2025-05-08 03:56:54 +03:00
Issue 5236 - [patch] std.format.formattedRead/unformatValue does not support the raw reading of integer types
This commit is contained in:
parent
f6b4e89d64
commit
17d13e2066
1 changed files with 68 additions and 36 deletions
110
std/format.d
110
std/format.d
|
@ -4302,7 +4302,7 @@ T unformatValue(T, Range, Char)(ref Range input, ref FormatSpec!Char spec)
|
||||||
import std.conv : parse, text;
|
import std.conv : parse, text;
|
||||||
if (spec.spec == 's')
|
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,
|
enforce(find(acceptedSpecs!long, spec.spec).length,
|
||||||
text("Wrong unformat specifier '%", spec.spec , "' for ", T.stringof));
|
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',
|
enforce(spec.spec == 's',
|
||||||
text("Wrong unformat specifier '%", spec.spec , "' for ", T.stringof));
|
text("Wrong unformat specifier '%", spec.spec , "' for ", T.stringof));
|
||||||
|
|
||||||
return parse!T(input);
|
static if(__traits(compiles, parse!T(input)) ) return parse!T(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private T rawReadWrapper(T, Range)(ref Range 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))
|
|
||||||
{
|
{
|
||||||
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(
|
enforce(
|
||||||
isSomeString!Range || ElementType!(Range).sizeof == 1,
|
isSomeString!Range || ElementType!(Range).sizeof == 1,
|
||||||
"Cannot parse input of type %s".format(Range.stringof)
|
"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();
|
input.popFront();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return x.typed;
|
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,
|
enforce(find(acceptedSpecs!T, spec.spec).length,
|
||||||
text("Wrong unformat specifier '%", spec.spec , "' for ", T.stringof));
|
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
|
version(none)unittest
|
||||||
|
@ -4600,7 +4632,7 @@ T unformatValue(T, Range, Char)(ref Range input, ref FormatSpec!Char spec)
|
||||||
enforce(spec.spec == 's',
|
enforce(spec.spec == 's',
|
||||||
text("Wrong unformat specifier '%", spec.spec , "' for ", T.stringof));
|
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
|
@system pure unittest
|
||||||
|
@ -4694,7 +4726,7 @@ T unformatValue(T, Range, Char)(ref Range input, ref FormatSpec!Char spec)
|
||||||
enforce(spec.spec == 's',
|
enforce(spec.spec == 's',
|
||||||
text("Wrong unformat specifier '%", spec.spec , "' for ", T.stringof));
|
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
|
@system pure unittest
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue