Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 38 additions & 4 deletions std/typecons.d
Original file line number Diff line number Diff line change
Expand Up @@ -1294,11 +1294,11 @@ if (distinctFieldNames!(Specs))
* Returns:
* The string representation of this `Tuple`.
*/
string toString()() const
string toString()()
{
import std.array : appender;
auto app = appender!string();
this.toString((const(char)[] chunk) => app ~= chunk);
toString((const(char)[] chunk) => app ~= chunk);
return app.data;
}

Expand All @@ -1320,14 +1320,14 @@ if (distinctFieldNames!(Specs))
* sink = A `char` accepting delegate
* fmt = A $(REF FormatSpec, std,format)
*/
void toString(DG)(scope DG sink) const
void toString(DG)(scope DG sink)
{
auto f = FormatSpec!char();
toString(sink, f);
}

/// ditto
void toString(DG, Char)(scope DG sink, scope const ref FormatSpec!Char fmt) const
void toString(DG, Char)(scope DG sink, scope const ref FormatSpec!Char fmt)
{
import std.format : format, FormatException;
import std.format.write : formattedWrite;
Expand Down Expand Up @@ -1822,6 +1822,40 @@ private template ReverseTupleSpecs(T...)
assert(t[0] == 10 && t[1] == "str");
assert(t.to!string == `Tuple!(int, string)(10, "str")`, t.to!string);
}
/* https://github.com/dlang/phobos/issues/9811
* Note: This is just documenting current behaviour, dependent on `std.format` implementation
* details. None of this is defined in a spec or should be regarded as rigid.
*/
{
static struct X
{
/** Usually, toString() should be const where possible.
* But as long as the tuple is also non-const, this will work
*/
string toString()
{
return "toString non-const";
}
}
assert(tuple(X()).to!string == "Tuple!(X)(toString non-const)");
const t = tuple(X());
// This is an implementation detail of `format`
// if the tuple is const, than non-const toString will not be called
assert(t.to!string == "const(Tuple!(X))(const(X)())");

static struct X2
{
string toString() const /* const toString will work in more cases */
{
return "toString const";
}
}
assert(tuple(X2()).to!string == "Tuple!(X2)(toString const)");
const t2 = tuple(X2());
// This is an implementation detail of `format`
// if the tuple is const, than non-const toString will not be called
assert(t2.to!string == "const(Tuple!(X2))(toString const)");
}
{
Tuple!(int, "a", double, "b") x;
static assert(x.a.offsetof == x[0].offsetof);
Expand Down
Loading