mirror of
https://github.com/dlang/phobos.git
synced 2025-05-04 09:00:22 +03:00
Clean up after making formating floating point numbers @nogc.
This commit is contained in:
parent
afc2df6ef2
commit
3206e52aae
4 changed files with 976 additions and 1023 deletions
8
changelog/formatting_floats_nogc.dd
Normal file
8
changelog/formatting_floats_nogc.dd
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
Floating point numbers don't allocate with the GC anymore.
|
||||||
|
|
||||||
|
The implementation of formatting floating point numbers has been
|
||||||
|
reworked. We made sure that working examples never allocate with the
|
||||||
|
GC, however, we are still using exceptions which are GC managed.
|
||||||
|
Therefore, code that uses formatting correctly will never allocate,
|
||||||
|
but in the case of exceptions, the GC will be used to allocate the
|
||||||
|
exception. We are working on DIP 1008 to solve this issue.
|
File diff suppressed because it is too large
Load diff
|
@ -506,9 +506,7 @@ if (is(FloatingPointTypeOf!T) && !is(T == enum) && !hasToString!(T, Char))
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.spec = spec2;
|
fs.spec = spec2;
|
||||||
buf = printFloat(buf2[], w, val, fs, mode);
|
printFloat(w, val, fs, mode);
|
||||||
len = buf.length;
|
|
||||||
if (len == 0) return;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -561,87 +559,87 @@ if (is(FloatingPointTypeOf!T) && !is(T == enum) && !hasToString!(T, Char))
|
||||||
|
|
||||||
len = min(n, buf2.length-1);
|
len = min(n, buf2.length-1);
|
||||||
buf = buf2;
|
buf = buf2;
|
||||||
}
|
|
||||||
|
|
||||||
if (fs.flSeparator && !inf && !nan)
|
if (fs.flSeparator && !inf && !nan)
|
||||||
{
|
|
||||||
ptrdiff_t indexOfRemovable()
|
|
||||||
{
|
{
|
||||||
if (len < 2)
|
ptrdiff_t indexOfRemovable()
|
||||||
return -1;
|
|
||||||
|
|
||||||
size_t start = (buf[0 .. 1].indexOfAny(" 0123456789") == -1) ? 1 : 0;
|
|
||||||
if (len < 2 + start)
|
|
||||||
return -1;
|
|
||||||
if ((buf[start] == ' ') || (buf[start] == '0' && buf[start + 1] != '.'))
|
|
||||||
return start;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ptrdiff_t dot, firstDigit, ePos, dotIdx, firstLen;
|
|
||||||
size_t separatorScoreCnt;
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
dot = buf[0 .. len].indexOf('.');
|
|
||||||
firstDigit = buf[0 .. len].indexOfAny("0123456789");
|
|
||||||
ePos = buf[0 .. len].indexOf('e');
|
|
||||||
dotIdx = dot == -1 ? ePos == -1 ? len : ePos : dot;
|
|
||||||
|
|
||||||
firstLen = dotIdx - firstDigit;
|
|
||||||
separatorScoreCnt = (firstLen > 0) ? (firstLen - 1) / fs.separators : 0;
|
|
||||||
|
|
||||||
ptrdiff_t removableIdx = (len + separatorScoreCnt > fs.width) ? indexOfRemovable() : -1;
|
|
||||||
if ((removableIdx != -1) &&
|
|
||||||
((firstLen - (buf[removableIdx] == '0' ? 2 : 1)) / fs.separators + len - 1 >= fs.width))
|
|
||||||
{
|
{
|
||||||
buf[removableIdx .. $ - 1] = buf.dup[removableIdx + 1 .. $];
|
if (len < 2)
|
||||||
len--;
|
return -1;
|
||||||
|
|
||||||
|
size_t start = (buf[0 .. 1].indexOfAny(" 0123456789") == -1) ? 1 : 0;
|
||||||
|
if (len < 2 + start)
|
||||||
|
return -1;
|
||||||
|
if ((buf[start] == ' ') || (buf[start] == '0' && buf[start + 1] != '.'))
|
||||||
|
return start;
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
immutable afterDotIdx = (ePos != -1) ? ePos : len;
|
ptrdiff_t dot, firstDigit, ePos, dotIdx, firstLen;
|
||||||
|
size_t separatorScoreCnt;
|
||||||
|
|
||||||
// plus, minus, prefix
|
while (true)
|
||||||
if (firstDigit > 0)
|
|
||||||
{
|
|
||||||
put(w, buf[0 .. firstDigit]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// digits until dot with separator
|
|
||||||
for (auto j = 0; j < firstLen; ++j)
|
|
||||||
{
|
|
||||||
if (j > 0 && (firstLen - j) % fs.separators == 0)
|
|
||||||
{
|
{
|
||||||
put(w, fs.separatorChar);
|
dot = buf[0 .. len].indexOf('.');
|
||||||
|
firstDigit = buf[0 .. len].indexOfAny("0123456789");
|
||||||
|
ePos = buf[0 .. len].indexOf('e');
|
||||||
|
dotIdx = dot == -1 ? ePos == -1 ? len : ePos : dot;
|
||||||
|
|
||||||
|
firstLen = dotIdx - firstDigit;
|
||||||
|
separatorScoreCnt = (firstLen > 0) ? (firstLen - 1) / fs.separators : 0;
|
||||||
|
|
||||||
|
ptrdiff_t removableIdx = (len + separatorScoreCnt > fs.width) ? indexOfRemovable() : -1;
|
||||||
|
if ((removableIdx != -1) &&
|
||||||
|
((firstLen - (buf[removableIdx] == '0' ? 2 : 1)) / fs.separators + len - 1 >= fs.width))
|
||||||
|
{
|
||||||
|
buf[removableIdx .. $ - 1] = buf.dup[removableIdx + 1 .. $];
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
put(w, buf[j + firstDigit]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// print dot for decimal numbers only or with '#' format specifier
|
immutable afterDotIdx = (ePos != -1) ? ePos : len;
|
||||||
if (dot != -1 || fs.flHash)
|
|
||||||
{
|
|
||||||
put(w, '.');
|
|
||||||
}
|
|
||||||
|
|
||||||
// digits after dot
|
// plus, minus, prefix
|
||||||
for (auto j = dotIdx + 1; j < afterDotIdx; ++j)
|
if (firstDigit > 0)
|
||||||
{
|
{
|
||||||
put(w, buf[j]);
|
put(w, buf[0 .. firstDigit]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// rest
|
// digits until dot with separator
|
||||||
if (ePos != -1)
|
for (auto j = 0; j < firstLen; ++j)
|
||||||
{
|
{
|
||||||
put(w, buf[afterDotIdx .. len]);
|
if (j > 0 && (firstLen - j) % fs.separators == 0)
|
||||||
|
{
|
||||||
|
put(w, fs.separatorChar);
|
||||||
|
}
|
||||||
|
put(w, buf[j + firstDigit]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// print dot for decimal numbers only or with '#' format specifier
|
||||||
|
if (dot != -1 || fs.flHash)
|
||||||
|
{
|
||||||
|
put(w, '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// digits after dot
|
||||||
|
for (auto j = dotIdx + 1; j < afterDotIdx; ++j)
|
||||||
|
{
|
||||||
|
put(w, buf[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// rest
|
||||||
|
if (ePos != -1)
|
||||||
|
{
|
||||||
|
put(w, buf[afterDotIdx .. len]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
put(w, buf[0 .. len]);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
put(w, buf[0 .. len]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1511,8 +1511,6 @@ Note:
|
||||||
|
|
||||||
$(UL
|
$(UL
|
||||||
$(LI An exception is thrown.)
|
$(LI An exception is thrown.)
|
||||||
$(LI A floating point number of type `real` is formatted.)
|
|
||||||
$(LI The representation of a floating point number exceeds 500 characters.)
|
|
||||||
$(LI A custom `toString` function of a compound type allocates.))
|
$(LI A custom `toString` function of a compound type allocates.))
|
||||||
*/
|
*/
|
||||||
char[] sformat(Char, Args...)(return scope char[] buf, scope const(Char)[] fmt, Args args)
|
char[] sformat(Char, Args...)(return scope char[] buf, scope const(Char)[] fmt, Args args)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue