Refactor std/format/internal/write.d: Spaces and line breaks

This commit is contained in:
berni44 2021-02-25 10:44:03 +01:00 committed by The Dlang Bot
parent b764e63375
commit ec96dc96e0

View file

@ -42,19 +42,41 @@ if (is(BooleanTypeOf!T) && !is(T == enum) && !hasToString!(T, Char))
formatTest(true, "true"); formatTest(true, "true");
}); });
} }
@system unittest @system unittest
{ {
class C1 { bool val; alias val this; this(bool v){ val = v; } } class C1
class C2 { bool val; alias val this; this(bool v){ val = v; } {
override string toString() const { return "C"; } } bool val;
alias val this;
this(bool v){ val = v; }
}
class C2 {
bool val;
alias val this;
this(bool v){ val = v; }
override string toString() const { return "C"; }
}
formatTest(new C1(false), "false"); formatTest(new C1(false), "false");
formatTest(new C1(true), "true"); formatTest(new C1(true), "true");
formatTest(new C2(false), "C"); formatTest(new C2(false), "C");
formatTest(new C2(true), "C"); formatTest(new C2(true), "C");
struct S1 { bool val; alias val this; } struct S1
struct S2 { bool val; alias val this; {
string toString() const { return "S"; } } bool val;
alias val this;
}
struct S2
{
bool val;
alias val this;
string toString() const { return "S"; }
}
formatTest(S1(false), "false"); formatTest(S1(false), "false");
formatTest(S1(true), "true"); formatTest(S1(true), "true");
formatTest(S2(false), "S"); formatTest(S2(false), "S");
@ -77,8 +99,7 @@ package(std.format) void formatValueImpl(Writer, T, Char)(auto ref Writer w, T o
if (is(immutable T == immutable typeof(null)) && !is(T == enum) && !hasToString!(T, Char)) if (is(immutable T == immutable typeof(null)) && !is(T == enum) && !hasToString!(T, Char))
{ {
const spec = f.spec; const spec = f.spec;
enforceFmt(spec == 's', enforceFmt(spec == 's', "null literal cannot match %" ~ spec);
"null literal cannot match %" ~ spec);
writeAligned(w, "null", f); writeAligned(w, "null", f);
} }
@ -115,6 +136,7 @@ if (is(IntegralTypeOf!T) && !is(T == enum) && !hasToString!(T, Char))
auto raw = (ref val) @trusted { auto raw = (ref val) @trusted {
return (cast(const char*) &val)[0 .. val.sizeof]; return (cast(const char*) &val)[0 .. val.sizeof];
}(val); }(val);
if (needToSwapEndianess(f)) if (needToSwapEndianess(f))
{ {
foreach_reverse (c; raw) foreach_reverse (c; raw)
@ -244,8 +266,9 @@ private void formatUnsigned(Writer, T, Char)
if (finalWidth < fs.width) if (finalWidth < fs.width)
finalWidth = fs.width + (padChar == '0') * (((fs.width - prefixWidth) % (fs.separators + 1) == 0) ? 1 : 0); finalWidth = fs.width + (padChar == '0') * (((fs.width - prefixWidth) % (fs.separators + 1) == 0) ? 1 : 0);
separatorsCount = (padChar == '0') ? (finalWidth - prefixWidth - 1) / (fs.separators + 1) : separatorsCount = (padChar == '0')
((digits.length > 0) ? (digits.length - 1) / fs.separators : 0); ? (finalWidth - prefixWidth - 1) / (fs.separators + 1)
: ((digits.length > 0) ? (digits.length - 1) / fs.separators : 0);
} }
else else
{ {
@ -340,15 +363,37 @@ private void formatUnsigned(Writer, T, Char)
@system unittest @system unittest
{ {
class C1 { long val; alias val this; this(long v){ val = v; } } class C1
class C2 { long val; alias val this; this(long v){ val = v; } {
override string toString() const { return "C"; } } long val;
alias val this;
this(long v){ val = v; }
}
class C2
{
long val;
alias val this;
this(long v){ val = v; }
override string toString() const { return "C"; }
}
formatTest(new C1(10), "10"); formatTest(new C1(10), "10");
formatTest(new C2(10), "C"); formatTest(new C2(10), "C");
struct S1 { long val; alias val this; } struct S1
struct S2 { long val; alias val this; {
string toString() const { return "S"; } } long val;
alias val this;
}
struct S2
{
long val;
alias val this;
string toString() const { return "S"; }
}
formatTest(S1(10), "10"); formatTest(S1(10), "10");
formatTest(S2(10), "S"); formatTest(S2(10), "S");
} }
@ -482,6 +527,7 @@ if (is(FloatingPointTypeOf!T) && !is(T == enum) && !hasToString!(T, Char))
auto raw = (ref val) @trusted { auto raw = (ref val) @trusted {
return (cast(const char*) &val)[0 .. val.sizeof]; return (cast(const char*) &val)[0 .. val.sizeof];
}(val); }(val);
if (needToSwapEndianess(f)) if (needToSwapEndianess(f))
{ {
foreach_reverse (c; raw) foreach_reverse (c; raw)
@ -494,6 +540,7 @@ if (is(FloatingPointTypeOf!T) && !is(T == enum) && !hasToString!(T, Char))
} }
return; return;
} }
enforceFmt(find("fgFGaAeEs", spec).length, enforceFmt(find("fgFGaAeEs", spec).length,
"incompatible format character for floating point argument: %" ~ spec); "incompatible format character for floating point argument: %" ~ spec);
@ -604,8 +651,7 @@ useSnprintf:
tval); tval);
}(); }();
enforceFmt(n >= 0, enforceFmt(n >= 0, "floating point formatting failure");
"floating point formatting failure");
len = min(n, buf2.length-1); len = min(n, buf2.length-1);
buf = buf2; buf = buf2;
@ -722,15 +768,36 @@ useSnprintf:
{ {
formatTest(2.25, "2.25"); formatTest(2.25, "2.25");
class C1 { double val; alias val this; this(double v){ val = v; } } class C1
class C2 { double val; alias val this; this(double v){ val = v; } {
override string toString() const { return "C"; } } double val;
alias val this;
this(double v){ val = v; }
}
class C2
{
double val;
alias val this;
this(double v){ val = v; }
override string toString() const { return "C"; }
}
formatTest(new C1(2.25), "2.25"); formatTest(new C1(2.25), "2.25");
formatTest(new C2(2.25), "C"); formatTest(new C2(2.25), "C");
struct S1 { double val; alias val this; } struct S1
struct S2 { double val; alias val this; {
string toString() const { return "S"; } } double val;
alias val this;
}
struct S2
{
double val;
alias val this;
string toString() const { return "S"; }
}
formatTest(S1(2.25), "2.25"); formatTest(S1(2.25), "2.25");
formatTest(S2(2.25), "S"); formatTest(S2(2.25), "S");
} }
@ -979,15 +1046,37 @@ if (is(CharTypeOf!T) && !is(T == enum) && !hasToString!(T, Char))
@system unittest @system unittest
{ {
class C1 { char val; alias val this; this(char v){ val = v; } } class C1
class C2 { char val; alias val this; this(char v){ val = v; } {
override string toString() const { return "C"; } } char val;
alias val this;
this(char v){ val = v; }
}
class C2
{
char val;
alias val this;
this(char v){ val = v; }
override string toString() const { return "C"; }
}
formatTest(new C1('c'), "c"); formatTest(new C1('c'), "c");
formatTest(new C2('c'), "C"); formatTest(new C2('c'), "C");
struct S1 { char val; alias val this; } struct S1
struct S2 { char val; alias val this; {
string toString() const { return "S"; } } char val;
alias val this;
}
struct S2
{
char val;
alias val this;
string toString() const { return "S"; }
}
formatTest(S1('c'), "c"); formatTest(S1('c'), "c");
formatTest(S2('c'), "S"); formatTest(S2('c'), "S");
} }
@ -1035,26 +1124,58 @@ if (is(StringTypeOf!T) && !is(StaticArrayTypeOf!T) && !is(T == enum) && !hasToSt
@system unittest @system unittest
{ {
// Test for bug 5371 for classes // Test for bug 5371 for classes
class C1 { const string var; alias var this; this(string s){ var = s; } } class C1
class C2 { string var; alias var this; this(string s){ var = s; } } {
const string var;
alias var this;
this(string s){ var = s; }
}
class C2
{
string var;
alias var this;
this(string s){ var = s; }
}
formatTest(new C1("c1"), "c1"); formatTest(new C1("c1"), "c1");
formatTest(new C2("c2"), "c2"); formatTest(new C2("c2"), "c2");
// Test for bug 5371 for structs // Test for bug 5371 for structs
struct S1 { const string var; alias var this; } struct S1
struct S2 { string var; alias var this; } {
const string var;
alias var this;
}
struct S2
{
string var;
alias var this;
}
formatTest(S1("s1"), "s1"); formatTest(S1("s1"), "s1");
formatTest(S2("s2"), "s2"); formatTest(S2("s2"), "s2");
} }
@system unittest @system unittest
{ {
class C3 { string val; alias val this; this(string s){ val = s; } class C3
override string toString() const { return "C"; } } {
string val;
alias val this;
this(string s){ val = s; }
override string toString() const { return "C"; }
}
formatTest(new C3("c3"), "C"); formatTest(new C3("c3"), "C");
struct S3 { string val; alias val this; struct S3
string toString() const { return "S"; } } {
string val; alias val this;
string toString() const { return "S"; }
}
formatTest(S3("s3"), "S"); formatTest(S3("s3"), "S");
} }
@ -1164,6 +1285,7 @@ if (is(DynamicArrayTypeOf!T) && !is(StringTypeOf!T) && !is(T == enum) && !hasToS
static if (flags & 4) static if (flags & 4)
string toString() const { return "S"; } string toString() const { return "S"; }
} }
formatTest(S!0b000([0, 1, 2]), "S!0([0, 1, 2])"); formatTest(S!0b000([0, 1, 2]), "S!0([0, 1, 2])");
formatTest(S!0b001([0, 1, 2]), "[0, 1, 2]"); // Test for bug 7628 formatTest(S!0b001([0, 1, 2]), "[0, 1, 2]"); // Test for bug 7628
formatTest(S!0b010([0, 1, 2]), "[0, 2, 4]"); formatTest(S!0b010([0, 1, 2]), "[0, 2, 4]");
@ -1191,6 +1313,7 @@ if (is(DynamicArrayTypeOf!T) && !is(StringTypeOf!T) && !is(T == enum) && !hasToS
static if (flags & 4) static if (flags & 4)
override string toString() const { return "C"; } override string toString() const { return "C"; }
} }
formatTest(new C!0b000([0, 1, 2]), (new C!0b000([])).toString()); formatTest(new C!0b000([0, 1, 2]), (new C!0b000([])).toString());
formatTest(new C!0b001([0, 1, 2]), "[0, 1, 2]"); // Test for bug 7628 formatTest(new C!0b001([0, 1, 2]), "[0, 1, 2]"); // Test for bug 7628
formatTest(new C!0b010([0, 1, 2]), "[0, 2, 4]"); formatTest(new C!0b010([0, 1, 2]), "[0, 2, 4]");
@ -1223,7 +1346,12 @@ if (is(DynamicArrayTypeOf!T) && !is(StringTypeOf!T) && !is(T == enum) && !hasToS
const short[] a = [1, 2, 3]; const short[] a = [1, 2, 3];
formatTest(a, "[1, 2, 3]"); formatTest(a, "[1, 2, 3]");
struct S { const(int[]) arr; alias arr this; } struct S
{
const(int[]) arr;
alias arr this;
}
auto s = S([1,2,3]); auto s = S([1,2,3]);
formatTest(s, "[1, 2, 3]"); formatTest(s, "[1, 2, 3]");
} }
@ -1234,6 +1362,7 @@ if (is(DynamicArrayTypeOf!T) && !is(StringTypeOf!T) && !is(T == enum) && !hasToS
struct Range struct Range
{ {
@safe: @safe:
string value; string value;
@property bool empty() const { return !value.length; } @property bool empty() const { return !value.length; }
@property dchar front() const { return value.front; } @property dchar front() const { return value.front; }
@ -1673,15 +1802,37 @@ if (is(AssocArrayTypeOf!T) && !is(T == enum) && !hasToString!(T, Char))
@system unittest @system unittest
{ {
class C1 { int[char] val; alias val this; this(int[char] v){ val = v; } } class C1
class C2 { int[char] val; alias val this; this(int[char] v){ val = v; } {
override string toString() const { return "C"; } } int[char] val;
alias val this;
this(int[char] v){ val = v; }
}
class C2
{
int[char] val;
alias val this;
this(int[char] v){ val = v; }
override string toString() const { return "C"; }
}
formatTest(new C1(['c':1, 'd':2]), [`['c':1, 'd':2]`, `['d':2, 'c':1]`]); formatTest(new C1(['c':1, 'd':2]), [`['c':1, 'd':2]`, `['d':2, 'c':1]`]);
formatTest(new C2(['c':1, 'd':2]), "C"); formatTest(new C2(['c':1, 'd':2]), "C");
struct S1 { int[char] val; alias val this; } struct S1
struct S2 { int[char] val; alias val this; {
string toString() const { return "S"; } } int[char] val;
alias val this;
}
struct S2
{
int[char] val;
alias val this;
string toString() const { return "S"; }
}
formatTest(S1(['c':1, 'd':2]), [`['c':1, 'd':2]`, `['d':2, 'c':1]`]); formatTest(S1(['c':1, 'd':2]), [`['c':1, 'd':2]`, `['d':2, 'c':1]`]);
formatTest(S2(['c':1, 'd':2]), "S"); formatTest(S2(['c':1, 'd':2]), "S");
} }
@ -1716,26 +1867,28 @@ package(std.format) template hasToString(T, Char)
enum hasToString = HasToStringResult.none; enum hasToString = HasToStringResult.none;
} }
else static if (is(typeof( else static if (is(typeof(
{T val = void; {
T val = void;
const FormatSpec!Char f; const FormatSpec!Char f;
static struct S {void put(scope Char s){}} static struct S {void put(scope Char s){}}
S s; S s;
val.toString(s, f); val.toString(s, f);
// force toString to take parameters by ref // force toString to take parameters by ref
static assert(!__traits(compiles, val.toString(s, FormatSpec!Char()))); static assert(!__traits(compiles, val.toString(s, FormatSpec!Char())));
static assert(!__traits(compiles, val.toString(S(), f)));} static assert(!__traits(compiles, val.toString(S(), f)));
))) })))
{ {
enum hasToString = HasToStringResult.customPutWriterFormatSpec; enum hasToString = HasToStringResult.customPutWriterFormatSpec;
} }
else static if (is(typeof( else static if (is(typeof(
{T val = void; {
T val = void;
static struct S {void put(scope Char s){}} static struct S {void put(scope Char s){}}
S s; S s;
val.toString(s); val.toString(s);
// force toString to take parameters by ref // force toString to take parameters by ref
static assert(!__traits(compiles, val.toString(S())));} static assert(!__traits(compiles, val.toString(S())));
))) })))
{ {
enum hasToString = HasToStringResult.customPutWriter; enum hasToString = HasToStringResult.customPutWriter;
} }
@ -2001,6 +2154,7 @@ if (is(T == class) && !is(T == enum))
{ {
import std.array : appender; import std.array : appender;
import std.range.interfaces; import std.range.interfaces;
// class range (https://issues.dlang.org/show_bug.cgi?id=5154) // class range (https://issues.dlang.org/show_bug.cgi?id=5154)
auto c = inputRangeObject([1,2,3,4]); auto c = inputRangeObject([1,2,3,4]);
formatTest(c, "[1, 2, 3, 4]"); formatTest(c, "[1, 2, 3, 4]");
@ -2637,8 +2791,7 @@ if (isDelegate!T)
"testing (1) (3) (2) wyda3"); "testing (1) (3) (2) wyda3");
int[0] empt = []; int[0] empt = [];
formatTest( "(%s)", empt, formatTest("(%s)", empt, "([])");
"([])" );
} }
// Fix for https://issues.dlang.org/show_bug.cgi?id=1591 // Fix for https://issues.dlang.org/show_bug.cgi?id=1591
@ -2668,8 +2821,7 @@ package(std.format) T getNth(string kind, alias Condition, T, A...)(uint index,
} }
} }
default: default:
throw new FormatException( throw new FormatException(text("Missing ", kind, " argument"));
text("Missing ", kind, " argument"));
} }
} }
@ -2744,4 +2896,3 @@ if (isSomeString!T)
writeAligned(w, "a本Ä", spec); writeAligned(w, "a本Ä", spec);
assert(w.data == "a本Ä ", w.data); assert(w.data == "a本Ä ", w.data);
} }