mirror of
https://github.com/dlang/phobos.git
synced 2025-04-30 07:00:37 +03:00
std.conv: parse not handling some cases
This commit is contained in:
parent
dbf108b451
commit
231f8b664e
1 changed files with 55 additions and 43 deletions
92
std/conv.d
92
std/conv.d
|
@ -1901,65 +1901,73 @@ Target parse(Target, Source)(ref Source s)
|
||||||
// smaller types are handled like integers
|
// smaller types are handled like integers
|
||||||
auto v = .parse!(Select!(Target.min < 0, int, uint))(s);
|
auto v = .parse!(Select!(Target.min < 0, int, uint))(s);
|
||||||
auto result = ()@trusted{ return cast(Target) v; }();
|
auto result = ()@trusted{ return cast(Target) v; }();
|
||||||
if (result != v)
|
if (result == v)
|
||||||
goto Loverflow;
|
|
||||||
return result;
|
return result;
|
||||||
|
throw new ConvOverflowException("Overflow in integral conversion");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Larger than int types
|
// Larger than int types
|
||||||
|
|
||||||
static if (Target.min < 0)
|
static if (Target.min < 0)
|
||||||
int sign = 0;
|
bool sign = 0;
|
||||||
else
|
else
|
||||||
enum int sign = 0;
|
enum bool sign = 0;
|
||||||
Target v = 0;
|
|
||||||
bool atStart = true;
|
enum char maxLastDigit = Target.min < 0 ? 7 : 5;
|
||||||
enum char maxLastDigit = Target.min < 0 ? '7' : '5';
|
Unqual!(typeof(s.front)) c;
|
||||||
while (!s.empty)
|
|
||||||
{
|
if (s.empty)
|
||||||
immutable c = s.front;
|
|
||||||
if (c >= '0' && c <= '9')
|
|
||||||
{
|
|
||||||
if (v >= Target.max/10 &&
|
|
||||||
(v != Target.max/10 || c + sign > maxLastDigit))
|
|
||||||
goto Loverflow;
|
|
||||||
v = cast(Target) (v * 10 + (c - '0'));
|
|
||||||
s.popFront();
|
|
||||||
atStart = false;
|
|
||||||
}
|
|
||||||
else static if (Target.min < 0)
|
|
||||||
{
|
|
||||||
if (c == '-' && atStart)
|
|
||||||
{
|
|
||||||
s.popFront();
|
|
||||||
sign = -1;
|
|
||||||
}
|
|
||||||
else if (c == '+' && atStart)
|
|
||||||
s.popFront();
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (atStart)
|
|
||||||
goto Lerr;
|
goto Lerr;
|
||||||
|
|
||||||
|
c = s.front;
|
||||||
|
s.popFront();
|
||||||
static if (Target.min < 0)
|
static if (Target.min < 0)
|
||||||
{
|
{
|
||||||
if (sign == -1)
|
switch (c)
|
||||||
{
|
{
|
||||||
v = -v;
|
case '-':
|
||||||
|
sign = true;
|
||||||
|
goto case '+';
|
||||||
|
case '+':
|
||||||
|
if (s.empty)
|
||||||
|
goto Lerr;
|
||||||
|
c = s.front;
|
||||||
|
s.popFront();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return v;
|
c -= '0';
|
||||||
|
if (c <= 9)
|
||||||
|
{
|
||||||
|
Target v = cast(Target)c;
|
||||||
|
while (!s.empty)
|
||||||
|
{
|
||||||
|
c = s.front - '0';
|
||||||
|
if (c > 9)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (v < Target.max/10 ||
|
||||||
|
(v == Target.max/10 && c <= maxLastDigit + sign))
|
||||||
|
{
|
||||||
|
v = cast(Target) (v * 10 + c);
|
||||||
|
s.popFront();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new ConvOverflowException("Overflow in integral conversion");
|
||||||
}
|
}
|
||||||
|
|
||||||
Loverflow:
|
if (sign)
|
||||||
throw new ConvOverflowException("Overflow in integral conversion");
|
v = -v;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
Lerr:
|
Lerr:
|
||||||
throw convError!(Source, Target)(s);
|
throw convError!(Source, Target)(s);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@safe pure unittest
|
@safe pure unittest
|
||||||
{
|
{
|
||||||
|
@ -2080,6 +2088,10 @@ Lerr:
|
||||||
"1-",
|
"1-",
|
||||||
"xx",
|
"xx",
|
||||||
"123h",
|
"123h",
|
||||||
|
"-+1",
|
||||||
|
"--1",
|
||||||
|
"+-1",
|
||||||
|
"++1",
|
||||||
];
|
];
|
||||||
foreach (j, s; errors1)
|
foreach (j, s; errors1)
|
||||||
assertThrown!ConvException(to!Int(s));
|
assertThrown!ConvException(to!Int(s));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue