Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Commit

Permalink
eliminate more custom int to string conversions
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright committed Oct 19, 2015
1 parent 6ec905e commit 6bc890c
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 17 deletions.
20 changes: 5 additions & 15 deletions src/core/demangle.d
Original file line number Diff line number Diff line change
Expand Up @@ -1722,19 +1722,7 @@ char[] demangleType( const(char)[] buf, char[] dst = null )
*/
char[] mangle(T)(const(char)[] fqn, char[] dst = null) @safe pure nothrow
{
static size_t numToString(char[] dst, size_t val) @safe pure nothrow
{
char[20] buf = void;
size_t i = buf.length;
do
{
buf[--i] = cast(char)(val % 10 + '0');
} while (val /= 10);
immutable len = buf.length - i;
if (dst.length >= len)
dst[0 .. len] = buf[i .. $];
return len;
}
import core.internal.string : numDigits, unsignedToTempString;

static struct DotSplitter
{
Expand Down Expand Up @@ -1764,15 +1752,17 @@ char[] mangle(T)(const(char)[] fqn, char[] dst = null) @safe pure nothrow

size_t len = "_D".length;
foreach (comp; DotSplitter(fqn))
len += numToString(null, comp.length) + comp.length;
len += numDigits(comp.length) + comp.length;
len += T.mangleof.length;
if (dst.length < len) dst.length = len;

size_t i = "_D".length;
dst[0 .. i] = "_D";
foreach (comp; DotSplitter(fqn))
{
i += numToString(dst[i .. $], comp.length);
const ndigits = numDigits(comp.length);
unsignedToTempString(comp.length, dst[i .. i + ndigits]);
i += ndigits;
dst[i .. i + comp.length] = comp[];
i += comp.length;
}
Expand Down
62 changes: 60 additions & 2 deletions src/core/internal/string.d
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ nothrow:

alias UnsignedStringBuf = char[20];

char[] unsignedToTempString(ulong value, char[] buf, uint radix) @safe
char[] unsignedToTempString(ulong value, char[] buf, uint radix = 10) @safe
{
size_t i = buf.length;
do
Expand All @@ -41,7 +41,7 @@ private struct TempStringNoAlloc

auto unsignedToTempString(ulong value, uint radix) @safe
{
TempStringNoAlloc result;
TempStringNoAlloc result = void;
result._len = unsignedToTempString(value, result._buf, radix).length & 0xff;
return result;
}
Expand Down Expand Up @@ -132,6 +132,64 @@ unittest
assert(long.min.signedToTempString(2) == "-1000000000000000000000000000000000000000000000000000000000000000");
}


/********************************
* Determine number of digits that will result from a
* conversion of value to a string.
* Params:
* value = number to convert
* radix = radix
* Returns:
* number of digits
*/
int numDigits(uint radix = 10)(ulong value) @safe
{
int n = 1;
while (1)
{
if (value <= uint.max)
{
uint v = cast(uint)value;
while (1)
{
if (v < radix)
return n;
if (v < radix * radix)
return n + 1;
if (v < radix * radix * radix)
return n + 2;
if (v < radix * radix * radix * radix)
return n + 3;
n += 4;
v /= radix * radix * radix * radix;
}
}
n += 4;
value /= radix * radix * radix * radix;
}
}

unittest
{
assert(0.numDigits == 1);
assert(9.numDigits == 1);
assert(10.numDigits == 2);
assert(99.numDigits == 2);
assert(100.numDigits == 3);
assert(999.numDigits == 3);
assert(1000.numDigits == 4);
assert(9999.numDigits == 4);
assert(10000.numDigits == 5);
assert(99999.numDigits == 5);
assert(uint.max.numDigits == 10);
assert(ulong.max.numDigits == 20);

assert(0.numDigits!2 == 1);
assert(1.numDigits!2 == 1);
assert(2.numDigits!2 == 2);
assert(3.numDigits!2 == 2);
}

int dstrcmp( in char[] s1, in char[] s2 ) @trusted
{
import core.stdc.string : memcmp;
Expand Down

0 comments on commit 6bc890c

Please sign in to comment.