mirror of
https://github.com/dlang/phobos.git
synced 2025-05-14 17:05:58 +03:00
Refactor std/format/internal/write.d: Spaces and line breaks
This commit is contained in:
parent
b764e63375
commit
ec96dc96e0
1 changed files with 406 additions and 255 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue