Topic: C++ formatting library proposal
Author: Victor Zverovich <victor.zverovich@gmail.com>
Date: Tue, 06 Jun 2017 13:41:11 +0000
Raw View
--f403045c2cbc6f248105514ac637
Content-Type: text/plain; charset="UTF-8"
I'm working on a proposal for a new formatting functionality for the C++
standard library based on the fmt library (https://github.com/fmtlib/fmt).
The first draft of the proposal is available at
http://fmtlib.net/Text%20Formatting.html and I would appreciate any
comments.
- Victor
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANawtxaVMmgecHONHp1HqsZTTzbVgnb_ZhqqPG4jxT%2B%2Bu4kjwg%40mail.gmail.com.
--f403045c2cbc6f248105514ac637
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div><span style=3D"font-size:13px;color:rgb(33,33,33)">I&=
#39;m working on a proposal for a new formatting functionality for the C++ =
standard library </span><span style=3D"color:rgb(33,33,33)"><span class=3D"=
inbox-inbox-Apple-converted-space">based on the fmt library (</span></span>=
<font color=3D"#212121"><a href=3D"https://github.com/fmtlib/fmt">https://g=
ithub.com/fmtlib/fmt</a>).</font><br></div><div><span style=3D"font-size:13=
px;color:rgb(33,33,33)"><span class=3D"inbox-inbox-Apple-converted-space"><=
br></span></span></div><div><span style=3D"font-size:13px;color:rgb(33,33,3=
3)"><span class=3D"inbox-inbox-Apple-converted-space">The first draft of th=
e proposal is available at=C2=A0</span></span><a href=3D"http://fmtlib.net/=
Text%20Formatting.html" target=3D"_blank" style=3D"font-size:13px">http://f=
mtlib.net/Text%20Formatting.html</a><font color=3D"#212121">=C2=A0and I wou=
ld appreciate any comments.</font></div><div><font color=3D"#212121"><br></=
font></div><div><font color=3D"#212121">- Victor</font></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CANawtxaVMmgecHONHp1HqsZTTzbVgnb_Zhqq=
PG4jxT%2B%2Bu4kjwg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANawtxaVMmge=
cHONHp1HqsZTTzbVgnb_ZhqqPG4jxT%2B%2Bu4kjwg%40mail.gmail.com</a>.<br />
--f403045c2cbc6f248105514ac637--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 6 Jun 2017 07:04:37 -0700 (PDT)
Raw View
------=_Part_3183_1484621312.1496757877303
Content-Type: multipart/alternative;
boundary="----=_Part_3184_1316613881.1496757877303"
------=_Part_3184_1316613881.1496757877303
Content-Type: text/plain; charset="UTF-8"
On Tuesday, June 6, 2017 at 9:41:26 AM UTC-4, Victor Zverovich wrote:
>
> I'm working on a proposal for a new formatting functionality for the C++
> standard library based on the fmt library (https://github.com/fmtlib/fmt).
>
> The first draft of the proposal is available at
> http://fmtlib.net/Text%20Formatting.html and I would appreciate any
> comments.
>
> - Victor
>
I'm concerned about this:
The formatting library uses a null-terminated string view basic_cstring_view
> instead of basic_string_view. This results in somewhat smaller and faster
> code because the string size, which is not used, doesn't have to be
> computed and passed. Also having a termination character makes parsing
> easier.
>
This really hurts users of `basic_string_view`, since their views are *not*
NUL-terminated. Such users don't necessarily have to calculate the string
size either; the `sv` user-defined literal will generate the size based on
the input literal.
Your insistence on `basic_cstring_view` only aids scenarios where the user
has an unsized, NUL-terminated string. So they would have to not be using
`basic_string` or similar types (which are sized).
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/e6e42f40-be11-46a4-824f-37199e9fa8da%40isocpp.org.
------=_Part_3184_1316613881.1496757877303
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, June 6, 2017 at 9:41:26 AM UTC-4, Victor Zvero=
vich wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><d=
iv><span style=3D"font-size:13px;color:rgb(33,33,33)">I'm working on a =
proposal for a new formatting functionality for the C++ standard library </=
span><span style=3D"color:rgb(33,33,33)"><span>based on the fmt library (</=
span></span><font color=3D"#212121"><a href=3D"https://github.com/fmtlib/fm=
t" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'https=
://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Ffmtlib%2Ffmt\x26sa\x3=
dD\x26sntz\x3d1\x26usg\x3dAFQjCNHczylSI1dpD7vrOq7kB4ix9U5bbQ';return tr=
ue;" onclick=3D"this.href=3D'https://www.google.com/url?q\x3dhttps%3A%2=
F%2Fgithub.com%2Ffmtlib%2Ffmt\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHczyl=
SI1dpD7vrOq7kB4ix9U5bbQ';return true;">https://github.com/fmtlib/fmt</a=
><wbr>).</font><br></div><div><span style=3D"font-size:13px;color:rgb(33,33=
,33)"><span><br></span></span></div><div><span style=3D"font-size:13px;colo=
r:rgb(33,33,33)"><span>The first draft of the proposal is available at=C2=
=A0</span></span><a href=3D"http://fmtlib.net/Text%20Formatting.html" style=
=3D"font-size:13px" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.=
href=3D'http://www.google.com/url?q\x3dhttp%3A%2F%2Ffmtlib.net%2FText%2=
520Formatting.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHZTnDLRkoRH6OSti=
61EVjg03ldwg';return true;" onclick=3D"this.href=3D'http://www.goog=
le.com/url?q\x3dhttp%3A%2F%2Ffmtlib.net%2FText%2520Formatting.html\x26sa\x3=
dD\x26sntz\x3d1\x26usg\x3dAFQjCNHZTnDLRkoRH6OSti61EVjg03ldwg';return tr=
ue;">http://fmtlib.net/Text%<wbr>20Formatting.html</a><font color=3D"#21212=
1">=C2=A0and I would appreciate any comments.</font></div><div><font color=
=3D"#212121"><br></font></div><div><font color=3D"#212121">- Victor</font><=
/div></div></blockquote><div><br>I'm concerned about this:<br><br><bloc=
kquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; border-lef=
t: 1px solid rgb(204, 204, 204); padding-left: 1ex;">The formatting library=
uses a null-terminated string view
<code>basic_cstring_view</code> instead of <code>basic_string_view</code>.
This results in somewhat smaller and faster code because the string size,
which is not used, doesn't have to be computed and passed. Also having
a termination character makes parsing easier. <br></blockquote><div><br>Thi=
s really hurts users of `basic_string_view`, since their views are <i>not</=
i> NUL-terminated. Such users don't necessarily have to calculate the s=
tring size either; the `sv` user-defined literal will generate the size bas=
ed on the input literal.<br><br>Your insistence on `basic_cstring_view` onl=
y aids scenarios where the user has an unsized, NUL-terminated string. So t=
hey would have to not be using `basic_string` or similar types (which are s=
ized).<br></div></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/e6e42f40-be11-46a4-824f-37199e9fa8da%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/e6e42f40-be11-46a4-824f-37199e9fa8da=
%40isocpp.org</a>.<br />
------=_Part_3184_1316613881.1496757877303--
------=_Part_3183_1484621312.1496757877303--
.
Author: Victor Zverovich <victor.zverovich@gmail.com>
Date: Tue, 06 Jun 2017 14:40:48 +0000
Raw View
--94eb2c1cc8eca84b9e05514b9b04
Content-Type: text/plain; charset="UTF-8"
> So they would have to not be using `basic_string` or similar types (which
are sized).
Not really, because `basic_cstring_view` can be easily constructed from
`basic_string`, but I agree there is a tradeoff between code size and
usability here. I was considering replacing `basic_cstring_view` with
`basic_string_view` to avoid an extra type but decided to hear the feedback
first. Note that `basic_cstring_view` is only used for the format string
itself which is very often a string literal.
Cheers,
Victor
On Tue, Jun 6, 2017 at 7:04 AM Nicol Bolas <jmckesson@gmail.com> wrote:
> On Tuesday, June 6, 2017 at 9:41:26 AM UTC-4, Victor Zverovich wrote:
>>
>> I'm working on a proposal for a new formatting functionality for the C++
>> standard library based on the fmt library (https://github.com/fmtlib/fmt
>> ).
>>
>> The first draft of the proposal is available at
>> http://fmtlib.net/Text%20Formatting.html and I would appreciate any
>> comments.
>>
>> - Victor
>>
>
> I'm concerned about this:
>
> The formatting library uses a null-terminated string view
>> basic_cstring_view instead of basic_string_view. This results in
>> somewhat smaller and faster code because the string size, which is not
>> used, doesn't have to be computed and passed. Also having a termination
>> character makes parsing easier.
>>
>
> This really hurts users of `basic_string_view`, since their views are
> *not* NUL-terminated. Such users don't necessarily have to calculate the
> string size either; the `sv` user-defined literal will generate the size
> based on the input literal.
>
> Your insistence on `basic_cstring_view` only aids scenarios where the user
> has an unsized, NUL-terminated string. So they would have to not be using
> `basic_string` or similar types (which are sized).
>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/e6e42f40-be11-46a4-824f-37199e9fa8da%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/e6e42f40-be11-46a4-824f-37199e9fa8da%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANawtxau4XgLESz4d-ALzH3hVz_RJN5bZUxT-%3DghHNGd41e8jw%40mail.gmail.com.
--94eb2c1cc8eca84b9e05514b9b04
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">> So they would have to not be using `basic_string` or =
similar types (which are sized).<div><br></div><div>Not really, because `ba=
sic_cstring_view` can be easily constructed from `basic_string`, but I agre=
e there is a tradeoff between code size and usability here. I was consideri=
ng replacing `basic_cstring_view` with `basic_string_view` to avoid an extr=
a type but decided to hear the feedback first. Note that `basic_cstring_vie=
w` is only used for the format string itself which is very often a string l=
iteral.</div><div><br></div><div>Cheers,</div><div>Victor</div><div><br><di=
v class=3D"gmail_quote"><div dir=3D"ltr">On Tue, Jun 6, 2017 at 7:04 AM Nic=
ol Bolas <<a href=3D"mailto:jmckesson@gmail.com">jmckesson@gmail.com</a>=
> wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 =
0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On Tue=
sday, June 6, 2017 at 9:41:26 AM UTC-4, Victor Zverovich wrote:<blockquote =
class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #=
ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><span style=3D"font-size:=
13px;color:rgb(33,33,33)">I'm working on a proposal for a new formattin=
g functionality for the C++ standard library </span><span style=3D"color:rg=
b(33,33,33)"><span>based on the fmt library (</span></span><font color=3D"#=
212121"><a href=3D"https://github.com/fmtlib/fmt" rel=3D"nofollow" target=
=3D"_blank">https://github.com/fmtlib/fmt</a>).</font><br></div><div><span =
style=3D"font-size:13px;color:rgb(33,33,33)"><span><br></span></span></div>=
<div><span style=3D"font-size:13px;color:rgb(33,33,33)"><span>The first dra=
ft of the proposal is available at=C2=A0</span></span><a href=3D"http://fmt=
lib.net/Text%20Formatting.html" style=3D"font-size:13px" rel=3D"nofollow" t=
arget=3D"_blank">http://fmtlib.net/Text%20Formatting.html</a><font color=3D=
"#212121">=C2=A0and I would appreciate any comments.</font></div><div><font=
color=3D"#212121"><br></font></div><div><font color=3D"#212121">- Victor</=
font></div></div></blockquote></div><div dir=3D"ltr"><div><br>I'm conce=
rned about this:<br><br><blockquote class=3D"gmail_quote" style=3D"margin:0=
px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">T=
he formatting library uses a null-terminated string view
<code>basic_cstring_view</code> instead of <code>basic_string_view</code>.
This results in somewhat smaller and faster code because the string size,
which is not used, doesn't have to be computed and passed. Also having
a termination character makes parsing easier. <br></blockquote><div><br>Thi=
s really hurts users of `basic_string_view`, since their views are <i>not</=
i> NUL-terminated. Such users don't necessarily have to calculate the s=
tring size either; the `sv` user-defined literal will generate the size bas=
ed on the input literal.<br><br>Your insistence on `basic_cstring_view` onl=
y aids scenarios where the user has an unsized, NUL-terminated string. So t=
hey would have to not be using `basic_string` or similar types (which are s=
ized).<br></div></div></div>
<p></p>
-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/e6e42f40-be11-46a4-824f-37199e9fa8da%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/e6e42f40-be11-=
46a4-824f-37199e9fa8da%40isocpp.org</a>.<br>
</blockquote></div></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CANawtxau4XgLESz4d-ALzH3hVz_RJN5bZUxT=
-%3DghHNGd41e8jw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANawtxau4XgLES=
z4d-ALzH3hVz_RJN5bZUxT-%3DghHNGd41e8jw%40mail.gmail.com</a>.<br />
--94eb2c1cc8eca84b9e05514b9b04--
.
Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Tue, 6 Jun 2017 08:37:14 -0700 (PDT)
Raw View
------=_Part_3219_121702481.1496763434378
Content-Type: multipart/alternative;
boundary="----=_Part_3220_1732168857.1496763434378"
------=_Part_3220_1732168857.1496763434378
Content-Type: text/plain; charset="UTF-8"
You may want to overload format() for both const Char* and
basic_string_view to avoid having to count the characters when not
necessary, while avoiding a deep copy just to add a \0 if you have a
std::string to start from. Internally you can stop parsing when you reach a
\0 or the end iterator. Allowing a \0 in a std::string to propagate to the
output will most likely do more harm than good. Introducing a
basic_cstring_view seems like overdoing it.
Den tisdag 6 juni 2017 kl. 16:41:04 UTC+2 skrev Victor Zverovich:
>
> > So they would have to not be using `basic_string` or similar types
> (which are sized).
>
> Not really, because `basic_cstring_view` can be easily constructed from
> `basic_string`, but I agree there is a tradeoff between code size and
> usability here. I was considering replacing `basic_cstring_view` with
> `basic_string_view` to avoid an extra type but decided to hear the feedback
> first. Note that `basic_cstring_view` is only used for the format string
> itself which is very often a string literal.
>
> Cheers,
> Victor
>
> On Tue, Jun 6, 2017 at 7:04 AM Nicol Bolas <jmck...@gmail.com
> <javascript:>> wrote:
>
>> On Tuesday, June 6, 2017 at 9:41:26 AM UTC-4, Victor Zverovich wrote:
>>>
>>> I'm working on a proposal for a new formatting functionality for the C++
>>> standard library based on the fmt library (https://github.com/fmtlib/fmt
>>> ).
>>>
>>> The first draft of the proposal is available at
>>> http://fmtlib.net/Text%20Formatting.html and I would appreciate any
>>> comments.
>>>
>>> - Victor
>>>
>>
>> I'm concerned about this:
>>
>> The formatting library uses a null-terminated string view
>>> basic_cstring_view instead of basic_string_view. This results in
>>> somewhat smaller and faster code because the string size, which is not
>>> used, doesn't have to be computed and passed. Also having a termination
>>> character makes parsing easier.
>>>
>>
>> This really hurts users of `basic_string_view`, since their views are
>> *not* NUL-terminated. Such users don't necessarily have to calculate the
>> string size either; the `sv` user-defined literal will generate the size
>> based on the input literal.
>>
>> Your insistence on `basic_cstring_view` only aids scenarios where the
>> user has an unsized, NUL-terminated string. So they would have to not be
>> using `basic_string` or similar types (which are sized).
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to std-proposal...@isocpp.org <javascript:>.
>> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
>> To view this discussion on the web visit
>> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/e6e42f40-be11-46a4-824f-37199e9fa8da%40isocpp.org
>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/e6e42f40-be11-46a4-824f-37199e9fa8da%40isocpp.org?utm_medium=email&utm_source=footer>
>> .
>>
>
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/7dd81741-80ed-4edd-8274-c3cee8c53b1b%40isocpp.org.
------=_Part_3220_1732168857.1496763434378
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">You may want to overload format() for both const Char* and=
basic_string_view to avoid having to count the characters when not necessa=
ry, while avoiding a deep copy just to add a \0 if you have a std::string t=
o start from. Internally you can stop parsing when you reach a \0 or the en=
d iterator. Allowing a \0 in a std::string to propagate to the output will =
most likely do more harm than good. Introducing a basic_cstring_view seems =
like overdoing it.<br><br>Den tisdag 6 juni 2017 kl. 16:41:04 UTC+2 skrev V=
ictor Zverovich:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"lt=
r">> So they would have to not be using `basic_string` or similar types =
(which are sized).<div><br></div><div>Not really, because `basic_cstring_vi=
ew` can be easily constructed from `basic_string`, but I agree there is a t=
radeoff between code size and usability here. I was considering replacing `=
basic_cstring_view` with `basic_string_view` to avoid an extra type but dec=
ided to hear the feedback first. Note that `basic_cstring_view` is only use=
d for the format string itself which is very often a string literal.</div><=
div><br></div><div>Cheers,</div><div>Victor</div><div><br><div class=3D"gma=
il_quote"><div dir=3D"ltr">On Tue, Jun 6, 2017 at 7:04 AM Nicol Bolas <<=
a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"5biLkjktA=
QAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:';retu=
rn true;" onclick=3D"this.href=3D'javascript:';return true;">jmck..=
..@gmail.com</a>> wrote:<br></div><blockquote class=3D"gmail_quote" style=
=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr">On Tuesday, June 6, 2017 at 9:41:26 AM UTC-4, Victor Zverovich wro=
te:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bo=
rder-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><span styl=
e=3D"font-size:13px;color:rgb(33,33,33)">I'm working on a proposal for =
a new formatting functionality for the C++ standard library </span><span st=
yle=3D"color:rgb(33,33,33)"><span>based on the fmt library (</span></span><=
font color=3D"#212121"><a href=3D"https://github.com/fmtlib/fmt" rel=3D"nof=
ollow" target=3D"_blank" onmousedown=3D"this.href=3D'https://www.google=
..com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Ffmtlib%2Ffmt\x26sa\x3dD\x26sntz\x3=
d1\x26usg\x3dAFQjCNHczylSI1dpD7vrOq7kB4ix9U5bbQ';return true;" onclick=
=3D"this.href=3D'https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.c=
om%2Ffmtlib%2Ffmt\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHczylSI1dpD7vrOq7=
kB4ix9U5bbQ';return true;">https://github.com/fmtlib/fmt</a><wbr>).</fo=
nt><br></div><div><span style=3D"font-size:13px;color:rgb(33,33,33)"><span>=
<br></span></span></div><div><span style=3D"font-size:13px;color:rgb(33,33,=
33)"><span>The first draft of the proposal is available at=C2=A0</span></sp=
an><a href=3D"http://fmtlib.net/Text%20Formatting.html" style=3D"font-size:=
13px" rel=3D"nofollow" target=3D"_blank" onmousedown=3D"this.href=3D'ht=
tp://www.google.com/url?q\x3dhttp%3A%2F%2Ffmtlib.net%2FText%2520Formatting.=
html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHZTnDLRkoRH6OSti61EVjg03ldwg&#=
39;;return true;" onclick=3D"this.href=3D'http://www.google.com/url?q\x=
3dhttp%3A%2F%2Ffmtlib.net%2FText%2520Formatting.html\x26sa\x3dD\x26sntz\x3d=
1\x26usg\x3dAFQjCNHZTnDLRkoRH6OSti61EVjg03ldwg';return true;">http://fm=
tlib.net/Text%<wbr>20Formatting.html</a><font color=3D"#212121">=C2=A0and I=
would appreciate any comments.</font></div><div><font color=3D"#212121"><b=
r></font></div><div><font color=3D"#212121">- Victor</font></div></div></bl=
ockquote></div><div dir=3D"ltr"><div><br>I'm concerned about this:<br><=
br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bord=
er-left:1px solid rgb(204,204,204);padding-left:1ex">The formatting library=
uses a null-terminated string view
<code>basic_cstring_view</code> instead of <code>basic_string_view</code>.
This results in somewhat smaller and faster code because the string size,
which is not used, doesn't have to be computed and passed. Also having
a termination character makes parsing easier. <br></blockquote><div><br>Thi=
s really hurts users of `basic_string_view`, since their views are <i>not</=
i> NUL-terminated. Such users don't necessarily have to calculate the s=
tring size either; the `sv` user-defined literal will generate the size bas=
ed on the input literal.<br><br>Your insistence on `basic_cstring_view` onl=
y aids scenarios where the user has an unsized, NUL-terminated string. So t=
hey would have to not be using `basic_string` or similar types (which are s=
ized).<br></div></div></div>
<p></p>
-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
5biLkjktAQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:&=
#39;;return true;" onclick=3D"this.href=3D'javascript:';return true=
;">std-proposal...@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"javascript:" target=3D"_bla=
nk" gdf-obfuscated-mailto=3D"5biLkjktAQAJ" rel=3D"nofollow" onmousedown=3D"=
this.href=3D'javascript:';return true;" onclick=3D"this.href=3D'=
;javascript:';return true;">std-pr...@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/e6e42f40-be11-46a4-824f-37199e9fa8da%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter" target=3D"_blank" =
rel=3D"nofollow" onmousedown=3D"this.href=3D'https://groups.google.com/=
a/isocpp.org/d/msgid/std-proposals/e6e42f40-be11-46a4-824f-37199e9fa8da%40i=
socpp.org?utm_medium\x3demail\x26utm_source\x3dfooter';return true;" on=
click=3D"this.href=3D'https://groups.google.com/a/isocpp.org/d/msgid/st=
d-proposals/e6e42f40-be11-46a4-824f-37199e9fa8da%40isocpp.org?utm_medium\x3=
demail\x26utm_source\x3dfooter';return true;">https://groups.google.com=
/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/e6e42f40-be11-46a4-<wbr>824f-=
37199e9fa8da%40isocpp.org</a><wbr>.<br>
</blockquote></div></div></div>
</blockquote></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/7dd81741-80ed-4edd-8274-c3cee8c53b1b%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/7dd81741-80ed-4edd-8274-c3cee8c53b1b=
%40isocpp.org</a>.<br />
------=_Part_3220_1732168857.1496763434378--
------=_Part_3219_121702481.1496763434378--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 6 Jun 2017 09:06:02 -0700 (PDT)
Raw View
------=_Part_2879_592857426.1496765162747
Content-Type: multipart/alternative;
boundary="----=_Part_2880_1016189469.1496765162747"
------=_Part_2880_1016189469.1496765162747
Content-Type: text/plain; charset="UTF-8"
On Tuesday, June 6, 2017 at 10:41:04 AM UTC-4, Victor Zverovich wrote:
>
> > So they would have to not be using `basic_string` or similar types
> (which are sized).
>
> Not really, because `basic_cstring_view` can be easily constructed from
> `basic_string`, but I agree there is a tradeoff between code size and
> usability here. I was considering replacing `basic_cstring_view` with
> `basic_string_view` to avoid an extra type but decided to hear the feedback
> first. Note that `basic_cstring_view` is only used for the format string
> itself which is very often a string literal.
>
"very often" is true for some cases, but not for many others that your
system would be suitable for.
The primary reason for positional arguments is to make translations
easier/possible. Generally speaking, translations aren't stored in
executables as string literals; they're stored in other files. If those are
plain text files, perhaps with some markup to designate the end of one
format, I see no reason that I should have to put `\0` characters in all of
them.
Bengt's suggestion seems the most reasonable here: just provide a separate
overload for NUL-terminated strings than for `string_view`s. You say that
this is for "code size" reasons, but I fail to see how the code size will
be impacted significantly enough to be worth the hassle.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/3b317ab3-688f-4db6-8a3e-b5fb4fca3b85%40isocpp.org.
------=_Part_2880_1016189469.1496765162747
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, June 6, 2017 at 10:41:04 AM UTC-4, Victor Zver=
ovich wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">&=
gt; So they would have to not be using `basic_string` or similar types (whi=
ch are sized).<div><br></div><div>Not really, because `basic_cstring_view` =
can be easily constructed from `basic_string`, but I agree there is a trade=
off between code size and usability here. I was considering replacing `basi=
c_cstring_view` with `basic_string_view` to avoid an extra type but decided=
to hear the feedback first. Note that `basic_cstring_view` is only used fo=
r the format string itself which is very often a string literal.</div></div=
></blockquote><div><br>"very often" is true for some cases, but n=
ot for many others that your system would be suitable for.</div><br>The pri=
mary reason for positional arguments is to make translations easier/possibl=
e. Generally speaking, translations aren't stored in executables as str=
ing literals; they're stored in other files. If those are plain text fi=
les, perhaps with some markup to designate the end of one format, I see no =
reason that I should have to put `\0` characters in all of them.<br><br>Ben=
gt's suggestion seems the most reasonable here: just provide a separate=
overload for NUL-terminated strings than for `string_view`s. You say that =
this is for "code size" reasons, but I fail to see how the code s=
ize will be impacted significantly enough to be worth the hassle.<br></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/3b317ab3-688f-4db6-8a3e-b5fb4fca3b85%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/3b317ab3-688f-4db6-8a3e-b5fb4fca3b85=
%40isocpp.org</a>.<br />
------=_Part_2880_1016189469.1496765162747--
------=_Part_2879_592857426.1496765162747--
.
Author: Thiago Macieira <thiago@macieira.org>
Date: Tue, 06 Jun 2017 10:38:30 -0700
Raw View
On Tuesday, 6 June 2017 09:06:02 PDT Nicol Bolas wrote:
> "very often" is true for some cases, but not for many others that your
> system would be suitable for.
>
> The primary reason for positional arguments is to make translations
> easier/possible. Generally speaking, translations aren't stored in
> executables as string literals; they're stored in other files. If those are
> plain text files, perhaps with some markup to designate the end of one
> format, I see no reason that I should have to put `\0` characters in all of
> them.
If it's a binary file (like .qm), then most likely the size is stored somewhere
due to the construction of the file (indexing, etc.). The presence of a null
terminator is likely in file formats meant to be used with C API (like
libintl's .mo), but native C++ APIs may want to skip that.
> Bengt's suggestion seems the most reasonable here: just provide a separate
> overload for NUL-terminated strings than for `string_view`s. You say that
> this is for "code size" reasons, but I fail to see how the code size will
> be impacted significantly enough to be worth the hassle.
Good compilers optimise strlen of a string literal to a constexpr constant
anyway, when compiled in release mode.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/3199898.gF26Z4pyRH%40tjmaciei-mobl1.
.
Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Tue, 6 Jun 2017 13:44:20 -0700 (PDT)
Raw View
------=_Part_3702_1424298548.1496781860833
Content-Type: multipart/alternative;
boundary="----=_Part_3703_1907718954.1496781860834"
------=_Part_3703_1907718954.1496781860834
Content-Type: text/plain; charset="UTF-8"
>
>
> Good compilers optimise strlen of a string literal to a constexpr constant
> anyway, when compiled in release mode.
>
Of course, you're right, basic_string_view seems the right choice then,
after all.
> --
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
> Software Architect - Intel Open Source Technology Center
>
>
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/341e6114-5a68-4aaa-bafe-a2dc150f26c6%40isocpp.org.
------=_Part_3703_1907718954.1496781860834
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><br>Good comp=
ilers optimise strlen of a string literal to a constexpr constant=20
<br>anyway, when compiled in release mode.
<br></blockquote><div><br></div><div>Of course, you're right, basic_str=
ing_view seems the right choice then, after all.</div><div><br></div><block=
quote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-le=
ft: 1px #ccc solid;padding-left: 1ex;">
<br>--=20
<br>Thiago Macieira - thiago (AT) <a href=3D"http://macieira.info" target=
=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'http://www.goo=
gle.com/url?q\x3dhttp%3A%2F%2Fmacieira.info\x26sa\x3dD\x26sntz\x3d1\x26usg\=
x3dAFQjCNEswDUBNCNanbu7euhqLn_62FW8ag';return true;" onclick=3D"this.hr=
ef=3D'http://www.google.com/url?q\x3dhttp%3A%2F%2Fmacieira.info\x26sa\x=
3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEswDUBNCNanbu7euhqLn_62FW8ag';return t=
rue;">macieira.info</a> - thiago (AT) <a href=3D"http://kde.org" target=3D"=
_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'http://www.google.=
com/url?q\x3dhttp%3A%2F%2Fkde.org\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNH=
GRJdo5_JYG1DowztwAHAKs80XSA';return true;" onclick=3D"this.href=3D'=
http://www.google.com/url?q\x3dhttp%3A%2F%2Fkde.org\x26sa\x3dD\x26sntz\x3d1=
\x26usg\x3dAFQjCNHGRJdo5_JYG1DowztwAHAKs80XSA';return true;">kde.org</a=
>
<br>=C2=A0 =C2=A0Software Architect - Intel Open Source Technology Center
<br>
<br></blockquote></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/341e6114-5a68-4aaa-bafe-a2dc150f26c6%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/341e6114-5a68-4aaa-bafe-a2dc150f26c6=
%40isocpp.org</a>.<br />
------=_Part_3703_1907718954.1496781860834--
------=_Part_3702_1424298548.1496781860833--
.
Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Tue, 6 Jun 2017 15:12:27 -0700 (PDT)
Raw View
------=_Part_3588_1583789080.1496787147431
Content-Type: multipart/alternative;
boundary="----=_Part_3589_1478075260.1496787147431"
------=_Part_3589_1478075260.1496787147431
Content-Type: text/plain; charset="UTF-8"
I like this functionality a lot, it has been sorely lacking in C++ and is
becoming more and more a standard in many other languages.
Some comments:
- I would like the part before the : inside {} to allow any text. This
allows translators to understand better the meaning of the inserted value
and thus produce better translations. Not writing anything before the :
would still
be equivalent to writing the next consecutive number. I think you removed
this capability from the python implementation as C++ does not have named
arguments but it still has value in conveying information between
programmer and the person doing translation.
- Some kind of standard interface to internationalization string
replacement could be incorporated in format(), so that we don't have to
write _() or something around the literal.
- How to specify using . for decimal char in a country where , is standard
and vice versa. n only seems to relate to thousand separator handling, but
the usual problem is to get the right decimal character in float number
output. Many file formats (JSON for instance) require a dot even in
countries where comma is standard. This is a recurring problem as "someone
else" may set your locale on a global level. I have a similar library
where I use comma or dot (in the dot position in the format string) to
denote themselves as decimal char while semicolon denotes "the locale
decimal char". While creating your own buffer type which overrides the
locale() method is possible it is much more work than defining the decimal
char in the format string.
- I don't particularly like the partial reuse of the C formatting
conventions with a specified order of the parts of the format string, as it
is hard to learn. Sure, it is rather easy whern you have learned printf,
but do we want future generations of programmers have to go through that
detour? Better start from scratch with something logical, where the order
of characters is not crucial.
- It may be better to send the formatting string snippet to format_value()
as a basic_string_view rather than relying on all the function overloads to
remember to bump the ptr correctly. At least provide a method in ctx to
forward the ptr and return the basic_string_view containing the format part
in case you want to preserve the possibility to nest {} inside the
formatting string. This simplifies for the fairly large share of
format_value functions which are implemented but don't care about any
formatting details.
- A maximum inserted length is often useful to limit the output. One case
is when formatting large doubles in the f format. This can get ridiculous
in printf. Another is potentially long file names, where you may want to
limit the string length.
- It is hard to understand the "arg store" idea and how this goes together
with calling format_value on each parameter. It may be that the fmt::args
and basic_args are actually the same. There is also arg_store and basic_arg
and the visit() function which seem more like internal details of the
implementation. Even as an implementation it seems overly complex, and I
for one can't understand how visit can call separate user defined
format_value functions if arg_store is not templated on the argument types.
- It would be nice if it was easy to create a formatting object from a
format specification string. This object should have methods to format the
standard types that fomat() works for "out of the box". In this way you can
easily override format_value for instance for std::vector<T>, passing each
element to a formatting object you have created. Of course you can also
call format_value() for each T provided it exists, but this incurs quite an
overhead as the same format specification string is parsed over and over
again for each array element. Taking this thought to the logical conclusion
means that the customization point for a user defined type should be a
function create_formatter<T>(string_view format_specification_string)
rather than format_value. The formatter returned from create_formatter then
has a method format(const T& value) which does the formatting job. This
allows the vector optimization to be taken to vectors of vectors etc.
Continuing on this tangent I think it may make sense to allow pre-creating
a formatting object for an entire format string, so that the parsing of
that string occurs only once. Lets call this class formatter<Ts...>.
Example:
template<typename... Ts> class formatter {
public:
formatter(string_view format_string); // This parses the format_string
and stores the objects returned from create_formatter<T> for each of the Ts.
void run(buffer& buf, const Ts&.. args); // Perform the formatting
to a buffer
string run(buffer& buf, const Ts&... args); // Perform the formatting
and return a string
};
// The format function is then defined as:
template<typename... Ts> string format(string_view format_string, const Ts&
values)
{
formatter<Ts...> fmt(format_string);
return fmt.run(values...);
}
// A good compiler hopefully generates the same code as in the current
implementation.
// A loop for printing many lines would be more effective if written:
formatter<int, string, double> fmt("#{IX}: {NAME}, {PRICE:.2"); //
Preparse format
for (item : inventory)
cout << fmt.run(item.ix, item.name, item.price);
Den tisdag 6 juni 2017 kl. 16:04:37 UTC+2 skrev Nicol Bolas:
>
> On Tuesday, June 6, 2017 at 9:41:26 AM UTC-4, Victor Zverovich wrote:
>>
>> I'm working on a proposal for a new formatting functionality for the C++
>> standard library based on the fmt library (https://github.com/fmtlib/fmt
>> ).
>>
>> The first draft of the proposal is available at
>> http://fmtlib.net/Text%20Formatting.html and I would appreciate any
>> comments.
>>
>> - Victor
>>
>
> I'm concerned about this:
>
> The formatting library uses a null-terminated string view
>> basic_cstring_view instead of basic_string_view. This results in
>> somewhat smaller and faster code because the string size, which is not
>> used, doesn't have to be computed and passed. Also having a termination
>> character makes parsing easier.
>>
>
> This really hurts users of `basic_string_view`, since their views are
> *not* NUL-terminated. Such users don't necessarily have to calculate the
> string size either; the `sv` user-defined literal will generate the size
> based on the input literal.
>
> Your insistence on `basic_cstring_view` only aids scenarios where the user
> has an unsized, NUL-terminated string. So they would have to not be using
> `basic_string` or similar types (which are sized).
>
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/4777755b-5984-4ef3-8fc5-a3e17aa94469%40isocpp.org.
------=_Part_3589_1478075260.1496787147431
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>I like this functionality a lot, it has been sorely l=
acking in C++ and is becoming more and more a standard in many other langua=
ges.</div><div><br></div><div>Some comments:<br></div><div><br></div><div>-=
I would like the part before the : inside {} to allow any text. This allow=
s translators to understand better the meaning of the inserted value and th=
us produce better translations. Not writing anything before the : would sti=
ll</div><div>be equivalent to writing the next consecutive number. I think =
you removed this capability from the python implementation as C++ does not =
have named arguments but it still has value in conveying information betwee=
n programmer and the person doing translation.</div><div><br></div><div>- S=
ome kind of standard interface to internationalization string replacement c=
ould be incorporated in format(), so that we don't have to write _() or=
something around the literal.</div><div><br></div><div>- How to specify us=
ing . for decimal char in a country where , is standard and vice versa. n o=
nly seems to relate to thousand separator handling, but the usual problem i=
s to get the right decimal character in float number output. Many file form=
ats (JSON for instance) require a dot even in countries where comma is stan=
dard. This is a recurring problem as "someone else" may set your =
locale on a =C2=A0global level. I have a similar library where I use comma =
or dot (in the dot position in the format string) to denote themselves as d=
ecimal char while semicolon denotes "the locale decimal char". Wh=
ile creating your own buffer type which overrides the locale() method is po=
ssible it is much more work than defining the decimal char in the format st=
ring.</div><div><br></div><div>- I don't particularly like the partial =
reuse of the C formatting conventions with a specified order of the parts o=
f the format string, as it is hard to learn. Sure, it is rather easy whern =
you have learned printf, but do we want future generations of programmers h=
ave to go through that detour? Better start from scratch with something log=
ical, where the order of characters is not crucial.</div><div><br></div><di=
v>- It may be better to send the formatting string snippet to format_value(=
) as a basic_string_view rather than relying on all the function overloads =
to remember to bump the ptr correctly. At least provide a method in ctx to =
forward the ptr and return the basic_string_view containing the format part=
in case you want to preserve the possibility to nest {} inside the formatt=
ing string. This simplifies for the fairly large share of format_value func=
tions which are implemented but don't care about any formatting details=
..</div><div><br></div><div>- A maximum inserted length is often useful to l=
imit the output. One case is when formatting large doubles in the f format.=
This can get ridiculous in printf. Another is potentially long file names,=
where you may want to limit the string length.</div><div><br></div><div>- =
It is hard to understand the "arg store" idea and how this goes t=
ogether with calling format_value on each parameter. It may be that the fmt=
::args and basic_args are actually the same. There is also arg_store and ba=
sic_arg and the visit() function which seem more like internal details of t=
he implementation. Even as an implementation it seems overly complex, and I=
for one can't understand how visit can call separate user defined form=
at_value functions if arg_store is not templated on the argument types.</di=
v><div><br></div><div>- It would be nice if it was easy to create a formatt=
ing object from a format specification string. This object should have meth=
ods to format the standard types that fomat() works for "out of the bo=
x". In this way you can easily override format_value for instance for =
std::vector<T>, passing each element to a formatting object you have =
created. Of course you can also call format_value() for each T provided it =
exists, but this incurs quite an overhead as the same format specification =
string is parsed over and over again for each array element. Taking this th=
ought to the logical conclusion means that the customization point for a us=
er defined type should be a function create_formatter<T>(string_view =
format_specification_string) rather than format_value. The formatter return=
ed from create_formatter then has a method format(const T& value) which=
does the formatting job. This allows the vector optimization to be taken t=
o vectors of vectors etc. Continuing on this tangent I think it may make se=
nse to allow pre-creating a formatting object for an entire format string, =
so that the parsing of that string occurs only once. Lets call this class f=
ormatter<Ts...>. Example:</div><div><br></div><div>template<typena=
me... Ts> class formatter {</div><div>public:</div><div>=C2=A0 =C2=A0 fo=
rmatter(string_view format_string); =C2=A0// This parses the format_string =
and stores the objects returned from create_formatter<T> for each of =
the Ts.</div><div><br></div><div>=C2=A0 =C2=A0 void run(buffer& buf, co=
nst Ts&.. args); =C2=A0 =C2=A0// Perform the formatting to a buffer</di=
v><div>=C2=A0 =C2=A0 string run(buffer& buf, const Ts&... args); //=
Perform the formatting and return a string</div><div>};</div><div><br></di=
v><div>// The format function is then defined as:</div><div>template<typ=
ename... Ts> string format(string_view format_string, const Ts& valu=
es)</div><div>{</div><div>=C2=A0 =C2=A0 =C2=A0formatter<Ts...> fmt(fo=
rmat_string);</div><div>=C2=A0 =C2=A0 =C2=A0return fmt.run(values...);</div=
><div>}</div><div>// A good compiler hopefully generates the same code as i=
n the current implementation.</div><div>// A loop for printing many lines w=
ould be more effective if written:</div><div><br></div><div>formatter<in=
t, string, double> fmt("#{IX}: {NAME}, {PRICE:.2"); =C2=A0 // =
Preparse format</div><div>for (item : inventory)</div><div>=C2=A0 =C2=A0 co=
ut << fmt.run(item.ix, item.name, item.price);</div><div><br></div><d=
iv><br></div><div><br></div><div><br></div><div><br></div><div><br></div><d=
iv><br></div><div><br><br>Den tisdag 6 juni 2017 kl. 16:04:37 UTC+2 skrev N=
icol Bolas:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">On=
Tuesday, June 6, 2017 at 9:41:26 AM UTC-4, Victor Zverovich wrote:<blockqu=
ote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1=
px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><span style=3D"font-s=
ize:13px;color:rgb(33,33,33)">I'm working on a proposal for a new forma=
tting functionality for the C++ standard library </span><span style=3D"colo=
r:rgb(33,33,33)"><span>based on the fmt library (</span></span><font color=
=3D"#212121"><a href=3D"https://github.com/fmtlib/fmt" rel=3D"nofollow" tar=
get=3D"_blank" onmousedown=3D"this.href=3D'https://www.google.com/url?q=
\x3dhttps%3A%2F%2Fgithub.com%2Ffmtlib%2Ffmt\x26sa\x3dD\x26sntz\x3d1\x26usg\=
x3dAFQjCNHczylSI1dpD7vrOq7kB4ix9U5bbQ';return true;" onclick=3D"this.hr=
ef=3D'https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Ffmtlib=
%2Ffmt\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHczylSI1dpD7vrOq7kB4ix9U5bbQ=
';return true;">https://github.com/fmtlib/fmt</a><wbr>).</font><br></di=
v><div><span style=3D"font-size:13px;color:rgb(33,33,33)"><span><br></span>=
</span></div><div><span style=3D"font-size:13px;color:rgb(33,33,33)"><span>=
The first draft of the proposal is available at=C2=A0</span></span><a href=
=3D"http://fmtlib.net/Text%20Formatting.html" style=3D"font-size:13px" rel=
=3D"nofollow" target=3D"_blank" onmousedown=3D"this.href=3D'http://www.=
google.com/url?q\x3dhttp%3A%2F%2Ffmtlib.net%2FText%2520Formatting.html\x26s=
a\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHZTnDLRkoRH6OSti61EVjg03ldwg';retur=
n true;" onclick=3D"this.href=3D'http://www.google.com/url?q\x3dhttp%3A=
%2F%2Ffmtlib.net%2FText%2520Formatting.html\x26sa\x3dD\x26sntz\x3d1\x26usg\=
x3dAFQjCNHZTnDLRkoRH6OSti61EVjg03ldwg';return true;">http://fmtlib.net/=
Text%<wbr>20Formatting.html</a><font color=3D"#212121">=C2=A0and I would ap=
preciate any comments.</font></div><div><font color=3D"#212121"><br></font>=
</div><div><font color=3D"#212121">- Victor</font></div></div></blockquote>=
<div><br>I'm concerned about this:<br><br><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,20=
4);padding-left:1ex">The formatting library uses a null-terminated string v=
iew
<code>basic_cstring_view</code> instead of <code>basic_string_view</code>.
This results in somewhat smaller and faster code because the string size,
which is not used, doesn't have to be computed and passed. Also having
a termination character makes parsing easier. <br></blockquote><div><br>Thi=
s really hurts users of `basic_string_view`, since their views are <i>not</=
i> NUL-terminated. Such users don't necessarily have to calculate the s=
tring size either; the `sv` user-defined literal will generate the size bas=
ed on the input literal.<br><br>Your insistence on `basic_cstring_view` onl=
y aids scenarios where the user has an unsized, NUL-terminated string. So t=
hey would have to not be using `basic_string` or similar types (which are s=
ized).<br></div></div></div></blockquote></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/4777755b-5984-4ef3-8fc5-a3e17aa94469%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/4777755b-5984-4ef3-8fc5-a3e17aa94469=
%40isocpp.org</a>.<br />
------=_Part_3589_1478075260.1496787147431--
------=_Part_3588_1583789080.1496787147431--
.
Author: Victor Zverovich <victor.zverovich@gmail.com>
Date: Wed, 07 Jun 2017 14:42:03 +0000
Raw View
--94eb2c0e43d4f9039005515fbdb7
Content-Type: text/plain; charset="UTF-8"
I was hoping to avoid having extra overloads so maybe will just go with
basic_string_view. I don't remember the numbers but there was a noticeable
regression on the code bloat benchmark (
https://github.com/fmtlib/fmt#compile-time-and-code-bloat) when doing this
due to passing an extra size argument and more formatting arguments
spilling on stack, but the benchmark is somewhat artificial and it may not
be important in practice.
- Victor
On Tue, Jun 6, 2017 at 9:06 AM Nicol Bolas <jmckesson@gmail.com> wrote:
> On Tuesday, June 6, 2017 at 10:41:04 AM UTC-4, Victor Zverovich wrote:
>>
>> > So they would have to not be using `basic_string` or similar types
>> (which are sized).
>>
>> Not really, because `basic_cstring_view` can be easily constructed from
>> `basic_string`, but I agree there is a tradeoff between code size and
>> usability here. I was considering replacing `basic_cstring_view` with
>> `basic_string_view` to avoid an extra type but decided to hear the feedback
>> first. Note that `basic_cstring_view` is only used for the format string
>> itself which is very often a string literal.
>>
>
> "very often" is true for some cases, but not for many others that your
> system would be suitable for.
>
> The primary reason for positional arguments is to make translations
> easier/possible. Generally speaking, translations aren't stored in
> executables as string literals; they're stored in other files. If those are
> plain text files, perhaps with some markup to designate the end of one
> format, I see no reason that I should have to put `\0` characters in all of
> them.
>
> Bengt's suggestion seems the most reasonable here: just provide a separate
> overload for NUL-terminated strings than for `string_view`s. You say that
> this is for "code size" reasons, but I fail to see how the code size will
> be impacted significantly enough to be worth the hassle.
>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/3b317ab3-688f-4db6-8a3e-b5fb4fca3b85%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/3b317ab3-688f-4db6-8a3e-b5fb4fca3b85%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANawtxb8E_ws50JJpd7bG_NZeL1EjnWZKU1_kojKXmAa8z%2BETA%40mail.gmail.com.
--94eb2c0e43d4f9039005515fbdb7
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">I was hoping to avoid having extra overloads so maybe will=
just go with basic_string_view. I don't remember the numbers but there=
was a noticeable regression on the code bloat benchmark (<a href=3D"https:=
//github.com/fmtlib/fmt#compile-time-and-code-bloat">https://github.com/fmt=
lib/fmt#compile-time-and-code-bloat</a>) when doing this due to passing an =
extra size argument and more formatting arguments spilling on stack, but th=
e benchmark is somewhat artificial and it may not be important in practice.=
<br><br>- Victor<br><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Tue,=
Jun 6, 2017 at 9:06 AM Nicol Bolas <<a href=3D"mailto:jmckesson@gmail.c=
om">jmckesson@gmail.com</a>> wrote:<br></div><blockquote class=3D"gmail_=
quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1=
ex"><div dir=3D"ltr">On Tuesday, June 6, 2017 at 10:41:04 AM UTC-4, Victor =
Zverovich wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-=
left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">&g=
t; So they would have to not be using `basic_string` or similar types (whic=
h are sized).<div><br></div><div>Not really, because `basic_cstring_view` c=
an be easily constructed from `basic_string`, but I agree there is a tradeo=
ff between code size and usability here. I was considering replacing `basic=
_cstring_view` with `basic_string_view` to avoid an extra type but decided =
to hear the feedback first. Note that `basic_cstring_view` is only used for=
the format string itself which is very often a string literal.</div></div>=
</blockquote></div><div dir=3D"ltr"><div><br>"very often" is true=
for some cases, but not for many others that your system would be suitable=
for.</div><br>The primary reason for positional arguments is to make trans=
lations easier/possible. Generally speaking, translations aren't stored=
in executables as string literals; they're stored in other files. If t=
hose are plain text files, perhaps with some markup to designate the end of=
one format, I see no reason that I should have to put `\0` characters in a=
ll of them.<br><br>Bengt's suggestion seems the most reasonable here: j=
ust provide a separate overload for NUL-terminated strings than for `string=
_view`s. You say that this is for "code size" reasons, but I fail=
to see how the code size will be impacted significantly enough to be worth=
the hassle.<br></div>
<p></p>
-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/3b317ab3-688f-4db6-8a3e-b5fb4fca3b85%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/3b317ab3-688f-=
4db6-8a3e-b5fb4fca3b85%40isocpp.org</a>.<br>
</blockquote></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CANawtxb8E_ws50JJpd7bG_NZeL1EjnWZKU1_=
kojKXmAa8z%2BETA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANawtxb8E_ws50=
JJpd7bG_NZeL1EjnWZKU1_kojKXmAa8z%2BETA%40mail.gmail.com</a>.<br />
--94eb2c0e43d4f9039005515fbdb7--
.
Author: Victor Zverovich <victor.zverovich@gmail.com>
Date: Thu, 08 Jun 2017 13:45:12 +0000
Raw View
--94eb2c0e43d47150fa0551731080
Content-Type: text/plain; charset="UTF-8"
Thanks for such a detailed feedback.
> I would like the part before the : inside {} to allow any text.
The fmt library <https://github.com/fmtlib/fmt>, this proposal is based on,
supports named arguments:
format("The answer is {answer:}", arg(answer, 42));
or, with user defined literals,
format("The answer is {answer:}", "answer"_a=42);
but I decided to omit this feature from the first draft of the proposal to
keep it manageable. It should be possible to add named arguments as an
extension.
> Some kind of standard interface to internationalization string
replacement could be incorporated in format(), so that we don't have to
write _() or something around the literal.
I think some i18n features can be built on top of this formatting library.
In particular, a user can easily create a formatting function with the same
API as `format` that looks up the format string in the database of
translations. This doesn't address marking string for translation though.
The latter is more of a tooling issue.
> How to specify using . for decimal char in a country where , is standard
and vice versa.
As in Python, the default format is locale-independent for exactly the same
reason that you mention - many output formats require this. So the default
output uses '.' as a decimal separator. Locale-specific number formatting
is done with the 'n' format specifier in which case either the current
locale is used or the user can provide a locale via a buffer. It might be
worth adding a simpler API for providing a custom locale, e.g. via a
separate format overload.
> I don't particularly like the partial reuse of the C formatting
conventions with a specified order of the parts of the format string, as it
is hard to learn.
I guess the grammar can be extended to allow reordering some of the
specifiers, but will create some questions such as how to handle duplicate
specifiers and why some specifiers can be reordered and some not (for
example, you can't move fill without introducing ambiguity). The current
syntax has the advantage that it has already been proven to work in Python
and Rust as well as a few C++ libraries.
> It may be better to send the formatting string snippet to format_value()
as a basic_string_view rather than relying on all the function overloads to
remember to bump the ptr correctly. At least provide a method in ctx to
forward the ptr and return the basic_string_view containing the format part
...
Providing such method sounds like a good idea. I'll add it to my TODO list.
> A maximum inserted length is often useful to limit the output.
Do you mean something like snprintf?
> It is hard to understand the "arg store" idea and how this goes together
with calling format_value on each parameter.
arg_store is basically an std::array of variants representing arguments.
For a user-defined type the variant stores a pointer to the object (as
void*) and a pointer to a little wrapper function that casts the pointer to
the correct type and invokes the format_value function.
> It may be that the fmt::args and basic_args are actually the same.
They are the same for the standard context type, but users can create
custom formatters and contexts. For example, one can implement a printf
formatter and a printf_context re-using much of the argument passing
machinery. In fact this is what the fmt library does - it implements both
Python-like and printf formatters.
> There is also arg_store and basic_arg and the visit() function which seem
more like internal details of the implementation.
arg_store needs to be exposed via the public API because this is the type
that stores the arguments, but it's opaque and won't be used directly most
of the time. Users who implement formatting functions can just use
make_args to construct it, e.g.:
template <class ...Args>
string format_error(cstring_view format_str, const Args&... args) {
return "error: " + vformat(format_str, make_args(args));
}
> Even as an implementation it seems overly complex, and I for one can't
understand how visit can call separate user defined format_value functions
if arg_store is not templated on the argument types.
As I mentioned above the argument types are erased (cast to void*) and
pointers to little helper functions that know how to recover the types are
passed around (https://github.com/fmtlib/fmt/blob/std/fmt/format.h#L1267).
The implementation is somewhat elaborate to achieve good performance and
extensibility but I tried to simplify is as much as I could.
> It would be nice if it was easy to create a formatting object from a
format specification string.
That's an interesting idea, let me think about it and get back to you.
Cheers,
Victor
On Tue, Jun 6, 2017 at 3:12 PM Bengt Gustafsson <
bengt.gustafsson@beamways.com> wrote:
> I like this functionality a lot, it has been sorely lacking in C++ and is
> becoming more and more a standard in many other languages.
>
> Some comments:
>
> - I would like the part before the : inside {} to allow any text. This
> allows translators to understand better the meaning of the inserted value
> and thus produce better translations. Not writing anything before the :
> would still
> be equivalent to writing the next consecutive number. I think you removed
> this capability from the python implementation as C++ does not have named
> arguments but it still has value in conveying information between
> programmer and the person doing translation.
>
> - Some kind of standard interface to internationalization string
> replacement could be incorporated in format(), so that we don't have to
> write _() or something around the literal.
>
> - How to specify using . for decimal char in a country where , is standard
> and vice versa. n only seems to relate to thousand separator handling, but
> the usual problem is to get the right decimal character in float number
> output. Many file formats (JSON for instance) require a dot even in
> countries where comma is standard. This is a recurring problem as "someone
> else" may set your locale on a global level. I have a similar library
> where I use comma or dot (in the dot position in the format string) to
> denote themselves as decimal char while semicolon denotes "the locale
> decimal char". While creating your own buffer type which overrides the
> locale() method is possible it is much more work than defining the decimal
> char in the format string.
>
> - I don't particularly like the partial reuse of the C formatting
> conventions with a specified order of the parts of the format string, as it
> is hard to learn. Sure, it is rather easy whern you have learned printf,
> but do we want future generations of programmers have to go through that
> detour? Better start from scratch with something logical, where the order
> of characters is not crucial.
>
> - It may be better to send the formatting string snippet to format_value()
> as a basic_string_view rather than relying on all the function overloads to
> remember to bump the ptr correctly. At least provide a method in ctx to
> forward the ptr and return the basic_string_view containing the format part
> in case you want to preserve the possibility to nest {} inside the
> formatting string. This simplifies for the fairly large share of
> format_value functions which are implemented but don't care about any
> formatting details.
>
> - A maximum inserted length is often useful to limit the output. One case
> is when formatting large doubles in the f format. This can get ridiculous
> in printf. Another is potentially long file names, where you may want to
> limit the string length.
>
> - It is hard to understand the "arg store" idea and how this goes together
> with calling format_value on each parameter. It may be that the fmt::args
> and basic_args are actually the same. There is also arg_store and basic_arg
> and the visit() function which seem more like internal details of the
> implementation. Even as an implementation it seems overly complex, and I
> for one can't understand how visit can call separate user defined
> format_value functions if arg_store is not templated on the argument types.
>
> - It would be nice if it was easy to create a formatting object from a
> format specification string. This object should have methods to format the
> standard types that fomat() works for "out of the box". In this way you can
> easily override format_value for instance for std::vector<T>, passing each
> element to a formatting object you have created. Of course you can also
> call format_value() for each T provided it exists, but this incurs quite an
> overhead as the same format specification string is parsed over and over
> again for each array element. Taking this thought to the logical conclusion
> means that the customization point for a user defined type should be a
> function create_formatter<T>(string_view format_specification_string)
> rather than format_value. The formatter returned from create_formatter then
> has a method format(const T& value) which does the formatting job. This
> allows the vector optimization to be taken to vectors of vectors etc.
> Continuing on this tangent I think it may make sense to allow pre-creating
> a formatting object for an entire format string, so that the parsing of
> that string occurs only once. Lets call this class formatter<Ts...>.
> Example:
>
> template<typename... Ts> class formatter {
> public:
> formatter(string_view format_string); // This parses the
> format_string and stores the objects returned from create_formatter<T> for
> each of the Ts.
>
> void run(buffer& buf, const Ts&.. args); // Perform the formatting
> to a buffer
> string run(buffer& buf, const Ts&... args); // Perform the formatting
> and return a string
> };
>
> // The format function is then defined as:
> template<typename... Ts> string format(string_view format_string, const
> Ts& values)
> {
> formatter<Ts...> fmt(format_string);
> return fmt.run(values...);
> }
> // A good compiler hopefully generates the same code as in the current
> implementation.
> // A loop for printing many lines would be more effective if written:
>
> formatter<int, string, double> fmt("#{IX}: {NAME}, {PRICE:.2"); //
> Preparse format
> for (item : inventory)
> cout << fmt.run(item.ix, item.name, item.price);
>
>
>
>
>
>
>
>
>
> Den tisdag 6 juni 2017 kl. 16:04:37 UTC+2 skrev Nicol Bolas:
>>
>> On Tuesday, June 6, 2017 at 9:41:26 AM UTC-4, Victor Zverovich wrote:
>>>
>>> I'm working on a proposal for a new formatting functionality for the C++
>>> standard library based on the fmt library (https://github.com/fmtlib/fmt
>>> ).
>>>
>>> The first draft of the proposal is available at
>>> http://fmtlib.net/Text%20Formatting.html and I would appreciate any
>>> comments.
>>>
>>> - Victor
>>>
>>
>> I'm concerned about this:
>>
>> The formatting library uses a null-terminated string view
>>> basic_cstring_view instead of basic_string_view. This results in
>>> somewhat smaller and faster code because the string size, which is not
>>> used, doesn't have to be computed and passed. Also having a termination
>>> character makes parsing easier.
>>>
>>
>> This really hurts users of `basic_string_view`, since their views are
>> *not* NUL-terminated. Such users don't necessarily have to calculate the
>> string size either; the `sv` user-defined literal will generate the size
>> based on the input literal.
>>
>> Your insistence on `basic_cstring_view` only aids scenarios where the
>> user has an unsized, NUL-terminated string. So they would have to not be
>> using `basic_string` or similar types (which are sized).
>>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/4777755b-5984-4ef3-8fc5-a3e17aa94469%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/4777755b-5984-4ef3-8fc5-a3e17aa94469%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANawtxahOu8AgCkNYUfpP%2BSsAAE12SeXyouq%3D0TB3ppfNf4h_g%40mail.gmail.com.
--94eb2c0e43d47150fa0551731080
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Thanks for such a detailed feedback.</div><div><br></=
div>> I would like the part before the : inside {} to allow any text.<di=
v><br></div><div><a href=3D"https://github.com/fmtlib/fmt">The fmt library<=
/a>, this proposal is based on, supports named arguments:</div><div><br></d=
iv><div>=C2=A0 format("The answer is {answer:}", arg(answer, 42))=
;<br><br>or, with user defined literals,</div><div><br></div><div>=C2=A0 fo=
rmat("The answer is {answer:}", "answer"_a=3D42);<br><b=
r>but I decided to omit this feature from the first draft of the proposal t=
o keep it manageable. It should be possible to add named arguments as an ex=
tension.</div><div><br></div><div>> Some kind of standard interface to i=
nternationalization string replacement could be incorporated in format(), s=
o that we don't have to write _() or something around the literal.</div=
><div><br></div><div>I think some i18n features can be built on top of this=
formatting library. In particular, a user can easily create a formatting f=
unction with the same API as `format` that looks up the format string in th=
e database of translations. This doesn't address marking string for tra=
nslation though. The latter is more of a tooling issue.</div><div><br></div=
><div>> How to specify using . for decimal char in a country where , is =
standard and vice versa.</div><div><br></div><div>As in Python, the default=
format is locale-independent for exactly the same reason that you mention =
- many output formats require this. So the default output uses '.' =
as a decimal separator. Locale-specific number formatting is done with the =
'n' format specifier in which case either the current locale is use=
d or the user can provide a locale via a buffer. It might be worth adding a=
simpler API for providing a custom locale, e.g. via a separate format over=
load.</div><div><br></div><div>> I don't particularly like the parti=
al reuse of the C formatting conventions with a specified order of the part=
s of the format string, as it is hard to learn.</div><div><br></div><div>I =
guess the grammar can be extended to allow reordering some of the specifier=
s, but will create some questions such as how to handle duplicate specifier=
s and why some specifiers can be reordered and some not (for example, you c=
an't move fill without introducing ambiguity). The current syntax has t=
he advantage that it has already been proven to work in Python and Rust as =
well as a few C++ libraries.</div><div><br></div><div>> It may be better=
to send the formatting string snippet to format_value() as a basic_string_=
view rather than relying on all the function overloads to remember to bump =
the ptr correctly. At least provide a method in ctx to forward the ptr and =
return the basic_string_view containing the format part<span class=3D"inbox=
-inbox-Apple-converted-space">=C2=A0...</span></div><div><span class=3D"inb=
ox-inbox-Apple-converted-space"><br></span></div><div>Providing such method=
sounds like a good idea. I'll add it to my TODO list.</div><div><span =
class=3D"inbox-inbox-Apple-converted-space"><br></span></div><div><span cla=
ss=3D"inbox-inbox-Apple-converted-space">>=C2=A0</span>A maximum inserte=
d length is often useful to limit the output.</div><div><br></div><div>Do y=
ou mean something like snprintf?</div><div><br></div><div>> It is hard t=
o understand the "arg store" idea and how this goes together with=
calling format_value on each parameter.</div><div><br></div><div>arg_store=
is basically an std::array of variants representing arguments. For a user-=
defined type the variant stores a pointer to the object (as void*) and a po=
inter to a little wrapper function that casts the pointer to the correct ty=
pe and invokes the format_value function.</div><div><br></div><div>> It =
may be that the fmt::args and basic_args are actually the same.</div><div><=
br></div><div>They are the same for the standard context type, but users ca=
n create custom formatters and contexts. For example, one can implement a p=
rintf formatter and a printf_context re-using much of the argument passing =
machinery. In fact this is what the fmt library does - it implements both P=
ython-like and printf formatters.</div><div><br></div><div>> There is al=
so arg_store and basic_arg and the visit() function which seem more like in=
ternal details of the implementation.</div><div><br></div><div>arg_store ne=
eds to be exposed via the public API because this is the type that stores t=
he arguments, but it's opaque and won't be used directly most of th=
e time. Users who implement formatting functions can just use make_args to =
construct it, e.g.:</div><div><div><br></div><div>template <class ...Arg=
s></div><div>string format_error(cstring_view format_str, const Args&=
;... args) {</div></div><div>=C2=A0 return "error: "=C2=A0+ vform=
at(format_str, make_args(args));</div><div>}</div><div><br></div><div>> =
Even as an implementation it seems overly complex, and I for one can't =
understand how visit can call separate user defined format_value functions =
if arg_store is not templated on the argument types.<br></div><div><br></di=
v><div>As I mentioned above the argument types are erased (cast to void*) a=
nd pointers to little helper functions that know how to recover the types a=
re passed around (<a href=3D"https://github.com/fmtlib/fmt/blob/std/fmt/for=
mat.h#L1267">https://github.com/fmtlib/fmt/blob/std/fmt/format.h#L1267</a>)=
.. The implementation is somewhat elaborate to achieve good performance and =
extensibility but I tried to simplify is as much as I could.</div><div><br>=
</div><div>> It would be nice if it was easy to create a formatting obje=
ct from a format specification string.</div><div><br></div><div>That's =
an interesting idea, let me think about it and get back to you.</div><div><=
br></div><div>Cheers,</div><div>Victor</div><div><br><div class=3D"gmail_qu=
ote"><div dir=3D"ltr">On Tue, Jun 6, 2017 at 3:12 PM Bengt Gustafsson <<=
a href=3D"mailto:bengt.gustafsson@beamways.com">bengt.gustafsson@beamways.c=
om</a>> wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margi=
n:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">=
<div>I like this functionality a lot, it has been sorely lacking in C++ and=
is becoming more and more a standard in many other languages.</div><div><b=
r></div><div>Some comments:<br></div><div><br></div><div>- I would like the=
part before the : inside {} to allow any text. This allows translators to =
understand better the meaning of the inserted value and thus produce better=
translations. Not writing anything before the : would still</div><div>be e=
quivalent to writing the next consecutive number. I think you removed this =
capability from the python implementation as C++ does not have named argume=
nts but it still has value in conveying information between programmer and =
the person doing translation.</div><div><br></div><div>- Some kind of stand=
ard interface to internationalization string replacement could be incorpora=
ted in format(), so that we don't have to write _() or something around=
the literal.</div><div><br></div><div>- How to specify using . for decimal=
char in a country where , is standard and vice versa. n only seems to rela=
te to thousand separator handling, but the usual problem is to get the righ=
t decimal character in float number output. Many file formats (JSON for ins=
tance) require a dot even in countries where comma is standard. This is a r=
ecurring problem as "someone else" may set your locale on a =C2=
=A0global level. I have a similar library where I use comma or dot (in the =
dot position in the format string) to denote themselves as decimal char whi=
le semicolon denotes "the locale decimal char". While creating yo=
ur own buffer type which overrides the locale() method is possible it is mu=
ch more work than defining the decimal char in the format string.</div><div=
><br></div><div>- I don't particularly like the partial reuse of the C =
formatting conventions with a specified order of the parts of the format st=
ring, as it is hard to learn. Sure, it is rather easy whern you have learne=
d printf, but do we want future generations of programmers have to go throu=
gh that detour? Better start from scratch with something logical, where the=
order of characters is not crucial.</div><div><br></div><div>- It may be b=
etter to send the formatting string snippet to format_value() as a basic_st=
ring_view rather than relying on all the function overloads to remember to =
bump the ptr correctly. At least provide a method in ctx to forward the ptr=
and return the basic_string_view containing the format part in case you wa=
nt to preserve the possibility to nest {} inside the formatting string. Thi=
s simplifies for the fairly large share of format_value functions which are=
implemented but don't care about any formatting details.</div><div><br=
></div><div>- A maximum inserted length is often useful to limit the output=
.. One case is when formatting large doubles in the f format. This can get r=
idiculous in printf. Another is potentially long file names, where you may =
want to limit the string length.</div><div><br></div><div>- It is hard to u=
nderstand the "arg store" idea and how this goes together with ca=
lling format_value on each parameter. It may be that the fmt::args and basi=
c_args are actually the same. There is also arg_store and basic_arg and the=
visit() function which seem more like internal details of the implementati=
on. Even as an implementation it seems overly complex, and I for one can=
9;t understand how visit can call separate user defined format_value functi=
ons if arg_store is not templated on the argument types.</div><div><br></di=
v><div>- It would be nice if it was easy to create a formatting object from=
a format specification string. This object should have methods to format t=
he standard types that fomat() works for "out of the box". In thi=
s way you can easily override format_value for instance for std::vector<=
T>, passing each element to a formatting object you have created. Of cou=
rse you can also call format_value() for each T provided it exists, but thi=
s incurs quite an overhead as the same format specification string is parse=
d over and over again for each array element. Taking this thought to the lo=
gical conclusion means that the customization point for a user defined type=
should be a function create_formatter<T>(string_view format_specific=
ation_string) rather than format_value. The formatter returned from create_=
formatter then has a method format(const T& value) which does the forma=
tting job. This allows the vector optimization to be taken to vectors of ve=
ctors etc. Continuing on this tangent I think it may make sense to allow pr=
e-creating a formatting object for an entire format string, so that the par=
sing of that string occurs only once. Lets call this class formatter<Ts.=
...>. Example:</div><div><br></div><div>template<typename... Ts> cl=
ass formatter {</div><div>public:</div><div>=C2=A0 =C2=A0 formatter(string_=
view format_string); =C2=A0// This parses the format_string and stores the =
objects returned from create_formatter<T> for each of the Ts.</div><d=
iv><br></div><div>=C2=A0 =C2=A0 void run(buffer& buf, const Ts&.. a=
rgs); =C2=A0 =C2=A0// Perform the formatting to a buffer</div><div>=C2=A0 =
=C2=A0 string run(buffer& buf, const Ts&... args); // Perform the f=
ormatting and return a string</div><div>};</div><div><br></div><div>// The =
format function is then defined as:</div><div>template<typename... Ts>=
; string format(string_view format_string, const Ts& values)</div><div>=
{</div><div>=C2=A0 =C2=A0 =C2=A0formatter<Ts...> fmt(format_string);<=
/div><div>=C2=A0 =C2=A0 =C2=A0return fmt.run(values...);</div><div>}</div><=
div>// A good compiler hopefully generates the same code as in the current =
implementation.</div><div>// A loop for printing many lines would be more e=
ffective if written:</div><div><br></div><div>formatter<int, string, dou=
ble> fmt("#{IX}: {NAME}, {PRICE:.2"); =C2=A0 // Preparse forma=
t</div><div>for (item : inventory)</div><div>=C2=A0 =C2=A0 cout << fm=
t.run(item.ix, <a href=3D"http://item.name" target=3D"_blank">item.name</a>=
, item.price);</div></div><div dir=3D"ltr"><div><br></div><div><br></div><d=
iv><br></div><div><br></div><div><br></div><div><br></div><div><br></div><d=
iv><br><br>Den tisdag 6 juni 2017 kl. 16:04:37 UTC+2 skrev Nicol Bolas:<blo=
ckquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On Tuesday, June 6, 20=
17 at 9:41:26 AM UTC-4, Victor Zverovich wrote:<blockquote class=3D"gmail_q=
uote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddin=
g-left:1ex"><div dir=3D"ltr"><div><span style=3D"font-size:13px;color:rgb(3=
3,33,33)">I'm working on a proposal for a new formatting functionality =
for the C++ standard library </span><span style=3D"color:rgb(33,33,33)"><sp=
an>based on the fmt library (</span></span><font color=3D"#212121"><a href=
=3D"https://github.com/fmtlib/fmt" rel=3D"nofollow" target=3D"_blank">https=
://github.com/fmtlib/fmt</a>).</font><br></div><div><span style=3D"font-siz=
e:13px;color:rgb(33,33,33)"><span><br></span></span></div><div><span style=
=3D"font-size:13px;color:rgb(33,33,33)"><span>The first draft of the propos=
al is available at=C2=A0</span></span><a href=3D"http://fmtlib.net/Text%20F=
ormatting.html" style=3D"font-size:13px" rel=3D"nofollow" target=3D"_blank"=
>http://fmtlib.net/Text%20Formatting.html</a><font color=3D"#212121">=C2=A0=
and I would appreciate any comments.</font></div><div><font color=3D"#21212=
1"><br></font></div><div><font color=3D"#212121">- Victor</font></div></div=
></blockquote><div><br>I'm concerned about this:<br><br><blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid =
rgb(204,204,204);padding-left:1ex">The formatting library uses a null-termi=
nated string view
<code>basic_cstring_view</code> instead of <code>basic_string_view</code>.
This results in somewhat smaller and faster code because the string size,
which is not used, doesn't have to be computed and passed. Also having
a termination character makes parsing easier. <br></blockquote><div><br>Thi=
s really hurts users of `basic_string_view`, since their views are <i>not</=
i> NUL-terminated. Such users don't necessarily have to calculate the s=
tring size either; the `sv` user-defined literal will generate the size bas=
ed on the input literal.<br><br>Your insistence on `basic_cstring_view` onl=
y aids scenarios where the user has an unsized, NUL-terminated string. So t=
hey would have to not be using `basic_string` or similar types (which are s=
ized).<br></div></div></div></blockquote></div></div>
<p></p>
-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/4777755b-5984-4ef3-8fc5-a3e17aa94469%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/4777755b-5984-=
4ef3-8fc5-a3e17aa94469%40isocpp.org</a>.<br>
</blockquote></div></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CANawtxahOu8AgCkNYUfpP%2BSsAAE12SeXyo=
uq%3D0TB3ppfNf4h_g%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANawtxahOu8A=
gCkNYUfpP%2BSsAAE12SeXyouq%3D0TB3ppfNf4h_g%40mail.gmail.com</a>.<br />
--94eb2c0e43d47150fa0551731080--
.
Author: =?UTF-8?Q?Klaim_=2D_Jo=C3=ABl_Lamotte?= <mjklaim@gmail.com>
Date: Thu, 8 Jun 2017 18:04:49 +0200
Raw View
--001a11415aca2792b10551750307
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
On 8 June 2017 at 15:45, Victor Zverovich <victor.zverovich@gmail.com>
wrote:
> Thanks for such a detailed feedback.
>
> > I would like the part before the : inside {} to allow any text.
>
> The fmt library <https://github.com/fmtlib/fmt>, this proposal is based
> on, supports named arguments:
>
> format("The answer is {answer:}", arg(answer, 42));
>
> or, with user defined literals,
>
> format("The answer is {answer:}", "answer"_a=3D42);
>
> but I decided to omit this feature from the first draft of the proposal t=
o
> keep it manageable. It should be possible to add named arguments as an
> extension.
>
Consider mentioning this in the paper in a section about potential
extensions.
Jo=C3=ABl Lamotte
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CAOU91OOthaUFnZhcerdPEDP3uOTcBW9k-K52UmuJm5DE2A4=
gfQ%40mail.gmail.com.
--001a11415aca2792b10551750307
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">=
On 8 June 2017 at 15:45, Victor Zverovich <span dir=3D"ltr"><<a href=3D"=
mailto:victor.zverovich@gmail.com" target=3D"_blank">victor.zverovich@gmail=
..com</a>></span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:=
1ex"><div>Thanks for such a detailed feedback.</div><span class=3D"gmail-">=
<div><br></div>> I would like the part before the : inside {} to allow a=
ny text.<div><br></div></span><div><a href=3D"https://github.com/fmtlib/fmt=
" target=3D"_blank">The fmt library</a>, this proposal is based on, support=
s named arguments:</div><div><br></div><div>=C2=A0 format("The answer =
is {answer:}", arg(answer, 42));<br><br>or, with user defined literals=
,</div><div><br></div><div>=C2=A0 format("The answer is {answer:}"=
;, "answer"_a=3D42);<br><br>but I decided to omit this feature fr=
om the first draft of the proposal to keep it manageable. It should be poss=
ible to add named arguments as an extension.</div></blockquote></div><br>Co=
nsider mentioning this in the paper in a section about potential extensions=
..<br></div><div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra">=
Jo=C3=ABl Lamotte</div><div class=3D"gmail_extra"><br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAOU91OOthaUFnZhcerdPEDP3uOTcBW9k-K52=
UmuJm5DE2A4gfQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOU91OOthaUFnZhc=
erdPEDP3uOTcBW9k-K52UmuJm5DE2A4gfQ%40mail.gmail.com</a>.<br />
--001a11415aca2792b10551750307--
.
Author: Victor Zverovich <victor.zverovich@gmail.com>
Date: Sat, 24 Jun 2017 18:52:37 +0000
Raw View
--94eb2c1959fe5106260552b939b5
Content-Type: text/plain; charset="UTF-8"
> It would be nice if it was easy to create a formatting object from a
format specification string.
I think this is a great idea and I finally got a chance to experiment with
it.
The main drawback of having a separate formatting object is that it makes
writing a formatter for a user-defined type more complicated, because you
need to define 3 things: a formatter class, a parsing function and a
formatting function. In the current proposal everything is combined in
format_value which, on one hand, leads to less boilerplate but, on the
other hand, is more restrictive.
template <>
class formatter<MyClass> {
public:
explicit formatter(context &ctx) {
// Parse the format string.
}
void format(buffer &buf, MyClass &value) {
// Format value.
}
private:
// Formatting state.
};
One way to reduce boilerplate is by returning the formatter object as a
lambda from the parsing function, e.g.
auto parse_format<MyClass>(context &ctx) {
// Parse the format string.
return [/* Formatting state */](buffer &buf, MyClass &value) {
// Format value.
};
}
Unfortunately this doesn't work if parse_format has to take additional
template arguments such as a char type:
// Doesn't compile
template <typename Char>
auto parse_format<MyClass>(basic_context<Char> &ctx) {
// Parse the format string.
return [/* Formatting state */](basic_buffer<Char> &buf, MyClass &value) {
// Format value.
};
}
A possible workaround is to use enable_if:
template <typename T, typename U>
using enable_format = typename std::enable_if<std::is_same<T,
U>::value>::type;
template <typename T, typename Char, typename = enable_format<T, MyClass>>
auto parse_format(basic_context<Char> &ctx) {
// Parse the format string.
return [/* Formatting state */](basic_buffer<Char> &buf, MyClass &value) {
// Format value.
};
}
This workaround does the job (implemented in experimental branch:
https://github.com/fmtlib/fmt/tree/ext) but I am not super happy about it.
Any ideas on how to improve this are appreciated.
Best regards,
Victor
On Tue, Jun 6, 2017 at 3:12 PM Bengt Gustafsson <
bengt.gustafsson@beamways.com> wrote:
> I like this functionality a lot, it has been sorely lacking in C++ and is
> becoming more and more a standard in many other languages.
>
> Some comments:
>
> - I would like the part before the : inside {} to allow any text. This
> allows translators to understand better the meaning of the inserted value
> and thus produce better translations. Not writing anything before the :
> would still
> be equivalent to writing the next consecutive number. I think you removed
> this capability from the python implementation as C++ does not have named
> arguments but it still has value in conveying information between
> programmer and the person doing translation.
>
> - Some kind of standard interface to internationalization string
> replacement could be incorporated in format(), so that we don't have to
> write _() or something around the literal.
>
> - How to specify using . for decimal char in a country where , is standard
> and vice versa. n only seems to relate to thousand separator handling, but
> the usual problem is to get the right decimal character in float number
> output. Many file formats (JSON for instance) require a dot even in
> countries where comma is standard. This is a recurring problem as "someone
> else" may set your locale on a global level. I have a similar library
> where I use comma or dot (in the dot position in the format string) to
> denote themselves as decimal char while semicolon denotes "the locale
> decimal char". While creating your own buffer type which overrides the
> locale() method is possible it is much more work than defining the decimal
> char in the format string.
>
> - I don't particularly like the partial reuse of the C formatting
> conventions with a specified order of the parts of the format string, as it
> is hard to learn. Sure, it is rather easy whern you have learned printf,
> but do we want future generations of programmers have to go through that
> detour? Better start from scratch with something logical, where the order
> of characters is not crucial.
>
> - It may be better to send the formatting string snippet to format_value()
> as a basic_string_view rather than relying on all the function overloads to
> remember to bump the ptr correctly. At least provide a method in ctx to
> forward the ptr and return the basic_string_view containing the format part
> in case you want to preserve the possibility to nest {} inside the
> formatting string. This simplifies for the fairly large share of
> format_value functions which are implemented but don't care about any
> formatting details.
>
> - A maximum inserted length is often useful to limit the output. One case
> is when formatting large doubles in the f format. This can get ridiculous
> in printf. Another is potentially long file names, where you may want to
> limit the string length.
>
> - It is hard to understand the "arg store" idea and how this goes together
> with calling format_value on each parameter. It may be that the fmt::args
> and basic_args are actually the same. There is also arg_store and basic_arg
> and the visit() function which seem more like internal details of the
> implementation. Even as an implementation it seems overly complex, and I
> for one can't understand how visit can call separate user defined
> format_value functions if arg_store is not templated on the argument types.
>
> - It would be nice if it was easy to create a formatting object from a
> format specification string. This object should have methods to format the
> standard types that fomat() works for "out of the box". In this way you can
> easily override format_value for instance for std::vector<T>, passing each
> element to a formatting object you have created. Of course you can also
> call format_value() for each T provided it exists, but this incurs quite an
> overhead as the same format specification string is parsed over and over
> again for each array element. Taking this thought to the logical conclusion
> means that the customization point for a user defined type should be a
> function create_formatter<T>(string_view format_specification_string)
> rather than format_value. The formatter returned from create_formatter then
> has a method format(const T& value) which does the formatting job. This
> allows the vector optimization to be taken to vectors of vectors etc.
> Continuing on this tangent I think it may make sense to allow pre-creating
> a formatting object for an entire format string, so that the parsing of
> that string occurs only once. Lets call this class formatter<Ts...>.
> Example:
>
> template<typename... Ts> class formatter {
> public:
> formatter(string_view format_string); // This parses the
> format_string and stores the objects returned from create_formatter<T> for
> each of the Ts.
>
> void run(buffer& buf, const Ts&.. args); // Perform the formatting
> to a buffer
> string run(buffer& buf, const Ts&... args); // Perform the formatting
> and return a string
> };
>
> // The format function is then defined as:
> template<typename... Ts> string format(string_view format_string, const
> Ts& values)
> {
> formatter<Ts...> fmt(format_string);
> return fmt.run(values...);
> }
> // A good compiler hopefully generates the same code as in the current
> implementation.
> // A loop for printing many lines would be more effective if written:
>
> formatter<int, string, double> fmt("#{IX}: {NAME}, {PRICE:.2"); //
> Preparse format
> for (item : inventory)
> cout << fmt.run(item.ix, item.name, item.price);
>
>
>
>
>
>
>
>
>
> Den tisdag 6 juni 2017 kl. 16:04:37 UTC+2 skrev Nicol Bolas:
>>
>> On Tuesday, June 6, 2017 at 9:41:26 AM UTC-4, Victor Zverovich wrote:
>>>
>>> I'm working on a proposal for a new formatting functionality for the C++
>>> standard library based on the fmt library (https://github.com/fmtlib/fmt
>>> ).
>>>
>>> The first draft of the proposal is available at
>>> http://fmtlib.net/Text%20Formatting.html and I would appreciate any
>>> comments.
>>>
>>> - Victor
>>>
>>
>> I'm concerned about this:
>>
>> The formatting library uses a null-terminated string view
>>> basic_cstring_view instead of basic_string_view. This results in
>>> somewhat smaller and faster code because the string size, which is not
>>> used, doesn't have to be computed and passed. Also having a termination
>>> character makes parsing easier.
>>>
>>
>> This really hurts users of `basic_string_view`, since their views are
>> *not* NUL-terminated. Such users don't necessarily have to calculate the
>> string size either; the `sv` user-defined literal will generate the size
>> based on the input literal.
>>
>> Your insistence on `basic_cstring_view` only aids scenarios where the
>> user has an unsized, NUL-terminated string. So they would have to not be
>> using `basic_string` or similar types (which are sized).
>>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/4777755b-5984-4ef3-8fc5-a3e17aa94469%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/4777755b-5984-4ef3-8fc5-a3e17aa94469%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANawtxZQEpgN7Uf_1%2BdCLDAtFT0DHKwfeAZjOwe8Y1jUdRKR2Q%40mail.gmail.com.
--94eb2c1959fe5106260552b939b5
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">>=C2=A0<span style=3D"color:rgb(33,33,33);font-size:13p=
x">It would be nice if it was easy to create a formatting object from a for=
mat specification string.</span><div><font color=3D"#212121"><br></font></d=
iv><div><font color=3D"#212121">I think this is a great idea and I finally =
got a chance to experiment with it.=C2=A0</font></div><div><font color=3D"#=
212121"><br></font></div><div><font color=3D"#212121">The main drawback of =
having a separate formatting object is that it makes writing a formatter fo=
r a user-defined type more complicated, because you need to define 3 things=
: a formatter class, a parsing function and a formatting function.=C2=A0</f=
ont><span style=3D"color:rgb(33,33,33)">In the current proposal everything =
is combined in format_value which, on one hand, leads to less boilerplate b=
ut, on the other hand, is more restrictive.</span></div><div><span style=3D=
"color:rgb(33,33,33)"><br></span></div><div><span style=3D"color:rgb(33,33,=
33)">template <></span></div><div><font color=3D"#212121">class forma=
tter<MyClass> {</font></div><div><font color=3D"#212121">=C2=A0public=
:</font></div><div><font color=3D"#212121">=C2=A0 explicit formatter(contex=
t &ctx) {</font></div><div><font color=3D"#212121">=C2=A0 =C2=A0 // Par=
se the format string.</font></div><div><font color=3D"#212121">=C2=A0 }</fo=
nt></div><div><font color=3D"#212121"><br></font></div><div><font color=3D"=
#212121">=C2=A0 void format(</font><span style=3D"color:rgb(33,33,33)">buff=
er &buf, MyClass &value) {</span></div><div><span style=3D"color:rg=
b(33,33,33)">=C2=A0 =C2=A0=C2=A0</span><span style=3D"color:rgb(33,33,33)">=
// Format value.</span></div><div><span style=3D"color:rgb(33,33,33)">=C2=
=A0 }</span></div><div><font color=3D"#212121"><br></font></div><div><font =
color=3D"#212121">=C2=A0private:</font></div><div><font color=3D"#212121">=
=C2=A0 // Formatting state.</font></div><div><font color=3D"#212121">};</fo=
nt></div><div><font color=3D"#212121"><br></font></div><div><font color=3D"=
#212121">One way to reduce boilerplate is by returning the formatter object=
as a lambda from the parsing function, e.g.</font></div><div><br></div><di=
v><font color=3D"#212121">auto parse_format<MyClass>(context &ctx=
) {</font></div><div><font color=3D"#212121">=C2=A0 // Parse the format str=
ing.</font></div><div><font color=3D"#212121">=C2=A0 return [/* Formatting =
state */](buffer &buf, MyClass &value) {</font></div><div><font col=
or=3D"#212121">=C2=A0 =C2=A0 // Format value.</font></div><div><font color=
=3D"#212121">=C2=A0 };</font></div><div><font color=3D"#212121">}</font></d=
iv><div><br></div><div><font color=3D"#212121">Unfortunately this doesn'=
;t work if=C2=A0</font><span style=3D"color:rgb(33,33,33)">parse_format has=
to take additional template arguments such as a char type:</span></div><di=
v><span style=3D"color:rgb(33,33,33)"><br></span></div><div><span style=3D"=
color:rgb(33,33,33)">// Doesn't compile</span></div><div><span style=3D=
"color:rgb(33,33,33)">template <typename Char></span></div><div><div>=
<font color=3D"#212121">auto parse_format<MyClass>(basic_context<C=
har> &ctx) {</font></div><div><font color=3D"#212121">=C2=A0 // Pars=
e the format string.</font></div><div><font color=3D"#212121">=C2=A0 return=
[/*=C2=A0</font><span style=3D"color:rgb(33,33,33)">Formatting state</span=
><font color=3D"#212121">=C2=A0*/](basic_buffer<Char> &buf, MyCla=
ss &value) {</font></div><div><font color=3D"#212121">=C2=A0 =C2=A0 // =
Format value.</font></div><div><font color=3D"#212121">=C2=A0 };</font></di=
v><div><font color=3D"#212121">}</font></div></div><div><font color=3D"#212=
121"><br></font></div><div><font color=3D"#212121">A possible workaround is=
to use enable_if:</font></div><div><font color=3D"#212121"><br></font></di=
v><div><font color=3D"#212121"><div>template <typename T, typename U>=
</div><div>using enable_format =3D typename std::enable_if<std::is_same&=
lt;T, U>::value>::type;</div><div><br></div><div><div style=3D"color:=
rgb(0,0,0)"><span style=3D"color:rgb(33,33,33)">template <typename T, ty=
pename Char, typename =3D enable_format<T, MyClass>></span></div><=
div style=3D"color:rgb(0,0,0)"><div><font color=3D"#212121">auto parse_form=
at(basic_context<Char> &ctx) {</font></div><div><font color=3D"#2=
12121">=C2=A0 // Parse the format string.</font></div><div><font color=3D"#=
212121">=C2=A0 return [/*=C2=A0</font><span style=3D"color:rgb(33,33,33)">F=
ormatting state</span><font color=3D"#212121">=C2=A0*/](basic_buffer<Cha=
r> &buf, MyClass &value) {</font></div><div><font color=3D"#2121=
21">=C2=A0 =C2=A0 // Format value.</font></div><div><font color=3D"#212121"=
>=C2=A0 };</font></div><div><font color=3D"#212121">}</font></div><div><fon=
t color=3D"#212121"><br></font></div><div><font color=3D"#212121">This work=
around does the job (implemented in experimental branch:=C2=A0</font><a hre=
f=3D"https://github.com/fmtlib/fmt/tree/ext">https://github.com/fmtlib/fmt/=
tree/ext</a><span style=3D"color:rgb(33,33,33)">)</span><span style=3D"colo=
r:rgb(33,33,33)">=C2=A0but I am not super happy about it. Any ideas on how =
to improve this are appreciated.</span></div><div><span style=3D"color:rgb(=
33,33,33)"><br></span></div><div><span style=3D"color:rgb(33,33,33)">Best r=
egards,</span></div><div><span style=3D"color:rgb(33,33,33)">Victor</span><=
/div></div></div></font></div><div><br><div class=3D"gmail_quote"><div dir=
=3D"ltr">On Tue, Jun 6, 2017 at 3:12 PM Bengt Gustafsson <<a href=3D"mai=
lto:bengt.gustafsson@beamways.com">bengt.gustafsson@beamways.com</a>> wr=
ote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;=
border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>I like t=
his functionality a lot, it has been sorely lacking in C++ and is becoming =
more and more a standard in many other languages.</div><div><br></div><div>=
Some comments:<br></div><div><br></div><div>- I would like the part before =
the : inside {} to allow any text. This allows translators to understand be=
tter the meaning of the inserted value and thus produce better translations=
.. Not writing anything before the : would still</div><div>be equivalent to =
writing the next consecutive number. I think you removed this capability fr=
om the python implementation as C++ does not have named arguments but it st=
ill has value in conveying information between programmer and the person do=
ing translation.</div><div><br></div><div>- Some kind of standard interface=
to internationalization string replacement could be incorporated in format=
(), so that we don't have to write _() or something around the literal.=
</div><div><br></div><div>- How to specify using . for decimal char in a co=
untry where , is standard and vice versa. n only seems to relate to thousan=
d separator handling, but the usual problem is to get the right decimal cha=
racter in float number output. Many file formats (JSON for instance) requir=
e a dot even in countries where comma is standard. This is a recurring prob=
lem as "someone else" may set your locale on a =C2=A0global level=
.. I have a similar library where I use comma or dot (in the dot position in=
the format string) to denote themselves as decimal char while semicolon de=
notes "the locale decimal char". While creating your own buffer t=
ype which overrides the locale() method is possible it is much more work th=
an defining the decimal char in the format string.</div><div><br></div><div=
>- I don't particularly like the partial reuse of the C formatting conv=
entions with a specified order of the parts of the format string, as it is =
hard to learn. Sure, it is rather easy whern you have learned printf, but d=
o we want future generations of programmers have to go through that detour?=
Better start from scratch with something logical, where the order of chara=
cters is not crucial.</div><div><br></div><div>- It may be better to send t=
he formatting string snippet to format_value() as a basic_string_view rathe=
r than relying on all the function overloads to remember to bump the ptr co=
rrectly. At least provide a method in ctx to forward the ptr and return the=
basic_string_view containing the format part in case you want to preserve =
the possibility to nest {} inside the formatting string. This simplifies fo=
r the fairly large share of format_value functions which are implemented bu=
t don't care about any formatting details.</div><div><br></div><div>- A=
maximum inserted length is often useful to limit the output. One case is w=
hen formatting large doubles in the f format. This can get ridiculous in pr=
intf. Another is potentially long file names, where you may want to limit t=
he string length.</div><div><br></div><div>- It is hard to understand the &=
quot;arg store" idea and how this goes together with calling format_va=
lue on each parameter. It may be that the fmt::args and basic_args are actu=
ally the same. There is also arg_store and basic_arg and the visit() functi=
on which seem more like internal details of the implementation. Even as an =
implementation it seems overly complex, and I for one can't understand =
how visit can call separate user defined format_value functions if arg_stor=
e is not templated on the argument types.</div><div><br></div><div>- It wou=
ld be nice if it was easy to create a formatting object from a format speci=
fication string. This object should have methods to format the standard typ=
es that fomat() works for "out of the box". In this way you can e=
asily override format_value for instance for std::vector<T>, passing =
each element to a formatting object you have created. Of course you can als=
o call format_value() for each T provided it exists, but this incurs quite =
an overhead as the same format specification string is parsed over and over=
again for each array element. Taking this thought to the logical conclusio=
n means that the customization point for a user defined type should be a fu=
nction create_formatter<T>(string_view format_specification_string) r=
ather than format_value. The formatter returned from create_formatter then =
has a method format(const T& value) which does the formatting job. This=
allows the vector optimization to be taken to vectors of vectors etc. Cont=
inuing on this tangent I think it may make sense to allow pre-creating a fo=
rmatting object for an entire format string, so that the parsing of that st=
ring occurs only once. Lets call this class formatter<Ts...>. Example=
:</div><div><br></div><div>template<typename... Ts> class formatter {=
</div><div>public:</div><div>=C2=A0 =C2=A0 formatter(string_view format_str=
ing); =C2=A0// This parses the format_string and stores the objects returne=
d from create_formatter<T> for each of the Ts.</div><div><br></div><d=
iv>=C2=A0 =C2=A0 void run(buffer& buf, const Ts&.. args); =C2=A0 =
=C2=A0// Perform the formatting to a buffer</div><div>=C2=A0 =C2=A0 string =
run(buffer& buf, const Ts&... args); // Perform the formatting and =
return a string</div><div>};</div><div><br></div><div>// The format functio=
n is then defined as:</div><div>template<typename... Ts> string forma=
t(string_view format_string, const Ts& values)</div><div>{</div><div>=
=C2=A0 =C2=A0 =C2=A0formatter<Ts...> fmt(format_string);</div><div>=
=C2=A0 =C2=A0 =C2=A0return fmt.run(values...);</div><div>}</div><div>// A g=
ood compiler hopefully generates the same code as in the current implementa=
tion.</div><div>// A loop for printing many lines would be more effective i=
f written:</div><div><br></div><div>formatter<int, string, double> fm=
t("#{IX}: {NAME}, {PRICE:.2"); =C2=A0 // Preparse format</div><di=
v>for (item : inventory)</div><div>=C2=A0 =C2=A0 cout << fmt.run(item=
..ix, <a href=3D"http://item.name" target=3D"_blank">item.name</a>, item.pri=
ce);</div></div><div dir=3D"ltr"><div><br></div><div><br></div><div><br></d=
iv><div><br></div><div><br></div><div><br></div><div><br></div><div><br><br=
>Den tisdag 6 juni 2017 kl. 16:04:37 UTC+2 skrev Nicol Bolas:<blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #cc=
c solid;padding-left:1ex"><div dir=3D"ltr">On Tuesday, June 6, 2017 at 9:41=
:26 AM UTC-4, Victor Zverovich wrote:<blockquote class=3D"gmail_quote" styl=
e=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex=
"><div dir=3D"ltr"><div><span style=3D"font-size:13px;color:rgb(33,33,33)">=
I'm working on a proposal for a new formatting functionality for the C+=
+ standard library </span><span style=3D"color:rgb(33,33,33)"><span>based o=
n the fmt library (</span></span><font color=3D"#212121"><a href=3D"https:/=
/github.com/fmtlib/fmt" rel=3D"nofollow" target=3D"_blank">https://github.c=
om/fmtlib/fmt</a>).</font><br></div><div><span style=3D"font-size:13px;colo=
r:rgb(33,33,33)"><span><br></span></span></div><div><span style=3D"font-siz=
e:13px;color:rgb(33,33,33)"><span>The first draft of the proposal is availa=
ble at=C2=A0</span></span><a href=3D"http://fmtlib.net/Text%20Formatting.ht=
ml" style=3D"font-size:13px" rel=3D"nofollow" target=3D"_blank">http://fmtl=
ib.net/Text%20Formatting.html</a><font color=3D"#212121">=C2=A0and I would =
appreciate any comments.</font></div><div><font color=3D"#212121"><br></fon=
t></div><div><font color=3D"#212121">- Victor</font></div></div></blockquot=
e><div><br>I'm concerned about this:<br><br><blockquote class=3D"gmail_=
quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,=
204);padding-left:1ex">The formatting library uses a null-terminated string=
view
<code>basic_cstring_view</code> instead of <code>basic_string_view</code>.
This results in somewhat smaller and faster code because the string size,
which is not used, doesn't have to be computed and passed. Also having
a termination character makes parsing easier. <br></blockquote><div><br>Thi=
s really hurts users of `basic_string_view`, since their views are <i>not</=
i> NUL-terminated. Such users don't necessarily have to calculate the s=
tring size either; the `sv` user-defined literal will generate the size bas=
ed on the input literal.<br><br>Your insistence on `basic_cstring_view` onl=
y aids scenarios where the user has an unsized, NUL-terminated string. So t=
hey would have to not be using `basic_string` or similar types (which are s=
ized).<br></div></div></div></blockquote></div></div>
<p></p>
-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/4777755b-5984-4ef3-8fc5-a3e17aa94469%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/4777755b-5984-=
4ef3-8fc5-a3e17aa94469%40isocpp.org</a>.<br>
</blockquote></div></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CANawtxZQEpgN7Uf_1%2BdCLDAtFT0DHKwfeA=
ZjOwe8Y1jUdRKR2Q%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANawtxZQEpgN7U=
f_1%2BdCLDAtFT0DHKwfeAZjOwe8Y1jUdRKR2Q%40mail.gmail.com</a>.<br />
--94eb2c1959fe5106260552b939b5--
.