mirror of
https://github.com/dlang/phobos.git
synced 2025-05-12 23:29:01 +03:00
Issue 5371 - ambiguous stringnize of class with alias this
By fixing bug 2777, we can implement StringTypeOf more properly.
This commit is contained in:
parent
740f3ec78a
commit
e34a7debfd
2 changed files with 43 additions and 72 deletions
39
std/format.d
39
std/format.d
|
@ -1261,10 +1261,11 @@ if (isSomeChar!T)
|
|||
void formatValue(Writer, T, Char)(Writer w, T val, ref FormatSpec!Char f)
|
||||
if (isSomeString!T && !isStaticArray!T && !is(T == enum))
|
||||
{
|
||||
Unqual!(StringTypeOf!T) str = val; // for `alias this`, see bug5371
|
||||
|
||||
if (f.spec == 's')
|
||||
{
|
||||
StringTypeOf!T val2 = val; // for `alias this`
|
||||
auto s = val2[0 .. f.precision < $ ? f.precision : $];
|
||||
auto s = str[0 .. f.precision < $ ? f.precision : $];
|
||||
if (!f.flDash)
|
||||
{
|
||||
// right align
|
||||
|
@ -1282,17 +1283,17 @@ if (isSomeString!T && !isStaticArray!T && !is(T == enum))
|
|||
}
|
||||
else
|
||||
{
|
||||
static if (is(typeof(val[0]) : const(char)))
|
||||
static if (is(typeof(str[0]) : const(char)))
|
||||
{
|
||||
formatRange(w, val, f);
|
||||
formatRange(w, str, f);
|
||||
}
|
||||
else static if (is(typeof(val[0]) : const(wchar)))
|
||||
else static if (is(typeof(str[0]) : const(wchar)))
|
||||
{
|
||||
formatRange(w, val, f);
|
||||
formatRange(w, str, f);
|
||||
}
|
||||
else static if (is(typeof(val[0]) : const(dchar)))
|
||||
else static if (is(typeof(str[0]) : const(dchar)))
|
||||
{
|
||||
formatRange(w, val, f);
|
||||
formatRange(w, str, f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1306,6 +1307,28 @@ unittest
|
|||
assert(w.data == "abc");
|
||||
}
|
||||
|
||||
unittest
|
||||
{
|
||||
// 5371
|
||||
class C1
|
||||
{
|
||||
const(string) var = "C1";
|
||||
alias var this;
|
||||
}
|
||||
class C2
|
||||
{
|
||||
string var = "C2";
|
||||
alias var this;
|
||||
}
|
||||
auto c1 = new C1();
|
||||
auto c2 = new C2();
|
||||
|
||||
FormatSpec!char f;
|
||||
auto a = appender!string();
|
||||
formatValue(a, c1, f);
|
||||
formatValue(a, c2, f);
|
||||
}
|
||||
|
||||
/**
|
||||
Input ranges are formatted like arrays.
|
||||
*/
|
||||
|
|
76
std/traits.d
76
std/traits.d
|
@ -3196,75 +3196,23 @@ version (unittest) private template Intify(T) { alias int Intify; }
|
|||
*/
|
||||
template StringTypeOf(T) if (isSomeString!T)
|
||||
{
|
||||
static if (is(T == class) || is(T == struct))
|
||||
{
|
||||
static if (is(T : const(char[])))
|
||||
{
|
||||
static if (is(T : char[]))
|
||||
alias char[] StringTypeOf;
|
||||
else static if (is(T : immutable(char[])))
|
||||
alias immutable(char)[] StringTypeOf;
|
||||
else
|
||||
alias const(char)[] StringTypeOf;
|
||||
}
|
||||
else static if (is(T : const(wchar[])))
|
||||
{
|
||||
static if (is(T : wchar[]))
|
||||
alias wchar[] StringTypeOf;
|
||||
else static if (is(T : immutable(wchar[])))
|
||||
alias immutable(wchar)[] StringTypeOf;
|
||||
else
|
||||
alias const(wchar)[] StringTypeOf;
|
||||
}
|
||||
else
|
||||
{
|
||||
static if (is(T : dchar[]))
|
||||
alias dchar[] StringTypeOf;
|
||||
else static if (is(T : immutable(dchar[])))
|
||||
alias immutable(dchar)[] StringTypeOf;
|
||||
else
|
||||
alias const(dchar)[] StringTypeOf;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
alias T StringTypeOf;
|
||||
}
|
||||
alias typeof(T.init[]) StringTypeOf;
|
||||
}
|
||||
unittest
|
||||
{
|
||||
class C(Char, int n)
|
||||
foreach (Ch; TypeTuple!(char, wchar, dchar))
|
||||
{
|
||||
static if (n==0) Char[] val;
|
||||
static if (n==1) const(Char)[] val;
|
||||
static if (n==2) const(Char[]) val;
|
||||
static if (n==3) immutable(Char)[] val;
|
||||
static if (n==4) immutable(Char[]) val;
|
||||
alias val this;
|
||||
}
|
||||
struct S(Char, int n)
|
||||
{
|
||||
static if (n==0) Char[] val;
|
||||
static if (n==1) const(Char)[] val;
|
||||
static if (n==2) const(Char[]) val;
|
||||
static if (n==3) immutable(Char)[] val;
|
||||
static if (n==4) immutable(Char[]) val;
|
||||
alias val this;
|
||||
}
|
||||
foreach (Char; TypeTuple!(char, wchar, dchar))
|
||||
{
|
||||
static assert(is(StringTypeOf!(C!(Char, 0)) == Char[]));
|
||||
static assert(is(StringTypeOf!(C!(Char, 1)) == const(Char)[]));
|
||||
static assert(is(StringTypeOf!(C!(Char, 2)) == const(Char)[])); // cannot get exact string type
|
||||
static assert(is(StringTypeOf!(C!(Char, 3)) == immutable(Char)[]));
|
||||
static assert(is(StringTypeOf!(C!(Char, 4)) == immutable(Char)[])); // cannot get exact string type
|
||||
foreach (Char; TypeTuple!(Ch, const(Ch), immutable(Ch)))
|
||||
{
|
||||
foreach (Str; TypeTuple!(Char[], const(Char[]), immutable(Char[])))
|
||||
{
|
||||
class C(Str) { Str val; alias val this; }
|
||||
struct S(Str) { Str val; alias val this; }
|
||||
|
||||
|
||||
static assert(is(StringTypeOf!(S!(Char, 0)) == Char[]));
|
||||
static assert(is(StringTypeOf!(S!(Char, 1)) == const(Char)[]));
|
||||
static assert(is(StringTypeOf!(S!(Char, 2)) == const(Char)[])); // cannot get exact string type
|
||||
static assert(is(StringTypeOf!(S!(Char, 3)) == immutable(Char)[]));
|
||||
static assert(is(StringTypeOf!(S!(Char, 4)) == immutable(Char)[])); // cannot get exact string type
|
||||
static assert(is(StringTypeOf!(C!Str) == Str));
|
||||
static assert(is(StringTypeOf!(S!Str) == Str));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue