diff options
| -rw-r--r-- | source/tanya/format/package.d | 355 |
1 files changed, 179 insertions, 176 deletions
diff --git a/source/tanya/format/package.d b/source/tanya/format/package.d index 2c19ada..322f031 100644 --- a/source/tanya/format/package.d +++ b/source/tanya/format/package.d @@ -505,101 +505,120 @@ if (T.sizeof == U.sizeof) copy((&src)[0 .. 1], (&dest)[0 .. 1]); } -private ref String printToString(string fmt, Args...)(return ref String result, - auto ref Args args) +private void formatReal(T)(ref T arg ,ref String result) +if (isFloatingPoint!T) { - static if (is(Unqual!(Args[0]) == typeof(null))) + char[512] buffer; // Big enough for e+308 or e-307. + char[8] tail = 0; + char[] bufferSlice = buffer[64 .. $]; + uint precision = 6; + bool negative; + int decimalPoint; + + // Read the double into a string. + auto realString = real2String(arg, buffer, decimalPoint, negative); + auto length = cast(uint) realString.length; + + // Clamp the precision and delete extra zeros after clamp. + uint n = precision; + if (length > precision) { - result.insertBack("null"); + length = precision; } - else static if(is(Unqual!(Args[0]) == bool)) + while ((length > 1) && (precision != 0) && (realString[length - 1] == '0')) { - result.insertBack(args[0] ? "true" : "false"); + --precision; + --length; } - else static if (is(Unqual!(typeof(args[0].stringify())) == String)) - { - result.insertBack(args[0].stringify()[]); - } - else static if (isClass!(Args[0])) + + if (negative) { - result.insertBack(args[0].toString()); + result.insertBack('-'); } - else static if (isInterface!(Args[0])) + if (decimalPoint == special) { - result.insertBack(Args[0].classinfo.name); + result.insertBack(realString); + return; } - else static if (isStruct!(Args[0])) - { - result.insertBack(typeid(Args[0]).name); - } - else static if (isSomeString!(Args[0])) // String + + // Should we use sceintific notation? + if ((decimalPoint <= -4) || (decimalPoint > cast(int) n)) { - if (args[0] is null) + if (precision > length) { - result.insertBack("null"); + precision = length - 1; } - else + else if (precision > 0) { - result.insertBack(args[0]); + // When using scientific notation, there is one digit before the + // decimal. + --precision; } - } - else static if (isSomeChar!(Args[0])) // Char - { - result.insertBack(args[0]); - } - else static if (isFloatingPoint!(Args[0])) // Float - { - char[512] buffer; // Big enough for e+308 or e-307. - char[8] tail = 0; - char[] bufferSlice = buffer[64 .. $]; - uint precision = 6; - bool negative; - int decimalPoint; - // Read the double into a string. - auto realString = real2String(args[0], buffer, decimalPoint, negative); - auto length = cast(uint) realString.length; + // Handle leading chars. + bufferSlice.front = realString[0]; + bufferSlice.popFront(); - // Clamp the precision and delete extra zeros after clamp. - uint n = precision; - if (length > precision) + if (precision != 0) { - length = precision; + bufferSlice.front = period; + bufferSlice.popFront(); } - while ((length > 1) - && (precision != 0) - && (realString[length - 1] == '0')) + + // Handle after decimal. + if ((length - 1) > precision) { - --precision; - --length; + length = precision + 1; } + realString[1 .. length].copy(bufferSlice); + bufferSlice.popFrontExactly(length - 1); - if (negative) + // Dump the exponent. + tail[1] = 'e'; + --decimalPoint; + if (decimalPoint < 0) { - result.insertBack('-'); + tail[2] = '-'; + decimalPoint = -decimalPoint; } - if (decimalPoint == special) + else { - result.insertBack(realString); - goto ParamEnd; + tail[2] = '+'; } - // Should we use sceintific notation? - if ((decimalPoint <= -4) || (decimalPoint > cast(int) n)) + n = decimalPoint >= 100 ? 5 : 4; + + tail[0] = cast(char) n; + while (true) { - if (precision > length) - { - precision = length - 1; - } - else if (precision > 0) + tail[n] = '0' + decimalPoint % 10; + if (n <= 3) { - // When using scientific notation, there is one digit before the - // decimal. - --precision; + break; } + --n; + decimalPoint /= 10; + } + } + else + { + if (decimalPoint > 0) + { + precision = decimalPoint < (cast(int) length) + ? length - decimalPoint + : 0; + } + else + { + precision = -decimalPoint + + (precision > length ? length : precision); + } - // Handle leading chars. - bufferSlice.front = realString[0]; + // Handle the three decimal varieties. + if (decimalPoint <= 0) + { + // Handle 0.000*000xxxx. + bufferSlice.front = '0'; bufferSlice.popFront(); if (precision != 0) @@ -607,141 +626,126 @@ private ref String printToString(string fmt, Args...)(return ref String result, bufferSlice.front = period; bufferSlice.popFront(); } - - // Handle after decimal. - if ((length - 1) > precision) + n = -decimalPoint; + if (n > precision) { - length = precision + 1; + n = precision; } - realString[1 .. length].copy(bufferSlice); - bufferSlice.popFrontExactly(length - 1); - // Dump the exponent. - tail[1] = 'e'; - --decimalPoint; - if (decimalPoint < 0) + fill!'0'(bufferSlice[0 .. n]); + bufferSlice.popFrontExactly(n); + + if ((length + n) > precision) { - tail[2] = '-'; - decimalPoint = -decimalPoint; + length = precision - n; } - else + + realString[0 .. length].copy(bufferSlice); + bufferSlice.popFrontExactly(length); + } + else if (cast(uint) decimalPoint >= length) + { + // Handle xxxx000*000.0. + n = 0; + do { - tail[2] = '+'; + bufferSlice.front = realString[n]; + bufferSlice.popFront(); + ++n; } + while (n < length); + if (n < cast(uint) decimalPoint) + { + n = decimalPoint - n; - n = decimalPoint >= 100 ? 5 : 4; - - tail[0] = cast(char) n; - while (true) + fill!'0'(bufferSlice[0 .. n]); + bufferSlice.popFrontExactly(n); + } + if (precision != 0) { - tail[n] = '0' + decimalPoint % 10; - if (n <= 3) - { - break; - } - --n; - decimalPoint /= 10; + bufferSlice.front = period; + bufferSlice.popFront(); } } else { - if (decimalPoint > 0) - { - precision = decimalPoint < (cast(int) length) - ? length - decimalPoint - : 0; - } - else + // Handle xxxxx.xxxx000*000. + n = 0; + do { - precision = -decimalPoint - + (precision > length ? length : precision); + bufferSlice.front = realString[n]; + bufferSlice.popFront(); + ++n; } + while (n < cast(uint) decimalPoint); - // Handle the three decimal varieties. - if (decimalPoint <= 0) + if (precision > 0) { - // Handle 0.000*000xxxx. - bufferSlice.front = '0'; + bufferSlice.front = period; bufferSlice.popFront(); - - if (precision != 0) - { - bufferSlice.front = period; - bufferSlice.popFront(); - } - n = -decimalPoint; - if (n > precision) - { - n = precision; - } - - fill!'0'(bufferSlice[0 .. n]); - bufferSlice.popFrontExactly(n); - - if ((length + n) > precision) - { - length = precision - n; - } - - realString[0 .. length].copy(bufferSlice); - bufferSlice.popFrontExactly(length); } - else if (cast(uint) decimalPoint >= length) + if ((length - decimalPoint) > precision) { - // Handle xxxx000*000.0. - n = 0; - do - { - bufferSlice.front = realString[n]; - bufferSlice.popFront(); - ++n; - } - while (n < length); - if (n < cast(uint) decimalPoint) - { - n = decimalPoint - n; - - fill!'0'(bufferSlice[0 .. n]); - bufferSlice.popFrontExactly(n); - } - if (precision != 0) - { - bufferSlice.front = period; - bufferSlice.popFront(); - } + length = precision + decimalPoint; } - else - { - // Handle xxxxx.xxxx000*000. - n = 0; - do - { - bufferSlice.front = realString[n]; - bufferSlice.popFront(); - ++n; - } - while (n < cast(uint) decimalPoint); - if (precision > 0) - { - bufferSlice.front = period; - bufferSlice.popFront(); - } - if ((length - decimalPoint) > precision) - { - length = precision + decimalPoint; - } - - realString[n .. length].copy(bufferSlice); - bufferSlice.popFrontExactly(length - n); - } + realString[n .. length].copy(bufferSlice); + bufferSlice.popFrontExactly(length - n); } + } - // Get the length that we've copied. - length = cast(uint) (buffer.length - bufferSlice.length); + // Get the length that we've copied. + length = cast(uint) (buffer.length - bufferSlice.length); - result.insertBack(buffer[64 .. length]); // Number. - result.insertBack(tail[1 .. tail[0] + 1]); // Tail. + result.insertBack(buffer[64 .. length]); // Number. + result.insertBack(tail[1 .. tail[0] + 1]); // Tail. +} + +private ref String printToString(string fmt, Args...)(return ref String result, + auto ref Args args) +{ + static if (is(Unqual!(Args[0]) == typeof(null))) + { + result.insertBack("null"); + } + else static if(is(Unqual!(Args[0]) == bool)) + { + result.insertBack(args[0] ? "true" : "false"); + } + else static if (is(Unqual!(typeof(args[0].stringify())) == String)) + { + result.insertBack(args[0].stringify()[]); + } + else static if (isClass!(Args[0])) + { + result.insertBack(args[0].toString()); + } + else static if (isInterface!(Args[0])) + { + result.insertBack(Args[0].classinfo.name); + } + else static if (isStruct!(Args[0])) + { + result.insertBack(typeid(Args[0]).name); + } + else static if (isSomeString!(Args[0])) // String + { + if (args[0] is null) + { + result.insertBack("null"); + } + else + { + result.insertBack(args[0]); + } + } + else static if (isSomeChar!(Args[0])) // Char + { + result.insertBack(args[0]); + } + else static if (isFloatingPoint!(Args[0])) // Float + { + formatReal(args[0], result); } else static if (isPointer!(Args[0])) // Pointer { @@ -768,7 +772,6 @@ private ref String printToString(string fmt, Args...)(return ref String result, { result.insertBack(Args[0].stringof); } -ParamEnd: return result; } |
