-
-
Notifications
You must be signed in to change notification settings - Fork 741
Cleanup and improve std.format #298
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Make reflective formattings CTFEable. Thanks for Don's fixing dmd! |
OK, now we can test this pull without any compiler fixes. |
I'm not very fond of "%|", it adds complication. But I guess there's no way without it or something like it. The problem is there's no way to specify a terminator, for example you can't format the array [1, 2, 3] as "1;2;3;" and the empty array as "". If you force adding a terminator after the format specifier a la |
You can use |
Looks like this has bit rotten a little.. merge conflicts. What's left to get this pull committed? It's been open a good while. |
Updated. |
Now fails due to some delegate related issues, likely due to recent changes.. |
I've already posted #593 for more escape check. |
formatValue and unformatValue use same order with template specialization.
… class & struct cases
@@ -572,25 +591,25 @@ struct FormatSpec(Char) | |||
This string is inserted before each sequence (e.g. array) | |||
formatted (by default $(D "[")). | |||
*/ | |||
static const(Char)[] seqBefore = "["; | |||
enum const(Char)[] seqBefore = "["; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why aren't these enums immutable
? const
buys us nothing here as far as I can tell. e.g.
enum immutable Char[] seqAfter = "]";
Shouldn't all of these variables that you just changed from static to enum be changed to be immutable
like that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The thing I had thought is "Change formatting with global state is less useful. They should be only default values for sequence formating". So I had converted them to manifest constant simply.
Therefore, I can agree to change const to immutable. But
enum immutable Char[] seqAfter = "]";
causes "conflicting storage class immutable" error. So I'll change them to
enum immutable(Char)[] seqAfter = "]";
like string type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If fully immutable doesn't work, that's fine, though with the recent changes to IFTI, it's generally less of a problem than it was. It doesn't really matter in this case though. You end up with a new copy of the enum every time you use it anyway. It's being const instead of immutable that's the real issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's being const instead of immutable that's the real issue.
?? These manifest constants are dynamic array, and the compiler stores the content of string literal at most once into exe file.
So, yes, manifest constant creates a copy in each place that used, but it is 8 byte structure (in 32 bit system), not full copy of string.
I think the change from const(Char)[]
to immutable(Char)[]` is better, because it expresses the elements never modified.
But it is not real issue.
} | ||
} | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why bother with the return;
when it's already at the end of the function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, there is not at the end of the function. The return statement is need.
There are a lot of calls to |
As I wrote in above comment, I don't like I had thought to define |
|
Applied review result. |
Jonathan, since you spent time getting into this diff, you may want to merge it when ready. |
Cleanup and improve std.format
Merged. |
Thanks for your reviewing and merging, @jmdavis! |
This pull request introduced a regression: |
Remove digger setup and use the compiler from Travis
Points:
Cleanup template specializations for more maintainable.
Add
toString(sink)
support.It is useful when format specifier does not need.
Add format specifier
%|
for nested range formattingPreviously, In
%( xxx %s yyy %)
yyy is interpreted as separator implicitly.But this rule is not good for nested range formatting.
e.g.
{%(<%(%d%)>, %)}
with[[1,2,3], [4,5,6]]
makes{<123>, <456}
.New
%|
format specifiers explicitly divide format strings for element and for separator.It is used only inside
%(
and%)
e.g.
{%(<%(%d%)>%|, %)}
with[[1,2,3], [4,5,6]]
makes{<123>, <456>}
.Add '%c" specifier for character type formatting
It is already supported for unformatting.
And also, it is necessary for nested range formatting. Now, inside compound format specifier,
%s
runs proper element formatting (do escape for strings, characters, and ranges). It is useful, but in some cases we need a way to avoid escaping.%c
just do it for characters.Issue 5354 - formatValue: range templates introduce 3 bugs related to class & struct cases
Check
toString
is overridden in runtime for class input range object.Add toString(sink, ...) support for class and interface types
Add tests and improvements for reflective formatting.
'Reflective' means:
And now, reflective formatting is CTFEable, except floating point formatting.