Add struct formatting

This commit is contained in:
Eugen Wissner 2017-12-14 19:47:13 +01:00
parent 2a68048fc1
commit 3c996d7c57

View File

@ -323,9 +323,9 @@ private HP raise2Power10(const HP value, int power)
} }
/* /*
* Given a float value, returns the significant bits in bits, and the position * Given a float value, returns the significant bits, and the position of the
* of the decimal point in $(D_PARAM exponent). +/-Inf and NaN are specified * decimal point in $(D_PARAM exponent). +/-Inf and NaN are specified by
* by special values returned in the $(D_PARAM exponent). Sing bit is set in * special values returned in the $(D_PARAM exponent). Sing bit is set in
* $(D_PARAM sign). * $(D_PARAM sign).
*/ */
private const(char)[] real2String(double value, private const(char)[] real2String(double value,
@ -505,7 +505,7 @@ if (T.sizeof == U.sizeof)
copy((&src)[0 .. 1], (&dest)[0 .. 1]); copy((&src)[0 .. 1], (&dest)[0 .. 1]);
} }
private void formatReal(T)(ref T arg ,ref String result) private void formatReal(T)(ref T arg, ref String result)
if (isFloatingPoint!T) if (isFloatingPoint!T)
{ {
char[512] buffer; // Big enough for e+308 or e-307. char[512] buffer; // Big enough for e+308 or e-307.
@ -701,6 +701,34 @@ if (isFloatingPoint!T)
result.insertBack(tail[1 .. tail[0] + 1]); // Tail. result.insertBack(tail[1 .. tail[0] + 1]); // Tail.
} }
private void formatStruct(T)(ref T arg, ref String result)
if (is(T == struct))
{
template pred(alias f)
{
static if (f == "this")
{
// Exclude context pointer from nested structs.
enum bool pred = false;
}
else
{
enum bool pred = !isSomeFunction!(__traits(getMember, arg, f));
}
}
alias fields = Filter!(pred, __traits(allMembers, T));
static if (fields.length > 0)
{
printToString!"{}"(result, __traits(getMember, arg, fields[0]));
foreach (field; fields[1 .. $])
{
result.insertBack(", ");
printToString!"{}"(result, __traits(getMember, arg, field));
}
}
}
private ref String printToString(string fmt, Args...)(return ref String result, private ref String printToString(string fmt, Args...)(return ref String result,
auto ref Args args) auto ref Args args)
{ {
@ -716,17 +744,20 @@ private ref String printToString(string fmt, Args...)(return ref String result,
{ {
result.insertBack(args[0].stringify()[]); result.insertBack(args[0].stringify()[]);
} }
else static if (isClass!(Args[0])) else static if (is(Args[0] == class))
{ {
result.insertBack(args[0].toString()); result.insertBack(args[0].toString());
} }
else static if (isInterface!(Args[0])) else static if (is(Args[0] == interface))
{ {
result.insertBack(Args[0].classinfo.name); result.insertBack(Args[0].classinfo.name);
} }
else static if (isStruct!(Args[0])) else static if (is(Args[0] == struct))
{ {
result.insertBack(typeid(Args[0]).name); result.insertBack(Args[0].stringof);
result.insertBack('(');
formatStruct(args[0], result);
result.insertBack(')');
} }
else static if (isSomeString!(Args[0])) // String else static if (isSomeString!(Args[0])) // String
{ {
@ -850,16 +881,39 @@ package(tanya) String format(string fmt, Args...)(auto ref Args args)
assert(format!"{}"(cast(void*) null) == "0x0"); assert(format!"{}"(cast(void*) null) == "0x0");
} }
// Aggregate types. // Structs.
@system unittest // Object.toString has no attributes. @nogc pure @safe unittest
{ {
import tanya.memory; static struct WithoutStringify1
import tanya.memory.smartref; {
int a;
static struct WithoutStringify void func()
{ {
} }
assert(format!"{}"(WithoutStringify()) == typeid(WithoutStringify).name); }
assert(format!"{}"(WithoutStringify1(6)) == "WithoutStringify1(6)");
static struct WithoutStringify2
{
}
assert(format!"{}"(WithoutStringify2()) == "WithoutStringify2()");
static struct WithoutStringify3
{
int a = -2;
int b = 8;
}
assert(format!"{}"(WithoutStringify3()) == "WithoutStringify3(-2, 8)");
struct Nested
{
int i;
void func()
{
}
}
assert(format!"{}"(Nested()) == "Nested(0)");
static struct WithStringify static struct WithStringify
{ {
@ -869,6 +923,13 @@ package(tanya) String format(string fmt, Args...)(auto ref Args args)
} }
} }
assert(format!"{}"(WithStringify()) == "stringify method"); assert(format!"{}"(WithStringify()) == "stringify method");
}
// Aggregate types.
@system unittest // Object.toString has no attributes.
{
import tanya.memory;
import tanya.memory.smartref;
interface I interface I
{ {