diff --git a/std/format.d b/std/format.d index 12a12f1f6..cfa724d06 100644 --- a/std/format.d +++ b/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. */ diff --git a/std/traits.d b/std/traits.d index 0bf952581..869781eda 100644 --- a/std/traits.d +++ b/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)); + } + } } }