Topic: string_view::is_null()
Author: abolz.lists@gmail.com
Date: Fri, 27 Dec 2013 04:52:12 -0800 (PST)
Raw View
------=_Part_5003_473001.1388148732176
Content-Type: text/plain; charset=ISO-8859-1
Is there a reason why string_view is not nullable?
Nullable here means default constructed or constructed from a nullptr
(and a zero length). Then adding a is_null() (or null()) member
function which can then be used to distinguish the string_view from an
empty string.
This should not affect data() which returns a non-null pointer.
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_5003_473001.1388148732176
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><p>Is there a reason why string_view is not nullable?</p><=
div>Nullable here means default constructed or constructed from a null=
ptr</div><div>(and a zero length). Then adding a is_null() (or null()) memb=
er</div><div>function which can then be used to distinguish the string_view=
from an</div><div>empty string.</div><div><br></div><p>This should not aff=
ect data() which returns a non-null pointer.<br></p></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_5003_473001.1388148732176--
.
Author: "=?utf-8?B?YmlsbHkub25lYWxAZ21haWwuY29t?=" <billy.oneal@gmail.com>
Date: Fri, 27 Dec 2013 08:28:47 -0800
Raw View
------=_Part_0_1388161727454
Content-Type: text/plain; charset=ISO-8859-1
Content-Disposition: inline
Because it is designed to approximate a "std::string const&" which isn't nullable either.
Sent from a touchscreen. Please excuse the brevity and tpyos.
----- Reply message -----
From: abolz.lists@gmail.com
To: <std-proposals@isocpp.org>
Subject: [std-proposals] string_view::is_null()
Date: Fri, Dec 27, 2013 4:52 AM
Is there a reason why string_view is not nullable?Nullable here means default constructed or constructed from a nullptr
(and a zero length). Then adding a is_null() (or null()) member
function which can then be used to distinguish the string_view from an
empty string.
This should not affect data() which returns a non-null pointer.
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_0_1388161727454
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline
<div style=3D"font-size: 12pt; font-family: Calibri,sans-serif;"><div>Becau=
se it is designed to approximate a "std::string const&" which isn't nul=
lable either.</div><div><br></div><div>Sent from a touchscreen. Please excu=
se the brevity and tpyos.</div><br><div id=3D"htc_header">----- Reply messa=
ge -----<br>From: abolz.lists@gmail.com<br>To: <std-proposals@isocpp.org=
><br>Subject: [std-proposals] string_view::is_null()<br>Date: Fri, Dec 2=
7, 2013 4:52 AM</div></div><br><div dir=3D"ltr"><p>Is there a reason why st=
ring_view is not nullable?</p><div>Nullable here means default constru=
cted or constructed from a nullptr</div><div>(and a zero length). Then addi=
ng a is_null() (or null()) member</div><div>function which can then be used=
to distinguish the string_view from an</div><div>empty string.</div><div><=
br></div><p>This should not affect data() which returns a non-null pointer.=
<br></p></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_0_1388161727454--
.
Author: Marshall Clow <mclow.lists@gmail.com>
Date: Fri, 27 Dec 2013 21:01:34 -0800
Raw View
--Apple-Mail=_18F814F5-564C-478D-85DC-021547C3D448
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=windows-1252
On Dec 27, 2013, at 4:52 AM, abolz.lists@gmail.com wrote:
> Is there a reason why string_view is not nullable?
>=20
> Nullable here means default constructed or constructed from a nullptr
> (and a zero length). Then adding a is_null() (or null()) member
> function which can then be used to distinguish the string_view from an
> empty string.
i think that attempting to distinguish between an empty string_view that =
=93used to point at something=94
and an empty string view =93that never pointed at anything=94 is a use case=
to be discouraged, rather than
something that should be enshrined in the standard.
> This should not affect data() which returns a non-null pointer.
>=20
I disagree here with the proposal as currently written.
I believe that the requirement that data() always return a non-null pointer=
is misguided.
if sv.size () =3D=3D 0 or sv.empty () [same thing], there is nothing that y=
ou can do with sv.data()
(except compare it to null, and that doesn=92t tell you anything useful).
An empty string view need not point *anywhere*, or have any data behind it.
=97 Marshall
P.S. In my implementation, I=92m tempted to have a default-constructed stri=
ng_view return a value of 1 from data().
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--Apple-Mail=_18F814F5-564C-478D-85DC-021547C3D448
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=windows-1252
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;">On Dec 27, 2013, at 4:=
52 AM, <a href=3D"mailto:abolz.lists@gmail.com">abolz.lists@gmail.com</a> w=
rote:<br><div><br class=3D"Apple-interchange-newline"><blockquote type=3D"c=
ite"><div dir=3D"ltr"><p>Is there a reason why string_view is not nullable?=
</p><div>Nullable here means default constructed or constructed from a=
nullptr</div><div>(and a zero length). Then adding a is_null() (or null())=
member</div><div>function which can then be used to distinguish the string=
_view from an</div><div>empty string.</div></div></blockquote><div><br></di=
v>i think that attempting to distinguish between an empty string_view that =
=93used to point at something=94</div><div>and an empty string view =93that=
never pointed at anything=94 is a use case to be discouraged, rather than<=
/div><div>something that should be enshrined in the standard.</div><div><br=
></div><div><blockquote type=3D"cite"><div dir=3D"ltr"><p>This should not a=
ffect data() which returns a non-null pointer.</p></div></blockquote></div>=
<div>I disagree here with the proposal as currently written.</div><div><div=
>I believe that the requirement that data() always return a non-null pointe=
r is misguided.</div><div><br></div></div><div>if sv.size () =3D=3D 0 or sv=
..empty () [same thing], there is nothing that you can do with sv.data()</di=
v><div>(except compare it to null, and that doesn=92t tell you anything use=
ful).</div><div><br></div><div>An empty string view need not point *anywher=
e*, or have any data behind it.</div><div><br></div><div>=97 Marshall</div>=
<div><br></div><div>P.S.<span class=3D"Apple-tab-span" style=3D"white-space=
:pre"> </span>In my implementation, I=92m tempted to have a default-co=
nstructed string_view return a value of 1 from data().</div><div><br></div>=
</body></html>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--Apple-Mail=_18F814F5-564C-478D-85DC-021547C3D448--
.
Author: Jeffrey Yasskin <jyasskin@google.com>
Date: Sat, 28 Dec 2013 09:59:37 -0800
Raw View
--047d7bdc90bc8f2fac04ee9bfa65
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable
On Fri, Dec 27, 2013 at 9:01 PM, Marshall Clow <mclow.lists@gmail.com>wrote=
:
> On Dec 27, 2013, at 4:52 AM, abolz.lists@gmail.com wrote:
>
> Is there a reason why string_view is not nullable?
> Nullable here means default constructed or constructed from a nullptr
> (and a zero length). Then adding a is_null() (or null()) member
> function which can then be used to distinguish the string_view from an
> empty string.
>
>
> i think that attempting to distinguish between an empty string_view that
> =93used to point at something=94
> and an empty string view =93that never pointed at anything=94 is a use ca=
se to
> be discouraged, rather than
> something that should be enshrined in the standard.
>
> This should not affect data() which returns a non-null pointer.
>
> I disagree here with the proposal as currently written.
> I believe that the requirement that data() always return a non-null
> pointer is misguided.
>
> if sv.size () =3D=3D 0 or sv.empty () [same thing], there is nothing that=
you
> can do with sv.data()
> (except compare it to null, and that doesn=92t tell you anything useful).
>
The thing is, if nullptr is a possible return value for data(), people do
start using it to convey information. If they get a null out exactly when
they put a null in, it is telling them something useful. The only way to
"discourage" it is to make it never happen. If we let string_view::data()
pass through null, we're enshrining the use you don't like in the standard.
>
> An empty string view need not point *anywhere*, or have any data behind i=
t.
>
> =97 Marshall
>
> P.S. In my implementation, I=92m tempted to have a default-constructed
> string_view return a value of 1 from data().
>
That's totally fine on all the platforms I've ever used. There are a few
I've heard of where it could be a problem, but no need to worry about those
until your implementation gets ported to them.
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--047d7bdc90bc8f2fac04ee9bfa65
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On F=
ri, Dec 27, 2013 at 9:01 PM, Marshall Clow <span dir=3D"ltr"><<a href=3D=
"mailto:mclow.lists@gmail.com" target=3D"_blank" class=3D"cremed">mclow.lis=
ts@gmail.com</a>></span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div style=3D"word-wrap:break-word"><div cla=
ss=3D"im">On Dec 27, 2013, at 4:52 AM, <a href=3D"mailto:abolz.lists@gmail.=
com" target=3D"_blank" class=3D"cremed">abolz.lists@gmail.com</a> wrote:<br=
>
</div><div><div class=3D"im"><br><blockquote type=3D"cite"><div dir=3D"ltr"=
><p>Is there a reason why string_view is not nullable?</p><div>Nullable her=
e=A0means default constructed or constructed from a nullptr</div><div>(and =
a zero length). Then adding a is_null() (or null()) member</div>
<div>function which can then be used to distinguish the string_view from an=
</div><div>empty string.</div></div></blockquote><div><br></div></div>i thi=
nk that attempting to distinguish between an empty string_view that =93used=
to point at something=94</div>
<div>and an empty string view =93that never pointed at anything=94 is a use=
case to be discouraged, rather than</div><div>something that should be ens=
hrined in the standard.</div><div class=3D"im"><div><br></div><div><blockqu=
ote type=3D"cite">
<div dir=3D"ltr"><p>This should not affect data() which returns a non-null =
pointer.</p></div></blockquote></div></div><div>I disagree here with the pr=
oposal as currently written.</div><div><div>I believe that the requirement =
that data() always return a non-null pointer is misguided.=A0</div>
</div></div></blockquote><blockquote class=3D"gmail_quote" style=3D"margin:=
0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style=3D"word-=
wrap:break-word"><div><div><br></div></div><div>if sv.size () =3D=3D 0 or s=
v.empty () [same thing], there is nothing that you can do with sv.data()</d=
iv>
<div>(except compare it to null, and that doesn=92t tell you anything usefu=
l).</div></div></blockquote><div><br></div><div>The thing is, if nullptr is=
a possible return value for data(), people do start using it to convey inf=
ormation. If they get a null out exactly when they put a null in, it is tel=
ling them something useful. The only way to "discourage" it is to=
make it never happen. If we let string_view::data() pass through null, we&=
#39;re enshrining the use you don't like in the standard.</div>
<div>=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;=
border-left:1px #ccc solid;padding-left:1ex"><div style=3D"word-wrap:break-=
word"><div><br></div><div>An empty string view need not point *anywhere*, o=
r have any data behind it.</div>
<span class=3D"HOEnZb"><font color=3D"#888888"><div><br></div><div>=97 Mars=
hall</div></font></span><div><br></div><div>P.S.<span style=3D"white-space:=
pre-wrap"> </span>In my implementation,=A0I=92m tempted to have a default-c=
onstructed string_view return a value of 1 from data().</div>
</div></blockquote><div><br></div><div>That's totally fine on all the p=
latforms I've ever used. There are a few I've heard of where it cou=
ld be a problem, but no need to worry about those until your implementation=
gets ported to them.</div>
</div></div></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--047d7bdc90bc8f2fac04ee9bfa65--
.
Author: Peter Bigot <bigotp@acm.org>
Date: Sat, 28 Dec 2013 11:21:12 -0800 (PST)
Raw View
------=_Part_1548_9020491.1388258472691
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable
On Friday, December 27, 2013 11:01:34 PM UTC-6, Marshall wrote:
>
> On Dec 27, 2013, at 4:52 AM, abolz...@gmail.com <javascript:> wrote:
>
> Is there a reason why string_view is not nullable?
> Nullable here means default constructed or constructed from a nullptr
> (and a zero length). Then adding a is_null() (or null()) member
> function which can then be used to distinguish the string_view from an
> empty string.
>
>
> i think that attempting to distinguish between an empty string_view that=
=20
> =93used to point at something=94
> and an empty string view =93that never pointed at anything=94 is a use ca=
se to=20
> be discouraged, rather than
> something that should be enshrined in the standard.
>
-1 ; I think it's an obvious and valuable feature.
This should not affect data() which returns a non-null pointer.
>
> I disagree here with the proposal as currently written.
> I believe that the requirement that data() always return a non-null=20
> pointer is misguided.
>
> if sv.size () =3D=3D 0 or sv.empty () [same thing], there is nothing that=
you=20
> can do with sv.data()
> (except compare it to null, and that doesn=92t tell you anything useful).
>
My understanding (which I'd like confirmed) is that sv.data() is still=20
useful as it provides a valid position within the referenced object, which=
=20
might be referenced by other string_view instances or in its native form.
Thus, for example, a function object conforming to the delimiters interface=
=20
documented at=20
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3593.html#delimite=
rs=20
might return a zero-length string to denote a zero-length delimiter (e.g.,=
=20
the position following a period in an English sentence). In this case it=
=20
is the value of sv.data() that tells the caller where the delimited=20
sequence ends and the next sequence begins.
=20
>
> An empty string view need not point *anywhere*, or have any data behind i=
t.
>
> =97 Marshall
>
> P.S. In my implementation, I=92m tempted to have a default-constructed=20
> string_view return a value of 1 from data().
>
>
As I understand it there is no expression that can legitimately dereference=
=20
that pointer, so it sounds like a clean solution to the problem.
Peter
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_1548_9020491.1388258472691
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br>On Friday, December 27, 2013 11:01:34 PM UTC-6, Marsha=
ll wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"word-wr=
ap:break-word">On Dec 27, 2013, at 4:52 AM, <a href=3D"javascript:" target=
=3D"_blank" gdf-obfuscated-mailto=3D"XU-iYk-oi4kJ" onmousedown=3D"this.href=
=3D'javascript:';return true;" onclick=3D"this.href=3D'javascript:';return =
true;">abolz...@gmail.com</a> wrote:<br><div><br><blockquote type=3D"cite">=
<div dir=3D"ltr"><p>Is there a reason why string_view is not nullable?</p><=
div>Nullable here means default constructed or constructed from a null=
ptr</div><div>(and a zero length). Then adding a is_null() (or null()) memb=
er</div><div>function which can then be used to distinguish the string_view=
from an</div><div>empty string.</div></div></blockquote><div><br></div>i t=
hink that attempting to distinguish between an empty string_view that =93us=
ed to point at something=94</div><div>and an empty string view =93that neve=
r pointed at anything=94 is a use case to be discouraged, rather than</div>=
<div>something that should be enshrined in the standard.</div></div></block=
quote><div><br>-1 ; I think it's an obvious and valuable feature.<br><br></=
div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex=
;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"word-wrap:br=
eak-word"><div></div><div><blockquote type=3D"cite"><div dir=3D"ltr"><p>Thi=
s should not affect data() which returns a non-null pointer.</p></div></blo=
ckquote></div><div>I disagree here with the proposal as currently written.<=
/div><div><div>I believe that the requirement that data() always return a n=
on-null pointer is misguided.</div><div><br></div></div><div>if sv.size () =
=3D=3D 0 or sv.empty () [same thing], there is nothing that you can do with=
sv.data()</div><div>(except compare it to null, and that doesn=92t tell yo=
u anything useful).</div></div></blockquote><div><br>My understanding (whic=
h I'd like confirmed) is that sv.data() is still useful as it provides a va=
lid position within the referenced object, which might be referenced by oth=
er string_view instances or in its native form.<br><br>Thus, for example, a=
function object conforming to the delimiters interface documented at http:=
//www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3593.html#delimiters mi=
ght return a zero-length string to denote a zero-length delimiter (e.g., th=
e position following a period in an English sentence). In this case i=
t is the value of sv.data() that tells the caller where the delimited seque=
nce ends and the next sequence begins.<br><br> <br></div><blockquote c=
lass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px=
#ccc solid;padding-left: 1ex;"><div style=3D"word-wrap:break-word"><div><b=
r></div><div>An empty string view need not point *anywhere*, or have any da=
ta behind it.</div><div><br></div><div>=97 Marshall</div><div><br></div><di=
v>P.S.<span style=3D"white-space:pre"> </span>In my implementation, I=
=92m tempted to have a default-constructed string_view return a value of 1 =
from data().</div><div><br></div></div></blockquote><div><br>As I understan=
d it there is no expression that can legitimately dereference that pointer,=
so it sounds like a clean solution to the problem.<br><br>Peter<br></div><=
/div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_1548_9020491.1388258472691--
.
Author: Peter Bigot <bigotp@acm.org>
Date: Sat, 28 Dec 2013 11:27:52 -0800 (PST)
Raw View
------=_Part_1283_28188992.1388258872556
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable
On Saturday, December 28, 2013 1:21:12 PM UTC-6, Peter Bigot wrote:
>
>
> On Friday, December 27, 2013 11:01:34 PM UTC-6, Marshall wrote:
>>
>>
>> if sv.size () =3D=3D 0 or sv.empty () [same thing], there is nothing tha=
t you=20
>> can do with sv.data()
>> (except compare it to null, and that doesn=92t tell you anything useful)=
..
>>
>
> My understanding (which I'd like confirmed) is that sv.data() is still=20
> useful as it provides a valid position within the referenced object, whic=
h=20
> might be referenced by other string_view instances or in its native form.
>
> Thus, for example, a function object conforming to the delimiters=20
> interface documented at=20
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3593.html#delimi=
tersmight return a zero-length string to denote a zero-length delimiter (e.=
g.,=20
> the position following a period in an English sentence). In this case it=
=20
> is the value of sv.data() that tells the caller where the delimited=20
> sequence ends and the next sequence begins.
>
>
Sorry; I misread the details of that proposal: it explicitly uses an empty=
=20
delimiter to indicate "not found" (too bad; zero-length delimiters would be=
=20
useful). It does, though, specify "not found" as an empty string_view=20
where sv.data() is the end of the referenced string, which avoids the need=
=20
to special-case the end of the last token.
Peter
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_1283_28188992.1388258872556
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Saturday, December 28, 2013 1:21:12 PM UTC-6, P=
eter Bigot wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr"><br>On Friday, December 27, 2013 11:01:34 PM UTC-6, Marshall wrote:<blo=
ckquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><div style=3D"word-wrap:break-word"><br=
><div>if sv.size () =3D=3D 0 or sv.empty () [same thing], there is nothing =
that you can do with sv.data()</div><div>(except compare it to null, and th=
at doesn=92t tell you anything useful).</div></div></blockquote><div><br>My=
understanding (which I'd like confirmed) is that sv.data() is still useful=
as it provides a valid position within the referenced object, which might =
be referenced by other string_view instances or in its native form.<br><br>=
Thus, for example, a function object conforming to the delimiters interface=
documented at <a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/paper=
s/2013/n3593.html#delimiters" target=3D"_blank" onmousedown=3D"this.href=3D=
'http://www.google.com/url?q\75http%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%=
2Fwg21%2Fdocs%2Fpapers%2F2013%2Fn3593.html%23delimiters\46sa\75D\46sntz\075=
1\46usg\75AFQjCNGCC2kdT2gdNH-KLrrmzVuupb4nqQ';return true;" onclick=3D"this=
..href=3D'http://www.google.com/url?q\75http%3A%2F%2Fwww.open-std.org%2Fjtc1=
%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2013%2Fn3593.html%23delimiters\46sa\75D\46=
sntz\0751\46usg\75AFQjCNGCC2kdT2gdNH-KLrrmzVuupb4nqQ';return true;">http://=
www.open-std.org/jtc1/<wbr>sc22/wg21/docs/papers/2013/<wbr>n3593.html#delim=
iters</a> might return a zero-length string to denote a zero-length delimit=
er (e.g., the position following a period in an English sentence). In=
this case it is the value of sv.data() that tells the caller where the del=
imited sequence ends and the next sequence begins.<br><br></div></div></blo=
ckquote><div><br>Sorry; I misread the details of that proposal: it explicit=
ly uses an empty delimiter to indicate "not found" (too bad; zero-length de=
limiters would be useful). It does, though, specify "not found" as an=
empty string_view where sv.data() is the end of the referenced string, whi=
ch avoids the need to special-case the end of the last token.</div><br>Pete=
r<br></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_1283_28188992.1388258872556--
.
Author: Marshall Clow <mclow.lists@gmail.com>
Date: Sun, 29 Dec 2013 09:35:17 -0800
Raw View
--Apple-Mail=_4AC57258-D88D-4E30-A372-36F025A63F0F
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=windows-1252
On Dec 28, 2013, at 11:21 AM, Peter Bigot <bigotp@acm.org> wrote:
>=20
> On Friday, December 27, 2013 11:01:34 PM UTC-6, Marshall wrote:
> On Dec 27, 2013, at 4:52 AM, abolz...@gmail.com wrote:
>=20
>> Is there a reason why string_view is not nullable?
>>=20
>> Nullable here means default constructed or constructed from a nullptr
>> (and a zero length). Then adding a is_null() (or null()) member
>> function which can then be used to distinguish the string_view from an
>> empty string.
>=20
> i think that attempting to distinguish between an empty string_view that =
=93used to point at something=94
> and an empty string view =93that never pointed at anything=94 is a use ca=
se to be discouraged, rather than
> something that should be enshrined in the standard.
>=20
> -1 ; I think it's an obvious and valuable feature.
>=20
>> This should not affect data() which returns a non-null pointer.
>>=20
>=20
> I disagree here with the proposal as currently written.
> I believe that the requirement that data() always return a non-null point=
er is misguided.
>=20
> if sv.size () =3D=3D 0 or sv.empty () [same thing], there is nothing that=
you can do with sv.data()
> (except compare it to null, and that doesn=92t tell you anything useful).
>=20
> My understanding (which I'd like confirmed) is that sv.data() is still us=
eful as it provides a valid position within the referenced object, which mi=
ght be referenced by other string_view instances or in its native form.
a string view refers to a half open range (just like an iterator pair).
sv.data() a pointer to the beginning of that range, just like sv.begin() is=
an iterator to the beginning of that range.
If sv.size() =3D=3D 0, then dereferencing sv.data() or sv.begin() is undefi=
ned behavior.
Also, I can=92t find anywhere in the specification does it guarantee that t=
he following code works:
const char *foo =3D =93abc=94;
string_view sv1 ( foo, 3 ); // size() =3D=3D 3
sv1. remove_suffix (3); // size() =3D=3D 0
assert ( sv1.size() =3D=3D 0);=09
assert ( sv1.data() =3D=3D foo ); // will probably work - but might not.
=97 Marshall
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--Apple-Mail=_4AC57258-D88D-4E30-A372-36F025A63F0F
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=windows-1252
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>On Dec 2=
8, 2013, at 11:21 AM, Peter Bigot <<a href=3D"mailto:bigotp@acm.org">big=
otp@acm.org</a>> wrote:</div><br class=3D"Apple-interchange-newline"><bl=
ockquote type=3D"cite"><div dir=3D"ltr"><br>On Friday, December 27, 2013 11=
:01:34 PM UTC-6, Marshall wrote:<blockquote class=3D"gmail_quote" style=3D"=
margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;=
"><div style=3D"word-wrap:break-word">On Dec 27, 2013, at 4:52 AM, <a href=
=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"XU-iYk-oi4kJ" o=
nmousedown=3D"this.href=3D'javascript:';return true;" onclick=3D"this.href=
=3D'javascript:';return true;">abolz...@gmail.com</a> wrote:<br><div><br><b=
lockquote type=3D"cite"><div dir=3D"ltr"><p>Is there a reason why string_vi=
ew is not nullable?</p><div>Nullable here means default constructed or=
constructed from a nullptr</div><div>(and a zero length). Then adding a is=
_null() (or null()) member</div><div>function which can then be used to dis=
tinguish the string_view from an</div><div>empty string.</div></div></block=
quote><div><br></div>i think that attempting to distinguish between an empt=
y string_view that =93used to point at something=94</div><div>and an empty =
string view =93that never pointed at anything=94 is a use case to be discou=
raged, rather than</div><div>something that should be enshrined in the stan=
dard.</div></div></blockquote><div><br>-1 ; I think it's an obvious and val=
uable feature.<br><br></div><blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><d=
iv style=3D"word-wrap:break-word"><div></div><div><blockquote type=3D"cite"=
><div dir=3D"ltr"><p>This should not affect data() which returns a non-null=
pointer.</p></div></blockquote></div><div>I disagree here with the proposa=
l as currently written.</div><div><div>I believe that the requirement that =
data() always return a non-null pointer is misguided.</div><div><br></div><=
/div><div>if sv.size () =3D=3D 0 or sv.empty () [same thing], there is noth=
ing that you can do with sv.data()</div><div>(except compare it to null, an=
d that doesn=92t tell you anything useful).</div></div></blockquote><div><b=
r>My understanding (which I'd like confirmed) is that sv.data() is still us=
eful as it provides a valid position within the referenced object, which mi=
ght be referenced by other string_view instances or in its native form.<br>=
</div></div></blockquote><div><br></div></div>a string view refers to a hal=
f open range (just like an iterator pair).<div>sv.data() a pointer to the b=
eginning of that range, just like sv.begin() is an iterator to the beginnin=
g of that range.</div><div><br></div><div>If sv.size() =3D=3D 0, then deref=
erencing sv.data() or sv.begin() is undefined behavior.</div><div><br></div=
><div>Also, I can=92t find anywhere in the specification does it guarantee =
that the following code works:</div><div><br></div><div><span class=3D"Appl=
e-tab-span" style=3D"white-space:pre"> </span>const char *foo =3D =93abc=94=
;</div><div><span class=3D"Apple-tab-span" style=3D"white-space:pre"> </spa=
n>string_view sv1 ( foo, 3 );<span class=3D"Apple-tab-span" style=3D"white-=
space:pre"> </span>// size() =3D=3D 3</div><div><span class=3D"Apple-tab-sp=
an" style=3D"white-space:pre"> </span>sv1. remove_suffix (3);<span cla=
ss=3D"Apple-tab-span" style=3D"white-space:pre"> </span>// size() =3D=3D 0<=
/div><div><span class=3D"Apple-tab-span" style=3D"white-space:pre"> </span>=
assert ( sv1.size() =3D=3D 0);<span class=3D"Apple-tab-span" style=3D"white=
-space:pre"> </span></div><div><span class=3D"Apple-tab-span" style=3D"whit=
e-space:pre"> </span>assert ( sv1.data() =3D=3D foo );<span class=3D"Apple-=
tab-span" style=3D"white-space:pre"> </span>// will probably work - but mig=
ht not.</div><div><br></div><div>=97 Marshall</div></body></html>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--Apple-Mail=_4AC57258-D88D-4E30-A372-36F025A63F0F--
.
Author: Peter Bigot <bigotp@acm.org>
Date: Sun, 29 Dec 2013 12:15:50 -0600
Raw View
--e89a8ff1cbda307d6304eeb051f6
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable
On Sun, Dec 29, 2013 at 11:35 AM, Marshall Clow <mclow.lists@gmail.com>wrot=
e:
>
> On Dec 28, 2013, at 11:21 AM, Peter Bigot <bigotp@acm.org> wrote:
>
>
> On Friday, December 27, 2013 11:01:34 PM UTC-6, Marshall wrote:
>>
>> On Dec 27, 2013, at 4:52 AM, abolz...@gmail.com wrote:
>>
> This should not affect data() which returns a non-null pointer.
>>
>> I disagree here with the proposal as currently written.
>> I believe that the requirement that data() always return a non-null
>> pointer is misguided.
>>
>> if sv.size () =3D=3D 0 or sv.empty () [same thing], there is nothing tha=
t you
>> can do with sv.data()
>> (except compare it to null, and that doesn=92t tell you anything useful)=
..
>>
>
> My understanding (which I'd like confirmed) is that sv.data() is still
> useful as it provides a valid position within the referenced object, whic=
h
> might be referenced by other string_view instances or in its native form.
>
>
> a string view refers to a half open range (just like an iterator pair).
> sv.data() a pointer to the beginning of that range, just like sv.begin()
> is an iterator to the beginning of that range.
>
Agreed.
>
> If sv.size() =3D=3D 0, then dereferencing sv.data() or sv.begin() is unde=
fined
> behavior.
>
Agreed.
Also, per [string.view.access] the requirements disallow expression sv[0]
in this case (unlike str[0] if str is a std::string, where the expression
is permitted but the referenced object may not be modified). A subtlety
worth keeping in mind (libstdc++ missed that one).
>
> Also, I can=92t find anywhere in the specification does it guarantee that
> the following code works:
>
> const char *foo =3D =93abc=94;
> string_view sv1 ( foo, 3 ); // size() =3D=3D 3
>
The definition of the constructor in section x.1 [string.view.cons]
guarantees sv1.data() =3D=3D foo.
> sv1. remove_suffix (3); // size() =3D=3D 0
>
Per [string.view.modifiers] this is equivalent to sv1 =3D sv1.substr(0,
sv1.size() - 3).
Per [string.view.ops] the definition of substr makes the RHS equivalent to
string_view(sv1.data() + 0, sv1.size() - 3).
Same constructor as above, so if that temporary object is tv, tv.data() =3D=
=3D
sv1.data()+0 =3D=3D foo+0 =3D=3D foo.
> assert ( sv1.size() =3D=3D 0);
> assert ( sv1.data() =3D=3D foo ); // will probably work - but might not.
>
AFAICT this must be true.
If my reasoning is wrong, string_view becomes significantly less valuable
to me, so do please point out my error.
FWIW my first reading of N3593 was probably correct and zero-length
string_view values returned from a delimiter find() may point into the
middle of an input range; they only indicate "not found" when the data()
member references the end position of the input.
Peter
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--e89a8ff1cbda307d6304eeb051f6
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On S=
un, Dec 29, 2013 at 11:35 AM, Marshall Clow <span dir=3D"ltr"><<a href=
=3D"mailto:mclow.lists@gmail.com" target=3D"_blank">mclow.lists@gmail.com</=
a>></span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div style=3D"word-wrap:break-word"><div cla=
ss=3D"im"><br><div><div>On Dec 28, 2013, at 11:21 AM, Peter Bigot <<a hr=
ef=3D"mailto:bigotp@acm.org" target=3D"_blank">bigotp@acm.org</a>> wrote=
:</div>
<br><blockquote type=3D"cite"><div dir=3D"ltr"><br>On Friday, December 27, =
2013 11:01:34 PM UTC-6, Marshall wrote:<blockquote class=3D"gmail_quote" st=
yle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1=
ex">
<div style=3D"word-wrap:break-word">On Dec 27, 2013, at 4:52 AM, <a>abolz..=
..@gmail.com</a> wrote:<br></div></blockquote><blockquote class=3D"gmail_quo=
te" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-=
left:1ex">
<div style=3D"word-wrap:break-word"><div></div><div><blockquote type=3D"cit=
e"><div dir=3D"ltr"><p>This should not affect data() which returns a non-nu=
ll pointer.</p></div></blockquote></div><div>I disagree here with the propo=
sal as currently written.</div>
<div><div>I believe that the requirement that data() always return a non-nu=
ll pointer is misguided.</div><div><br></div></div><div>if sv.size () =3D=
=3D 0 or sv.empty () [same thing], there is nothing that you can do with sv=
..data()</div>
<div>(except compare it to null, and that doesn=92t tell you anything usefu=
l).</div></div></blockquote><div><br>My understanding (which I'd like c=
onfirmed) is that sv.data() is still useful as it provides a valid position=
within the referenced object, which might be referenced by other string_vi=
ew instances or in its native form.<br>
</div></div></blockquote><div><br></div></div></div>a string view refers to=
a half open range (just like an iterator pair).<div>sv.data() a pointer to=
the beginning of that range, just like sv.begin() is an iterator to the be=
ginning of that range.</div>
</div></blockquote><div><br></div><div>Agreed.<br>=A0<br></div><blockquote =
class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid=
;padding-left:1ex"><div style=3D"word-wrap:break-word"><div><br></div><div>=
If sv.size() =3D=3D 0, then dereferencing sv.data() or sv.begin() is undefi=
ned behavior.</div>
</div></blockquote><div><br></div><div>Agreed.<br><br>Also, per [string.vie=
w.access] the requirements disallow expression sv[0] in this case (unlike s=
tr[0] if str is a std::string, where the expression is permitted but the re=
ferenced object may not be modified).=A0 A subtlety worth keeping in mind (=
libstdc++ missed that one).<br>
=A0<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;b=
order-left:1px #ccc solid;padding-left:1ex"><div style=3D"word-wrap:break-w=
ord"><div><br></div><div>Also, I can=92t find anywhere in the specification=
does it guarantee that the following code works:</div>
<div><br></div><div><span style=3D"white-space:pre-wrap"> </span>const char=
*foo =3D =93abc=94;</div><div><span style=3D"white-space:pre-wrap"> </span=
>string_view sv1 ( foo, 3 );<span style=3D"white-space:pre-wrap"> </span>//=
size() =3D=3D 3</div>
</div></blockquote><div><br></div><div>The definition of the constructor in=
section x.1 [string.view.cons] guarantees sv1.data() =3D=3D foo.<br>=A0<br=
></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-=
left:1px #ccc solid;padding-left:1ex">
<div style=3D"word-wrap:break-word"><div><span style=3D"white-space:pre-wra=
p"> </span>sv1.=A0remove_suffix (3);<span style=3D"white-space:pre-wrap"> <=
/span>// size() =3D=3D 0</div></div></blockquote><div><br></div><div>Per [s=
tring.view.modifiers] this is equivalent to sv1 =3D sv1.substr(0, sv1.size(=
) - 3).<br>
<br>Per [string.view.ops] the definition of substr makes the RHS equivalent=
to string_view(sv1.data() + 0, sv1.size() - 3).<br><br>Same constructor as=
above, so if that temporary object is tv, tv.data() =3D=3D sv1.data()+0 =
=3D=3D foo+0 =3D=3D foo.<br>
<br></div><div></div><div>=A0</div><blockquote class=3D"gmail_quote" style=
=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div sty=
le=3D"word-wrap:break-word"><div><span style=3D"white-space:pre-wrap"> </sp=
an>assert ( sv1.size() =3D=3D 0);<span style=3D"white-space:pre-wrap"> </sp=
an></div>
<div><span style=3D"white-space:pre-wrap"> </span>assert ( sv1.data() =3D=
=3D foo );<span style=3D"white-space:pre-wrap"> </span>// will probably wor=
k - but might not.</div></div></blockquote><div><br></div><div>AFAICT this =
must be true.<br>
<br></div><div>If my reasoning is wrong, string_view becomes significantly =
less valuable to me, so do please point out my error.<br></div><div><br></d=
iv><div>FWIW my first reading of N3593 was probably correct and zero-length=
string_view values returned from a delimiter find()=A0 may point into the =
middle of an input range; they only indicate "not found" when the=
data() member references the end position of the input.<br>
</div><div>=A0<br></div></div>Peter<br></div></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--e89a8ff1cbda307d6304eeb051f6--
.
Author: abolz.lists@gmail.com
Date: Sun, 29 Dec 2013 11:15:07 -0800 (PST)
Raw View
------=_Part_5037_20131352.1388344507283
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable
Am Sonntag, 29. Dezember 2013 19:15:50 UTC+1 schrieb Peter Bigot:
> On Sun, Dec 29, 2013 at 11:35 AM, Marshall Clow <mclow...@gmail.com<javas=
cript:>
> > wrote:
>
>>
>> On Dec 28, 2013, at 11:21 AM, Peter Bigot <big...@acm.org <javascript:>>=
=20
>> wrote:
>>
>>
>> On Friday, December 27, 2013 11:01:34 PM UTC-6, Marshall wrote:
>>>
>>> On Dec 27, 2013, at 4:52 AM, abolz...@gmail.com wrote:
>>>
>> This should not affect data() which returns a non-null pointer.
>>>
>>> I disagree here with the proposal as currently written.
>>> I believe that the requirement that data() always return a non-null=20
>>> pointer is misguided.
>>>
>>> if sv.size () =3D=3D 0 or sv.empty () [same thing], there is nothing th=
at=20
>>> you can do with sv.data()
>>> (except compare it to null, and that doesn=92t tell you anything useful=
).
>>>
>>
>> My understanding (which I'd like confirmed) is that sv.data() is still=
=20
>> useful as it provides a valid position within the referenced object, whi=
ch=20
>> might be referenced by other string_view instances or in its native form=
..
>>
>>
>> a string view refers to a half open range (just like an iterator pair).
>> sv.data() a pointer to the beginning of that range, just like sv.begin()=
=20
>> is an iterator to the beginning of that range.
>>
>
> Agreed.
> =20
>
>>
>> If sv.size() =3D=3D 0, then dereferencing sv.data() or sv.begin() is=20
>> undefined behavior.
>>
>
> Agreed.
>
> Also, per [string.view.access] the requirements disallow expression sv[0]=
=20
> in this case (unlike str[0] if str is a std::string, where the expression=
=20
> is permitted but the referenced object may not be modified). A subtlety=
=20
> worth keeping in mind (libstdc++ missed that one).
> =20
>
>>
>> Also, I can=92t find anywhere in the specification does it guarantee tha=
t=20
>> the following code works:
>>
>> const char *foo =3D =93abc=94;
>> string_view sv1 ( foo, 3 ); // size() =3D=3D 3
>>
>
> The definition of the constructor in section x.1 [string.view.cons]=20
> guarantees sv1.data() =3D=3D foo.
> =20
>
>> sv1. remove_suffix (3); // size() =3D=3D 0
>>
>
> Per [string.view.modifiers] this is equivalent to sv1 =3D sv1.substr(0,=
=20
> sv1.size() - 3).
>
> Per [string.view.ops] the definition of substr makes the RHS equivalent t=
o=20
> string_view(sv1.data() + 0, sv1.size() - 3).
>
> Same constructor as above, so if that temporary object is tv, tv.data() =
=3D=3D=20
> sv1.data()+0 =3D=3D foo+0 =3D=3D foo.
>
> =20
>
>> assert ( sv1.size() =3D=3D 0);=20
>> assert ( sv1.data() =3D=3D foo ); // will probably work - but might not=
..
>>
>
> AFAICT this must be true.
>
> If my reasoning is wrong, string_view becomes significantly less valuable=
=20
> to me, so do please point out my error.
>
Yes.
When used as a replacement for "string const&" one should already test for
non-null pointers, I think. The precondition for the constructors just make=
s
it impossible to use string_view as a pair (char const*, length).
=20
>
> FWIW my first reading of N3593 was probably correct and zero-length=20
> string_view values returned from a delimiter find() may point into the=
=20
> middle of an input range; they only indicate "not found" when the data()=
=20
> member references the end position of the input.
> =20
> Peter
>
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_5037_20131352.1388344507283
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Am Sonntag, 29. Dezember 2013 19:15:50 UTC+1 schrieb Peter=
Bigot:<br><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><div class=3D"gmail_quote">On Sun, Dec 29, 2013 at 11:35 AM, Marshall Cl=
ow <span dir=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-obfu=
scated-mailto=3D"DQxoQDrUQU0J" onmousedown=3D"this.href=3D'javascript:';ret=
urn true;" onclick=3D"this.href=3D'javascript:';return true;">mclow...@gmai=
l.com</a>></span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div style=3D"word-wrap:break-word"><div><br=
><div><div>On Dec 28, 2013, at 11:21 AM, Peter Bigot <<a href=3D"javascr=
ipt:" target=3D"_blank" gdf-obfuscated-mailto=3D"DQxoQDrUQU0J" onmousedown=
=3D"this.href=3D'javascript:';return true;" onclick=3D"this.href=3D'javascr=
ipt:';return true;">big...@acm.org</a>> wrote:</div>
<br><blockquote type=3D"cite"><div dir=3D"ltr"><br>On Friday, December 27, =
2013 11:01:34 PM UTC-6, Marshall wrote:<blockquote class=3D"gmail_quote" st=
yle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1=
ex">
<div style=3D"word-wrap:break-word">On Dec 27, 2013, at 4:52 AM, <a>abolz..=
..@gmail.com</a> wrote:<br></div></blockquote><blockquote class=3D"gmail_quo=
te" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-=
left:1ex">
<div style=3D"word-wrap:break-word"><div></div><div><blockquote type=3D"cit=
e"><div dir=3D"ltr"><p>This should not affect data() which returns a non-nu=
ll pointer.</p></div></blockquote></div><div>I disagree here with the propo=
sal as currently written.</div>
<div><div>I believe that the requirement that data() always return a non-nu=
ll pointer is misguided.</div><div><br></div></div><div>if sv.size () =3D=
=3D 0 or sv.empty () [same thing], there is nothing that you can do with sv=
..data()</div>
<div>(except compare it to null, and that doesn=92t tell you anything usefu=
l).</div></div></blockquote><div><br>My understanding (which I'd like confi=
rmed) is that sv.data() is still useful as it provides a valid position wit=
hin the referenced object, which might be referenced by other string_view i=
nstances or in its native form.<br>
</div></div></blockquote><div><br></div></div></div>a string view refers to=
a half open range (just like an iterator pair).<div>sv.data() a pointer to=
the beginning of that range, just like sv.begin() is an iterator to the be=
ginning of that range.</div>
</div></blockquote><div><br></div><div>Agreed.<br> <br></div><blockquo=
te class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc so=
lid;padding-left:1ex"><div style=3D"word-wrap:break-word"><div><br></div><d=
iv>If sv.size() =3D=3D 0, then dereferencing sv.data() or sv.begin() is und=
efined behavior.</div>
</div></blockquote><div><br></div><div>Agreed.<br><br>Also, per [string.vie=
w.access] the requirements disallow expression sv[0] in this case (unlike s=
tr[0] if str is a std::string, where the expression is permitted but the re=
ferenced object may not be modified). A subtlety worth keeping in min=
d (libstdc++ missed that one).<br>
<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div style=3D"word-wrap:brea=
k-word"><div><br></div><div>Also, I can=92t find anywhere in the specificat=
ion does it guarantee that the following code works:</div>
<div><br></div><div><span style=3D"white-space:pre-wrap"> </span>const char=
*foo =3D =93abc=94;</div><div><span style=3D"white-space:pre-wrap"> </span=
>string_view sv1 ( foo, 3 );<span style=3D"white-space:pre-wrap"> </span>//=
size() =3D=3D 3</div>
</div></blockquote><div><br></div><div>The definition of the constructor in=
section x.1 [string.view.cons] guarantees sv1.data() =3D=3D foo.<br> =
<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bord=
er-left:1px #ccc solid;padding-left:1ex">
<div style=3D"word-wrap:break-word"><div><span style=3D"white-space:pre-wra=
p"> </span>sv1. remove_suffix (3);<span style=3D"white-space:pre-wrap"=
> </span>// size() =3D=3D 0</div></div></blockquote><div><br></div><div>Per=
[string.view.modifiers] this is equivalent to sv1 =3D sv1.substr(0, sv1.si=
ze() - 3).<br>
<br>Per [string.view.ops] the definition of substr makes the RHS equivalent=
to string_view(sv1.data() + 0, sv1.size() - 3).<br><br>Same constructor as=
above, so if that temporary object is tv, tv.data() =3D=3D sv1.data()+0 =
=3D=3D foo+0 =3D=3D foo.<br>
<br></div><div></div><div> </div><blockquote class=3D"gmail_quote" sty=
le=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div s=
tyle=3D"word-wrap:break-word"><div><span style=3D"white-space:pre-wrap"> </=
span>assert ( sv1.size() =3D=3D 0);<span style=3D"white-space:pre-wrap"> </=
span></div>
<div><span style=3D"white-space:pre-wrap"> </span>assert ( sv1.data() =3D=
=3D foo );<span style=3D"white-space:pre-wrap"> </span>// will probably wor=
k - but might not.</div></div></blockquote><div><br></div><div>AFAICT this =
must be true.<br>
<br></div><div>If my reasoning is wrong, string_view becomes significantly =
less valuable to me, so do please point out my error.<br></div></div></div>=
</div></blockquote><div><br></div><div><div>Yes.</div><div>When used as a r=
eplacement for "string const&" one should already test for</div><div>no=
n-null pointers, I think. The precondition for the constructors just makes<=
/div><div>it impossible to use string_view as a pair (char const*, length).=
</div></div><div> </div><blockquote class=3D"gmail_quote" style=3D"mar=
gin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><=
div dir=3D"ltr"><div><div class=3D"gmail_quote"><div></div><div><br></div><=
div>FWIW my first reading of N3593 was probably correct and zero-length str=
ing_view values returned from a delimiter find() may point into the m=
iddle of an input range; they only indicate "not found" when the data() mem=
ber references the end position of the input.<br>
</div><div> <br></div></div>Peter<br></div></div>
</blockquote></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_5037_20131352.1388344507283--
.
Author: Jeffrey Yasskin <jyasskin@google.com>
Date: Sun, 29 Dec 2013 20:07:21 -0800
Raw View
On Sun, Dec 29, 2013 at 10:15 AM, Peter Bigot <bigotp@acm.org> wrote:
> On Sun, Dec 29, 2013 at 11:35 AM, Marshall Clow <mclow.lists@gmail.com>
> wrote:
>>
>>
>> On Dec 28, 2013, at 11:21 AM, Peter Bigot <bigotp@acm.org> wrote:
>>
>>
>> On Friday, December 27, 2013 11:01:34 PM UTC-6, Marshall wrote:
>>>
>>> On Dec 27, 2013, at 4:52 AM, abolz...@gmail.com wrote:
>>>
>>> This should not affect data() which returns a non-null pointer.
>>>
>>> I disagree here with the proposal as currently written.
>>> I believe that the requirement that data() always return a non-null
>>> pointer is misguided.
>>>
>>> if sv.size () =3D=3D 0 or sv.empty () [same thing], there is nothing th=
at you
>>> can do with sv.data()
>>> (except compare it to null, and that doesn=92t tell you anything useful=
).
>>
>>
>> My understanding (which I'd like confirmed) is that sv.data() is still
>> useful as it provides a valid position within the referenced object, whi=
ch
>> might be referenced by other string_view instances or in its native form=
..
>>
>>
>> a string view refers to a half open range (just like an iterator pair).
>> sv.data() a pointer to the beginning of that range, just like sv.begin()
>> is an iterator to the beginning of that range.
>
>
> Agreed.
>
>>
>>
>> If sv.size() =3D=3D 0, then dereferencing sv.data() or sv.begin() is und=
efined
>> behavior.
>
>
> Agreed.
>
> Also, per [string.view.access] the requirements disallow expression sv[0]=
in
> this case (unlike str[0] if str is a std::string, where the expression is
> permitted but the referenced object may not be modified). A subtlety wor=
th
> keeping in mind (libstdc++ missed that one).
>
>>
>>
>> Also, I can=92t find anywhere in the specification does it guarantee tha=
t
>> the following code works:
>>
>> const char *foo =3D =93abc=94;
>> string_view sv1 ( foo, 3 ); // size() =3D=3D 3
>
>
> The definition of the constructor in section x.1 [string.view.cons]
> guarantees sv1.data() =3D=3D foo.
>
>>
>> sv1. remove_suffix (3); // size() =3D=3D 0
>
>
> Per [string.view.modifiers] this is equivalent to sv1 =3D sv1.substr(0,
> sv1.size() - 3).
>
> Per [string.view.ops] the definition of substr makes the RHS equivalent t=
o
> string_view(sv1.data() + 0, sv1.size() - 3).
>
> Same constructor as above, so if that temporary object is tv, tv.data() =
=3D=3D
> sv1.data()+0 =3D=3D foo+0 =3D=3D foo.
>
>
>>
>> assert ( sv1.size() =3D=3D 0);
>> assert ( sv1.data() =3D=3D foo ); // will probably work - but might not.
>
>
> AFAICT this must be true.
Yeah, because this all makes sv1 equivalent to string_view(foo, 0),
and that guarantees that data()=3D=3Dfoo, the assert()s have to pass.
Hopefully the new version at
https://github.com/google/cxx-std-draft/blob/string-ref-paper/string_view.h=
tml,
which describes things in terms of exposition-only data_ and size_
members, makes this clearer.
Jeffrey
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Tue, 7 Jan 2014 03:23:38 -0800 (PST)
Raw View
------=_Part_10824_11378047.1389093818902
Content-Type: text/plain; charset=ISO-8859-1
On Monday, December 30, 2013 5:07:21 AM UTC+1, Jeffrey Yasskin wrote:
>
>
> Hopefully the new version at
>
> https://github.com/google/cxx-std-draft/blob/string-ref-paper/string_view.html,
>
> which describes things in terms of exposition-only data_ and size_
> members, makes this clearer.
>
>
Is a HTML view of that document available?
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_10824_11378047.1389093818902
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Monday, December 30, 2013 5:07:21 AM UTC+1, Jeffrey Yas=
skin wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><br>Hopefully the n=
ew version at
<br><a href=3D"https://github.com/google/cxx-std-draft/blob/string-ref-pape=
r/string_view.html" target=3D"_blank" onmousedown=3D"this.href=3D'https://w=
ww.google.com/url?q\75https%3A%2F%2Fgithub.com%2Fgoogle%2Fcxx-std-draft%2Fb=
lob%2Fstring-ref-paper%2Fstring_view.html\46sa\75D\46sntz\0751\46usg\75AFQj=
CNEuSmBupByxp5oJE_tx90pVAN1FVg';return true;" onclick=3D"this.href=3D'https=
://www.google.com/url?q\75https%3A%2F%2Fgithub.com%2Fgoogle%2Fcxx-std-draft=
%2Fblob%2Fstring-ref-paper%2Fstring_view.html\46sa\75D\46sntz\0751\46usg\75=
AFQjCNEuSmBupByxp5oJE_tx90pVAN1FVg';return true;">https://github.com/google=
/cxx-<wbr>std-draft/blob/string-ref-<wbr>paper/string_view.html</a>,
<br>which describes things in terms of exposition-only data_ and size_
<br>members, makes this clearer.
<br><br></blockquote><div><br></div><div>Is a HTML view of that document av=
ailable? </div></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_10824_11378047.1389093818902--
.
Author: Jeffrey Yasskin <jyasskin@google.com>
Date: Wed, 8 Jan 2014 11:14:24 -0800
Raw View
On Tue, Jan 7, 2014 at 3:23 AM, Olaf van der Spek <olafvdspek@gmail.com> wrote:
> On Monday, December 30, 2013 5:07:21 AM UTC+1, Jeffrey Yasskin wrote:
>>
>>
>> Hopefully the new version at
>>
>> https://github.com/google/cxx-std-draft/blob/string-ref-paper/string_view.html,
>> which describes things in terms of exposition-only data_ and size_
>> members, makes this clearer.
>>
>
> Is a HTML view of that document available?
https://rawgithub.com/google/cxx-std-draft/string-ref-paper/string_view.html
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Wed, 15 Jan 2014 04:20:11 -0800 (PST)
Raw View
------=_Part_299_27037740.1389788411800
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Saturday, December 28, 2013 6:59:37 PM UTC+1, Jeffrey Yasskin wrote:
>
> i think that attempting to distinguish between an empty string_view that=
=20
>> =E2=80=9Cused to point at something=E2=80=9D
>> and an empty string view =E2=80=9Cthat never pointed at anything=E2=80=
=9D is a use case=20
>> to be discouraged, rather than
>> something that should be enshrined in the standard.
>>
>> This should not affect data() which returns a non-null pointer.
>>
>> I disagree here with the proposal as currently written.
>> I believe that the requirement that data() always return a non-null=20
>> pointer is misguided.=20
>>
>
>> if sv.size () =3D=3D 0 or sv.empty () [same thing], there is nothing tha=
t you=20
>> can do with sv.data()
>> (except compare it to null, and that doesn=E2=80=99t tell you anything u=
seful).
>>
>
> The thing is, if nullptr is a possible return value for data(), people do=
=20
> start using it to convey information. If they get a null out exactly when=
=20
> they put a null in, it is telling them something useful. The only way to=
=20
> "discourage" it is to make it never happen. If we let string_view::data()=
=20
> pass through null, we're enshrining the use you don't like in the standar=
d.
> =20
>
In some cases being able to distinguish between null and empty is required.=
=20
string_view could easily support this distinction, what's the reason it=20
should be discouraged?
optional<string_view> is an obvious suggestion but that increases code=20
complexity at the call site when the distinction is not required.
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_299_27037740.1389788411800
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Saturday, December 28, 2013 6:59:37 PM UTC+1, Jeffrey Y=
asskin wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=
<div><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"=
margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style=
=3D"word-wrap:break-word"><div>i think that attempting to distinguish betwe=
en an empty string_view that =E2=80=9Cused to point at something=E2=80=9D</=
div>
<div>and an empty string view =E2=80=9Cthat never pointed at anything=E2=80=
=9D is a use case to be discouraged, rather than</div><div>something that s=
hould be enshrined in the standard.</div><div><div><br></div><div><blockquo=
te type=3D"cite">
<div dir=3D"ltr"><p>This should not affect data() which returns a non-null =
pointer.</p></div></blockquote></div></div><div>I disagree here with the pr=
oposal as currently written.</div><div><div>I believe that the requirement =
that data() always return a non-null pointer is misguided. </div>
</div></div></blockquote><blockquote class=3D"gmail_quote" style=3D"margin:=
0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style=3D"word-=
wrap:break-word"><div><div><br></div></div><div>if sv.size () =3D=3D 0 or s=
v.empty () [same thing], there is nothing that you can do with sv.data()</d=
iv>
<div>(except compare it to null, and that doesn=E2=80=99t tell you anything=
useful).</div></div></blockquote><div><br></div><div>The thing is, if null=
ptr is a possible return value for data(), people do start using it to conv=
ey information. If they get a null out exactly when they put a null in, it =
is telling them something useful. The only way to "discourage" it is to mak=
e it never happen. If we let string_view::data() pass through null, we're e=
nshrining the use you don't like in the standard.</div>
<div> </div></div></div></div></blockquote><div>In some cases being ab=
le to distinguish between null and empty is required. string_view could eas=
ily support this distinction, what's the reason it should be discouraged?</=
div><div><br></div><div>optional<string_view> is an obvious suggestio=
n but that increases code complexity at the call site when the distinction =
is not required.</div></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_299_27037740.1389788411800--
.
Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Wed, 15 Jan 2014 04:28:39 -0800 (PST)
Raw View
------=_Part_932_25236934.1389788919462
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Saturday, December 28, 2013 6:01:34 AM UTC+1, Marshall wrote:
>
> if sv.size () =3D=3D 0 or sv.empty () [same thing], there is nothing that=
you=20
> can do with sv.data()
> (except compare it to null, and that doesn=E2=80=99t tell you anything us=
eful).
>
Are you sure?
IMO an empty string_view could still point into a string and I should be=20
able to use that pointer to for example construct a new string_view.
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_932_25236934.1389788919462
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Saturday, December 28, 2013 6:01:34 AM UTC+1, Marshall =
wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"word-wrap:=
break-word"><div>if sv.size () =3D=3D 0 or sv.empty () [same thing], there =
is nothing that you can do with sv.data()</div><div>(except compare it to n=
ull, and that doesn=E2=80=99t tell you anything useful).</div></div></block=
quote><div><br></div><div>Are you sure?</div><div>IMO an empty string_view =
could still point into a string and I should be able to use that pointer to=
for example construct a new string_view.</div></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_932_25236934.1389788919462--
.
Author: "=?utf-8?B?YmlsbHkub25lYWxAZ21haWwuY29t?=" <billy.oneal@gmail.com>
Date: Wed, 15 Jan 2014 09:15:36 -0800
Raw View
------=_Part_0_1389806136045
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline
It should be discouraged because we don't want to have to write null checks=
in every function under the sun; it is about preventing callers from suppl=
ying unexpected results.
string const & isn't allowed to be null; string_view shouldn't either.
Sent from a touchscreen. Please excuse the brevity and tpyos.
----- Reply message -----
From: "Olaf van der Spek" <olafvdspek@gmail.com>
To: <std-proposals@isocpp.org>
Subject: [std-proposals] string_view::is_null()
Date: Wed, Jan 15, 2014 4:20 AM
On Saturday, December 28, 2013 6:59:37 PM UTC+1, Jeffrey Yasskin wrote:i th=
ink that attempting to distinguish between an empty string_view that =E2=80=
=9Cused to point at something=E2=80=9D
and an empty string view =E2=80=9Cthat never pointed at anything=E2=80=9D i=
s a use case to be discouraged, rather than
something that should be enshrined in the standard.
This should not affect data() which returns a non-null pointer.
I disagree here with the proposal as currently written.
I believe that the requirement that data() always return a non-null pointer=
is misguided.=20
if sv.size () =3D=3D 0 or sv.empty () [same thing], there is nothing that y=
ou can do with sv.data()
(except compare it to null, and that doesn=E2=80=99t tell you anything usef=
ul).
The thing is, if nullptr is a possible return value for data(), people do s=
tart using it to convey information. If they get a null out exactly when th=
ey put a null in, it is telling them something useful. The only way to "dis=
courage" it is to make it never happen. If we let string_view::data() pass =
through null, we're enshrining the use you don't like in the standard.
In some cases being able to distinguish between null and empty is required.=
string_view could easily support this distinction, what's the reason it sh=
ould be discouraged?
optional<string_view> is an obvious suggestion but that increases code comp=
lexity at the call site when the distinction is not required.
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_0_1389806136045
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline
<div style=3D"font-size: 12pt; font-family: Calibri,sans-serif;"><div>It sh=
ould be discouraged because we don't want to have to write null checks in e=
very function under the sun; it is about preventing callers from supplying =
unexpected results.</div><div><br></div><div>string const & isn't allow=
ed to be null; string_view shouldn't either.</div><div><br></div><div>Sent =
from a touchscreen. Please excuse the brevity and tpyos.</div><br><div id=
=3D"htc_header">----- Reply message -----<br>From: "Olaf van der Spek&=
quot; <olafvdspek@gmail.com><br>To: <std-proposals@isocpp.org><=
br>Subject: [std-proposals] string_view::is_null()<br>Date: Wed, Jan 15, 20=
14 4:20 AM</div></div><br><div dir=3D"ltr">On Saturday, December 28, 2013 6=
:59:37 PM UTC+1, Jeffrey Yasskin wrote:<blockquote class=3D"gmail_quote" st=
yle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-lef=
t: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div style=3D"word-wrap:break-word"><div>i think that attempt=
ing to distinguish between an empty string_view that =E2=80=9Cused to point=
at something=E2=80=9D</div>
<div>and an empty string view =E2=80=9Cthat never pointed at anything=E2=80=
=9D is a use case to be discouraged, rather than</div><div>something that s=
hould be enshrined in the standard.</div><div><div><br></div><div><blockquo=
te type=3D"cite">
<div dir=3D"ltr"><p>This should not affect data() which returns a non-null =
pointer.</p></div></blockquote></div></div><div>I disagree here with the pr=
oposal as currently written.</div><div><div>I believe that the requirement =
that data() always return a non-null pointer is misguided. </div>
</div></div></blockquote><blockquote class=3D"gmail_quote" style=3D"margin:=
0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style=3D"word-=
wrap:break-word"><div><div><br></div></div><div>if sv.size () =3D=3D 0 or s=
v.empty () [same thing], there is nothing that you can do with sv.data()</d=
iv>
<div>(except compare it to null, and that doesn=E2=80=99t tell you anything=
useful).</div></div></blockquote><div><br></div><div>The thing is, if null=
ptr is a possible return value for data(), people do start using it to conv=
ey information. If they get a null out exactly when they put a null in, it =
is telling them something useful. The only way to "discourage" it is to mak=
e it never happen. If we let string_view::data() pass through null, we're e=
nshrining the use you don't like in the standard.</div>
<div> </div></div></div></div></blockquote><div>In some cases being ab=
le to distinguish between null and empty is required. string_view could eas=
ily support this distinction, what's the reason it should be discouraged?</=
div><div><br></div><div>optional<string_view> is an obvious suggestio=
n but that increases code complexity at the call site when the distinction =
is not required.</div></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_0_1389806136045--
.
Author: Thiago Macieira <thiago@macieira.org>
Date: Wed, 15 Jan 2014 09:22:22 -0800
Raw View
--nextPart1962733.DYyL6i9T4G
Content-Transfer-Encoding: 7Bit
Content-Type: text/plain; charset="us-ascii"
On quarta-feira, 15 de janeiro de 2014 04:20:11, Olaf van der Spek wrote:
> In some cases being able to distinguish between null and empty is required.
> string_view could easily support this distinction, what's the reason it
> should be discouraged?
Just FYI
Once std::string_view came into focus, I looked into QStringRef to see if it
could be updated for Qt 6 and support the same semantics. Whereas
std::string_view consists of two iterators (begin and end), QStringRef
actually contains a pointer to the original QString, plus an offset and length.
That's what I tried to change.
There were two reasons why that did work: one was specifically the isNull()
method, since the "nullness" is a property of the QString which a pair of
iterators cannot represent. That is, a null QString and an empty-but-null
QString can have the same data pointer.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
--nextPart1962733.DYyL6i9T4G
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.19 (GNU/Linux)
iD8DBQBS1sPOM/XwBW70U1gRAv0VAKCd8v6NMTx+hVdW7QSlISDlqaudZwCdHkFM
UTaHd2MHUF0j2IVyGhA7Vtc=
=aUV4
-----END PGP SIGNATURE-----
--nextPart1962733.DYyL6i9T4G--
.
Author: Jeffrey Yasskin <jyasskin@google.com>
Date: Wed, 15 Jan 2014 10:26:14 -0800
Raw View
On Wed, Jan 15, 2014 at 9:22 AM, Thiago Macieira <thiago@macieira.org> wrote:
> On quarta-feira, 15 de janeiro de 2014 04:20:11, Olaf van der Spek wrote:
>> In some cases being able to distinguish between null and empty is required.
>> string_view could easily support this distinction, what's the reason it
>> should be discouraged?
>
> Just FYI
>
> Once std::string_view came into focus, I looked into QStringRef to see if it
> could be updated for Qt 6 and support the same semantics. Whereas
> std::string_view consists of two iterators (begin and end), QStringRef
> actually contains a pointer to the original QString, plus an offset and length.
> That's what I tried to change.
>
> There were two reasons why that did work: one was specifically the isNull()
> method, since the "nullness" is a property of the QString which a pair of
> iterators cannot represent. That is, a null QString and an empty-but-null
> QString can have the same data pointer.
Can you look over some of the uses of isNull() in QT and see what
fraction are ones where both empty and null are possible values, and
the distinction is useful rather than just forcing the API to document
which one is used?
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Thiago Macieira <thiago@macieira.org>
Date: Wed, 15 Jan 2014 11:45:46 -0800
Raw View
On quarta-feira, 15 de janeiro de 2014 10:26:14, Jeffrey Yasskin wrote:
> Can you look over some of the uses of isNull() in QT and see what
> fraction are ones where both empty and null are possible values, and
> the distinction is useful rather than just forcing the API to document
> which one is used?
The far majority of the cases, people just need the empty case. That's what we
recommend. And unless some API in specific documents the distinction, using
isEmpty() is the right thing to do.
The null option comes in handy when you need to distinguish a field that might
be present but empty from a field that isn't present. QUrl makes use of that
and the equivalent std::networking::uri proposal just uses
std::optional<String> (String is a template). For example:
QUrl url1("foo:/"), url2("foo://@/?#");
QString query1 = url1.query(), query2 = url2.query();
Both query1 and query2 are empty, but only query1 is null, indicating that the
query was not present. The same applies to userInfo(), host(), and fragment(),
and would apply to authority() if the "@" weren't present.
And you can do:
url1.setQuery("");
url2.setQuery(QString());
to invert the situation.
The other common case for using nulls is in QVariant and that comes from the
QtSql module: all entries are returned as QVariants and they need to support
database tables that don't contain "NOT NULL" (that is, are nullable). So
QVariant can contain a null int that is different from a zero:
QVariant v1, v2{0};
v1.convert(QVariant::Int);
// v1.isNull() == true; v2.isNull() == false
We don't recommend relying on the nullness of a string. We only condone on the
above cases I described, but I wouldn't be surprised to find more uses. And,
trust me, there's quite a lot of headache involved in keeping the nullness of
certain types across transformations:
QString().toUtf8().isNull() == true;
QString("").toUtf8().isNull() == false;
And then there are weird questions like:
- does a null QString compare equal to an empty one? (yes)
- does a null QString startsWith() an empty one? Does the opposite?
- same for endsWith(), contains(), indexOf()
- is QString().left(1) null? How about QString().left(0)?
- and what about QString("hello").left(0)?
- if left, right and mid can return null, can leftRef, rightRef and midRef
(which return QStringRef)?
I don't know the answer to most of those questions, which means I would
recommend no one rely on a specific behaviour.
Most of it is unit-tested so we don't break it:
http://code.woboq.org/qt5/qtbase/tests/auto/corelib/tools/qstring/tst_qstring.cpp.html#_ZN11tst_QString10startsWithEv
http://code.woboq.org/qt5/qtbase/tests/auto/corelib/tools/qstring/tst_qstring.cpp.html#_ZN11tst_QString8endsWithEv
http://code.woboq.org/qt5/qtbase/tests/auto/corelib/tools/qstring/tst_qstring.cpp.html#_ZN11tst_QString4leftEv
http://code.woboq.org/qt5/qtbase/tests/auto/corelib/tools/qstring/tst_qstring.cpp.html#_ZN11tst_QString7leftRefEv
and what isn't tested I'd feel free to change behaviour at any time.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Nevin Liber <nevin@eviloverlord.com>
Date: Wed, 15 Jan 2014 13:52:17 -0600
Raw View
--001a1134d2dacd940c04f007a7f4
Content-Type: text/plain; charset=ISO-8859-1
On 15 January 2014 13:45, Thiago Macieira <thiago@macieira.org> wrote:
>
> The null option comes in handy when you need to distinguish a field that
> might
> be present but empty from a field that isn't present. QUrl makes use of
> that
> and the equivalent std::networking::uri proposal just uses
> std::optional<String> (String is a template).
That looks like a better solution to me. null and empty are different
conceptually and should not be merged together.
--
Nevin ":-)" Liber <mailto:nevin@eviloverlord.com> (847) 691-1404
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a1134d2dacd940c04f007a7f4
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On 15 January 2014 13:45, Thiago Macieira <span dir=3D"ltr=
"><<a href=3D"mailto:thiago@macieira.org" target=3D"_blank">thiago@macie=
ira.org</a>></span> wrote:<br>
<div class=3D"gmail_extra"><div class=3D"gmail_quote"><blockquote class=3D"=
gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-=
left:1ex"><br>
The null option comes in handy when you need to distinguish a field that mi=
ght<br>
be present but empty from a field that isn't present. QUrl makes use of=
that<br>
and the equivalent std::networking::uri proposal just uses<br>
std::optional<String> (String is a template).</blockquote><div><br></=
div><div>That looks like a better solution to me.=A0 null and empty are dif=
ferent conceptually and should not be merged together.<br></div></div>-- <b=
r>
=A0Nevin ":-)" Liber=A0 <mailto:<a href=3D"mailto:nevin@evilov=
erlord.com" target=3D"_blank">nevin@eviloverlord.com</a>>=A0 <a href=3D"=
tel:%28847%29%20691-1404" value=3D"+18476911404" target=3D"_blank">(847) 69=
1-1404</a>
</div></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--001a1134d2dacd940c04f007a7f4--
.
Author: abolz.lists@gmail.com
Date: Wed, 15 Jan 2014 12:27:05 -0800 (PST)
Raw View
------=_Part_3526_10633220.1389817625417
Content-Type: text/plain; charset=UTF-8
Am Mittwoch, 15. Januar 2014 20:45:46 UTC+1 schrieb Thiago Macieira:
>
> On quarta-feira, 15 de janeiro de 2014 10:26:14, Jeffrey Yasskin wrote:
> > Can you look over some of the uses of isNull() in QT and see what
> > fraction are ones where both empty and null are possible values, and
> > the distinction is useful rather than just forcing the API to document
> > which one is used?
>
> The far majority of the cases, people just need the empty case. That's
> what we
> recommend. And unless some API in specific documents the distinction,
> using
> isEmpty() is the right thing to do.
>
> The null option comes in handy when you need to distinguish a field that
> might
> be present but empty from a field that isn't present. QUrl makes use of
> that
> and the equivalent std::networking::uri proposal just uses
> std::optional<String> (String is a template). For example:
>
> QUrl url1("foo:/"), url2("foo://@/?#");
> QString query1 = url1.query(), query2 = url2.query();
>
> Both query1 and query2 are empty, but only query1 is null, indicating that
> the
> query was not present. The same applies to userInfo(), host(), and
> fragment(),
> and would apply to authority() if the "@" weren't present.
>
> And you can do:
>
> url1.setQuery("");
> url2.setQuery(QString());
>
> to invert the situation.
>
> The other common case for using nulls is in QVariant and that comes from
> the
> QtSql module: all entries are returned as QVariants and they need to
> support
> database tables that don't contain "NOT NULL" (that is, are nullable). So
> QVariant can contain a null int that is different from a zero:
>
> QVariant v1, v2{0};
> v1.convert(QVariant::Int);
> // v1.isNull() == true; v2.isNull() == false
>
> We don't recommend relying on the nullness of a string. We only condone on
> the
> above cases I described, but I wouldn't be surprised to find more uses.
> And,
> trust me, there's quite a lot of headache involved in keeping the nullness
> of
> certain types across transformations:
>
> QString().toUtf8().isNull() == true;
> QString("").toUtf8().isNull() == false;
>
> And then there are weird questions like:
> - does a null QString compare equal to an empty one? (yes)
> - does a null QString startsWith() an empty one? Does the opposite?
> - same for endsWith(), contains(), indexOf()
> - is QString().left(1) null? How about QString().left(0)?
> - and what about QString("hello").left(0)?
> - if left, right and mid can return null, can leftRef, rightRef and midRef
>
> (which return QStringRef)?
>
In general I would say keep the nullness and otherwise treat null and empty
strings the same.
But sometimes it is convenient to distinguish between a null and an empty
string.
I'd be fine with the current proposal if a named constructor
string_view::null() and a member
function string_view::is_null() were added.
>
> I don't know the answer to most of those questions, which means I would
> recommend no one rely on a specific behaviour.
>
> Most of it is unit-tested so we don't break it:
>
> http://code.woboq.org/qt5/qtbase/tests/auto/corelib/tools/qstring/tst_qstring.cpp.html#_ZN11tst_QString10startsWithEv
>
> http://code.woboq.org/qt5/qtbase/tests/auto/corelib/tools/qstring/tst_qstring.cpp.html#_ZN11tst_QString8endsWithEv
>
> http://code.woboq.org/qt5/qtbase/tests/auto/corelib/tools/qstring/tst_qstring.cpp.html#_ZN11tst_QString4leftEv
>
> http://code.woboq.org/qt5/qtbase/tests/auto/corelib/tools/qstring/tst_qstring.cpp.html#_ZN11tst_QString7leftRefEv
>
> and what isn't tested I'd feel free to change behaviour at any time.
>
> --
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
> Software Architect - Intel Open Source Technology Center
> PGP/GPG: 0x6EF45358; fingerprint:
> E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
>
>
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_3526_10633220.1389817625417
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Am Mittwoch, 15. Januar 2014 20:45:46 UTC+1 schrieb Thiago=
Macieira:<blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.=
8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-=
width: 1px; border-left-style: solid;">On quarta-feira, 15 de janeiro de 20=
14 10:26:14, Jeffrey Yasskin wrote:
<br>> Can you look over some of the uses of isNull() in QT and see what
<br>> fraction are ones where both empty and null are possible values, a=
nd
<br>> the distinction is useful rather than just forcing the API to docu=
ment
<br>> which one is used?
<br>
<br>The far majority of the cases, people just need the empty case. That's =
what we=20
<br>recommend. And unless some API in specific documents the distinction, u=
sing=20
<br>isEmpty() is the right thing to do.
<br>
<br>The null option comes in handy when you need to distinguish a field tha=
t might=20
<br>be present but empty from a field that isn't present. QUrl makes use of=
that=20
<br>and the equivalent std::networking::uri proposal just uses=20
<br>std::optional<String> (String is a template). For example:
<br>
<br> QUrl url1("foo:/"), url=
2("foo://@/?#");
<br> QString query1 =3D url1=
..query(), query2 =3D url2.query();
<br>
<br>Both query1 and query2 are empty, but only query1 is null, indicating t=
hat the=20
<br>query was not present. The same applies to userInfo(), host(), and frag=
ment(),=20
<br>and would apply to authority() if the "@" weren't present.
<br>
<br>And you can do:
<br>
<br> url1.setQuery("");
<br> url2.setQuery(QString(<=
wbr>));
<br>
<br>to invert the situation.
<br>
<br>The other common case for using nulls is in QVariant and that comes fro=
m the=20
<br>QtSql module: all entries are returned as QVariants and they need to su=
pport=20
<br>database tables that don't contain "NOT NULL" (that is, are nullable). =
So=20
<br>QVariant can contain a null int that is different from a zero:
<br>
<br> QVariant v1, v2{0};
<br> v1.convert(QVariant::<w=
br>Int);
<br> // v1.isNull() =3D=3D t=
rue; v2.isNull() =3D=3D false
<br>
<br>We don't recommend relying on the nullness of a string. We only condone=
on the=20
<br>above cases I described, but I wouldn't be surprised to find more uses.=
And,=20
<br>trust me, there's quite a lot of headache involved in keeping the nulln=
ess of=20
<br>certain types across transformations:
<br>
<br> QString().toUtf8().<wbr=
>isNull() =3D=3D true;
<br> QString("").toUtf8().<w=
br>isNull() =3D=3D false;
<br>
<br>And then there are weird questions like:=20
<br>- does a null QString compare equal to an empty one? (yes)
<br>- does a null QString startsWith() an empty one? Does the opposite?
<br>- same for endsWith(), contains(), indexOf()
<br>- is QString().left(1) null? How about QString().left(0)?
<br>- and what about QString("hello").left(0)?
<br>- if left, right and mid can return null, can leftRef, rightRef and mid=
Ref =20
<br> (which return QStringRef)?
<br></blockquote><div><br></div><div>In general I would say keep the nullne=
ss and otherwise treat null and empty strings the same.</div><div><br></div=
><div>But sometimes it is convenient to distinguish between a null and an e=
mpty string.</div><div><br></div><div>I'd be fine with the current proposal=
if a named constructor string_view::null() and a member</div><div>function=
string_view::is_null() were added.</div><div> </div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; bor=
der-left-color: rgb(204, 204, 204); border-left-width: 1px; border-left-sty=
le: solid;">
<br>I don't know the answer to most of those questions, which means I would=
=20
<br>recommend no one rely on a specific behaviour.=20
<br>
<br>Most of it is unit-tested so we don't break it:
<br><a onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F=
%2Fcode.woboq.org%2Fqt5%2Fqtbase%2Ftests%2Fauto%2Fcorelib%2Ftools%2Fqstring=
%2Ftst_qstring.cpp.html%23_ZN11tst_QString10startsWithEv\46sa\75D\46sntz\07=
51\46usg\75AFQjCNH0DkvTqaGjpdgeogyca4zHTXpj9A';return true;" onclick=3D"thi=
s.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fcode.woboq.org%2Fqt5%2=
Fqtbase%2Ftests%2Fauto%2Fcorelib%2Ftools%2Fqstring%2Ftst_qstring.cpp.html%2=
3_ZN11tst_QString10startsWithEv\46sa\75D\46sntz\0751\46usg\75AFQjCNH0DkvTqa=
Gjpdgeogyca4zHTXpj9A';return true;" href=3D"http://code.woboq.org/qt5/qtbas=
e/tests/auto/corelib/tools/qstring/tst_qstring.cpp.html#_ZN11tst_QString10s=
tartsWithEv" target=3D"_blank">http://code.woboq.org/qt5/<wbr>qtbase/tests/=
auto/corelib/<wbr>tools/qstring/tst_qstring.cpp.<wbr>html#_ZN11tst_<wbr>QSt=
ring10startsWithEv</a>
<br><a onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F=
%2Fcode.woboq.org%2Fqt5%2Fqtbase%2Ftests%2Fauto%2Fcorelib%2Ftools%2Fqstring=
%2Ftst_qstring.cpp.html%23_ZN11tst_QString8endsWithEv\46sa\75D\46sntz\0751\=
46usg\75AFQjCNEozKVuuIDN2zRdKK2fCefHltxC_Q';return true;" onclick=3D"this.h=
ref=3D'http://www.google.com/url?q\75http%3A%2F%2Fcode.woboq.org%2Fqt5%2Fqt=
base%2Ftests%2Fauto%2Fcorelib%2Ftools%2Fqstring%2Ftst_qstring.cpp.html%23_Z=
N11tst_QString8endsWithEv\46sa\75D\46sntz\0751\46usg\75AFQjCNEozKVuuIDN2zRd=
KK2fCefHltxC_Q';return true;" href=3D"http://code.woboq.org/qt5/qtbase/test=
s/auto/corelib/tools/qstring/tst_qstring.cpp.html#_ZN11tst_QString8endsWith=
Ev" target=3D"_blank">http://code.woboq.org/qt5/<wbr>qtbase/tests/auto/core=
lib/<wbr>tools/qstring/tst_qstring.cpp.<wbr>html#_ZN11tst_<wbr>QString8ends=
WithEv</a>
<br><a onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F=
%2Fcode.woboq.org%2Fqt5%2Fqtbase%2Ftests%2Fauto%2Fcorelib%2Ftools%2Fqstring=
%2Ftst_qstring.cpp.html%23_ZN11tst_QString4leftEv\46sa\75D\46sntz\0751\46us=
g\75AFQjCNF_uztsNplZ08s05SewQrc0SE4bqw';return true;" onclick=3D"this.href=
=3D'http://www.google.com/url?q\75http%3A%2F%2Fcode.woboq.org%2Fqt5%2Fqtbas=
e%2Ftests%2Fauto%2Fcorelib%2Ftools%2Fqstring%2Ftst_qstring.cpp.html%23_ZN11=
tst_QString4leftEv\46sa\75D\46sntz\0751\46usg\75AFQjCNF_uztsNplZ08s05SewQrc=
0SE4bqw';return true;" href=3D"http://code.woboq.org/qt5/qtbase/tests/auto/=
corelib/tools/qstring/tst_qstring.cpp.html#_ZN11tst_QString4leftEv" target=
=3D"_blank">http://code.woboq.org/qt5/<wbr>qtbase/tests/auto/corelib/<wbr>t=
ools/qstring/tst_qstring.cpp.<wbr>html#_ZN11tst_QString4leftEv</a>
<br><a onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F=
%2Fcode.woboq.org%2Fqt5%2Fqtbase%2Ftests%2Fauto%2Fcorelib%2Ftools%2Fqstring=
%2Ftst_qstring.cpp.html%23_ZN11tst_QString7leftRefEv\46sa\75D\46sntz\0751\4=
6usg\75AFQjCNErchfCONblsCTo3UCyQx6cSvRlnA';return true;" onclick=3D"this.hr=
ef=3D'http://www.google.com/url?q\75http%3A%2F%2Fcode.woboq.org%2Fqt5%2Fqtb=
ase%2Ftests%2Fauto%2Fcorelib%2Ftools%2Fqstring%2Ftst_qstring.cpp.html%23_ZN=
11tst_QString7leftRefEv\46sa\75D\46sntz\0751\46usg\75AFQjCNErchfCONblsCTo3U=
CyQx6cSvRlnA';return true;" href=3D"http://code.woboq.org/qt5/qtbase/tests/=
auto/corelib/tools/qstring/tst_qstring.cpp.html#_ZN11tst_QString7leftRefEv"=
target=3D"_blank">http://code.woboq.org/qt5/<wbr>qtbase/tests/auto/corelib=
/<wbr>tools/qstring/tst_qstring.cpp.<wbr>html#_ZN11tst_<wbr>QString7leftRef=
Ev</a>
<br>
<br>and what isn't tested I'd feel free to change behaviour at any time.
<br>
<br>--=20
<br>Thiago Macieira - thiago (AT) <a onmousedown=3D"this.href=3D'http://www=
..google.com/url?q\75http%3A%2F%2Fmacieira.info\46sa\75D\46sntz\0751\46usg\7=
5AFQjCNEswDUBNCNanbu7euhqLn_62FW8ag';return true;" onclick=3D"this.href=3D'=
http://www.google.com/url?q\75http%3A%2F%2Fmacieira.info\46sa\75D\46sntz\07=
51\46usg\75AFQjCNEswDUBNCNanbu7euhqLn_62FW8ag';return true;" href=3D"http:/=
/macieira.info" target=3D"_blank">macieira.info</a> - thiago (AT) <a onmous=
edown=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fkde.org\46=
sa\75D\46sntz\0751\46usg\75AFQjCNHGRJdo5_JYG1DowztwAHAKs80XSA';return true;=
" onclick=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fkde.or=
g\46sa\75D\46sntz\0751\46usg\75AFQjCNHGRJdo5_JYG1DowztwAHAKs80XSA';return t=
rue;" href=3D"http://kde.org" target=3D"_blank">kde.org</a>
<br> Software Architect - Intel Open Source Technology Center
<br> PGP/GPG: 0x6EF45358; fingerprint:
<br> E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4=
5358
<br>
<br></blockquote></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_3526_10633220.1389817625417--
.
Author: Jeffrey Yasskin <jyasskin@google.com>
Date: Wed, 15 Jan 2014 12:42:20 -0800
Raw View
On Wed, Jan 15, 2014 at 11:45 AM, Thiago Macieira <thiago@macieira.org> wrote:
> On quarta-feira, 15 de janeiro de 2014 10:26:14, Jeffrey Yasskin wrote:
>> Can you look over some of the uses of isNull() in QT and see what
>> fraction are ones where both empty and null are possible values, and
>> the distinction is useful rather than just forcing the API to document
>> which one is used?
>
> The far majority of the cases, people just need the empty case. That's what we
> recommend. And unless some API in specific documents the distinction, using
> isEmpty() is the right thing to do.
>
> The null option comes in handy when you need to distinguish a field that might
> be present but empty from a field that isn't present. QUrl makes use of that
> and the equivalent std::networking::uri proposal just uses
> std::optional<String> (String is a template). For example:
>
> QUrl url1("foo:/"), url2("foo://@/?#");
> QString query1 = url1.query(), query2 = url2.query();
>
> Both query1 and query2 are empty, but only query1 is null, indicating that the
> query was not present. The same applies to userInfo(), host(), and fragment(),
> and would apply to authority() if the "@" weren't present.
>
> And you can do:
>
> url1.setQuery("");
> url2.setQuery(QString());
>
> to invert the situation.
>
> The other common case for using nulls is in QVariant and that comes from the
> QtSql module: all entries are returned as QVariants and they need to support
> database tables that don't contain "NOT NULL" (that is, are nullable). So
> QVariant can contain a null int that is different from a zero:
>
> QVariant v1, v2{0};
> v1.convert(QVariant::Int);
> // v1.isNull() == true; v2.isNull() == false
>
> We don't recommend relying on the nullness of a string. We only condone on the
> above cases I described, but I wouldn't be surprised to find more uses. And,
> trust me, there's quite a lot of headache involved in keeping the nullness of
> certain types across transformations:
>
> QString().toUtf8().isNull() == true;
> QString("").toUtf8().isNull() == false;
>
> And then there are weird questions like:
> - does a null QString compare equal to an empty one? (yes)
> - does a null QString startsWith() an empty one? Does the opposite?
> - same for endsWith(), contains(), indexOf()
> - is QString().left(1) null? How about QString().left(0)?
> - and what about QString("hello").left(0)?
> - if left, right and mid can return null, can leftRef, rightRef and midRef
> (which return QStringRef)?
>
> I don't know the answer to most of those questions, which means I would
> recommend no one rely on a specific behaviour.
>
> Most of it is unit-tested so we don't break it:
> http://code.woboq.org/qt5/qtbase/tests/auto/corelib/tools/qstring/tst_qstring.cpp.html#_ZN11tst_QString10startsWithEv
> http://code.woboq.org/qt5/qtbase/tests/auto/corelib/tools/qstring/tst_qstring.cpp.html#_ZN11tst_QString8endsWithEv
> http://code.woboq.org/qt5/qtbase/tests/auto/corelib/tools/qstring/tst_qstring.cpp.html#_ZN11tst_QString4leftEv
> http://code.woboq.org/qt5/qtbase/tests/auto/corelib/tools/qstring/tst_qstring.cpp.html#_ZN11tst_QString7leftRefEv
>
> and what isn't tested I'd feel free to change behaviour at any time.
Thanks for the detailed discussion of QT's use. I agree there are some
times when "not present" is different from "empty", but the fact that
in "The far majority of the cases, people just need the empty case"
makes me think that the string_view proposal makes the right choice.
It's true that this means existing classes like QStringRef can't just
become typedefs, but my goal here has been to learn from existing
practice so that the standard can avoid making the same mistakes.
optional<> is always available for cases like SQL and URLs, and using
it means that the unusual case is called out rather than hiding inside
the same type used for the usual case.
Thanks again for trying it out,
Jeffrey
P.S. Other people need to make a stronger argument than "sometimes it
is convenient". Give concrete examples like Thiago did, or I can't do
anything with your email.
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Casey Carter <cartec69@gmail.com>
Date: Thu, 16 Jan 2014 14:46:31 -0800 (PST)
Raw View
------=_Part_669_21545897.1389912391642
Content-Type: text/plain; charset=UTF-8
On Wednesday, January 15, 2014 11:15:36 AM UTC-6, Billy O'Neal wrote:
>
> It should be discouraged because we don't want to have to write null
> checks in every function under the sun; it is about preventing callers from
> supplying unexpected results.
>
"Every function under the sun" must already be able to deal with an empty
string_view, given that a null string_view must also necessarily be empty,
there's no need to check for null as a special case.
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_669_21545897.1389912391642
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Wednesday, January 15, 2014 11:15:36 AM UTC-6, Billy O'=
Neal wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"font-=
size:12pt;font-family:Calibri,sans-serif"><div>It should be discouraged bec=
ause we don't want to have to write null checks in every function under the=
sun; it is about preventing callers from supplying unexpected results.</di=
v></div></blockquote><div><br></div><div>"Every function under the sun" mus=
t already be able to deal with an empty string_view, given that a null stri=
ng_view must also necessarily be empty, there's no need to check for null a=
s a special case.</div></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_669_21545897.1389912391642--
.
Author: "Billy O'Neal" <billy.oneal@gmail.com>
Date: Thu, 16 Jan 2014 15:10:12 -0800
Raw View
--001a11c204f289c7e704f01e89da
Content-Type: text/plain; charset=UTF-8
What do you expect
to_string(foo);
to return if foo is a null string_view?
Billy O'Neal
https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
http://stackoverflow.com/users/82320/billy-oneal
On Thu, Jan 16, 2014 at 2:46 PM, Casey Carter <cartec69@gmail.com> wrote:
> On Wednesday, January 15, 2014 11:15:36 AM UTC-6, Billy O'Neal wrote:
>>
>> It should be discouraged because we don't want to have to write null
>> checks in every function under the sun; it is about preventing callers from
>> supplying unexpected results.
>>
>
> "Every function under the sun" must already be able to deal with an empty
> string_view, given that a null string_view must also necessarily be empty,
> there's no need to check for null as a special case.
>
> --
>
> ---
> 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.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a11c204f289c7e704f01e89da
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>What do you expect</div><div><br></div><div>to_string=
(foo);</div><div><br></div><div>to return if foo is a null string_view?</di=
v></div><div class=3D"gmail_extra"><br clear=3D"all"><div><div dir=3D"ltr">=
<div>
Billy O'Neal</div><div><a href=3D"https://bitbucket.org/BillyONeal/" ta=
rget=3D"_blank">https://github.com/BillyONeal/</a></div><div><a href=3D"htt=
p://stackoverflow.com/users/82320/billy-oneal" target=3D"_blank">http://sta=
ckoverflow.com/users/82320/billy-oneal</a></div>
</div></div>
<br><br><div class=3D"gmail_quote">On Thu, Jan 16, 2014 at 2:46 PM, Casey C=
arter <span dir=3D"ltr"><<a href=3D"mailto:cartec69@gmail.com" target=3D=
"_blank">cartec69@gmail.com</a>></span> wrote:<br><blockquote class=3D"g=
mail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-l=
eft:1ex">
<div dir=3D"ltr">On Wednesday, January 15, 2014 11:15:36 AM UTC-6, Billy O&=
#39;Neal wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0p=
x 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-wid=
th:1px;border-left-style:solid">
<div style=3D"font-family:Calibri,sans-serif;font-size:12pt"><div>It should=
be discouraged because we don't want to have to write null checks in e=
very function under the sun; it is about preventing callers from supplying =
unexpected results.</div>
</div></blockquote><div><br></div><div>"Every function under the sun&q=
uot; must already be able to deal with an empty string_view, given that a n=
ull string_view must also necessarily be empty, there's no need to chec=
k for null as a special case.</div>
</div><span class=3D"HOEnZb"><font color=3D"#888888">
<p></p>
-- <br>
=C2=A0<br>
--- <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%2Bunsubscribe@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>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</font></span></blockquote></div><br></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--001a11c204f289c7e704f01e89da--
.
Author: Casey Carter <cartec69@gmail.com>
Date: Thu, 16 Jan 2014 19:08:27 -0800 (PST)
Raw View
------=_Part_881_12109438.1389928107851
Content-Type: text/plain; charset=UTF-8
On Thursday, January 16, 2014 5:10:12 PM UTC-6, Billy O'Neal wrote:
>
> What do you expect
>
> to_string(foo);
>
> to return if foo is a null string_view?
>
> Billy O'Neal
> https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
> http://stackoverflow.com/users/82320/billy-oneal
>
>
The same thing it would return for any other empty string_view - an empty
string.
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_881_12109438.1389928107851
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Thursday, January 16, 2014 5:10:12 PM UTC-6, Billy O'Ne=
al 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=
>What do you expect</div><div><br></div><div>to_string(foo);</div><div><br>=
</div><div>to return if foo is a null string_view?</div></div><div><br clea=
r=3D"all"><div><div dir=3D"ltr"><div>
Billy O'Neal</div><div><a href=3D"https://bitbucket.org/BillyONeal/" target=
=3D"_blank" onmousedown=3D"this.href=3D'https://www.google.com/url?q\75http=
s%3A%2F%2Fbitbucket.org%2FBillyONeal%2F\46sa\75D\46sntz\0751\46usg\75AFQjCN=
EUaaIry0cea0l0vX6ztWgwQ7_4Lg';return true;" onclick=3D"this.href=3D'https:/=
/www.google.com/url?q\75https%3A%2F%2Fbitbucket.org%2FBillyONeal%2F\46sa\75=
D\46sntz\0751\46usg\75AFQjCNEUaaIry0cea0l0vX6ztWgwQ7_4Lg';return true;">htt=
ps://github.com/BillyONeal/</a></div><div><a href=3D"http://stackoverflow.c=
om/users/82320/billy-oneal" target=3D"_blank" onmousedown=3D"this.href=3D'h=
ttp://www.google.com/url?q\75http%3A%2F%2Fstackoverflow.com%2Fusers%2F82320=
%2Fbilly-oneal\46sa\75D\46sntz\0751\46usg\75AFQjCNHY_gA133vyg0yY-U2PNMVA8cC=
SBg';return true;" onclick=3D"this.href=3D'http://www.google.com/url?q\75ht=
tp%3A%2F%2Fstackoverflow.com%2Fusers%2F82320%2Fbilly-oneal\46sa\75D\46sntz\=
0751\46usg\75AFQjCNHY_gA133vyg0yY-U2PNMVA8cCSBg';return true;">http://stack=
overflow.com/<wbr>users/82320/billy-oneal</a></div>
</div></div>
<br></div></blockquote><div><br></div><div>The same thing it would return f=
or any other empty string_view - an empty string.</div></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_881_12109438.1389928107851--
.
Author: abolz.lists@gmail.com
Date: Thu, 16 Jan 2014 22:59:51 -0800 (PST)
Raw View
------=_Part_6962_21373520.1389941991771
Content-Type: text/plain; charset=UTF-8
Am Mittwoch, 15. Januar 2014 21:42:20 UTC+1 schrieb Jeffrey Yasskin:
>
> On Wed, Jan 15, 2014 at 11:45 AM, Thiago Macieira <thi...@macieira.org<javascript:>>
> wrote:
> > On quarta-feira, 15 de janeiro de 2014 10:26:14, Jeffrey Yasskin wrote:
> >> Can you look over some of the uses of isNull() in QT and see what
> >> fraction are ones where both empty and null are possible values, and
> >> the distinction is useful rather than just forcing the API to document
> >> which one is used?
> >
> > The far majority of the cases, people just need the empty case. That's
> what we
> > recommend. And unless some API in specific documents the distinction,
> using
> > isEmpty() is the right thing to do.
> >
> > The null option comes in handy when you need to distinguish a field that
> might
> > be present but empty from a field that isn't present. QUrl makes use of
> that
> > and the equivalent std::networking::uri proposal just uses
> > std::optional<String> (String is a template). For example:
> >
> > QUrl url1("foo:/"), url2("foo://@/?#");
> > QString query1 = url1.query(), query2 = url2.query();
> >
> > Both query1 and query2 are empty, but only query1 is null, indicating
> that the
> > query was not present. The same applies to userInfo(), host(), and
> fragment(),
> > and would apply to authority() if the "@" weren't present.
> >
> > And you can do:
> >
> > url1.setQuery("");
> > url2.setQuery(QString());
> >
> > to invert the situation.
> >
> > The other common case for using nulls is in QVariant and that comes from
> the
> > QtSql module: all entries are returned as QVariants and they need to
> support
> > database tables that don't contain "NOT NULL" (that is, are nullable).
> So
> > QVariant can contain a null int that is different from a zero:
> >
> > QVariant v1, v2{0};
> > v1.convert(QVariant::Int);
> > // v1.isNull() == true; v2.isNull() == false
> >
> > We don't recommend relying on the nullness of a string. We only condone
> on the
> > above cases I described, but I wouldn't be surprised to find more uses.
> And,
> > trust me, there's quite a lot of headache involved in keeping the
> nullness of
> > certain types across transformations:
> >
> > QString().toUtf8().isNull() == true;
> > QString("").toUtf8().isNull() == false;
> >
> > And then there are weird questions like:
> > - does a null QString compare equal to an empty one? (yes)
> > - does a null QString startsWith() an empty one? Does the opposite?
> > - same for endsWith(), contains(), indexOf()
> > - is QString().left(1) null? How about QString().left(0)?
> > - and what about QString("hello").left(0)?
> > - if left, right and mid can return null, can leftRef, rightRef and
> midRef
> > (which return QStringRef)?
> >
> > I don't know the answer to most of those questions, which means I would
> > recommend no one rely on a specific behaviour.
> >
> > Most of it is unit-tested so we don't break it:
> >
> http://code.woboq.org/qt5/qtbase/tests/auto/corelib/tools/qstring/tst_qstring.cpp.html#_ZN11tst_QString10startsWithEv
> >
> http://code.woboq.org/qt5/qtbase/tests/auto/corelib/tools/qstring/tst_qstring.cpp.html#_ZN11tst_QString8endsWithEv
> >
> http://code.woboq.org/qt5/qtbase/tests/auto/corelib/tools/qstring/tst_qstring.cpp.html#_ZN11tst_QString4leftEv
> >
> http://code.woboq.org/qt5/qtbase/tests/auto/corelib/tools/qstring/tst_qstring.cpp.html#_ZN11tst_QString7leftRefEv
> >
> > and what isn't tested I'd feel free to change behaviour at any time.
>
> Thanks for the detailed discussion of QT's use. I agree there are some
> times when "not present" is different from "empty", but the fact that
> in "The far majority of the cases, people just need the empty case"
> makes me think that the string_view proposal makes the right choice.
> It's true that this means existing classes like QStringRef can't just
> become typedefs, but my goal here has been to learn from existing
> practice so that the standard can avoid making the same mistakes.
>
> optional<> is always available for cases like SQL and URLs, and using
> it means that the unusual case is called out rather than hiding inside
> the same type used for the usual case.
>
> Thanks again for trying it out,
> Jeffrey
>
> P.S. Other people need to make a stronger argument than "sometimes it
> is convenient". Give concrete examples like Thiago did, or I can't do
> anything with your email.
>
Well, I can't make a stronger argument than "convenience" since there is
optional<>, so its always possible to extend string_view with a null value.
In the past I used a string_view-like class to split strings into key-value
pairs. Using the nullness I could easily distinguish "key=" (empty value)
from "key" (null value).
I have also used this for string splitting: A function returning the next
delimiter might return an empty string (an empty delimiter found) or a
null string (no delimiter found).
I just looked into the string_view-like classes mentioned in the proposal
[1,2,3] and the boost implementation [4]. They all allow data() to
return null and pass through the pointer used to construct the string_view.
The original string_ref proposal did exactly the same.
However, N3512 changed this (without mentioning why I think, maybe I
missed something...) and the current proposal states that programmers
used this to signal conditions that differed from empty() and that this was
a source of confusion in interfaces and so is not allowed. Could you
give an example where null-strings resulted in such a confusion? I really
want to avoid making the same mistakes!
Thanks
Alex
[1]
*https://chromium.googlesource.com/chromium/src/base/+/refs/heads/master/strings/string_piece.h*<https://chromium.googlesource.com/chromium/src/base/+/refs/heads/master/strings/string_piece.h>
[2] *http://llvm.org/docs/doxygen/html/StringRef_8h_source.html*<http://llvm.org/docs/doxygen/html/StringRef_8h_source.html>
[3]
*https://github.com/bloomberg/bde/blob/master/groups/bsl/bslstl/bslstl_stringref.h*<https://github.com/bloomberg/bde/blob/master/groups/bsl/bslstl/bslstl_stringref.h>
[4]
*https://github.com/boostorg/utility/blob/master/include/boost/utility/string_ref.hpp*<https://github.com/boostorg/utility/blob/master/include/boost/utility/string_ref.hpp>
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_6962_21373520.1389941991771
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Am Mittwoch, 15. Januar 2014 21:42:20 UTC+1 schrieb Jeffre=
y Yasskin:<blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.=
8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-=
width: 1px; border-left-style: solid;">On Wed, Jan 15, 2014 at 11:45 AM, Th=
iago Macieira <<a onmousedown=3D"this.href=3D'javascript:';return true;"=
onclick=3D"this.href=3D'javascript:';return true;" href=3D"javascript:" ta=
rget=3D"_blank" gdf-obfuscated-mailto=3D"TwT5x0p7PRYJ">thi...@macieira.org<=
/a>> wrote:
<br>> On quarta-feira, 15 de janeiro de 2014 10:26:14, Jeffrey Yasskin w=
rote:
<br>>> Can you look over some of the uses of isNull() in QT and see w=
hat
<br>>> fraction are ones where both empty and null are possible value=
s, and
<br>>> the distinction is useful rather than just forcing the API to =
document
<br>>> which one is used?
<br>>
<br>> The far majority of the cases, people just need the empty case. Th=
at's what we
<br>> recommend. And unless some API in specific documents the distincti=
on, using
<br>> isEmpty() is the right thing to do.
<br>>
<br>> The null option comes in handy when you need to distinguish a fiel=
d that might
<br>> be present but empty from a field that isn't present. QUrl makes u=
se of that
<br>> and the equivalent std::networking::uri proposal just uses
<br>> std::optional<String> (String is a template). For example:
<br>>
<br>> QUrl url1("foo:/"), url2("foo://@/?#")=
;
<br>> QString query1 =3D url1.query(), query=
2 =3D url2.query();
<br>>
<br>> Both query1 and query2 are empty, but only query1 is null, indicat=
ing that the
<br>> query was not present. The same applies to userInfo(), host(), and=
fragment(),
<br>> and would apply to authority() if the "@" weren't present.
<br>>
<br>> And you can do:
<br>>
<br>> url1.setQuery("");
<br>> url2.setQuery(QString());
<br>>
<br>> to invert the situation.
<br>>
<br>> The other common case for using nulls is in QVariant and that come=
s from the
<br>> QtSql module: all entries are returned as QVariants and they need =
to support
<br>> database tables that don't contain "NOT NULL" (that is, are nullab=
le). So
<br>> QVariant can contain a null int that is different from a zero:
<br>>
<br>> QVariant v1, v2{0};
<br>> v1.convert(QVariant::Int);
<br>> // v1.isNull() =3D=3D true; v2.isNull(=
) =3D=3D false
<br>>
<br>> We don't recommend relying on the nullness of a string. We only co=
ndone on the
<br>> above cases I described, but I wouldn't be surprised to find more =
uses. And,
<br>> trust me, there's quite a lot of headache involved in keeping the =
nullness of
<br>> certain types across transformations:
<br>>
<br>> QString().toUtf8().isNull() =3D=3D tru=
e;
<br>> QString("").toUtf8().isNull() =3D=3D f=
alse;
<br>>
<br>> And then there are weird questions like:
<br>> - does a null QString compare equal to an empty one? (yes)
<br>> - does a null QString startsWith() an empty one? Does the opposite=
?
<br>> - same for endsWith(), contains(), indexOf()
<br>> - is QString().left(1) null? How about QString().left(0)?
<br>> - and what about QString("hello").left(0)?
<br>> - if left, right and mid can return null, can leftRef, rightRef an=
d midRef
<br>> (which return QStringRef)?
<br>>
<br>> I don't know the answer to most of those questions, which means I =
would
<br>> recommend no one rely on a specific behaviour.
<br>>
<br>> Most of it is unit-tested so we don't break it:
<br>> <a onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%=
3A%2F%2Fcode.woboq.org%2Fqt5%2Fqtbase%2Ftests%2Fauto%2Fcorelib%2Ftools%2Fqs=
tring%2Ftst_qstring.cpp.html%23_ZN11tst_QString10startsWithEv\46sa\75D\46sn=
tz\0751\46usg\75AFQjCNH0DkvTqaGjpdgeogyca4zHTXpj9A';return true;" onclick=
=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fcode.woboq.org%=
2Fqt5%2Fqtbase%2Ftests%2Fauto%2Fcorelib%2Ftools%2Fqstring%2Ftst_qstring.cpp=
..html%23_ZN11tst_QString10startsWithEv\46sa\75D\46sntz\0751\46usg\75AFQjCNH=
0DkvTqaGjpdgeogyca4zHTXpj9A';return true;" href=3D"http://code.woboq.org/qt=
5/qtbase/tests/auto/corelib/tools/qstring/tst_qstring.cpp.html#_ZN11tst_QSt=
ring10startsWithEv" target=3D"_blank">http://code.woboq.org/qt5/<wbr>qtbase=
/tests/auto/corelib/<wbr>tools/qstring/tst_qstring.cpp.<wbr>html#_ZN11tst_<=
wbr>QString10startsWithEv</a>
<br>> <a onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%=
3A%2F%2Fcode.woboq.org%2Fqt5%2Fqtbase%2Ftests%2Fauto%2Fcorelib%2Ftools%2Fqs=
tring%2Ftst_qstring.cpp.html%23_ZN11tst_QString8endsWithEv\46sa\75D\46sntz\=
0751\46usg\75AFQjCNEozKVuuIDN2zRdKK2fCefHltxC_Q';return true;" onclick=3D"t=
his.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fcode.woboq.org%2Fqt5=
%2Fqtbase%2Ftests%2Fauto%2Fcorelib%2Ftools%2Fqstring%2Ftst_qstring.cpp.html=
%23_ZN11tst_QString8endsWithEv\46sa\75D\46sntz\0751\46usg\75AFQjCNEozKVuuID=
N2zRdKK2fCefHltxC_Q';return true;" href=3D"http://code.woboq.org/qt5/qtbase=
/tests/auto/corelib/tools/qstring/tst_qstring.cpp.html#_ZN11tst_QString8end=
sWithEv" target=3D"_blank">http://code.woboq.org/qt5/<wbr>qtbase/tests/auto=
/corelib/<wbr>tools/qstring/tst_qstring.cpp.<wbr>html#_ZN11tst_<wbr>QString=
8endsWithEv</a>
<br>> <a onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%=
3A%2F%2Fcode.woboq.org%2Fqt5%2Fqtbase%2Ftests%2Fauto%2Fcorelib%2Ftools%2Fqs=
tring%2Ftst_qstring.cpp.html%23_ZN11tst_QString4leftEv\46sa\75D\46sntz\0751=
\46usg\75AFQjCNF_uztsNplZ08s05SewQrc0SE4bqw';return true;" onclick=3D"this.=
href=3D'http://www.google.com/url?q\75http%3A%2F%2Fcode.woboq.org%2Fqt5%2Fq=
tbase%2Ftests%2Fauto%2Fcorelib%2Ftools%2Fqstring%2Ftst_qstring.cpp.html%23_=
ZN11tst_QString4leftEv\46sa\75D\46sntz\0751\46usg\75AFQjCNF_uztsNplZ08s05Se=
wQrc0SE4bqw';return true;" href=3D"http://code.woboq.org/qt5/qtbase/tests/a=
uto/corelib/tools/qstring/tst_qstring.cpp.html#_ZN11tst_QString4leftEv" tar=
get=3D"_blank">http://code.woboq.org/qt5/<wbr>qtbase/tests/auto/corelib/<wb=
r>tools/qstring/tst_qstring.cpp.<wbr>html#_ZN11tst_QString4leftEv</a>
<br>> <a onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%=
3A%2F%2Fcode.woboq.org%2Fqt5%2Fqtbase%2Ftests%2Fauto%2Fcorelib%2Ftools%2Fqs=
tring%2Ftst_qstring.cpp.html%23_ZN11tst_QString7leftRefEv\46sa\75D\46sntz\0=
751\46usg\75AFQjCNErchfCONblsCTo3UCyQx6cSvRlnA';return true;" onclick=3D"th=
is.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fcode.woboq.org%2Fqt5%=
2Fqtbase%2Ftests%2Fauto%2Fcorelib%2Ftools%2Fqstring%2Ftst_qstring.cpp.html%=
23_ZN11tst_QString7leftRefEv\46sa\75D\46sntz\0751\46usg\75AFQjCNErchfCONbls=
CTo3UCyQx6cSvRlnA';return true;" href=3D"http://code.woboq.org/qt5/qtbase/t=
ests/auto/corelib/tools/qstring/tst_qstring.cpp.html#_ZN11tst_QString7leftR=
efEv" target=3D"_blank">http://code.woboq.org/qt5/<wbr>qtbase/tests/auto/co=
relib/<wbr>tools/qstring/tst_qstring.cpp.<wbr>html#_ZN11tst_<wbr>QString7le=
ftRefEv</a>
<br>>
<br>> and what isn't tested I'd feel free to change behaviour at any tim=
e.
<br>
<br>Thanks for the detailed discussion of QT's use. I agree there are some
<br>times when "not present" is different from "empty", but the fact that
<br>in "The far majority of the cases, people just need the empty case"
<br>makes me think that the string_view proposal makes the right choice.
<br>It's true that this means existing classes like QStringRef can't just
<br>become typedefs, but my goal here has been to learn from existing
<br>practice so that the standard can avoid making the same mistakes.
<br>
<br>optional<> is always available for cases like SQL and URLs, and u=
sing
<br>it means that the unusual case is called out rather than hiding inside
<br>the same type used for the usual case.
<br>
<br>Thanks again for trying it out,
<br>Jeffrey
<br>
<br>P.S. Other people need to make a stronger argument than "sometimes it
<br>is convenient". Give concrete examples like Thiago did, or I can't do
<br>anything with your email.
<br></blockquote><div><br></div><div>Well, I can't make a stronger argument=
than "convenience" since there is</div><div>optional<>, so its =
always possible to extend string_view with a null value.</div><div><br></di=
v><div>In the past I used a string_view-like class to split strings in=
to key-value</div><div>pairs. Using the nullness I could easily distinguish=
"key=3D" (empty value)</div><div>from "key" (null value).</div><div>I have=
also used this for string splitting: A function returning the next</div><d=
iv>delimiter might return an empty string (an empty delimiter found) o=
r a</div><div>null string (no delimiter found).</div><div><br></div><div>I =
just looked into the string_view-like classes mentioned in the proposal</di=
v><div>[1,2,3] and the boost implementation [4]. They all allow data() to</=
div><div>return null and pass through the pointer used to construct the str=
ing_view.</div><div>The original string_ref proposal did exactly the same.<=
/div><div><br></div><div>However, N3512 changed this (without mentioning wh=
y I think, maybe I</div><div>missed something...) and the current=
proposal states that programmers</div><div>used this to signal conditions =
that differed from empty() and that this was</div><div>a source of confusio=
n in interfaces and so is not allowed. Could you</div><div>give an example =
where null-strings resulted in such a confusion? I really</div><div>want to=
avoid making the same mistakes!</div><div><br></div><div>Thanks</div><div>=
Alex</div><div><br></div><div>[1] <a href=3D"https://chromium.googlesource.=
com/chromium/src/base/+/refs/heads/master/strings/string_piece.h"><u><font =
color=3D"#0066cc">https://chromium.googlesource.com/chromium/src/base/+/ref=
s/heads/master/strings/string_piece.h</font></u></a></div><div>[2] <a href=
=3D"http://llvm.org/docs/doxygen/html/StringRef_8h_source.html"><u><font co=
lor=3D"#0066cc">http://llvm.org/docs/doxygen/html/StringRef_8h_source.html<=
/font></u></a></div><div>[3] <a href=3D"https://github.com/bloomberg/bde/bl=
ob/master/groups/bsl/bslstl/bslstl_stringref.h"><u><font color=3D"#0066cc">=
https://github.com/bloomberg/bde/blob/master/groups/bsl/bslstl/bslstl_strin=
gref.h</font></u></a></div><div>[4] <a href=3D"https://github.com/boostorg/=
utility/blob/master/include/boost/utility/string_ref.hpp"><u><font color=3D=
"#0066cc">https://github.com/boostorg/utility/blob/master/include/boost/uti=
lity/string_ref.hpp</font></u></a></div></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_6962_21373520.1389941991771--
.
Author: Marshall Clow <mclow.lists@gmail.com>
Date: Fri, 17 Jan 2014 08:26:50 -0800
Raw View
--Apple-Mail=_769C02A7-776F-4F23-B5F6-273D5042B65C
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=windows-1252
On Jan 15, 2014, at 4:28 AM, Olaf van der Spek <olafvdspek@gmail.com> wrote=
:
> On Saturday, December 28, 2013 6:01:34 AM UTC+1, Marshall wrote:
> if sv.size () =3D=3D 0 or sv.empty () [same thing], there is nothing that=
you can do with sv.data()
> (except compare it to null, and that doesn=92t tell you anything useful).
>=20
> Are you sure?
> IMO an empty string_view could still point into a string and I should be =
able to use that pointer to for example construct a new string_view.
A string view references a half-open contiguous range of characters; [ data=
(), data()+size())
if size() =3D=3D 0, then the range of characters referenced by the string v=
iew is empty, and accessing them (either via dereferencing begin() or data(=
)) is (or should be) undefined behavior. (the same as any other container)
If in your program, you =93know=94 that the pointer returned by data() poin=
ts to something valid, well, that=92s on you to determine.
Code example:
char deref ( string_view sv ) { return *sv.data(); }
string_view sv1;
string_view sv2 { =93ABCDE=94 };
sv2.remove_prefix(5);
assert ( sv1 =3D=3D sv2 );
deref ( sv1 ); // may or may not blow up in your face
deref ( sv2 ); // this will probably =93work=94 ; but I don=92t know what =
it will return.
=97 Marshall
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--Apple-Mail=_769C02A7-776F-4F23-B5F6-273D5042B65C
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=windows-1252
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;">On Jan 15, 2014, at 4:=
28 AM, Olaf van der Spek <<a href=3D"mailto:olafvdspek@gmail.com">olafvd=
spek@gmail.com</a>> wrote:<br><div><br class=3D"Apple-interchange-newlin=
e"><blockquote type=3D"cite"><div dir=3D"ltr">On Saturday, December 28, 201=
3 6:01:34 AM UTC+1, Marshall wrote:<blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div style=3D"word-wrap:break-word"><div>if sv.size () =3D=3D 0 or sv=
..empty () [same thing], there is nothing that you can do with sv.data()</di=
v><div>(except compare it to null, and that doesn=92t tell you anything use=
ful).</div></div></blockquote><div><br></div><div>Are you sure?</div><div>I=
MO an empty string_view could still point into a string and I should be abl=
e to use that pointer to for example construct a new string_view.</div></di=
v></blockquote></div><div><br></div><div>A string view references a half-op=
en contiguous range of characters; [ data(), data()+size())</div><div><br><=
/div><div>if size() =3D=3D 0, then the range of characters referenced by th=
e string view is empty, and accessing them (either via dereferencing begin(=
) or data()) is (or should be) undefined behavior. (the same as any other c=
ontainer)</div><div><br></div><div>If in your program, you =93know=94 that =
the pointer returned by data() points to something valid, well, that=92s on=
you to determine.</div><div><br></div><div>Code example:</div><div><br></d=
iv><div><span class=3D"Apple-tab-span" style=3D"white-space:pre"> </span>ch=
ar deref ( string_view sv ) { return *sv.data(); }</div><div><br></div><div=
><span class=3D"Apple-tab-span" style=3D"white-space:pre"> </span>string_vi=
ew sv1;</div><div><span class=3D"Apple-tab-span" style=3D"white-space:pre">=
</span>string_view sv2 { =93ABCDE=94 };</div><div><span class=3D"Apple-tab=
-span" style=3D"white-space:pre"> </span>sv2.remove_prefix(5);</div><div><s=
pan class=3D"Apple-tab-span" style=3D"white-space:pre"> </span>assert ( sv1=
=3D=3D sv2 );</div><div><span class=3D"Apple-tab-span" style=3D"white-spac=
e:pre"> </span>deref ( sv1 );<span class=3D"Apple-tab-span" style=3D"white-=
space:pre"> </span>// may or may not blow up in your face</div><div><span c=
lass=3D"Apple-tab-span" style=3D"white-space:pre"> </span>deref ( sv2 );<sp=
an class=3D"Apple-tab-span" style=3D"white-space:pre"> </span>// this will =
probably =93work=94 ; but I don=92t know what it will return.</div><div><br=
></div><div>=97 Marshall</div><div><br></div></body></html>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--Apple-Mail=_769C02A7-776F-4F23-B5F6-273D5042B65C--
.
Author: Peter Bigot <bigotp@acm.org>
Date: Fri, 17 Jan 2014 10:34:37 -0800 (PST)
Raw View
------=_Part_6_3650826.1389983677618
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Friday, January 17, 2014 10:26:50 AM UTC-6, Marshall wrote:
>
> On Jan 15, 2014, at 4:28 AM, Olaf van der Spek <olafv...@gmail.com<javasc=
ript:>>=20
> wrote:
>
> On Saturday, December 28, 2013 6:01:34 AM UTC+1, Marshall wrote:
>>
>> if sv.size () =3D=3D 0 or sv.empty () [same thing], there is nothing tha=
t you=20
>> can do with sv.data()
>> (except compare it to null, and that doesn=E2=80=99t tell you anything u=
seful).
>>
>
> Are you sure?
> IMO an empty string_view could still point into a string and I should be=
=20
> able to use that pointer to for example construct a new string_view.
>
>
> A string view references a half-open contiguous range of characters; [=20
> data(), data()+size())
>
> if size() =3D=3D 0, then the range of characters referenced by the string=
view=20
> is empty, and accessing them (either via dereferencing begin() or data())=
=20
> is (or should be) undefined behavior. (the same as any other container)
>
> If in your program, you =E2=80=9Cknow=E2=80=9D that the pointer returned =
by data() points=20
> to something valid, well, that=E2=80=99s on you to determine.
>
> Code example:
>
> char deref ( string_view sv ) { return *sv.data(); }
>
> string_view sv1;
> string_view sv2 { =E2=80=9CABCDE=E2=80=9D };
> sv2.remove_prefix(5);
> assert ( sv1 =3D=3D sv2 );
> deref ( sv1 ); // may or may not blow up in your face
> deref ( sv2 ); // this will probably =E2=80=9Cwork=E2=80=9D ; but I don=
=E2=80=99t know what it=20
> will return.
>
> =E2=80=94 Marshall
>
>
While the half-open range argument is true in isolation, it's missing the=
=20
point that the value of data() is well-known based on how the string_view=
=20
was created and what operations have been performed on it. Adjusting the=20
string_view to the point where size() is zero does not invalidate data().
Based on how sv2 is constructed in that example, I believe it's guaranteed=
=20
that deref(sv2) will return the '\0' that terminates the string literal=20
used to initialize sv2, and that doing so does not invoke undefined=20
behavior. This follows from how sv2 is created and the definition of=20
remove_prefix.
Here's a more relevant example. There is no need for scare quotes when=20
stating that the programmer knows delim.data() always points to something=
=20
valid in the test code.
Peter
string_view
comma_delimiter (string_view sv)
{
string_view::size_type p{sv.find(',')};
if (string_view::npos =3D=3D p) {
return sv.substr(sv.size());
}
return sv.substr(p, 1);
}
string_view
case_change_delimiter (string_view sv)
{
for (string_view::size_type i =3D 1; i < sv.size(); ++i) {
string_view::value_type c1 =3D sv[i-1];
string_view::value_type c2 =3D sv[i];
if (isalpha(c1) && isalpha(c2) && (islower(c1) !=3D islower(c2))) {
return sv.substr(i, 0);
}
}
return sv.substr(sv.size());
}
TEST(Delimiter, Example)
{
const std::string base("A,Bcde");
string_view sv(base);
ASSERT_EQ(base.data(), sv.data());
/* Locate the comma as a single-character delimiter */
string_view delim(comma_delimiter(sv));
ASSERT_EQ(1, delim.size());
ASSERT_EQ(1, (delim.data() - sv.data()));
ASSERT_EQ(",", delim);
/* Locate the case change as zero-width delimiter */
delim =3D case_change_delimiter(sv);
ASSERT_EQ(0, delim.size());
ASSERT_EQ(3, (delim.data() - sv.data()));
ASSERT_EQ("cde", sv.substr(delim.data()-sv.data()));
}
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_6_3650826.1389983677618
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Friday, January 17, 2014 10:26:50 AM UTC-6, Mar=
shall wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"word=
-wrap:break-word">On Jan 15, 2014, at 4:28 AM, Olaf van der Spek <<a hre=
f=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"MEVbJLx2UbAJ" =
onmousedown=3D"this.href=3D'javascript:';return true;" onclick=3D"this.href=
=3D'javascript:';return true;">olafv...@gmail.com</a>> wrote:<br><div><b=
r><blockquote type=3D"cite"><div dir=3D"ltr">On Saturday, December 28, 2013=
6:01:34 AM UTC+1, Marshall wrote:<blockquote class=3D"gmail_quote" style=
=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"=
><div style=3D"word-wrap:break-word"><div>if sv.size () =3D=3D 0 or sv.empt=
y () [same thing], there is nothing that you can do with sv.data()</div><di=
v>(except compare it to null, and that doesn=E2=80=99t tell you anything us=
eful).</div></div></blockquote><div><br></div><div>Are you sure?</div><div>=
IMO an empty string_view could still point into a string and I should be ab=
le to use that pointer to for example construct a new string_view.</div></d=
iv></blockquote></div><div><br></div><div>A string view references a half-o=
pen contiguous range of characters; [ data(), data()+size())</div><div><br>=
</div><div>if size() =3D=3D 0, then the range of characters referenced by t=
he string view is empty, and accessing them (either via dereferencing begin=
() or data()) is (or should be) undefined behavior. (the same as any other =
container)</div><div><br></div><div>If in your program, you =E2=80=9Cknow=
=E2=80=9D that the pointer returned by data() points to something valid, we=
ll, that=E2=80=99s on you to determine.</div><div><br></div><div>Code examp=
le:</div><div><br></div><div><span style=3D"white-space:pre"> </span>char d=
eref ( string_view sv ) { return *sv.data(); }</div><div><br></div><div><sp=
an style=3D"white-space:pre"> </span>string_view sv1;</div><div><span style=
=3D"white-space:pre"> </span>string_view sv2 { =E2=80=9CABCDE=E2=80=9D };</=
div><div><span style=3D"white-space:pre"> </span>sv2.remove_prefix(5);</div=
><div><span style=3D"white-space:pre"> </span>assert ( sv1 =3D=3D sv2 );</d=
iv><div><span style=3D"white-space:pre"> </span>deref ( sv1 );<span style=
=3D"white-space:pre"> </span>// may or may not blow up in your face</div><d=
iv><span style=3D"white-space:pre"> </span>deref ( sv2 );<span style=3D"whi=
te-space:pre"> </span>// this will probably =E2=80=9Cwork=E2=80=9D ; but I =
don=E2=80=99t know what it will return.</div><div><br></div><div>=E2=80=94 =
Marshall</div><div><br></div></div></blockquote><div><br>While the half-ope=
n range argument is true in isolation, it's missing the point that the valu=
e of data() is well-known based on how the string_view was created and what=
operations have been performed on it. Adjusting the string_view to the poi=
nt where size() is zero does not invalidate data().<br><br>Based on how sv2=
is constructed in that example, I believe it's guaranteed that deref(sv2) =
will return the '\0' that terminates the string literal used to initialize =
sv2, and that doing so does not invoke undefined behavior. This follo=
ws from how sv2 is created and the definition of remove_prefix.<br><br>Here=
's a more relevant example. There is no need for scare quotes when st=
ating that the programmer knows delim.data() always points to something val=
id in the test code.<br><br>Peter<br><br>string_view<br>comma_delimiter (st=
ring_view sv)<br>{<br> string_view::size_type p{sv.find(',')};<br>&nb=
sp; if (string_view::npos =3D=3D p) {<br> return sv.subst=
r(sv.size());<br> }<br> return sv.substr(p, 1);<br>}<br><br>str=
ing_view<br>case_change_delimiter (string_view sv)<br>{<br> for (stri=
ng_view::size_type i =3D 1; i < sv.size(); ++i) {<br> =
string_view::value_type c1 =3D sv[i-1];<br> string_view::=
value_type c2 =3D sv[i];<br> if (isalpha(c1) && i=
salpha(c2) && (islower(c1) !=3D islower(c2))) {<br> &nbs=
p; return sv.substr(i, 0);<br> }<br> }<=
br> return sv.substr(sv.size());<br>}<br><br>TEST(Delimiter, Example)=
<br>{<br> const std::string base("A,Bcde");<br> string_view sv(=
base);<br> ASSERT_EQ(base.data(), sv.data());<br><br> /* Locate=
the comma as a single-character delimiter */<br> string_view delim(c=
omma_delimiter(sv));<br> ASSERT_EQ(1, delim.size());<br> ASSERT=
_EQ(1, (delim.data() - sv.data()));<br> ASSERT_EQ(",", delim);<br><br=
> /* Locate the case change as zero-width delimiter */<br> deli=
m =3D case_change_delimiter(sv);<br> ASSERT_EQ(0, delim.size());<br>&=
nbsp; ASSERT_EQ(3, (delim.data() - sv.data()));<br> ASSERT_EQ("cde", =
sv.substr(delim.data()-sv.data()));<br>}<br><br></div></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_6_3650826.1389983677618--
.
Author: Nevin Liber <nevin@eviloverlord.com>
Date: Fri, 17 Jan 2014 13:58:37 -0600
Raw View
--047d7bb04c442e701004f02ffa41
Content-Type: text/plain; charset=ISO-8859-1
On 17 January 2014 12:34, Peter Bigot <bigotp@acm.org> wrote:
>
> While the half-open range argument is true in isolation, it's missing the
> point that the value of data() is well-known based on how the string_view
> was created and what operations have been performed on it.
>
How does the callee know how the string_view was created? If the callee
has more preconditions than those enforced by string_view, you might be
better off using a separate type. If the callee "knows" how it was
created, why use a string_view at all?
> Adjusting the string_view to the point where size() is zero does not
> invalidate data().
>
> Based on how sv2 is constructed in that example, I believe it's guaranteed
> that deref(sv2) will return the '\0' that terminates the string literal
> used to initialize sv2, and that doing so does not invoke undefined
> behavior.
>
What compilers are allowed to assume from the specification of the standard
library is an interesting question... :-)
Take for example:
std::vector<std::string> v(1);
auto p1 = v.data();
v.pop_back();
Can I legally do a placement new of a std::string into the space pointed to
by p1? Beats me.
--
Nevin ":-)" Liber <mailto:nevin@eviloverlord.com> (847) 691-1404
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--047d7bb04c442e701004f02ffa41
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On 17 January 2014 12:34, Peter Bigot <span dir=3D"ltr">&l=
t;<a href=3D"mailto:bigotp@acm.org" target=3D"_blank">bigotp@acm.org</a>>=
;</span> wrote:<br><div class=3D"gmail_extra"><div class=3D"gmail_quote"><b=
lockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px =
#ccc solid;padding-left:1ex">
<div dir=3D"ltr"><br><div>While the half-open range argument is true in iso=
lation, it's missing the point that the value of data() is well-known b=
ased on how the string_view was created and what operations have been perfo=
rmed on it.</div>
</div></blockquote><div><br></div><div>How does the callee know how the str=
ing_view was created?=A0 If the callee has more preconditions than those en=
forced by string_view, you might be better off using a separate type.=A0 If=
the callee "knows" how it was created, why use a string_view at =
all?<br>
</div><div>=A0</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> A=
djusting the string_view to the point where size() is zero does not invalid=
ate data().<br>
<br>Based on how sv2 is constructed in that example, I believe it's gua=
ranteed that deref(sv2) will return the '\0' that terminates the st=
ring literal used to initialize sv2, and that doing so does not invoke unde=
fined behavior.=A0</div>
</div></blockquote><div><br></div><div>What compilers are allowed to assume=
from the specification of the standard library is an interesting question.=
... :-)<br><br></div><div>Take for example:<br><br></div><div>std::vector<=
;std::string> v(1);<br>
</div><div>auto p1 =3D v.data();<br></div><div>v.pop_back();<br><br></div><=
div>Can I legally do a placement new of a std::string into the space pointe=
d to by p1?=A0 Beats me.</div></div>-- <br>=A0Nevin ":-)" Liber=
=A0 <mailto:<a href=3D"mailto:nevin@eviloverlord.com" target=3D"_blank">=
nevin@eviloverlord.com</a>>=A0 (847) 691-1404
</div></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--047d7bb04c442e701004f02ffa41--
.
Author: Jeffrey Yasskin <jyasskin@google.com>
Date: Fri, 17 Jan 2014 12:11:33 -0800
Raw View
On Fri, Jan 17, 2014 at 8:26 AM, Marshall Clow <mclow.lists@gmail.com> wrot=
e:
> On Jan 15, 2014, at 4:28 AM, Olaf van der Spek <olafvdspek@gmail.com> wro=
te:
>
> On Saturday, December 28, 2013 6:01:34 AM UTC+1, Marshall wrote:
>>
>> if sv.size () =3D=3D 0 or sv.empty () [same thing], there is nothing tha=
t you
>> can do with sv.data()
>> (except compare it to null, and that doesn=92t tell you anything useful)=
..
>
>
> Are you sure?
> IMO an empty string_view could still point into a string and I should be
> able to use that pointer to for example construct a new string_view.
>
>
> A string view references a half-open contiguous range of characters; [
> data(), data()+size())
>
> if size() =3D=3D 0, then the range of characters referenced by the string=
view
> is empty, and accessing them (either via dereferencing begin() or data())=
is
> (or should be) undefined behavior. (the same as any other container)
>
> If in your program, you =93know=94 that the pointer returned by data() po=
ints to
> something valid, well, that=92s on you to determine.
>
> Code example:
>
> char deref ( string_view sv ) { return *sv.data(); }
>
> string_view sv1;
> string_view sv2 { =93ABCDE=94 };
> sv2.remove_prefix(5);
> assert ( sv1 =3D=3D sv2 );
> deref ( sv1 ); // may or may not blow up in your face
> deref ( sv2 ); // this will probably =93work=94 ; but I don=92t know what=
it will
> return.
The string_view spec guarantees the value data() returns after
substr() and remove_prefix() operations, so the 'sv2' case is actually
guaranteed to return the '\0' at the end of "ABCDE". However,
*sv2.begin() has undefined behavior, because it goes through the
iterator type. The use I intended for this was the ability to write
things like:
const char str[] =3D "ABCDE";
string_view sv{str};
consume_letters(sv);
if (sv.data() =3D=3D std::end(str))
finished();
but I don't see a way to enable that without letting people also
dereference data() when the string_view is empty but they know
something about the value. (This assumes that knowing ptr1=3D=3Dptr2 means
that *ptr1 and *ptr2 are equally valid, which isn't the case for
things like realloc(), but I don't want to put any such corner cases
in the string_view spec if I can help it.)
I do see that this is a somewhat awkward middle ground, so I'm
definitely going to ask for a straw-poll in Issaquah about whether the
LWG wants data()=3D=3Dnullptr to be allowed. If it is, I intend to also
remove the precondition on the string_view(data, size) to let people
explicitly put nullptr in. I'm not sure if string_view() should be
guaranteed to produce data()=3D=3Dnullptr if that change happens.
It'll also be possible to change this after the first version of the
TS ships with string_view inside, if field experience indicates that
it's the wrong choice.
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: Nevin Liber <nevin@eviloverlord.com>
Date: Fri, 17 Jan 2014 14:18:44 -0600
Raw View
--f46d043c06be1bad3b04f0304289
Content-Type: text/plain; charset=ISO-8859-1
On 17 January 2014 14:11, Jeffrey Yasskin <jyasskin@google.com> wrote:
> If it is, I intend to also
> remove the precondition on the string_view(data, size) to let people
> explicitly put nullptr in.
I'd like to, mainly because it makes it easy to create a string_view from a
vector<char> by using v.data() and v.size(). Having to special case a
check for nullptr (such as in string::string(const char*, size_t)) for what
is otherwise a perfectly valid 0-sized range is just annoying.
--
Nevin ":-)" Liber <mailto:nevin@eviloverlord.com> (847) 691-1404
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--f46d043c06be1bad3b04f0304289
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On 17 January 2014 14:11, Jeffrey Yasskin <span dir=3D"ltr=
"><<a href=3D"mailto:jyasskin@google.com" target=3D"_blank">jyasskin@goo=
gle.com</a>></span> wrote:<br><div class=3D"gmail_extra"><div class=3D"g=
mail_quote">
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div class=3D"HOEnZb"><div class=3D"h5"><spa=
n style=3D"color:rgb(34,34,34)">If it is, I intend to also</span><br></div>=
</div>
remove the precondition on the string_view(data, size) to let people<br>
explicitly put nullptr in. </blockquote><div><br></div><div>I'd like to=
, mainly because it makes it easy to create a string_view from a vector<=
char> by using v.data() and v.size(). =A0Having to special case a check =
for nullptr (such as in string::string(const char*, size_t)) for what is ot=
herwise a perfectly valid 0-sized range is just annoying.</div>
</div>-- <br>=A0Nevin ":-)" Liber=A0 <mailto:<a href=3D"mailto=
:nevin@eviloverlord.com" target=3D"_blank">nevin@eviloverlord.com</a>>=
=A0 (847) 691-1404
</div></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--f46d043c06be1bad3b04f0304289--
.
Author: Jeffrey Yasskin <jyasskin@google.com>
Date: Fri, 17 Jan 2014 12:22:21 -0800
Raw View
On Fri, Jan 17, 2014 at 12:18 PM, Nevin Liber <nevin@eviloverlord.com> wrote:
> On 17 January 2014 14:11, Jeffrey Yasskin <jyasskin@google.com> wrote:
>>
>> If it is, I intend to also
>> remove the precondition on the string_view(data, size) to let people
>> explicitly put nullptr in.
>
>
> I'd like to, mainly because it makes it easy to create a string_view from a
> vector<char> by using v.data() and v.size(). Having to special case a check
> for nullptr (such as in string::string(const char*, size_t)) for what is
> otherwise a perfectly valid 0-sized range is just annoying.
Ah, vector.data() doesn't guarantee non-null results. :( That's a good argument.
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Peter Bigot <bigotp@acm.org>
Date: Fri, 17 Jan 2014 15:24:19 -0600
Raw View
--047d7b471e6a43b95b04f0312a0a
Content-Type: text/plain; charset=ISO-8859-1
On Fri, Jan 17, 2014 at 1:58 PM, Nevin Liber <nevin@eviloverlord.com> wrote:
> On 17 January 2014 12:34, Peter Bigot <bigotp@acm.org> wrote:
>
>>
>> While the half-open range argument is true in isolation, it's missing the
>> point that the value of data() is well-known based on how the string_view
>> was created and what operations have been performed on it.
>>
>
> How does the callee know how the string_view was created? If the callee
> has more preconditions than those enforced by string_view, you might be
> better off using a separate type. If the callee "knows" how it was
> created, why use a string_view at all?
>
I don't understand this argument. Where does a callee enter the picture?
Both Marshall's example and mine are self-contained: we can see how the
instances were created, we have N3762 which specifies what data() means
throughout the operations that were invoked, and from that we know that
data() points within a range that is still valid in the "caller" context
where it's used.
> Based on how sv2 is constructed in that example, I believe it's guaranteed
>> that deref(sv2) will return the '\0' that terminates the string literal
>> used to initialize sv2, and that doing so does not invoke undefined
>> behavior.
>>
>
> What compilers are allowed to assume from the specification of the
> standard library is an interesting question... :-)
>
> Take for example:
>
> std::vector<std::string> v(1);
> auto p1 = v.data();
> v.pop_back();
>
> Can I legally do a placement new of a std::string into the space pointed
> to by p1? Beats me.
>
I'd guess that'd depend in part on whether pop_back() might invalidate
data(), which I'm not motivated to research. For string_view I think it's
a lot simpler:
When a string_view is first created, it references a valid range [data(),
data()+size()) that itself is within an external object that the
string_view references. I'm unaware of any legal string_view operation
(except clear()) that can move data() outside that initially valid range:
every mutating operation leaves the string_view instance's range unchanged
or reduces it within existing bounds. The validity of the original range
derives from an object other than the string view, so as long as that range
is not invalidated (which in turn I think would necessarily involve a data
race), it should be possible to continue use the pointers that lie within
it, right?
Peter
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--047d7b471e6a43b95b04f0312a0a
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On F=
ri, Jan 17, 2014 at 1:58 PM, Nevin Liber <span dir=3D"ltr"><<a href=3D"m=
ailto:nevin@eviloverlord.com" target=3D"_blank">nevin@eviloverlord.com</a>&=
gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"im">On 17 Jan=
uary 2014 12:34, Peter Bigot <span dir=3D"ltr"><<a href=3D"mailto:bigotp=
@acm.org" target=3D"_blank">bigotp@acm.org</a>></span> wrote:<br>
</div><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div class=3D"i=
m"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left=
:1px #ccc solid;padding-left:1ex">
<div dir=3D"ltr"><br><div>While the half-open range argument is true in iso=
lation, it's missing the point that the value of data() is well-known b=
ased on how the string_view was created and what operations have been perfo=
rmed on it.</div>
</div></blockquote><div><br></div></div><div>How does the callee know how t=
he string_view was created?=A0 If the callee has more preconditions than th=
ose enforced by string_view, you might be better off using a separate type.=
=A0 If the callee "knows" how it was created, why use a string_vi=
ew at all?<br>
</div></div></div></div></blockquote><div><br></div><div>I don't unders=
tand this argument.=A0 Where does a callee enter the picture?=A0 Both Marsh=
all's example and mine are self-contained: we can see how the instances=
were created, we have N3762 which specifies what data() means throughout t=
he operations that were invoked, and from that we know that data() points w=
ithin a range that is still valid in the "caller" context where i=
t's used.<br>
</div><div>=A0 <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"><d=
iv class=3D"gmail_extra"><div class=3D"gmail_quote"><div class=3D"im"><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #cc=
c solid;padding-left:1ex">
<div dir=3D"ltr"><div> Based on how sv2 is constructed in that example, I b=
elieve it's guaranteed that deref(sv2) will return the '\0' tha=
t terminates the string literal used to initialize sv2, and that doing so d=
oes not invoke undefined behavior.=A0</div>
</div></blockquote><div><br></div></div><div>What compilers are allowed to =
assume from the specification of the standard library is an interesting que=
stion... :-)<br><br></div><div>Take for example:<br><br></div><div>std::vec=
tor<std::string> v(1);<br>
</div><div>auto p1 =3D v.data();<br></div><div>v.pop_back();<br><br></div><=
div>Can I legally do a placement new of a std::string into the space pointe=
d to by p1?=A0 Beats me.</div></div></div></div></blockquote><div><br></div=
>
<div>I'd guess that'd depend in part on whether pop_back() might in=
validate data(), which I'm not motivated to research.=A0 For string_vie=
w I think it's a lot simpler:<br><br>When a string_view is first create=
d, it references a valid range [data(), data()+size()) that itself is withi=
n an external object that the string_view references.=A0 I'm unaware of=
any legal string_view operation (except clear()) that can move data() outs=
ide that initially valid range: every mutating operation leaves the string_=
view instance's range unchanged or reduces it within existing bounds.=
=A0 The validity of the original range derives from an object other than th=
e string view, so as long as that range is not invalidated (which in turn I=
think would necessarily involve a data race), it should be possible to con=
tinue use the pointers that lie within it, right?<br>
<br></div></div>Peter<br></div></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--047d7b471e6a43b95b04f0312a0a--
.
Author: Peter Bigot <bigotp@acm.org>
Date: Fri, 17 Jan 2014 15:25:00 -0600
Raw View
--047d7b33c914b321fa04f0312c58
Content-Type: text/plain; charset=ISO-8859-1
On Fri, Jan 17, 2014 at 2:22 PM, Jeffrey Yasskin <jyasskin@google.com>wrote:
> On Fri, Jan 17, 2014 at 12:18 PM, Nevin Liber <nevin@eviloverlord.com>
> wrote:
> > On 17 January 2014 14:11, Jeffrey Yasskin <jyasskin@google.com> wrote:
> >>
> >> If it is, I intend to also
> >> remove the precondition on the string_view(data, size) to let people
> >> explicitly put nullptr in.
> >
> >
> > I'd like to, mainly because it makes it easy to create a string_view
> from a
> > vector<char> by using v.data() and v.size(). Having to special case a
> check
> > for nullptr (such as in string::string(const char*, size_t)) for what is
> > otherwise a perfectly valid 0-sized range is just annoying.
>
> Ah, vector.data() doesn't guarantee non-null results. :( That's a good
> argument.
>
First, is that true? [data(), data()+size()) must be a valid range, but
I've been unable to find a definition of "valid range" in the standard so I
could understand whether an empty valid range permits its base to be a null
pointer.
Second, even if so std::string.data() does guarantee a non-null result,
doesn't it? In that case it's also required that data()+i ==
&operator[](i) for i in [0, size()] which led me to believe data() could
not be null, since the equality must hold for i==0 and operator[] must
return a reference to an object (hence the underlying pointer cannot be
null).
I've been swayed by the argument that there's no such thing as a null
std::string, so there should be no such thing as a null std::string_view.
This is easily assured by disallowing std::string_view(s, n) for a null s
just as std::string(s, n) is disallowed for null s.
I don't see it as unreasonable to require a check for that situation before
creating a std::string_view in situations where a char* pointer comes from
a source that might produce a null pointer. As Nevin points out, you have
to do it for std::string too.
Personally, I'd find it more annoying to have to constantly check in every
utility function that operates on string_view instances whether an input
sv.data() is null in addition to whether sv.size() is zero. I understood
std::string_view to serve the role of a reference type compatible with both
character arrays and std::strings, so just as with other reference types it
shouldn't be possible for the underlying pointer to be null.
My opinion, at any rate.
Peter
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--047d7b33c914b321fa04f0312c58
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On F=
ri, Jan 17, 2014 at 2:22 PM, Jeffrey Yasskin <span dir=3D"ltr"><<a href=
=3D"mailto:jyasskin@google.com" target=3D"_blank">jyasskin@google.com</a>&g=
t;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div class=3D"im">On Fri, Jan 17, 2014 at 12=
:18 PM, Nevin Liber <<a href=3D"mailto:nevin@eviloverlord.com">nevin@evi=
loverlord.com</a>> wrote:<br>
> On 17 January 2014 14:11, Jeffrey Yasskin <<a href=3D"mailto:jyassk=
in@google.com">jyasskin@google.com</a>> wrote:<br>
>><br>
>> If it is, I intend to also<br>
>> remove the precondition on the string_view(data, size) to let peop=
le<br>
>> explicitly put nullptr in.<br>
><br>
><br>
> I'd like to, mainly because it makes it easy to create a string_vi=
ew from a<br>
> vector<char> by using v.data() and v.size(). =A0Having to specia=
l case a check<br>
> for nullptr (such as in string::string(const char*, size_t)) for what =
is<br>
> otherwise a perfectly valid 0-sized range is just annoying.<br></div><=
/blockquote><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bo=
rder-left:1px #ccc solid;padding-left:1ex"><div class=3D"im">
<br>
</div>Ah, vector.data() doesn't guarantee non-null results. :( That'=
;s a good argument.<br></blockquote><div><br></div><div>First, is that true=
?=A0 [data(), data()+size()) must be a valid range, but I've been unabl=
e to find a definition of "valid range" in the standard so I coul=
d understand whether an empty valid range permits its base to be a null poi=
nter.<br>
</div></div><br></div><div class=3D"gmail_extra">Second, even if so std::st=
ring.data() does guarantee a non-null result, doesn't it?=A0 In that ca=
se it's also required that data()+i =3D=3D &operator[](i) for i in =
[0, size()] which led me to believe data() could not be null, since the equ=
ality must hold for i=3D=3D0 and operator[] must return a reference to an o=
bject (hence the underlying pointer cannot be null).<br>
<br>I've been swayed by the argument that there's no such thing as =
a null std::string, so there should be no such thing as a null std::string_=
view.=A0 This is easily assured by disallowing std::string_view(s, n) for a=
null s just as std::string(s, n) is disallowed for null s.<br>
<br>I don't see it as unreasonable to require a check for that situatio=
n before creating a std::string_view in situations where a char* pointer co=
mes from a source that might produce a null pointer.=A0 As Nevin points out=
, you have to do it for std::string too.<br>
<br>Personally, I'd find it more annoying to have to constantly check i=
n every utility function that operates on string_view instances whether an =
input sv.data() is null in addition to whether sv.size() is zero.=A0 I unde=
rstood std::string_view to serve the role of a reference type compatible wi=
th both character arrays and std::strings, so just as with other reference =
types it shouldn't be possible for the underlying pointer to be null.<b=
r>
<br></div><div class=3D"gmail_extra">My opinion, at any rate.<br></div><div=
class=3D"gmail_extra"><br></div><div class=3D"gmail_extra">Peter<br></div>=
</div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--047d7b33c914b321fa04f0312c58--
.
Author: Marshall Clow <mclow.lists@gmail.com>
Date: Fri, 17 Jan 2014 13:48:25 -0800
Raw View
--Apple-Mail=_392DBC53-EBD0-4E78-A8AA-0F4E5B1CDE0B
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=windows-1252
On Jan 17, 2014, at 10:34 AM, Peter Bigot <bigotp@acm.org> wrote:
>=20
>=20
> On Friday, January 17, 2014 10:26:50 AM UTC-6, Marshall wrote:
> On Jan 15, 2014, at 4:28 AM, Olaf van der Spek <olafv...@gmail.com> wrote=
:
>=20
>> On Saturday, December 28, 2013 6:01:34 AM UTC+1, Marshall wrote:
>> if sv.size () =3D=3D 0 or sv.empty () [same thing], there is nothing tha=
t you can do with sv.data()
>> (except compare it to null, and that doesn=92t tell you anything useful)=
..
>>=20
>> Are you sure?
>> IMO an empty string_view could still point into a string and I should be=
able to use that pointer to for example construct a new string_view.
>=20
>=20
> A string view references a half-open contiguous range of characters; [ da=
ta(), data()+size())
>=20
> if size() =3D=3D 0, then the range of characters referenced by the string=
view is empty, and accessing them (either via dereferencing begin() or dat=
a()) is (or should be) undefined behavior. (the same as any other container=
)
>=20
> If in your program, you =93know=94 that the pointer returned by data() po=
ints to something valid, well, that=92s on you to determine.
>=20
> Code example:
>=20
> char deref ( string_view sv ) { return *sv.data(); }
>=20
> string_view sv1;
> string_view sv2 { =93ABCDE=94 };
> sv2.remove_prefix(5);
> assert ( sv1 =3D=3D sv2 );
> deref ( sv1 ); // may or may not blow up in your face
> deref ( sv2 ); // this will probably =93work=94 ; but I don=92t know wha=
t it will return.
>=20
> =97 Marshall
>=20
>=20
> While the half-open range argument is true in isolation, it's missing the=
point that the value of data() is well-known based on how the string_view =
was created and what operations have been performed on it. Adjusting the st=
ring_view to the point where size() is zero does not invalidate data().
Peter =97
I think you=92re trying to add additional meaning to string_view.=20
It=92s a reference to a sequence of characters.
When the size =3D=3D 0, then it=92s a reference to NO characters.=20
Saying =93all, yes, but we *know* what it points to, and so, really, it ref=
ers to a character=94 is widening the definition of string_view.
Unnecessarily so, in my belief.
=97 Marshall
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--Apple-Mail=_392DBC53-EBD0-4E78-A8AA-0F4E5B1CDE0B
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=windows-1252
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>On Jan 1=
7, 2014, at 10:34 AM, Peter Bigot <<a href=3D"mailto:bigotp@acm.org">big=
otp@acm.org</a>> wrote:</div><br class=3D"Apple-interchange-newline"><bl=
ockquote type=3D"cite"><div style=3D"font-family: LucidaGrande; font-size: =
11px; font-style: normal; font-variant: normal; font-weight: normal; letter=
-spacing: normal; line-height: normal; orphans: auto; text-align: start; te=
xt-indent: 0px; text-transform: none; white-space: normal; widows: auto; wo=
rd-spacing: 0px; -webkit-text-stroke-width: 0px;"><div dir=3D"ltr"><br><br>=
On Friday, January 17, 2014 10:26:50 AM UTC-6, Marshall wrote:<blockquote c=
lass=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; border-left-width:=
1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padd=
ing-left: 1ex;"><div style=3D"word-wrap: break-word;">On Jan 15, 2014, at 4=
:28 AM, Olaf van der Spek <<a target=3D"_blank" gdf-obfuscated-mailto=3D=
"MEVbJLx2UbAJ">olafv...@gmail.com</a>> wrote:<br><div><br><blockquote ty=
pe=3D"cite"><div dir=3D"ltr">On Saturday, December 28, 2013 6:01:34 AM UTC+=
1, Marshall wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0px 0p=
x 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204);=
border-left-style: solid; padding-left: 1ex;"><div style=3D"word-wrap: bre=
ak-word;"><div>if sv.size () =3D=3D 0 or sv.empty () [same thing], there is=
nothing that you can do with sv.data()</div><div>(except compare it to nul=
l, and that doesn=92t tell you anything useful).</div></div></blockquote><d=
iv><br></div><div>Are you sure?</div><div>IMO an empty string_view could st=
ill point into a string and I should be able to use that pointer to for exa=
mple construct a new string_view.</div></div></blockquote></div><div><br></=
div><div>A string view references a half-open contiguous range of character=
s; [ data(), data()+size())</div><div><br></div><div>if size() =3D=3D 0, th=
en the range of characters referenced by the string view is empty, and acce=
ssing them (either via dereferencing begin() or data()) is (or should be) u=
ndefined behavior. (the same as any other container)</div><div><br></div><d=
iv>If in your program, you =93know=94 that the pointer returned by data() p=
oints to something valid, well, that=92s on you to determine.</div><div><br=
></div><div>Code example:</div><div><br></div><div><span style=3D"white-spa=
ce: pre;"> </span>char deref ( string_view sv ) { return *sv.data(); }</div=
><div><br></div><div><span style=3D"white-space: pre;"> </span>string_view =
sv1;</div><div><span style=3D"white-space: pre;"> </span>string_view sv2 { =
=93ABCDE=94 };</div><div><span style=3D"white-space: pre;"> </span>sv2.remo=
ve_prefix(5);</div><div><span style=3D"white-space: pre;"> </span>assert ( =
sv1 =3D=3D sv2 );</div><div><span style=3D"white-space: pre;"> </span>deref=
( sv1 );<span style=3D"white-space: pre;"> </span>// may or may not blow u=
p in your face</div><div><span style=3D"white-space: pre;"> </span>deref ( =
sv2 );<span style=3D"white-space: pre;"> </span>// this will probably =93wo=
rk=94 ; but I don=92t know what it will return.</div><div><br></div><div>=
=97 Marshall</div><div><br></div></div></blockquote><div><br>While the half=
-open range argument is true in isolation, it's missing the point that the =
value of data() is well-known based on how the string_view was created and =
what operations have been performed on it. Adjusting the string_view to the=
point where size() is zero does not invalidate data().</div></div></div></=
blockquote><br></div><div>Peter =97</div><div><br></div><div>I think you=92=
re trying to add additional meaning to string_view. </div><div>It=92s =
a reference to a sequence of characters.</div><div>When the size =3D=3D 0, =
then it=92s a reference to NO characters. </div><div><br></div><div>Sa=
ying =93all, yes, but we *know* what it points to, and so, really, it refer=
s to a character=94 is widening the definition of string_view.</div><div>Un=
necessarily so, in my belief.</div><div><br></div><div>=97 Marshall</div><d=
iv><br></div></body></html>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--Apple-Mail=_392DBC53-EBD0-4E78-A8AA-0F4E5B1CDE0B--
.
Author: Marshall Clow <mclow.lists@gmail.com>
Date: Fri, 17 Jan 2014 13:55:41 -0800
Raw View
--Apple-Mail=_6DD81798-CFCD-4E3C-8C18-83A4B141E511
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=windows-1252
On Jan 17, 2014, at 1:25 PM, Peter Bigot <bigotp@acm.org> wrote:
> On Fri, Jan 17, 2014 at 2:22 PM, Jeffrey Yasskin <jyasskin@google.com> wr=
ote:
> On Fri, Jan 17, 2014 at 12:18 PM, Nevin Liber <nevin@eviloverlord.com> wr=
ote:
> > On 17 January 2014 14:11, Jeffrey Yasskin <jyasskin@google.com> wrote:
> >>
> >> If it is, I intend to also
> >> remove the precondition on the string_view(data, size) to let people
> >> explicitly put nullptr in.
> >
> >
> > I'd like to, mainly because it makes it easy to create a string_view fr=
om a
> > vector<char> by using v.data() and v.size(). Having to special case a =
check
> > for nullptr (such as in string::string(const char*, size_t)) for what i=
s
> > otherwise a perfectly valid 0-sized range is just annoying.
>=20
> Ah, vector.data() doesn't guarantee non-null results. :( That's a good ar=
gument.
>=20
> First, is that true? [data(), data()+size()) must be a valid range, but =
I've been unable to find a definition of "valid range" in the standard so I=
could understand whether an empty valid range permits its base to be a nul=
l pointer.
>=20
> Second, even if so std::string.data() does guarantee a non-null result, d=
oesn't it? In that case it's also required that data()+i =3D=3D &operator[=
](i) for i in [0, size()] which led me to believe data() could not be null,=
since the equality must hold for i=3D=3D0 and operator[] must return a ref=
erence to an object (hence the underlying pointer cannot be null).
I think you mean, [0,i), not [0,i]
> I've been swayed by the argument that there's no such thing as a null std=
::string, so there should be no such thing as a null std::string_view. Thi=
s is easily assured by disallowing std::string_view(s, n) for a null s just=
as std::string(s, n) is disallowed for null s.
The difference here is that string manages its own storage, while string_vi=
ew does not.
> I don't see it as unreasonable to require a check for that situation befo=
re creating a std::string_view in situations where a char* pointer comes fr=
om a source that might produce a null pointer. As Nevin points out, you ha=
ve to do it for std::string too.
Maybe I missed something earlier in the discussion, but I believe that
std::string foo { nullptr, 0 };
is a perfectly legal way of creating an empty string.
Section 21.4.2 says only:
basic_string(const charT* s, size_type n,
const Allocator& a =3D Allocator());
Requires: s points to an array of at least n elements of charT.
> Personally, I'd find it more annoying to have to constantly check in ever=
y utility function that operates on string_view instances whether an input =
sv.data() is null in addition to whether sv.size() is zero.=20
I=92m afraid I don=92t see why you would do this. Can you give an example, =
please?
=97 Marshall
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--Apple-Mail=_6DD81798-CFCD-4E3C-8C18-83A4B141E511
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=windows-1252
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>On Jan 1=
7, 2014, at 1:25 PM, Peter Bigot <<a href=3D"mailto:bigotp@acm.org">bigo=
tp@acm.org</a>> wrote:</div><br class=3D"Apple-interchange-newline"><blo=
ckquote type=3D"cite"><div dir=3D"ltr"><div class=3D"gmail_extra"><div clas=
s=3D"gmail_quote">On Fri, Jan 17, 2014 at 2:22 PM, Jeffrey Yasskin <span di=
r=3D"ltr"><<a href=3D"mailto:jyasskin@google.com" target=3D"_blank">jyas=
skin@google.com</a>></span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div class=3D"im">On Fri, Jan 17, 2014 at 12=
:18 PM, Nevin Liber <<a href=3D"mailto:nevin@eviloverlord.com">nevin@evi=
loverlord.com</a>> wrote:<br>
> On 17 January 2014 14:11, Jeffrey Yasskin <<a href=3D"mailto:jyassk=
in@google.com">jyasskin@google.com</a>> wrote:<br>
>><br>
>> If it is, I intend to also<br>
>> remove the precondition on the string_view(data, size) to let peop=
le<br>
>> explicitly put nullptr in.<br>
><br>
><br>
> I'd like to, mainly because it makes it easy to create a string_view f=
rom a<br>
> vector<char> by using v.data() and v.size(). Having to spe=
cial case a check<br>
> for nullptr (such as in string::string(const char*, size_t)) for what =
is<br>
> otherwise a perfectly valid 0-sized range is just annoying.<br></div><=
/blockquote><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bo=
rder-left:1px #ccc solid;padding-left:1ex"><div class=3D"im">
<br>
</div>Ah, vector.data() doesn't guarantee non-null results. :( That's a goo=
d argument.<br></blockquote><div><br></div><div>First, is that true? =
[data(), data()+size()) must be a valid range, but I've been unable to find=
a definition of "valid range" in the standard so I could understand whethe=
r an empty valid range permits its base to be a null pointer.<br>
</div></div><br></div><div class=3D"gmail_extra">Second, even if so std::st=
ring.data() does guarantee a non-null result, doesn't it? In that cas=
e it's also required that data()+i =3D=3D &operator[](i) for i in [0, s=
ize()] which led me to believe data() could not be null, since the equality=
must hold for i=3D=3D0 and operator[] must return a reference to an object=
(hence the underlying pointer cannot be null).<br></div></div></blockquote=
><div><br></div>I think you mean, [0,i), not [0,i]</div><div><br></div><div=
><blockquote type=3D"cite"><div dir=3D"ltr"><div class=3D"gmail_extra">I've=
been swayed by the argument that there's no such thing as a null std::stri=
ng, so there should be no such thing as a null std::string_view. This=
is easily assured by disallowing std::string_view(s, n) for a null s just =
as std::string(s, n) is disallowed for null s.<br></div></div></blockquote>=
<div><br></div>The difference here is that string manages its own storage, =
while string_view does not.</div><div><br><blockquote type=3D"cite"><div di=
r=3D"ltr"><div class=3D"gmail_extra">I don't see it as unreasonable to requ=
ire a check for that situation before creating a std::string_view in situat=
ions where a char* pointer comes from a source that might produce a null po=
inter. As Nevin points out, you have to do it for std::string too.<br=
></div></div></blockquote><div><br></div>Maybe I missed something earlier i=
n the discussion, but I believe that</div><div><span class=3D"Apple-tab-spa=
n" style=3D"white-space:pre"> </span>std::string foo { nullptr, 0 };</div><=
div><br></div><div>is a perfectly legal way of creating an empty string.</d=
iv><div><br></div><div>Section 21.4.2 says only:</div><div><span class=3D"A=
pple-tab-span" style=3D"white-space:pre"> </span>basic_string(const charT* =
s, size_type n,<br><div> <span class=3D"Apple-ta=
b-span" style=3D"white-space:pre"> </span> const Allocat=
or& a =3D Allocator());</div><div><span class=3D"Apple-tab-span" style=
=3D"white-space:pre"> </span>Requires: s points to an array of at=
least n elements of charT.</div><div><br></div></div><div><=
br><blockquote type=3D"cite"><div dir=3D"ltr"><div class=3D"gmail_extra">Pe=
rsonally, I'd find it more annoying to have to constantly check in every ut=
ility function that operates on string_view instances whether an input sv.d=
ata() is null in addition to whether sv.size() is zero. </div></div><=
/blockquote><div><br></div>I=92m afraid I don=92t see why you would do this=
.. Can you give an example, please?</div><div><br></div><div>=97 Marshall</d=
iv><div><br></div></body></html>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--Apple-Mail=_6DD81798-CFCD-4E3C-8C18-83A4B141E511--
.
Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@gmail.com>
Date: Fri, 17 Jan 2014 23:04:51 +0100
Raw View
2014/1/17 Marshall Clow <mclow.lists@gmail.com>:
>
> Maybe I missed something earlier in the discussion, but I believe that
> std::string foo { nullptr, 0 };
>
> is a perfectly legal way of creating an empty string.
No, it is not, it undefined behaviour.
> Section 21.4.2 says only:
> basic_string(const charT* s, size_type n,
> const Allocator& a = Allocator());
> Requires: s points to an array of at least n elements of charT.
Exactly this requirement makes above code undefined. There exists an
explicit rule in [res.on.arguments] p1 b2 for this kind of wording:
"If a function argument is described as being an array, the pointer
actually passed to the function shall
have a value such that all address computations and accesses to
objects (that would be valid if the
pointer did point to the first element of such an array) are in fact valid."
- Daniel
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Jeffrey Yasskin <jyasskin@google.com>
Date: Fri, 17 Jan 2014 14:10:41 -0800
Raw View
--001a11c16f5e4d0d9704f031d106
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
On Fri, Jan 17, 2014 at 2:04 PM, Daniel Kr=FCgler
<daniel.kruegler@gmail.com>wrote:
> 2014/1/17 Marshall Clow <mclow.lists@gmail.com>:
> >
> > Maybe I missed something earlier in the discussion, but I believe that
> > std::string foo { nullptr, 0 };
> >
> > is a perfectly legal way of creating an empty string.
>
> No, it is not, it undefined behaviour.
>
> > Section 21.4.2 says only:
> > basic_string(const charT* s, size_type n,
> > const Allocator& a =3D Allocator());
> > Requires: s points to an array of at least n elements of charT.
>
> Exactly this requirement makes above code undefined. There exists an
> explicit rule in [res.on.arguments] p1 b2 for this kind of wording:
>
> "If a function argument is described as being an array, the pointer
> actually passed to the function shall
> have a value such that all address computations and accesses to
> objects (that would be valid if the
> pointer did point to the first element of such an array) are in fact
> valid."
>
>
Agreed. To mitigate this, if string_view::data() could return nullptr, I
believe we could still create strings using std::string(null_sv.begin(),
null_sv.end()).
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--001a11c16f5e4d0d9704f031d106
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On F=
ri, Jan 17, 2014 at 2:04 PM, Daniel Kr=FCgler <span dir=3D"ltr"><<a href=
=3D"mailto:daniel.kruegler@gmail.com" target=3D"_blank" class=3D"cremed">da=
niel.kruegler@gmail.com</a>></span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">2014/1/17 Marshall Clow <<a href=3D"mailt=
o:mclow.lists@gmail.com" class=3D"cremed">mclow.lists@gmail.com</a>>:<br=
>
<div class=3D"im">><br>
> Maybe I missed something earlier in the discussion, but I believe that=
<br>
> std::string foo { nullptr, 0 };<br>
><br>
> is a perfectly legal way of creating an empty string.<br>
<br>
</div>No, it is not, it undefined behaviour.<br>
<div class=3D"im"><br>
> Section 21.4.2 says only:<br>
> basic_string(const charT* s, size_type n,<br>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0const Allocator& a =3D Allocator());<br=
>
> Requires: s points to an array of at least n elements of charT.<br>
<br>
</div>Exactly this requirement makes above code undefined. There exists an<=
br>
explicit rule in [res.on.arguments] p1 b2 for this kind of wording:<br>
<br>
"If a function argument is described as being an array, the pointer<br=
>
actually passed to the function shall<br>
have a value such that all address computations and accesses to<br>
objects (that would be valid if the<br>
pointer did point to the first element of such an array) are in fact valid.=
"<br>
<span class=3D"HOEnZb"><font color=3D"#888888"><br></font></span></blockquo=
te><div><br></div></div></div><div class=3D"gmail_extra">Agreed. To mitigat=
e this, if string_view::data() could return nullptr, I believe we could sti=
ll create strings using std::string(null_sv.begin(), null_sv.end()).</div>
</div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--001a11c16f5e4d0d9704f031d106--
.
Author: "Billy O'Neal" <billy.oneal@gmail.com>
Date: Fri, 17 Jan 2014 14:17:53 -0800
Raw View
--001a11c309463040c104f031ec77
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
>"If a function argument is described as being an array, the
pointer actually passed to the function shall have a value such that all
address computations and accesses to objects (that would be valid if the
pointer did point to the first element of such an array) are in fact valid.=
"
So to clarify, if it were an array of size 0, you would be allowed to
increment the pointer by 1. (You would not be allowed to dereference the
pointer) You are never allowed to increment a null pointer, so data()
returning nullptr does not meet this requirement.
Billy O'Neal
https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
http://stackoverflow.com/users/82320/billy-oneal
On Fri, Jan 17, 2014 at 2:04 PM, Daniel Kr=C3=BCgler
<daniel.kruegler@gmail.com>wrote:
> 2014/1/17 Marshall Clow <mclow.lists@gmail.com>:
> >
> > Maybe I missed something earlier in the discussion, but I believe that
> > std::string foo { nullptr, 0 };
> >
> > is a perfectly legal way of creating an empty string.
>
> No, it is not, it undefined behaviour.
>
> > Section 21.4.2 says only:
> > basic_string(const charT* s, size_type n,
> > const Allocator& a =3D Allocator());
> > Requires: s points to an array of at least n elements of charT.
>
> Exactly this requirement makes above code undefined. There exists an
> explicit rule in [res.on.arguments] p1 b2 for this kind of wording:
>
> "If a function argument is described as being an array, the pointer
> actually passed to the function shall
> have a value such that all address computations and accesses to
> objects (that would be valid if the
> pointer did point to the first element of such an array) are in fact
> valid."
>
> - Daniel
>
> --
>
> ---
> 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.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--001a11c309463040c104f031ec77
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>>"If a function argument is described as bein=
g an array, the pointer=C2=A0actually passed to the function shall have a v=
alue such that all address computations and accesses to=C2=A0objects (that =
would be valid if the pointer did point to the first element of such an arr=
ay) are in fact valid."</div>
<div><br></div><div>So to clarify, if it were an array of size 0, you would=
be allowed to increment the pointer by 1. (You would not be allowed to der=
eference the pointer) You are never allowed to increment a null pointer, so=
data() returning nullptr does not meet this requirement.</div>
</div><div class=3D"gmail_extra"><br clear=3D"all"><div><div dir=3D"ltr"><d=
iv>Billy O'Neal</div><div><a href=3D"https://bitbucket.org/BillyONeal/"=
target=3D"_blank">https://github.com/BillyONeal/</a></div><div><a href=3D"=
http://stackoverflow.com/users/82320/billy-oneal" target=3D"_blank">http://=
stackoverflow.com/users/82320/billy-oneal</a></div>
</div></div>
<br><br><div class=3D"gmail_quote">On Fri, Jan 17, 2014 at 2:04 PM, Daniel =
Kr=C3=BCgler <span dir=3D"ltr"><<a href=3D"mailto:daniel.kruegler@gmail.=
com" target=3D"_blank">daniel.kruegler@gmail.com</a>></span> wrote:<br><=
blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px=
#ccc solid;padding-left:1ex">
2014/1/17 Marshall Clow <<a href=3D"mailto:mclow.lists@gmail.com">mclow.=
lists@gmail.com</a>>:<br>
<div class=3D"im">><br>
> Maybe I missed something earlier in the discussion, but I believe that=
<br>
> std::string foo { nullptr, 0 };<br>
><br>
> is a perfectly legal way of creating an empty string.<br>
<br>
</div>No, it is not, it undefined behaviour.<br>
<div class=3D"im"><br>
> Section 21.4.2 says only:<br>
> basic_string(const charT* s, size_type n,<br>
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0const Allocator& a=
=3D Allocator());<br>
> Requires: s points to an array of at least n elements of charT.<br>
<br>
</div>Exactly this requirement makes above code undefined. There exists an<=
br>
explicit rule in [res.on.arguments] p1 b2 for this kind of wording:<br>
<br>
"If a function argument is described as being an array, the pointer<br=
>
actually passed to the function shall<br>
have a value such that all address computations and accesses to<br>
objects (that would be valid if the<br>
pointer did point to the first element of such an array) are in fact valid.=
"<br>
<span class=3D"HOEnZb"><font color=3D"#888888"><br>
- Daniel<br>
</font></span><div class=3D"HOEnZb"><div class=3D"h5"><br>
--<br>
<br>
---<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%2Bunsubscribe@isocpp.org">std-propo=
sals+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>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--001a11c309463040c104f031ec77--
.
Author: Peter Bigot <bigotp@acm.org>
Date: Fri, 17 Jan 2014 14:43:09 -0800 (PST)
Raw View
------=_Part_119_20714774.1389998589706
Content-Type: text/plain; charset=UTF-8
On Friday, January 17, 2014 3:55:41 PM UTC-6, Marshall wrote:
>
>
> On Jan 17, 2014, at 1:25 PM, Peter Bigot <big...@acm.org <javascript:>>
> wrote:
>
> On Fri, Jan 17, 2014 at 2:22 PM, Jeffrey Yasskin <jyas...@google.com<javascript:>
> > wrote:
>
>> On Fri, Jan 17, 2014 at 12:18 PM, Nevin Liber <ne...@eviloverlord.com<javascript:>>
>> wrote:
>> > On 17 January 2014 14:11, Jeffrey Yasskin <jyas...@google.com<javascript:>>
>> wrote:
>> >>
>> >> If it is, I intend to also
>> >> remove the precondition on the string_view(data, size) to let people
>> >> explicitly put nullptr in.
>> >
>> >
>> > I'd like to, mainly because it makes it easy to create a string_view
>> from a
>> > vector<char> by using v.data() and v.size(). Having to special case a
>> check
>> > for nullptr (such as in string::string(const char*, size_t)) for what is
>> > otherwise a perfectly valid 0-sized range is just annoying.
>>
>
>> Ah, vector.data() doesn't guarantee non-null results. :( That's a good
>> argument.
>>
>
> First, is that true? [data(), data()+size()) must be a valid range, but
> I've been unable to find a definition of "valid range" in the standard so I
> could understand whether an empty valid range permits its base to be a null
> pointer.
>
> Second, even if so std::string.data() does guarantee a non-null result,
> doesn't it? In that case it's also required that data()+i ==
> &operator[](i) for i in [0, size()] which led me to believe data() could
> not be null, since the equality must hold for i==0 and operator[] must
> return a reference to an object (hence the underlying pointer cannot be
> null).
>
>
> I think you mean, [0,i), not [0,i]
>
>
No, I mean i in [0,size()] which in this case is [0,0]. 21.4.7.1 paragraph
1.
I've been swayed by the argument that there's no such thing as a null
> std::string, so there should be no such thing as a null std::string_view.
> This is easily assured by disallowing std::string_view(s, n) for a null s
> just as std::string(s, n) is disallowed for null s.
>
>
> The difference here is that string manages its own storage, while
> string_view does not.
>
As others have confirmed, std::string still doesn't permit a null pointer
for data(), so this isn't compelling to me.
Peter
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_119_20714774.1389998589706
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Friday, January 17, 2014 3:55:41 PM UTC-6, Mars=
hall wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"word-=
wrap:break-word"><br><div><div>On Jan 17, 2014, at 1:25 PM, Peter Bigot <=
;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"vr40JXE=
0I-wJ" onmousedown=3D"this.href=3D'javascript:';return true;" onclick=3D"th=
is.href=3D'javascript:';return true;">big...@acm.org</a>> wrote:</div><b=
lockquote type=3D"cite"><div dir=3D"ltr"><div><div class=3D"gmail_quote">On=
Fri, Jan 17, 2014 at 2:22 PM, Jeffrey Yasskin <span dir=3D"ltr"><<a hre=
f=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"vr40JXE0I-wJ" =
onmousedown=3D"this.href=3D'javascript:';return true;" onclick=3D"this.href=
=3D'javascript:';return true;">jyas...@google.com</a>></span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div>On Fri, Jan 17, 2014 at 12:18 PM, Nevin=
Liber <<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=
=3D"vr40JXE0I-wJ" onmousedown=3D"this.href=3D'javascript:';return true;" on=
click=3D"this.href=3D'javascript:';return true;">ne...@eviloverlord.com</a>=
> wrote:<br>
> On 17 January 2014 14:11, Jeffrey Yasskin <<a href=3D"javascript:" =
target=3D"_blank" gdf-obfuscated-mailto=3D"vr40JXE0I-wJ" onmousedown=3D"thi=
s.href=3D'javascript:';return true;" onclick=3D"this.href=3D'javascript:';r=
eturn true;">jyas...@google.com</a>> wrote:<br>
>><br>
>> If it is, I intend to also<br>
>> remove the precondition on the string_view(data, size) to let peop=
le<br>
>> explicitly put nullptr in.<br>
><br>
><br>
> I'd like to, mainly because it makes it easy to create a string_view f=
rom a<br>
> vector<char> by using v.data() and v.size(). Having to spe=
cial case a check<br>
> for nullptr (such as in string::string(const char*, size_t)) for what =
is<br>
> otherwise a perfectly valid 0-sized range is just annoying.<br></div><=
/blockquote><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bo=
rder-left:1px #ccc solid;padding-left:1ex"><div>
<br>
</div>Ah, vector.data() doesn't guarantee non-null results. :( That's a goo=
d argument.<br></blockquote><div><br></div><div>First, is that true? =
[data(), data()+size()) must be a valid range, but I've been unable to find=
a definition of "valid range" in the standard so I could understand whethe=
r an empty valid range permits its base to be a null pointer.<br>
</div></div><br></div><div>Second, even if so std::string.data() does guara=
ntee a non-null result, doesn't it? In that case it's also required t=
hat data()+i =3D=3D &operator[](i) for i in [0, size()] which led me to=
believe data() could not be null, since the equality must hold for i=3D=3D=
0 and operator[] must return a reference to an object (hence the underlying=
pointer cannot be null).<br></div></div></blockquote><div><br></div>I thin=
k you mean, [0,i), not [0,i]</div><div><br></div></div></blockquote><div><b=
r>No, I mean i in [0,size()] which in this case is [0,0]. 21.4.7.1 pa=
ragraph 1.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div s=
tyle=3D"word-wrap:break-word"><div></div><div><blockquote type=3D"cite"><di=
v dir=3D"ltr"><div>I've been swayed by the argument that there's no such th=
ing as a null std::string, so there should be no such thing as a null std::=
string_view. This is easily assured by disallowing std::string_view(s=
, n) for a null s just as std::string(s, n) is disallowed for null s.<br></=
div></div></blockquote><div><br></div>The difference here is that string ma=
nages its own storage, while string_view does not.</div></div></blockquote>=
<div><br>As others have confirmed, std::string still doesn't permit a null =
pointer for data(), so this isn't compelling to me.<br></div><br>Peter<br><=
/div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_119_20714774.1389998589706--
.
Author: gornishanov@gmail.com
Date: Fri, 17 Jan 2014 15:10:41 -0800 (PST)
Raw View
------=_Part_112_8601933.1390000241866
Content-Type: text/plain; charset=UTF-8
What if string_view provides a specialization for optional<string_view<>>?
That way optional<string_view> can be implemented very efficiently by
checking if sv.begin() == nullptr and does not consume any extra storage.
An extra benefit is that we have clear distinction between nullable types
(optional<T>) and regular types, int, vector, string_view, etc.
Will this solution satisfy the original poster?
>
>
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_112_8601933.1390000241866
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>What if string_view provides a specialization for opt=
ional<string_view<>>?</div><div><br></div><div>That way optiona=
l<string_view> can be implemented very efficiently by checking if sv.=
begin() =3D=3D nullptr and does not consume any extra storage. An extra ben=
efit is that we have clear distinction between nullable types (optional<=
T>) and regular types, int, vector, string_view, etc.</div><div><br></di=
v><div>Will this solution satisfy the original poster?<br></div><blockquote=
class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1e=
x; border-left-color: rgb(204, 204, 204); border-left-width: 1px; border-le=
ft-style: solid;"><div dir=3D"ltr"><br></div></blockquote></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_112_8601933.1390000241866--
.
Author: Marshall Clow <mclow.lists@gmail.com>
Date: Fri, 17 Jan 2014 15:51:34 -0800
Raw View
--Apple-Mail=_8631E139-3196-43A0-8E56-87132E4A6E18
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=windows-1252
On Jan 17, 2014, at 2:10 PM, Jeffrey Yasskin <jyasskin@google.com> wrote:
> Agreed. To mitigate this, if string_view::data() could return nullptr, I =
believe we could still create strings using std::string(null_sv.begin(), nu=
ll_sv.end()).
I thought that=92s why we had to_string().
=97 Marshall
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--Apple-Mail=_8631E139-3196-43A0-8E56-87132E4A6E18
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=windows-1252
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;">On Jan 17, 2014, at 2:=
10 PM, Jeffrey Yasskin <<a href=3D"mailto:jyasskin@google.com">jyasskin@=
google.com</a>> wrote:<br><div><br class=3D"Apple-interchange-newline"><=
blockquote type=3D"cite"><div dir=3D"ltr" style=3D"font-family: LucidaGrand=
e; font-size: 11px; font-style: normal; font-variant: normal; font-weight: =
normal; letter-spacing: normal; line-height: normal; orphans: auto; text-al=
ign: start; text-indent: 0px; text-transform: none; white-space: normal; wi=
dows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class=
=3D"gmail_extra">Agreed. To mitigate this, if string_view::data() could ret=
urn nullptr, I believe we could still create strings using std::string(null=
_sv.begin(), null_sv.end()).</div></div></blockquote><br></div><div>I thoug=
ht that=92s why we had to_string().</div><div><br></div><div>=97 Marshall</=
div><div><br></div><br></body></html>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--Apple-Mail=_8631E139-3196-43A0-8E56-87132E4A6E18--
.
Author: Jeffrey Yasskin <jyasskin@google.com>
Date: Fri, 17 Jan 2014 16:06:18 -0800
Raw View
On Fri, Jan 17, 2014 at 3:51 PM, Marshall Clow <mclow.lists@gmail.com> wrot=
e:
> On Jan 17, 2014, at 2:10 PM, Jeffrey Yasskin <jyasskin@google.com> wrote:
>
> Agreed. To mitigate this, if string_view::data() could return nullptr, I
> believe we could still create strings using std::string(null_sv.begin(),
> null_sv.end()).
>
>
> I thought that=92s why we had to_string().
We have to_string mostly for convenience, I think, although it is
another way to get from a null string_view to a std::string.
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Fri, 17 Jan 2014 17:00:12 -0800 (PST)
Raw View
------=_Part_2_12412770.1390006812394
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
I have not followed this entire thread, instead I hacked up a little=20
implementation which I used in implementing something for another thread on=
=20
an improved "printf" functionality. What I noticed was:
- I had use for a C array of string_view to keep the parts of the original=
=20
string that fell between each data inserted. This means that I must be able=
=20
to default construct string_view as there is no other way to construct an=
=20
array element.
- It is logical to do this default construction by setting m_begin and=20
m_end to nullptr, or m_begin to nullptr and m_size to 0.
- It must be allowed to take a default constructed string_view as the range=
=20
of a range based for statement __or__ to check if the range is in default=
=20
constucted state using something like os_null().
- both of these methods are impossible if the presumptions stated above=20
"begin() should never return nullptr" and "we don't need a special=20
is_null()". Well, not entirely. Of course you could create some bogus=20
object and use its address instead of nullptr.
Someone stated above that the \0 at the end of the string should be=20
accessible even if the string_view is empty. This is clearly impossible as=
=20
a string_view may be constructed as a part of a string which continues on.=
=20
Thus there is no \0 at *end() anytime.
This said I think that the very simple solution is to just set the=20
pointer(s) to nullptr in the default ctor, don't implement any special=20
is_null but return "null" iterators from begin and end in default=20
constructed string_view, which of course results in zero length if they are=
=20
subtracted. I don't really see a problem here, isn't this how all=20
containers do it. For instance a newly default constructed vector? Is the=
=20
issue whether you can rely on this to know wheter the string_view (or=20
vector) has been non-empty before? If so, follow the example of vector and=
=20
give the same promises on the standard level!
Den l=C3=B6rdagen den 18:e januari 2014 kl. 01:06:18 UTC+1 skrev Jeffrey Ya=
sskin:
>
> On Fri, Jan 17, 2014 at 3:51 PM, Marshall Clow <mclow...@gmail.com<javasc=
ript:>>=20
> wrote:=20
> > On Jan 17, 2014, at 2:10 PM, Jeffrey Yasskin <jyas...@google.com<javasc=
ript:>>=20
> wrote:=20
> >=20
> > Agreed. To mitigate this, if string_view::data() could return nullptr, =
I=20
> > believe we could still create strings using std::string(null_sv.begin()=
,=20
> > null_sv.end()).=20
> >=20
> >=20
> > I thought that=E2=80=99s why we had to_string().=20
>
> We have to_string mostly for convenience, I think, although it is=20
> another way to get from a null string_view to a std::string.=20
>
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_2_12412770.1390006812394
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">I have not followed this entire thread, instead I hacked u=
p a little implementation which I used in implementing something for anothe=
r thread on an improved "printf" functionality. What I noticed was:<div><br=
></div><div>- I had use for a C array of string_view to keep the parts of t=
he original string that fell between each data inserted. This means that I =
must be able to default construct string_view as there is no other way to c=
onstruct an array element.</div><div>- It is logical to do this default con=
struction by setting m_begin and m_end to nullptr, or m_begin to nullptr an=
d m_size to 0.</div><div>- It must be allowed to take a default constructed=
string_view as the range of a range based for statement __or__ to check if=
the range is in default constucted state using something like os_null().</=
div><div><br></div><div>- both of these methods are impossible if the presu=
mptions stated above "begin() should never return nullptr" and "we don't ne=
ed a special is_null()". Well, not entirely. Of course you could create som=
e bogus object and use its address instead of nullptr.</div><div><br></div>=
<div>Someone stated above that the \0 at the end of the string should be ac=
cessible even if the string_view is empty. This is clearly impossible as a =
string_view may be constructed as a part of a string which continues on. Th=
us there is no \0 at *end() anytime.</div><div><br></div><div>This said I t=
hink that the very simple solution is to just set the pointer(s) to nullptr=
in the default ctor, don't implement any special is_null but return "null"=
iterators from begin and end in default constructed string_view, which of =
course results in zero length if they are subtracted. I don't really see a =
problem here, isn't this how all containers do it. For instance a newly def=
ault constructed vector? Is the issue whether you can rely on this to know =
wheter the string_view (or vector) has been non-empty before? If so, follow=
the example of vector and give the same promises on the standard level!</d=
iv><div><br></div><div><br>Den l=C3=B6rdagen den 18:e januari 2014 kl. 01:0=
6:18 UTC+1 skrev Jeffrey Yasskin:<blockquote class=3D"gmail_quote" style=3D=
"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex=
;">On Fri, Jan 17, 2014 at 3:51 PM, Marshall Clow <<a href=3D"javascript=
:" target=3D"_blank" gdf-obfuscated-mailto=3D"-giuVlTiRDMJ" onmousedown=3D"=
this.href=3D'javascript:';return true;" onclick=3D"this.href=3D'javascript:=
';return true;">mclow...@gmail.com</a>> wrote:
<br>> On Jan 17, 2014, at 2:10 PM, Jeffrey Yasskin <<a href=3D"javasc=
ript:" target=3D"_blank" gdf-obfuscated-mailto=3D"-giuVlTiRDMJ" onmousedown=
=3D"this.href=3D'javascript:';return true;" onclick=3D"this.href=3D'javascr=
ipt:';return true;">jyas...@google.com</a>> wrote:
<br>>
<br>> Agreed. To mitigate this, if string_view::data() could return null=
ptr, I
<br>> believe we could still create strings using std::string(null_sv.be=
gin(),
<br>> null_sv.end()).
<br>>
<br>>
<br>> I thought that=E2=80=99s why we had to_string().
<br>
<br>We have to_string mostly for convenience, I think, although it is
<br>another way to get from a null string_view to a std::string.
<br></blockquote></div></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_2_12412770.1390006812394--
.
Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Fri, 17 Jan 2014 17:12:23 -0800 (PST)
Raw View
------=_Part_13_21255250.1390007543036
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Someone said that constructing a string from (nullpltr, 0) is not allowed,=
=20
and that is used as an argument here. How about looking into why this is=20
not allowed first? I can't see any practical reason for string nor for=20
string_view.
Someone else claimed that if nullptr could be returned from data() then=20
you'd have to test for this in _addition_ to testing for size() =3D=3D 0. I=
=20
can't understand ahy as if size() is 0 there is exactly 0 offsets at which=
=20
it is ok to dereference the pointer returned from data. This is more=20
information you get from testing whether the returned pointer is nullptr,=
=20
i.e. even if data() returned non-null there may be no elements to access,=
=20
but if size() returns 0 there can be _no_ elements whether the pointer is=
=20
null or not.
Den l=C3=B6rdagen den 18:e januari 2014 kl. 02:00:12 UTC+1 skrev Bengt=20
Gustafsson:
>
> I have not followed this entire thread, instead I hacked up a little=20
> implementation which I used in implementing something for another thread =
on=20
> an improved "printf" functionality. What I noticed was:
>
> - I had use for a C array of string_view to keep the parts of the origina=
l=20
> string that fell between each data inserted. This means that I must be ab=
le=20
> to default construct string_view as there is no other way to construct an=
=20
> array element.
> - It is logical to do this default construction by setting m_begin and=20
> m_end to nullptr, or m_begin to nullptr and m_size to 0.
> - It must be allowed to take a default constructed string_view as the=20
> range of a range based for statement __or__ to check if the range is in=
=20
> default constucted state using something like os_null().
>
> - both of these methods are impossible if the presumptions stated above=
=20
> "begin() should never return nullptr" and "we don't need a special=20
> is_null()". Well, not entirely. Of course you could create some bogus=20
> object and use its address instead of nullptr.
>
> Someone stated above that the \0 at the end of the string should be=20
> accessible even if the string_view is empty. This is clearly impossible a=
s=20
> a string_view may be constructed as a part of a string which continues on=
..=20
> Thus there is no \0 at *end() anytime.
>
> This said I think that the very simple solution is to just set the=20
> pointer(s) to nullptr in the default ctor, don't implement any special=20
> is_null but return "null" iterators from begin and end in default=20
> constructed string_view, which of course results in zero length if they a=
re=20
> subtracted. I don't really see a problem here, isn't this how all=20
> containers do it. For instance a newly default constructed vector? Is the=
=20
> issue whether you can rely on this to know wheter the string_view (or=20
> vector) has been non-empty before? If so, follow the example of vector an=
d=20
> give the same promises on the standard level!
>
>
> Den l=C3=B6rdagen den 18:e januari 2014 kl. 01:06:18 UTC+1 skrev Jeffrey=
=20
> Yasskin:
>>
>> On Fri, Jan 17, 2014 at 3:51 PM, Marshall Clow <mclow...@gmail.com>=20
>> wrote:=20
>> > On Jan 17, 2014, at 2:10 PM, Jeffrey Yasskin <jyas...@google.com>=20
>> wrote:=20
>> >=20
>> > Agreed. To mitigate this, if string_view::data() could return nullptr,=
=20
>> I=20
>> > believe we could still create strings using=20
>> std::string(null_sv.begin(),=20
>> > null_sv.end()).=20
>> >=20
>> >=20
>> > I thought that=E2=80=99s why we had to_string().=20
>>
>> We have to_string mostly for convenience, I think, although it is=20
>> another way to get from a null string_view to a std::string.=20
>>
>
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_13_21255250.1390007543036
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Someone said that constructing a string from (nullpltr, 0)=
is not allowed, and that is used as an argument here. How about looking in=
to why this is not allowed first? I can't see any practical reason for stri=
ng nor for string_view.<div><br></div><div>Someone else claimed that if nul=
lptr could be returned from data() then you'd have to test for this in _add=
ition_ to testing for size() =3D=3D 0. I can't understand ahy as if size() =
is 0 there is exactly 0 offsets at which it is ok to dereference the pointe=
r returned from data. This is more information you get from testing whether=
the returned pointer is nullptr, i.e. even if data() returned non-null the=
re may be no elements to access, but if size() returns 0 there can be _no_ =
elements whether the pointer is null or not.</div><div><br></div><div><br><=
/div><div>Den l=C3=B6rdagen den 18:e januari 2014 kl. 02:00:12 UTC+1 skrev =
Bengt Gustafsson:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr">I have not followed this entire thread, instead I hacked up a little im=
plementation which I used in implementing something for another thread on a=
n improved "printf" functionality. What I noticed was:<div><br></div><div>-=
I had use for a C array of string_view to keep the parts of the original s=
tring that fell between each data inserted. This means that I must be able =
to default construct string_view as there is no other way to construct an a=
rray element.</div><div>- It is logical to do this default construction by =
setting m_begin and m_end to nullptr, or m_begin to nullptr and m_size to 0=
..</div><div>- It must be allowed to take a default constructed string_view =
as the range of a range based for statement __or__ to check if the range is=
in default constucted state using something like os_null().</div><div><br>=
</div><div>- both of these methods are impossible if the presumptions state=
d above "begin() should never return nullptr" and "we don't need a special =
is_null()". Well, not entirely. Of course you could create some bogus objec=
t and use its address instead of nullptr.</div><div><br></div><div>Someone =
stated above that the \0 at the end of the string should be accessible even=
if the string_view is empty. This is clearly impossible as a string_view m=
ay be constructed as a part of a string which continues on. Thus there is n=
o \0 at *end() anytime.</div><div><br></div><div>This said I think that the=
very simple solution is to just set the pointer(s) to nullptr in the defau=
lt ctor, don't implement any special is_null but return "null" iterators fr=
om begin and end in default constructed string_view, which of course result=
s in zero length if they are subtracted. I don't really see a problem here,=
isn't this how all containers do it. For instance a newly default construc=
ted vector? Is the issue whether you can rely on this to know wheter the st=
ring_view (or vector) has been non-empty before? If so, follow the example =
of vector and give the same promises on the standard level!</div><div><br><=
/div><div><br>Den l=C3=B6rdagen den 18:e januari 2014 kl. 01:06:18 UTC+1 sk=
rev Jeffrey Yasskin:<blockquote class=3D"gmail_quote" style=3D"margin:0;mar=
gin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">On Fri, Jan 17,=
2014 at 3:51 PM, Marshall Clow <<a>mclow...@gmail.com</a>> wrote:
<br>> On Jan 17, 2014, at 2:10 PM, Jeffrey Yasskin <<a>jyas...@google=
..com</a>> wrote:
<br>>
<br>> Agreed. To mitigate this, if string_view::data() could return null=
ptr, I
<br>> believe we could still create strings using std::string(null_sv.be=
gin(),
<br>> null_sv.end()).
<br>>
<br>>
<br>> I thought that=E2=80=99s why we had to_string().
<br>
<br>We have to_string mostly for convenience, I think, although it is
<br>another way to get from a null string_view to a std::string.
<br></blockquote></div></div></blockquote></div></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_13_21255250.1390007543036--
.
Author: Miro Knejp <miro@knejp.de>
Date: Sat, 18 Jan 2014 03:13:10 +0100
Raw View
>
> - both of these methods are impossible if the presumptions stated
> above "begin() should never return nullptr" and "we don't need a
> special is_null()". Well, not entirely. Of course you could create
> some bogus object and use its address instead of nullptr.
>
Why not set the string_view to "" in the default constructor?
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Peter Bigot <bigotp@acm.org>
Date: Fri, 17 Jan 2014 18:15:43 -0800 (PST)
Raw View
------=_Part_206_29211677.1390011343349
Content-Type: text/plain; charset=UTF-8
On Friday, January 17, 2014 7:00:12 PM UTC-6, Bengt Gustafsson wrote:
>
> I have not followed this entire thread, instead I hacked up a little
> implementation which I used in implementing something for another thread on
> an improved "printf" functionality. What I noticed was:
>
> - I had use for a C array of string_view to keep the parts of the original
> string that fell between each data inserted. This means that I must be able
> to default construct string_view as there is no other way to construct an
> array element.
>
Sure, that's one approach.
> - It is logical to do this default construction by setting m_begin and
> m_end to nullptr, or m_begin to nullptr and m_size to 0.
>
Logical, perhaps; necessary, no. It's equally or more logical to treat it
the same as a default-constructed std::string. It was tentatively agreed
much earlier in this or another thread that doing so doesn't even require
allocating any memory to hold the "referenced" empty string, while still
preserving the requirement that data() have a value distinct from nullptr.
> - It must be allowed to take a default constructed string_view as the
> range of a range based for statement
>
Sure.
> __or__ to check if the range is in default constucted state using
> something like os_null().
>
Why? Is there something specific to ranges that makes a
default-constructed range significant?
> - both of these methods are impossible if the presumptions stated above
> "begin() should never return nullptr" and "we don't need a special
> is_null()". Well, not entirely. Of course you could create some bogus
> object and use its address instead of nullptr.
>
> Someone stated above that the \0 at the end of the string should be
> accessible even if the string_view is empty. This is clearly impossible as
> a string_view may be constructed as a part of a string which continues on.
> Thus there is no \0 at *end() anytime.
>
This may be referring to what I said about deref(sv2) in Marshall's
example, but if so it isn't an accurate summary. What I said is that if a
string_view is constructed from a string literal (which is necessarily
nul-terminated) and the default size calculated from traits::length(str),
then even though accessing the terminating nul from the string_view is not
legal the nul is still there and still legally accessible by using a char*
pointer which is known to point into that string literal.
Here's another example which avoids the nul and any assumptions about
persistence of the string literal:
const std::string base("ABCDE");
string_view sv(base);
ASSERT_EQ(base.data(), sv.data());
sv.remove_prefix(2);
ASSERT_EQ(base.data()+2, sv.data());
sv.remove_suffix(3);
ASSERT_EQ(0, sv.size());
ASSERT_EQ(base.data()+2, sv.data());
ASSERT_EQ('C', *sv.data());
sv in isolation only guarantees that [sv.data(), sv.data()+0) is a valid
range and specifically does not sanction the expression *sv.data().
But sv.data() is value- and type-equivalent to base.data()+2 by the
specification for string_view.
And accessing *(base.data()+2) is perfectly legitimate.
So why can't I substitute a value- and type-equivalent subexpression into
that dereference expression?
I'm hoping that somebody will explain why this is an invalid use of
std::string_view as currently described in
https://rawgithub.com/google/cxx-std-draft/string-ref-paper/string_view.html.
As for why I think allowing null sv.data() creates a new requirement to
check for null sv.data(): If you accept that sv.data() can be useful even
though sv.size() is zero---perhaps for nothing more than to calculate an
offset into the original string with sv.data()-base.data()---then it
becomes necessary to know that sv.data() is not null regardless of whether
sv.size() is zero so you don't perform pointer arithmetic on a null
pointer. Not always, but certainly if you're using sv.data() this way
(which I have found very convenient).
My preference is to impose the non-null requirement on the string_view type
just as it is imposed on std::string, rather than have to check it
manually. (AFAIK std::string has never permitted its data() function to
return a null pointer, so I don't see a lot of value in reviewing that
decision.)
Peter
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_206_29211677.1390011343349
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Friday, January 17, 2014 7:00:12 PM UTC-6, Bengt Gustaf=
sson 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">I =
have not followed this entire thread, instead I hacked up a little implemen=
tation which I used in implementing something for another thread on an impr=
oved "printf" functionality. What I noticed was:<div><br></div><div>- I had=
use for a C array of string_view to keep the parts of the original string =
that fell between each data inserted. This means that I must be able to def=
ault construct string_view as there is no other way to construct an array e=
lement.</div></div></blockquote><div><br>Sure, that's one approach.<br>&nbs=
p;<br></div><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"><=
div>- It is logical to do this default construction by setting m_begin and =
m_end to nullptr, or m_begin to nullptr and m_size to 0.</div></div></block=
quote><div><br>Logical, perhaps; necessary, no. It's equally or more =
logical to treat it the same as a default-constructed std::string. It=
was tentatively agreed much earlier in this or another thread that doing s=
o doesn't even require allocating any memory to hold the "referenced" empty=
string, while still preserving the requirement that data() have a value di=
stinct from nullptr.<br> <br></div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-le=
ft: 1ex;"><div dir=3D"ltr"><div>- It must be allowed to take a default cons=
tructed string_view as the range of a range based for statement</div></div>=
</blockquote><div><br>Sure.<br> <br></div><blockquote class=3D"gmail_q=
uote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pad=
ding-left: 1ex;"><div dir=3D"ltr"><div> __or__ to check if the range is in =
default constucted state using something like os_null().</div></div></block=
quote><div><br>Why? Is there something specific to ranges that makes =
a default-constructed range significant?<br></div><div><br></div><blockquot=
e 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><br></div><div>- b=
oth of these methods are impossible if the presumptions stated above "begin=
() should never return nullptr" and "we don't need a special is_null()". We=
ll, not entirely. Of course you could create some bogus object and use its =
address instead of nullptr.</div><div><br></div><div>Someone stated above t=
hat the \0 at the end of the string should be accessible even if the string=
_view is empty. This is clearly impossible as a string_view may be construc=
ted as a part of a string which continues on. Thus there is no \0 at *end()=
anytime.</div></div></blockquote><div><br>This may be referring to what I =
said about deref(sv2) in Marshall's example, but if so it isn't an accurate=
summary. What I said is that if a string_view is constructed from a =
string literal (which is necessarily nul-terminated) and the default size c=
alculated from traits::length(str), then even though accessing the terminat=
ing nul from the string_view is not legal the nul is still there and still =
legally accessible by using a char* pointer which is known to point into th=
at string literal.<br></div><br>Here's another example which avoids the nul=
and any assumptions about persistence of the string literal:<br><br> =
const std::string base("ABCDE");<br> string_view sv(base);<br> =
ASSERT_EQ(base.data(), sv.data());<br> sv.remove_prefix(2);<br> =
; ASSERT_EQ(base.data()+2, sv.data());<br> sv.remove_suffix(3);<br>&n=
bsp; ASSERT_EQ(0, sv.size());<br> ASSERT_EQ(base.data()+2, sv.data())=
;<br> ASSERT_EQ('C', *sv.data());<br><br>sv in isolation only guarant=
ees that [sv.data(), sv.data()+0) is a valid range and specifically does no=
t sanction the expression *sv.data().<br><br>But sv.data() is value- and ty=
pe-equivalent to base.data()+2 by the specification for string_view.<br><br=
>And accessing *(base.data()+2) is perfectly legitimate.<br><br>So why can'=
t I substitute a value- and type-equivalent subexpression into that derefer=
ence expression?<br><br>I'm hoping that somebody will explain why this is a=
n invalid use of std::string_view as currently described in https://rawgith=
ub.com/google/cxx-std-draft/string-ref-paper/string_view.html.<br><br>As fo=
r why I think allowing null sv.data() creates a new requirement to check fo=
r null sv.data(): If you accept that sv.data() can be useful even tho=
ugh sv.size() is zero---perhaps for nothing more than to calculate an offse=
t into the original string with sv.data()-base.data()---then it becomes nec=
essary to know that sv.data() is not null regardless of whether sv.size() i=
s zero so you don't perform pointer arithmetic on a null pointer. Not=
always, but certainly if you're using sv.data() this way (which I have fou=
nd very convenient).<br><br>My preference is to impose the non-null require=
ment on the string_view type just as it is imposed on std::string, rather t=
han have to check it manually. (AFAIK std::string has never per=
mitted its data() function to return a null pointer, so
I don't see a lot of value in reviewing that decision.)<br><br>Peter<br></=
div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_206_29211677.1390011343349--
.
Author: Marshall Clow <mclow.lists@gmail.com>
Date: Fri, 17 Jan 2014 20:19:07 -0800
Raw View
On Jan 17, 2014, at 6:13 PM, Miro Knejp <miro@knejp.de> wrote:
>>=20
>> - both of these methods are impossible if the presumptions stated above =
"begin() should never return nullptr" and "we don't need a special is_null(=
)". Well, not entirely. Of course you could create some bogus object and us=
e its address instead of nullptr.
>>=20
> Why not set the string_view to "" in the default constructor?
I believe that this is the current proposal.
However, this requires creating a global variable (which some implementatio=
ns will put in the code segment) for each default constructed string_view (=
yes, some implementations will merge them together in the same translation =
unit).
=97 Marshall
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: "=?utf-8?B?YmlsbHkub25lYWxAZ21haWwuY29t?=" <billy.oneal@gmail.com>
Date: Fri, 17 Jan 2014 21:43:48 -0800
Raw View
------=_Part_0_1390023828285
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline
No, it does not. The empty string can just be an extern char *, and put in =
a single TU.
If we want to allow string view to be null, it should just be what you get =
when you construct a string view from nullptr_t or default construct one. P=
assing (0, 0) should be an empty string, not null. Otherwise, it becomes di=
fficult to turn empty strings in many conditions into string_view s. For in=
stance, creating a string view from a COM BSTR becomes non-trivial, because=
a null BSTR is semantically empty, not null.
I still think if you want optional semantics that you should use optional, =
because it clearly defines what an API accepts. Otherwise people may be sur=
prised when different behavior occurs that isn't easily discernable from th=
e function's signature.
(But if they can be treated as empty most of the time my opinion moves from=
violent hatred to mere dislike :) )
Sent from a touchscreen. Please excuse the brevity and tpyos.
----- Reply message -----
From: "Marshall Clow" <mclow.lists@gmail.com>
To: <std-proposals@isocpp.org>
Subject: [std-proposals] string_view::is_null()
Date: Fri, Jan 17, 2014 8:19 PM
On Jan 17, 2014, at 6:13 PM, Miro Knejp <miro@knejp.de> wrote:
>>=20
>> - both of these methods are impossible if the presumptions stated above =
"begin() should never return nullptr" and "we don't need a special is_null(=
)". Well, not entirely. Of course you could create some bogus object and us=
e its address instead of nullptr.
>>=20
> Why not set the string_view to "" in the default constructor?
I believe that this is the current proposal.
However, this requires creating a global variable (which some implementatio=
ns will put in the code segment) for each default constructed string_view (=
yes, some implementations will merge them together in the same translation =
unit).
=E2=80=94 Marshall
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_0_1390023828285
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/htm=
l4/strict.dtd">
<html><head></head><body><div style=3D"font-size: 12pt; font-family: Calibr=
i,sans-serif;"><div>No, it does not. The empty string can just be an extern=
char *, and put in a single TU.</div><div><br></div><div>If we want to all=
ow string view to be null, it should just be what you get when you construc=
t a string view from nullptr_t or default construct one. Passing (0, 0) sho=
uld be an empty string, not null. Otherwise, it becomes difficult to turn e=
mpty strings in many conditions into string_view s. For instance, creating =
a string view from a COM BSTR becomes non-trivial, because a null BSTR is s=
emantically empty, not null.</div><div><br></div><div>I still think if you =
want optional semantics that you should use optional, because it clearly de=
fines what an API accepts. Otherwise people may be surprised when different=
behavior occurs that isn't easily discernable from the function's signatur=
e.</div><div><br></div><div>(But if they can be treated as empty most of th=
e time my opinion moves from violent hatred to mere dislike :) )</div><div>=
<br></div><div>Sent from a touchscreen. Please excuse the brevity and tpyos=
..</div><br><div id=3D"htc_header">----- Reply message -----<br>From: "=
Marshall Clow" <mclow.lists@gmail.com><br>To: <std-proposals@=
isocpp.org><br>Subject: [std-proposals] string_view::is_null()<br>Date: =
Fri, Jan 17, 2014 8:19 PM</div></div><br><pre style=3D"word-wrap: break-wor=
d; white-space: pre-wrap;">On Jan 17, 2014, at 6:13 PM, Miro Knejp <miro=
@knejp.de> wrote:
>>=20
>> - both of these methods are impossible if the presumptions stated =
above "begin() should never return nullptr" and "we don't need a special is=
_null()". Well, not entirely. Of course you could create some bogus object =
and use its address instead of nullptr.
>>=20
> Why not set the string_view to "" in the default constructor?
I believe that this is the current proposal.
However, this requires creating a global variable (which some implementatio=
ns will put in the code segment) for each default constructed string_view (=
yes, some implementations will merge them together in the same translation =
unit).
=E2=80=94 Marshall
--=20
---=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.
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/.">http://groups.google.com/a/isocpp.org/group/std-proposals/=
..</a>
</pre></body></html>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_0_1390023828285--
.
Author: abolz.lists@gmail.com
Date: Sat, 18 Jan 2014 07:30:17 -0800 (PST)
Raw View
------=_Part_327_24944384.1390059017415
Content-Type: text/plain; charset=UTF-8
Am Samstag, 18. Januar 2014 00:10:41 UTC+1 schrieb gorni...@gmail.com:
>
> What if string_view provides a specialization for optional<string_view<>>?
>
> That way optional<string_view> can be implemented very efficiently by
> checking if sv.begin() == nullptr and does not consume any extra storage.
> An extra benefit is that we have clear distinction between nullable types
> (optional<T>) and regular types, int, vector, string_view, etc.
>
> Will this solution satisfy the original poster?
>
An (unspecialized) optional<string_view> is not always an option. E.g. I
can't simply change a function like
void f(char const* s) {}
to
void f(optional<string_view> s) {}
because I can no longer write f("hello"). So the specialization should be
implicitly constructible from a char array.
And then an optional<string_view> constructed from a nullptr should be an
uninitialized optional since there
are no preconditions on f, I should be able to write
f(getenv("not-an-env-var")).
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_327_24944384.1390059017415
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Am Samstag, 18. Januar 2014 00:10:41 UTC+1 schrieb gorni..=
..@gmail.com:<blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px =
0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-lef=
t-width: 1px; border-left-style: solid;"><div dir=3D"ltr"><div>What if stri=
ng_view provides a specialization for optional<string_view<>>?<=
/div><div><br></div><div>That way optional<string_view> can be implem=
ented very efficiently by checking if sv.begin() =3D=3D nullptr and does no=
t consume any extra storage. An extra benefit is that we have clear distinc=
tion between nullable types (optional<T>) and regular types, int, vec=
tor, string_view, etc.</div><div><br></div><div>Will this solution satisfy =
the original poster?<br></div></div></blockquote><div><br></div><div>An (un=
specialized) optional<string_view> is not always an option. E.g. I ca=
n't simply change a function like</div><div><br></div><div>void f(char=
const* s) {}</div><div><br></div><div>to</div><div><br></div><div>void f(o=
ptional<string_view> s) {}</div><div><br></div><div>because I can no =
longer write f("hello"). So the specialization should be implicitly constru=
ctible from a char array.</div><div>And then an optional<string_vie=
w> constructed from a nullptr should be an uninitialized optional since =
there</div><div>are no preconditions on f, I should be able to write f(gete=
nv("not-an-env-var")).</div><div><br></div></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_327_24944384.1390059017415--
.
Author: abolz.lists@gmail.com
Date: Sat, 18 Jan 2014 07:36:17 -0800 (PST)
Raw View
------=_Part_422_23998461.1390059377973
Content-Type: text/plain; charset=UTF-8
Am Samstag, 18. Januar 2014 03:15:43 UTC+1 schrieb Peter Bigot:
>
> On Friday, January 17, 2014 7:00:12 PM UTC-6, Bengt Gustafsson wrote:
>>
>> I have not followed this entire thread, instead I hacked up a little
>> implementation which I used in implementing something for another thread on
>> an improved "printf" functionality. What I noticed was:
>>
>> - I had use for a C array of string_view to keep the parts of the
>> original string that fell between each data inserted. This means that I
>> must be able to default construct string_view as there is no other way to
>> construct an array element.
>>
>
> Sure, that's one approach.
>
>
>> - It is logical to do this default construction by setting m_begin and
>> m_end to nullptr, or m_begin to nullptr and m_size to 0.
>>
>
> Logical, perhaps; necessary, no. It's equally or more logical to treat it
> the same as a default-constructed std::string. It was tentatively agreed
> much earlier in this or another thread that doing so doesn't even require
> allocating any memory to hold the "referenced" empty string, while still
> preserving the requirement that data() have a value distinct from nullptr.
>
>
>> - It must be allowed to take a default constructed string_view as the
>> range of a range based for statement
>>
>
> Sure.
>
>
>> __or__ to check if the range is in default constucted state using
>> something like os_null().
>>
>
> Why? Is there something specific to ranges that makes a
> default-constructed range significant?
>
>
>> - both of these methods are impossible if the presumptions stated above
>> "begin() should never return nullptr" and "we don't need a special
>> is_null()". Well, not entirely. Of course you could create some bogus
>> object and use its address instead of nullptr.
>>
>> Someone stated above that the \0 at the end of the string should be
>> accessible even if the string_view is empty. This is clearly impossible as
>> a string_view may be constructed as a part of a string which continues on.
>> Thus there is no \0 at *end() anytime.
>>
>
> This may be referring to what I said about deref(sv2) in Marshall's
> example, but if so it isn't an accurate summary. What I said is that if a
> string_view is constructed from a string literal (which is necessarily
> nul-terminated) and the default size calculated from traits::length(str),
> then even though accessing the terminating nul from the string_view is not
> legal the nul is still there and still legally accessible by using a char*
> pointer which is known to point into that string literal.
>
> Here's another example which avoids the nul and any assumptions about
> persistence of the string literal:
>
> const std::string base("ABCDE");
> string_view sv(base);
> ASSERT_EQ(base.data(), sv.data());
> sv.remove_prefix(2);
> ASSERT_EQ(base.data()+2, sv.data());
> sv.remove_suffix(3);
> ASSERT_EQ(0, sv.size());
> ASSERT_EQ(base.data()+2, sv.data());
> ASSERT_EQ('C', *sv.data());
>
> sv in isolation only guarantees that [sv.data(), sv.data()+0) is a valid
> range and specifically does not sanction the expression *sv.data().
>
> But sv.data() is value- and type-equivalent to base.data()+2 by the
> specification for string_view.
>
> And accessing *(base.data()+2) is perfectly legitimate.
>
> So why can't I substitute a value- and type-equivalent subexpression into
> that dereference expression?
>
> I'm hoping that somebody will explain why this is an invalid use of
> std::string_view as currently described in
> https://rawgithub.com/google/cxx-std-draft/string-ref-paper/string_view.html
> .
>
> As for why I think allowing null sv.data() creates a new requirement to
> check for null sv.data(): If you accept that sv.data() can be useful even
> though sv.size() is zero---perhaps for nothing more than to calculate an
> offset into the original string with sv.data()-base.data()---then it
> becomes necessary to know that sv.data() is not null regardless of whether
> sv.size() is zero so you don't perform pointer arithmetic on a null
> pointer. Not always, but certainly if you're using sv.data() this way
> (which I have found very convenient).
>
For the current proposal this should work. Since you can't put a nullptr in
you can't get a nullptr out and sv.data() - base.data() is defined.
If a string_view would allow null data() then (assuming a string_view is
constructible from a nullptr, too) this would be ok too, since no
operation on a string_view changes the data pointer and subtracting a
nullptr from a nullptr is ok too.
If a stringview were allowed to be constructed from a nullptr, but data()
always returns non-null, then one actually has to check for base.data() !=
null.,
>
> My preference is to impose the non-null requirement on the string_view
> type just as it is imposed on std::string, rather than have to check it
> manually. (AFAIK std::string has never permitted its data() function to
> return a null pointer, so I don't see a lot of value in reviewing that
> decision.)
>
> Peter
>
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_422_23998461.1390059377973
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>Am Samstag, 18. Januar 2014 03:15:43 UTC+1 schrieb=
Peter Bigot:<blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px=
0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-le=
ft-width: 1px; border-left-style: solid;"><div dir=3D"ltr">On Friday, Janua=
ry 17, 2014 7:00:12 PM UTC-6, Bengt Gustafsson wrote:<blockquote class=3D"g=
mail_quote" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-l=
eft-color: rgb(204, 204, 204); border-left-width: 1px; border-left-style: s=
olid;"><div dir=3D"ltr">I have not followed this entire thread, instead I h=
acked up a little implementation which I used in implementing something for=
another thread on an improved "printf" functionality. What I noticed was:<=
div><br></div><div>- I had use for a C array of string_view to keep the par=
ts of the original string that fell between each data inserted. This means =
that I must be able to default construct string_view as there is no other w=
ay to construct an array element.</div></div></blockquote><div><br>Sure, th=
at's one approach.<br> <br></div><blockquote class=3D"gmail_quote" sty=
le=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(=
204, 204, 204); border-left-width: 1px; border-left-style: solid;"><div dir=
=3D"ltr"><div>- It is logical to do this default construction by setting m_=
begin and m_end to nullptr, or m_begin to nullptr and m_size to 0.</div></d=
iv></blockquote><div><br>Logical, perhaps; necessary, no. It's equall=
y or more logical to treat it the same as a default-constructed std::string=
.. It was tentatively agreed much earlier in this or another thread th=
at doing so doesn't even require allocating any memory to hold the "referen=
ced" empty string, while still preserving the requirement that data() have =
a value distinct from nullptr.<br> <br></div><blockquote class=3D"gmai=
l_quote" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left=
-color: rgb(204, 204, 204); border-left-width: 1px; border-left-style: soli=
d;"><div dir=3D"ltr"><div>- It must be allowed to take a default constructe=
d string_view as the range of a range based for statement</div></div></bloc=
kquote><div><br>Sure.<br> <br></div><blockquote class=3D"gmail_quote" =
style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: r=
gb(204, 204, 204); border-left-width: 1px; border-left-style: solid;"><div =
dir=3D"ltr"><div> __or__ to check if the range is in default constucted sta=
te using something like os_null().</div></div></blockquote><div><br>Why?&nb=
sp; Is there something specific to ranges that makes a default-constructed =
range significant?<br></div><div><br></div><blockquote class=3D"gmail_quote=
" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color:=
rgb(204, 204, 204); border-left-width: 1px; border-left-style: solid;"><di=
v dir=3D"ltr"><div><br></div><div>- both of these methods are impossible if=
the presumptions stated above "begin() should never return nullptr" and "w=
e don't need a special is_null()". Well, not entirely. Of course you could =
create some bogus object and use its address instead of nullptr.</div><div>=
<br></div><div>Someone stated above that the \0 at the end of the string sh=
ould be accessible even if the string_view is empty. This is clearly imposs=
ible as a string_view may be constructed as a part of a string which contin=
ues on. Thus there is no \0 at *end() anytime.</div></div></blockquote><div=
><br>This may be referring to what I said about deref(sv2) in Marshall's ex=
ample, but if so it isn't an accurate summary. What I said is that if=
a string_view is constructed from a string literal (which is necessarily n=
ul-terminated) and the default size calculated from traits::length(str), th=
en even though accessing the terminating nul from the string_view is not le=
gal the nul is still there and still legally accessible by using a char* po=
inter which is known to point into that string literal.<br></div><br>Here's=
another example which avoids the nul and any assumptions about persistence=
of the string literal:<br><br> const std::string base("ABCDE");<br>&=
nbsp; string_view sv(base);<br> ASSERT_EQ(base.data(), sv.data());<br=
> sv.remove_prefix(2);<br> ASSERT_EQ(base.data()+2, sv.data());=
<br> sv.remove_suffix(3);<br> ASSERT_EQ(0, sv.size());<br> =
; ASSERT_EQ(base.data()+2, sv.data());<br> ASSERT_EQ('C', *sv.data())=
;<br><br>sv in isolation only guarantees that [sv.data(), sv.data()+0) is a=
valid range and specifically does not sanction the expression *sv.data().<=
br><br>But sv.data() is value- and type-equivalent to base.data()+2 by the =
specification for string_view.<br><br>And accessing *(base.data()+2) is per=
fectly legitimate.<br><br>So why can't I substitute a value- and type-equiv=
alent subexpression into that dereference expression?<br><br>I'm hoping tha=
t somebody will explain why this is an invalid use of std::string_view as c=
urrently described in <a onmousedown=3D"this.href=3D'https://www.google.com=
/url?q\75https%3A%2F%2Frawgithub.com%2Fgoogle%2Fcxx-std-draft%2Fstring-ref-=
paper%2Fstring_view.html\46sa\75D\46sntz\0751\46usg\75AFQjCNGcbhKwzT7Onkqet=
OLUcnEkWlXaBQ';return true;" onclick=3D"this.href=3D'https://www.google.com=
/url?q\75https%3A%2F%2Frawgithub.com%2Fgoogle%2Fcxx-std-draft%2Fstring-ref-=
paper%2Fstring_view.html\46sa\75D\46sntz\0751\46usg\75AFQjCNGcbhKwzT7Onkqet=
OLUcnEkWlXaBQ';return true;" href=3D"https://rawgithub.com/google/cxx-std-d=
raft/string-ref-paper/string_view.html" target=3D"_blank">https://rawgithub=
..com/google/<wbr>cxx-std-draft/string-ref-<wbr>paper/string_view.html</a>.<=
br><br>As for why I think allowing null sv.data() creates a new requirement=
to check for null sv.data(): If you accept that sv.data() can be use=
ful even though sv.size() is zero---perhaps for nothing more than to calcul=
ate an offset into the original string with sv.data()-base.data()---then it=
becomes necessary to know that sv.data() is not null regardless of whether=
sv.size() is zero so you don't perform pointer arithmetic on a null pointe=
r. Not always, but certainly if you're using sv.data() this way (whic=
h I have found very convenient).<br></div></blockquote><div><br></div><div>=
For the current proposal this should work. Since you can't put a nullptr in=
you can't get a nullptr out and sv.data() - base.data() is defined.</div><=
div>If a string_view would allow null data() then (assuming a string_view i=
s constructible from a nullptr, too) this would be ok too, since no</div><d=
iv>operation on a string_view changes the data pointer and subtracting a nu=
llptr from a nullptr is ok too.</div><div>If a stringview were allowed to b=
e constructed from a nullptr, but data() always returns non-null, then one =
actually has to check for base.data() !=3D null., </div><blockquote cl=
ass=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; =
border-left-color: rgb(204, 204, 204); border-left-width: 1px; border-left-=
style: solid;"><div dir=3D"ltr"><br>My preference is to impose the non-null=
requirement on the string_view type just as it is imposed on std::string, =
rather than have to check it manually. (AFAIK std::string has n=
ever permitted its data() function to return a null pointer, so
I don't see a lot of value in reviewing that decision.)<br><br>Peter<br></=
div></blockquote></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_422_23998461.1390059377973--
.
Author: Peter Bigot <bigotp@acm.org>
Date: Sun, 19 Jan 2014 07:55:32 -0800 (PST)
Raw View
------=_Part_479_22096632.1390146932193
Content-Type: text/plain; charset=UTF-8
On Friday, January 17, 2014 10:19:07 PM UTC-6, Marshall wrote:
>
> On Jan 17, 2014, at 6:13 PM, Miro Knejp <mi...@knejp.de <javascript:>>
> wrote:
>
> >>
> >> - both of these methods are impossible if the presumptions stated above
> "begin() should never return nullptr" and "we don't need a special
> is_null()". Well, not entirely. Of course you could create some bogus
> object and use its address instead of nullptr.
> >>
> > Why not set the string_view to "" in the default constructor?
>
> I believe that this is the current proposal.
>
> However, this requires creating a global variable (which some
> implementations will put in the code segment) for each default constructed
> string_view (yes, some implementations will merge them together in the same
> translation unit).
>
I thought somebody had proposed a "will-probably-work" solution involving
casts of non-zero values to a pointer to avoid the global variable, but
here's another solution I believe is safe and well-defined:
Nothing in the current spec requires that the data() function return the
same value for distinct default-constructed string_view instances. So use
the following data members:
const charT * m_ptr;
union {
size_t m_len;
charT m_nul;
};
and have the default constructor set m_ptr to &m_nul and m_len to 0. The
result is a (unique) empty string reference.
I've tested this by modifying Boost's implementation and it works fine.
Note that only the m_len data member is actually used and is always zero
for the default-constructed value. There's no issue about accessing the
other union member because when size() is zero you can't legitimately
dereference data() unless you know from construction that it's pointing
into a non-empty range (and in this case it doesn't).
Peter
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_479_22096632.1390146932193
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Friday, January 17, 2014 10:19:07 PM UTC-6, Marshall wr=
ote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex=
;border-left: 1px #ccc solid;padding-left: 1ex;">On Jan 17, 2014, at 6:13 P=
M, Miro Knejp <<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-=
mailto=3D"GJocu11kx9YJ" onmousedown=3D"this.href=3D'javascript:';return tru=
e;" onclick=3D"this.href=3D'javascript:';return true;">mi...@knejp.de</a>&g=
t; wrote:
<br>
<br>>>=20
<br>>> - both of these methods are impossible if the presumptions sta=
ted above "begin() should never return nullptr" and "we don't need a specia=
l is_null()". Well, not entirely. Of course you could create some bogus obj=
ect and use its address instead of nullptr.
<br>>>=20
<br>> Why not set the string_view to "" in the default constructor?
<br>
<br>I believe that this is the current proposal.
<br>
<br>However, this requires creating a global variable (which some implement=
ations will put in the code segment) for each default constructed string_vi=
ew (yes, some implementations will merge them together in the same translat=
ion unit).
<br></blockquote><div><br>I thought somebody had proposed a "will-probably-=
work" solution involving casts of non-zero values to a pointer to avoid the=
global variable, but here's another solution I believe is safe and well-de=
fined:<br><br>Nothing in the current spec requires that the data() function=
return the same value for distinct default-constructed string_view instanc=
es. So use the following data members:<br><br> const charT * m_=
ptr;<br> union {<br> size_t m_len;<br> &=
nbsp; charT m_nul;<br> };<br><br>and have the default con=
structor set m_ptr to &m_nul and m_len to 0. The result is a (uni=
que) empty string reference.<br><br>I've tested this by modifying Boost's i=
mplementation and it works fine. Note that only the m_len data member=
is actually used and is always zero for the default-constructed value.&nbs=
p; There's no issue about accessing the other union member because when siz=
e() is zero you can't legitimately dereference data() unless you know from =
construction that it's pointing into a non-empty range (and in this case it=
doesn't).<br><br>Peter<br></div></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_479_22096632.1390146932193--
.
Author: Magnus Fromreide <magfr@lysator.liu.se>
Date: Sun, 19 Jan 2014 18:44:34 +0100
Raw View
On Sun, Jan 19, 2014 at 07:55:32AM -0800, Peter Bigot wrote:
> On Friday, January 17, 2014 10:19:07 PM UTC-6, Marshall wrote:
> >
> > On Jan 17, 2014, at 6:13 PM, Miro Knejp <mi...@knejp.de <javascript:>>
> > wrote:
> >
> > >>
> > >> - both of these methods are impossible if the presumptions stated above
> > "begin() should never return nullptr" and "we don't need a special
> > is_null()". Well, not entirely. Of course you could create some bogus
> > object and use its address instead of nullptr.
> > >>
> > > Why not set the string_view to "" in the default constructor?
> >
> > I believe that this is the current proposal.
> >
> > However, this requires creating a global variable (which some
> > implementations will put in the code segment) for each default constructed
> > string_view (yes, some implementations will merge them together in the same
> > translation unit).
> >
>
> I thought somebody had proposed a "will-probably-work" solution involving
> casts of non-zero values to a pointer to avoid the global variable, but
> here's another solution I believe is safe and well-defined:
>
> Nothing in the current spec requires that the data() function return the
> same value for distinct default-constructed string_view instances. So use
> the following data members:
>
> const charT * m_ptr;
> union {
> size_t m_len;
> charT m_nul;
> };
>
> and have the default constructor set m_ptr to &m_nul and m_len to 0. The
> result is a (unique) empty string reference.
>
> I've tested this by modifying Boost's implementation and it works fine.
> Note that only the m_len data member is actually used and is always zero
> for the default-constructed value. There's no issue about accessing the
> other union member because when size() is zero you can't legitimately
> dereference data() unless you know from construction that it's pointing
> into a non-empty range (and in this case it doesn't).
I have thought in a similar direction, but the problem is if you have two
string_view's, s1 and s2. Assume that s1 i empty, does the statement
s2 = s1; imply that s2.data() == s1.data()?
Then what happens if s1 is deallocated and it's memory is returned to the
system, won't s2.m_ptr then hold an illegal pointer value, one of those
where even loading it could trigger a hardware trap on some architectures.
/MF
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Peter Bigot <bigotp@acm.org>
Date: Sun, 19 Jan 2014 12:31:19 -0600
Raw View
--001a11c24dbc42210b04f056fb51
Content-Type: text/plain; charset=ISO-8859-1
On Sun, Jan 19, 2014 at 11:44 AM, Magnus Fromreide <magfr@lysator.liu.se>wrote:
> On Sun, Jan 19, 2014 at 07:55:32AM -0800, Peter Bigot wrote:
> > On Friday, January 17, 2014 10:19:07 PM UTC-6, Marshall wrote:
> > >
> > > On Jan 17, 2014, at 6:13 PM, Miro Knejp <mi...@knejp.de <javascript:>>
> > > wrote:
> > >
> > > >>
> > > >> - both of these methods are impossible if the presumptions stated
> above
> > > "begin() should never return nullptr" and "we don't need a special
> > > is_null()". Well, not entirely. Of course you could create some bogus
> > > object and use its address instead of nullptr.
> > > >>
> > > > Why not set the string_view to "" in the default constructor?
> > >
> > > I believe that this is the current proposal.
> > >
> > > However, this requires creating a global variable (which some
> > > implementations will put in the code segment) for each default
> constructed
> > > string_view (yes, some implementations will merge them together in the
> same
> > > translation unit).
> > >
> >
> > I thought somebody had proposed a "will-probably-work" solution involving
> > casts of non-zero values to a pointer to avoid the global variable, but
> > here's another solution I believe is safe and well-defined:
> >
> > Nothing in the current spec requires that the data() function return the
> > same value for distinct default-constructed string_view instances. So
> use
> > the following data members:
> >
> > const charT * m_ptr;
> > union {
> > size_t m_len;
> > charT m_nul;
> > };
> >
> > and have the default constructor set m_ptr to &m_nul and m_len to 0. The
> > result is a (unique) empty string reference.
> >
> > I've tested this by modifying Boost's implementation and it works fine.
> > Note that only the m_len data member is actually used and is always zero
> > for the default-constructed value. There's no issue about accessing the
> > other union member because when size() is zero you can't legitimately
> > dereference data() unless you know from construction that it's pointing
> > into a non-empty range (and in this case it doesn't).
>
> I have thought in a similar direction, but the problem is if you have two
> string_view's, s1 and s2. Assume that s1 i empty, does the statement
> s2 = s1; imply that s2.data() == s1.data()?
>
> Then what happens if s1 is deallocated and it's memory is returned to the
> system, won't s2.m_ptr then hold an illegal pointer value, one of those
> where even loading it could trigger a hardware trap on some architectures.
>
In my approach I detect in the assignment operator and copy constructor
whether the RHS is default-constructed, and if so invoke clear() on the
LHS/new instance. So in all cases either the reference is to a sequence
outside the instance, or it's an empty default-constructed (cleared)
instance where data() is a non-dereferenceable pointer to an internal charT
object: no cross-object pointers.
Now that you point it out, this does result in behavior non-conformant with
the current draft specification for the copy constructor and operator=
which are specified as =default.
On further reflection it'd better to store a null pointer in m_ptr to
represent a default-constructed value but to return &m_nul from data() when
m_ptr is null. Then the default implementations are retained. This still
means that data() will be always be non-null, but sv1.data() will not
compare equal to sv2.data() if one or both of the instances have been
cleared/default-constructed. (sv1 == sv2 will still hold, of course.)
Does that address the objection?
Peter
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a11c24dbc42210b04f056fb51
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On S=
un, Jan 19, 2014 at 11:44 AM, Magnus Fromreide <span dir=3D"ltr"><<a hre=
f=3D"mailto:magfr@lysator.liu.se" target=3D"_blank">magfr@lysator.liu.se</a=
>></span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div>On Sun, Jan 19, 2014 at 07:55:32AM -080=
0, Peter Bigot wrote:<br>
> On Friday, January 17, 2014 10:19:07 PM UTC-6, Marshall wrote:<br>
> ><br>
</div>> > On Jan 17, 2014, at 6:13 PM, Miro Knejp <<a href=3D"mail=
to:mi...@knejp.de" target=3D"_blank">mi...@knejp.de</a> <javascript:>=
><br>
<div><div>> > wrote:<br>
> ><br>
> > >><br>
> > >> - both of these methods are impossible if the presumptio=
ns stated above<br>
> > "begin() should never return nullptr" and "we don&=
#39;t need a special<br>
> > is_null()". Well, not entirely. Of course you could create s=
ome bogus<br>
> > object and use its address instead of nullptr.<br>
> > >><br>
> > > Why not set the string_view to "" in the default c=
onstructor?<br>
> ><br>
> > I believe that this is the current proposal.<br>
> ><br>
> > However, this requires creating a global variable (which some<br>
> > implementations will put in the code segment) for each default co=
nstructed<br>
> > string_view (yes, some implementations will merge them together i=
n the same<br>
> > translation unit).<br>
> ><br>
><br>
> I thought somebody had proposed a "will-probably-work" solut=
ion involving<br>
> casts of non-zero values to a pointer to avoid the global variable, bu=
t<br>
> here's another solution I believe is safe and well-defined:<br>
><br>
> Nothing in the current spec requires that the data() function return t=
he<br>
> same value for distinct default-constructed string_view instances. =A0=
So use<br>
> the following data members:<br>
><br>
> =A0 const charT * m_ptr;<br>
> =A0 union {<br>
> =A0 =A0 =A0size_t m_len;<br>
> =A0 =A0 =A0charT m_nul;<br>
> =A0 };<br>
><br>
> and have the default constructor set m_ptr to &m_nul and m_len to =
0. =A0The<br>
> result is a (unique) empty string reference.<br>
><br>
> I've tested this by modifying Boost's implementation and it wo=
rks fine.<br>
> Note that only the m_len data member is actually used and is always ze=
ro<br>
> for the default-constructed value. =A0There's no issue about acces=
sing the<br>
> other union member because when size() is zero you can't legitimat=
ely<br>
> dereference data() unless you know from construction that it's poi=
nting<br>
> into a non-empty range (and in this case it doesn't).<br>
<br>
</div></div>I have thought in a similar direction, but the problem is if yo=
u have two<br>
string_view's, s1 and s2. Assume that s1 i empty, does the statement<br=
>
s2 =3D s1; imply that s2.data() =3D=3D s1.data()?<br>
<br>
Then what happens if s1 is deallocated and it's memory is returned to t=
he<br>
system, won't s2.m_ptr then hold an illegal pointer value, one of those=
<br>
where even loading it could trigger a hardware trap on some architectures.<=
br></blockquote><div><br></div><div>In my approach I detect in the assignme=
nt operator and copy constructor whether the RHS is default-constructed, an=
d if so invoke clear() on the LHS/new instance.=A0 So in all cases either t=
he reference is to a sequence outside the instance, or it's an empty de=
fault-constructed (cleared) instance where data() is a non-dereferenceable =
pointer to an internal charT object: no cross-object pointers.<br>
<br></div><div>Now that you point it out, this does result in behavior non-=
conformant with the current draft specification for the copy constructor an=
d operator=3D which are specified as =3Ddefault.<br><br>On further reflecti=
on it'd better to store a null pointer in m_ptr to represent a default-=
constructed value but to return &m_nul from data() when m_ptr is null.=
=A0 Then the default implementations are retained.=A0 This still means that=
data() will be always be non-null, but sv1.data() will not compare equal t=
o sv2.data() if one or both of the instances have been cleared/default-cons=
tructed.=A0 (sv1 =3D=3D sv2 will still hold, of course.)<br>
<br></div><div>Does that address the objection?<br></div><div><br></div><di=
v>Peter<br></div><br></div></div></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--001a11c24dbc42210b04f056fb51--
.
Author: gornishanov@gmail.com
Date: Sun, 19 Jan 2014 10:31:58 -0800 (PST)
Raw View
------=_Part_401_757183.1390156318178
Content-Type: text/plain; charset=UTF-8
I did not propose using unspecialized optional. I suggested to add
specialization of optional<basic_string_view<...>> to string_view header.
Thus any use of optional<string_view> will pick up specialized version that
can have constructors that you desire.
I think it is beneficial to not to roll nullability into
string_view. optional is The Way to make type nullable and where possible,
one can use specialized optional to add additional constructors and/or
provide more efficient implementation than default optional.
On Saturday, January 18, 2014 7:30:17 AM UTC-8, Alexander Bolz wrote:
> Am Samstag, 18. Januar 2014 00:10:41 UTC+1 schrieb gorni...@gmail.com:
>>
>> What if string_view provides a specialization for optional<string_view<>>?
>>
>> That way optional<string_view> can be implemented very efficiently by
>> checking if sv.begin() == nullptr and does not consume any extra storage.
>> An extra benefit is that we have clear distinction between nullable types
>> (optional<T>) and regular types, int, vector, string_view, etc.
>>
>> Will this solution satisfy the original poster?
>>
>
> An (unspecialized) optional<string_view> is not always an option. E.g. I
> can't simply change a function like
>
> void f(char const* s) {}
>
> to
>
> void f(optional<string_view> s) {}
>
> because I can no longer write f("hello"). So the specialization should be
> implicitly constructible from a char array.
> And then an optional<string_view> constructed from a nullptr should be an
> uninitialized optional since there
> are no preconditions on f, I should be able to write
> f(getenv("not-an-env-var")).
>
>
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_401_757183.1390156318178
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>I did not propose using unspecialized optional. I sug=
gested to add specialization of optional<basic_string_view<...>>=
; to string_view header. Thus any use of optional<string_view> will p=
ick up specialized version that can have constructors that you desire.</div=
><div><br></div><div>I think it is beneficial to not to roll nullability in=
to string_view. optional is The Way to make type nullable and where po=
ssible, one can use specialized optional to add additional constructors and=
/or provide more efficient implementation than default optional.</div><div>=
<br><br>On Saturday, January 18, 2014 7:30:17 AM UTC-8, Alexander Bolz wrot=
e:</div><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8e=
x; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-wi=
dth: 1px; border-left-style: solid;"><div dir=3D"ltr">Am Samstag, 18. Janua=
r 2014 00:10:41 UTC+1 schrieb <a>gorni...@gmail.com</a>:<blockquote class=
=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; bor=
der-left-color: rgb(204, 204, 204); border-left-width: 1px; border-left-sty=
le: solid;"><div dir=3D"ltr"><div>What if string_view provides a specializa=
tion for optional<string_view<>>?</div><div><br></div><div>That=
way optional<string_view> can be implemented very efficiently by che=
cking if sv.begin() =3D=3D nullptr and does not consume any extra storage. =
An extra benefit is that we have clear distinction between nullable types (=
optional<T>) and regular types, int, vector, string_view, etc.</div><=
div><br></div><div>Will this solution satisfy the original poster?<br></div=
></div></blockquote><div><br></div><div>An (unspecialized) optional<stri=
ng_view> is not always an option. E.g. I can't simply change a func=
tion like</div><div><br></div><div>void f(char const* s) {}</div><div><br><=
/div><div>to</div><div><br></div><div>void f(optional<string_view> s)=
{}</div><div><br></div><div>because I can no longer write f("hello"). So t=
he specialization should be implicitly constructible from a char array=
..</div><div>And then an optional<string_view> constructed from a null=
ptr should be an uninitialized optional since there</div><div>are no precon=
ditions on f, I should be able to write f(getenv("not-an-env-var")).</div><=
div><br></div></div></blockquote></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_401_757183.1390156318178--
.
Author: "Paul A. Tessier" <phernost@gmail.com>
Date: Sun, 19 Jan 2014 14:00:43 -0500
Raw View
On 01/19/2014 12:44 PM, Magnus Fromreide wrote:
> On Sun, Jan 19, 2014 at 07:55:32AM -0800, Peter Bigot wrote:
>> On Friday, January 17, 2014 10:19:07 PM UTC-6, Marshall wrote:
>>> On Jan 17, 2014, at 6:13 PM, Miro Knejp <mi...@knejp.de <javascript:>>
>>> wrote:
>>>
>>>>> - both of these methods are impossible if the presumptions stated above
>>> "begin() should never return nullptr" and "we don't need a special
>>> is_null()". Well, not entirely. Of course you could create some bogus
>>> object and use its address instead of nullptr.
>>>> Why not set the string_view to "" in the default constructor?
>>> I believe that this is the current proposal.
>>>
>>> However, this requires creating a global variable (which some
>>> implementations will put in the code segment) for each default constructed
>>> string_view (yes, some implementations will merge them together in the same
>>> translation unit).
>>>
>> I thought somebody had proposed a "will-probably-work" solution involving
>> casts of non-zero values to a pointer to avoid the global variable, but
>> here's another solution I believe is safe and well-defined:
>>
>> Nothing in the current spec requires that the data() function return the
>> same value for distinct default-constructed string_view instances. So use
>> the following data members:
>>
>> const charT * m_ptr;
>> union {
>> size_t m_len;
>> charT m_nul;
>> };
>>
>> and have the default constructor set m_ptr to &m_nul and m_len to 0. The
>> result is a (unique) empty string reference.
>>
>> I've tested this by modifying Boost's implementation and it works fine.
>> Note that only the m_len data member is actually used and is always zero
>> for the default-constructed value. There's no issue about accessing the
>> other union member because when size() is zero you can't legitimately
>> dereference data() unless you know from construction that it's pointing
>> into a non-empty range (and in this case it doesn't).
> I have thought in a similar direction, but the problem is if you have two
> string_view's, s1 and s2. Assume that s1 i empty, does the statement
> s2 = s1; imply that s2.data() == s1.data()?
>
> Then what happens if s1 is deallocated and it's memory is returned to the
> system, won't s2.m_ptr then hold an illegal pointer value, one of those
> where even loading it could trigger a hardware trap on some architectures.
>
> /MF
>
If s1 and s2 are empty, only access to the metadata is rational. Using
operator[], front(), back(), etc. will produce undefined behavior.
s1.data() and s2.data() are irrelevant because, it points to the
beginning of a range of zero length. One could just as easily set
data() to null or some random value, when the string_view becomes empty
but, such actions are unneeded. The equality comparison is based on the
equality of the two ordered sets of characters from s1 and s2. All
empty views are equally empty and does not imply ( s2.data() ==
s1.data() ), just as ( s1 == s2 ) does not imply that ( &s1 == &s2 ).
If &s1 is deallocated and falls into a protected segment, any access to
it will trap, just like any other object. If both s1 and s2 where
referencing a string that was deallocated before they both became empty
then, both would trap, unless data() is randomized or set to some safe
location as I mentioned above but, this would be pointless as accessing
the referenced string of an empty view is undefined behavior.
To me the prevention of null being returned by data() is just an
artifact inherited from std::string. It seem like an early and
incomplete error check. You could also argue that all unreachable
segments be restricted.
If string_view was only a range of a std:string, forwarding all
std::string's warts through the interface would not be completely
unexpected. Especially when the wrapper is such a lightweight class.
Yet, string_view serves a wider purpose therefore, those warts should
ignored. I argue that std::string's interface should be relaxed and, not
that string_view's be restricted.
Consider std::array< char, 0 >. It's data() will return null, and the
rest of it's members behave as rationally. I see no reason for
string_view not to behave in a similar fashion. While std:string may
never return null for it's data(), it is inconsequential as string_view
maybe constructed from other sources.
Having a is_null() seems excessive. data() should be allowed to be null,
as this seems the simplest solution. Following the behavior of
std::array< char, 0 > seems to solve many of the other problems in the
interface being unable to handle data() and begin() being null.
While string_view is modeled after std::string's interface, the newer
std::array interface seems more flexible and also solves the default
empty initialization problem. Besides, any object that behaves
rationally when zeroed out, say by memset, is a plus.
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Magnus Fromreide <magfr@lysator.liu.se>
Date: Sun, 19 Jan 2014 20:22:40 +0100
Raw View
On Sun, Jan 19, 2014 at 12:31:19PM -0600, Peter Bigot wrote:
> On Sun, Jan 19, 2014 at 11:44 AM, Magnus Fromreide <magfr@lysator.liu.se>wrote:
>
> > On Sun, Jan 19, 2014 at 07:55:32AM -0800, Peter Bigot wrote:
> > > On Friday, January 17, 2014 10:19:07 PM UTC-6, Marshall wrote:
> > > >
> >
> > I have thought in a similar direction, but the problem is if you have two
> > string_view's, s1 and s2. Assume that s1 i empty, does the statement
> > s2 = s1; imply that s2.data() == s1.data()?
> >
> > Then what happens if s1 is deallocated and it's memory is returned to the
> > system, won't s2.m_ptr then hold an illegal pointer value, one of those
> > where even loading it could trigger a hardware trap on some architectures.
> >
>
> In my approach I detect in the assignment operator and copy constructor
> whether the RHS is default-constructed, and if so invoke clear() on the
> LHS/new instance. So in all cases either the reference is to a sequence
> outside the instance, or it's an empty default-constructed (cleared)
> instance where data() is a non-dereferenceable pointer to an internal charT
> object: no cross-object pointers.
>
> Now that you point it out, this does result in behavior non-conformant with
> the current draft specification for the copy constructor and operator=
> which are specified as =default.
>
> On further reflection it'd better to store a null pointer in m_ptr to
> represent a default-constructed value but to return &m_nul from data() when
> m_ptr is null. Then the default implementations are retained. This still
> means that data() will be always be non-null, but sv1.data() will not
> compare equal to sv2.data() if one or both of the instances have been
> cleared/default-constructed. (sv1 == sv2 will still hold, of course.)
>
> Does that address the objection?
The check at copy time seems to solve the problem.
The use of null as a flag value seems to interfere with the "allow null
string_views" and "have an optimized optional<string_view>" proposals
as both allow null's for other purposes.
/MF
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Alexander Bolz <abolz.lists@gmail.com>
Date: Sun, 19 Jan 2014 12:31:45 -0800 (PST)
Raw View
------=_Part_203_8166438.1390163505400
Content-Type: text/plain; charset=UTF-8
Am Sonntag, 19. Januar 2014 19:31:58 UTC+1 schrieb gorni...@gmail.com:
> I did not propose using unspecialized optional. I suggested to add
> specialization of optional<basic_string_view<...>> to string_view header.
> Thus any use of optional<string_view> will pick up specialized version that
> can have constructors that you desire.
>
Ok. But an unspecialized optional<string_view> is very different from a
nullable string_view.
And a specialized optional<string_view> would be very different from an
optional<T>.
I need to make sure that the specialized version is constructible from a
nullptr and
and then constructing a disengaged optional. Then what should
template <class... Args> constexpr explicit optional(in_place_t, Args&&...
args);
Postconditions: *this is engaged.
do?
What should the relational operators of this specialization look like? I
would like to be
able to write something like
void f(optional<string_view> s)
{
if (s == "abc") {}
if (s < "abc") {}
}
The default relational operators explicitly handle the nullness of the
optional. I don't want
that. I'd expect a disengaged optional<string_view> is like an empty
string. So I write specialized
versions for these relational operators which do exactly that. That would
be very confusing for
general algorithms which just compare optional<T>'s.
>
> I think it is beneficial to not to roll nullability into
> string_view. optional is The Way to make type nullable and where possible,
> one can use specialized optional to add additional constructors and/or
> provide more efficient implementation than default optional.
>
>
> On Saturday, January 18, 2014 7:30:17 AM UTC-8, Alexander Bolz wrote:
>
>> Am Samstag, 18. Januar 2014 00:10:41 UTC+1 schrieb gorni...@gmail.com:
>>>
>>> What if string_view provides a specialization for
>>> optional<string_view<>>?
>>>
>>> That way optional<string_view> can be implemented very efficiently by
>>> checking if sv.begin() == nullptr and does not consume any extra storage.
>>> An extra benefit is that we have clear distinction between nullable types
>>> (optional<T>) and regular types, int, vector, string_view, etc.
>>>
>>> Will this solution satisfy the original poster?
>>>
>>
>> An (unspecialized) optional<string_view> is not always an option. E.g. I
>> can't simply change a function like
>>
>> void f(char const* s) {}
>>
>> to
>>
>> void f(optional<string_view> s) {}
>>
>> because I can no longer write f("hello"). So the specialization should be
>> implicitly constructible from a char array.
>> And then an optional<string_view> constructed from a nullptr should be an
>> uninitialized optional since there
>> are no preconditions on f, I should be able to write
>> f(getenv("not-an-env-var")).
>>
>>
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_203_8166438.1390163505400
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Am Sonntag, 19. Januar 2014 19:31:58 UTC+1 schrieb gorni..=
..@gmail.com:<br><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"><div>I did not propose using unspecialized optional. I suggested to add =
specialization of optional<basic_string_view<...<wbr>>> to stri=
ng_view header. Thus any use of optional<string_view> will pick up sp=
ecialized version that can have constructors that you desire.</div></div></=
blockquote><div><br></div><div>Ok. But an unspecialized optional<string_=
view> is very different from a nullable string_view.</div><div>And a spe=
cialized optional<string_view> would be very different from an option=
al<T>.</div><div><br></div><div>I need to make sure that the speciali=
zed version is constructible from a nullptr and</div><div>and then construc=
ting a disengaged optional. Then what should</div><div><br></div><div><font=
face=3D"courier new, monospace">template <class... Args> constexpr e=
xplicit optional(in_place_t, Args&&... args);</font></div><div><spa=
n style=3D"font-family: 'courier new', monospace;">Postconditions: *this is=
engaged.</span><br></div><div><br></div><div>do?</div><div><br></div><div>=
What should the relational operators of this specialization look like? I wo=
uld like to be</div><div>able to write something like</div><div><br></div><=
div><font face=3D"courier new, monospace">void f(optional<string_view>=
; s)</font></div><div><font face=3D"courier new, monospace">{</font></div><=
div><font face=3D"courier new, monospace"> if (s =3D=3D "abc") {}</fo=
nt></div><div><font face=3D"courier new, monospace"> if (s < "abc"=
) {}</font></div><div><font face=3D"courier new, monospace">}</font></div><=
div><br></div><div>The default relational operators explicitly handle the n=
ullness of the optional. I don't want</div><div>that. I'd expect a disengag=
ed optional<string_view> is like an empty string. So I write speciali=
zed</div><div>versions for these relational operators which do exactly that=
.. That would be very confusing for</div><div>general algorithms which just =
compare optional<T>'s.</div><div> <br></div><blockquote class=3D=
"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc s=
olid;padding-left: 1ex;"><div dir=3D"ltr"><div><br></div><div>I think it is=
beneficial to not to roll nullability into string_view. optional is T=
he Way to make type nullable and where possible, one can use specialized op=
tional to add additional constructors and/or provide more efficient impleme=
ntation than default optional.</div><div><br><br>On Saturday, January 18, 2=
014 7:30:17 AM UTC-8, Alexander Bolz wrote:</div><blockquote class=3D"gmail=
_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-colo=
r:rgb(204,204,204);border-left-width:1px;border-left-style:solid"><div dir=
=3D"ltr">Am Samstag, 18. Januar 2014 00:10:41 UTC+1 schrieb <a>gorni...@gma=
il.com</a>:<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.=
8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1=
px;border-left-style:solid"><div dir=3D"ltr"><div>What if string_view provi=
des a specialization for optional<string_view<>>?</div><div><br=
></div><div>That way optional<string_view> can be implemented very ef=
ficiently by checking if sv.begin() =3D=3D nullptr and does not consume any=
extra storage. An extra benefit is that we have clear distinction between =
nullable types (optional<T>) and regular types, int, vector, string_v=
iew, etc.</div><div><br></div><div>Will this solution satisfy the original =
poster?<br></div></div></blockquote><div><br></div><div>An (unspecialized) =
optional<string_view> is not always an option. E.g. I can't simply&nb=
sp;change a function like</div><div><br></div><div>void f(char const* s) {}=
</div><div><br></div><div>to</div><div><br></div><div>void f(optional<st=
ring_view> s) {}</div><div><br></div><div>because I can no longer write =
f("hello"). So the specialization should be implicitly constructible from&n=
bsp;a char array.</div><div>And then an optional<string_view> constru=
cted from a nullptr should be an uninitialized optional since there</div><d=
iv>are no preconditions on f, I should be able to write f(getenv("not-an-en=
v-var")).</div><div><br></div></div></blockquote></div></blockquote></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_203_8166438.1390163505400--
.
Author: Alexander Bolz <abolz.lists@gmail.com>
Date: Sun, 19 Jan 2014 12:37:59 -0800 (PST)
Raw View
------=_Part_346_17237154.1390163879753
Content-Type: text/plain; charset=UTF-8
Am Sonntag, 19. Januar 2014 20:00:43 UTC+1 schrieb Paul Tessier:
> On 01/19/2014 12:44 PM, Magnus Fromreide wrote:
> > On Sun, Jan 19, 2014 at 07:55:32AM -0800, Peter Bigot wrote:
> >> On Friday, January 17, 2014 10:19:07 PM UTC-6, Marshall wrote:
> >>> On Jan 17, 2014, at 6:13 PM, Miro Knejp <mi...@knejp.de<javascript:>>
> >>> wrote:
> >>>
> >>>>> - both of these methods are impossible if the presumptions stated
> above
> >>> "begin() should never return nullptr" and "we don't need a special
> >>> is_null()". Well, not entirely. Of course you could create some bogus
> >>> object and use its address instead of nullptr.
> >>>> Why not set the string_view to "" in the default constructor?
> >>> I believe that this is the current proposal.
> >>>
> >>> However, this requires creating a global variable (which some
> >>> implementations will put in the code segment) for each default
> constructed
> >>> string_view (yes, some implementations will merge them together in the
> same
> >>> translation unit).
> >>>
> >> I thought somebody had proposed a "will-probably-work" solution
> involving
> >> casts of non-zero values to a pointer to avoid the global variable, but
> >> here's another solution I believe is safe and well-defined:
> >>
> >> Nothing in the current spec requires that the data() function return
> the
> >> same value for distinct default-constructed string_view instances. So
> use
> >> the following data members:
> >>
> >> const charT * m_ptr;
> >> union {
> >> size_t m_len;
> >> charT m_nul;
> >> };
> >>
> >> and have the default constructor set m_ptr to &m_nul and m_len to 0.
> The
> >> result is a (unique) empty string reference.
> >>
> >> I've tested this by modifying Boost's implementation and it works fine.
> >> Note that only the m_len data member is actually used and is always
> zero
> >> for the default-constructed value. There's no issue about accessing
> the
> >> other union member because when size() is zero you can't legitimately
> >> dereference data() unless you know from construction that it's pointing
> >> into a non-empty range (and in this case it doesn't).
> > I have thought in a similar direction, but the problem is if you have
> two
> > string_view's, s1 and s2. Assume that s1 i empty, does the statement
> > s2 = s1; imply that s2.data() == s1.data()?
> >
> > Then what happens if s1 is deallocated and it's memory is returned to
> the
> > system, won't s2.m_ptr then hold an illegal pointer value, one of those
> > where even loading it could trigger a hardware trap on some
> architectures.
> >
> > /MF
> >
>
> If s1 and s2 are empty, only access to the metadata is rational. Using
> operator[], front(), back(), etc. will produce undefined behavior.
> s1.data() and s2.data() are irrelevant because, it points to the
> beginning of a range of zero length. One could just as easily set
> data() to null or some random value, when the string_view becomes empty
> but, such actions are unneeded. The equality comparison is based on the
> equality of the two ordered sets of characters from s1 and s2. All
> empty views are equally empty and does not imply ( s2.data() ==
> s1.data() ), just as ( s1 == s2 ) does not imply that ( &s1 == &s2 ).
>
> If &s1 is deallocated and falls into a protected segment, any access to
> it will trap, just like any other object. If both s1 and s2 where
> referencing a string that was deallocated before they both became empty
> then, both would trap, unless data() is randomized or set to some safe
> location as I mentioned above but, this would be pointless as accessing
> the referenced string of an empty view is undefined behavior.
>
>
> To me the prevention of null being returned by data() is just an
> artifact inherited from std::string. It seem like an early and
> incomplete error check. You could also argue that all unreachable
> segments be restricted.
>
> If string_view was only a range of a std:string, forwarding all
> std::string's warts through the interface would not be completely
> unexpected. Especially when the wrapper is such a lightweight class.
> Yet, string_view serves a wider purpose therefore, those warts should
> ignored. I argue that std::string's interface should be relaxed and, not
> that string_view's be restricted.
>
> Consider std::array< char, 0 >. It's data() will return null, and the
> rest of it's members behave as rationally.
This is not correct. I just looked it up in N3797:
23.3.2.8. says "begin() == end() == unique value. The return value of data()is unspecified"
> I see no reason for
> string_view not to behave in a similar fashion. While std:string may
> never return null for it's data(), it is inconsequential as string_view
> maybe constructed from other sources.
>
> Having a is_null() seems excessive. data() should be allowed to be null,
> as this seems the simplest solution. Following the behavior of
> std::array< char, 0 > seems to solve many of the other problems in the
> interface being unable to handle data() and begin() being null.
>
> While string_view is modeled after std::string's interface, the newer
> std::array interface seems more flexible and also solves the default
> empty initialization problem. Besides, any object that behaves
> rationally when zeroed out, say by memset, is a plus.
>
>
>
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_346_17237154.1390163879753
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Am Sonntag, 19. Januar 2014 20:00:43 UTC+1 schrieb Paul Te=
ssier:<br><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 01/19/2014 12:44 =
PM, Magnus Fromreide wrote:
<br>> On Sun, Jan 19, 2014 at 07:55:32AM -0800, Peter Bigot wrote:
<br>>> On Friday, January 17, 2014 10:19:07 PM UTC-6, Marshall wrote:
<br>>>> On Jan 17, 2014, at 6:13 PM, Miro Knejp <<a>mi...@knejp=
..de</a> <javascript:>>
<br>>>> wrote:
<br>>>>
<br>>>>>> - both of these methods are impossible if the pres=
umptions stated above
<br>>>> "begin() should never return nullptr" and "we don't need a=
special
<br>>>> is_null()". Well, not entirely. Of course you could create=
some bogus
<br>>>> object and use its address instead of nullptr.
<br>>>>> Why not set the string_view to "" in the default const=
ructor?
<br>>>> I believe that this is the current proposal.
<br>>>>
<br>>>> However, this requires creating a global variable (which s=
ome
<br>>>> implementations will put in the code segment) for each def=
ault constructed
<br>>>> string_view (yes, some implementations will merge them tog=
ether in the same
<br>>>> translation unit).
<br>>>>
<br>>> I thought somebody had proposed a "will-probably-work" solutio=
n involving
<br>>> casts of non-zero values to a pointer to avoid the global vari=
able, but
<br>>> here's another solution I believe is safe and well-defined:
<br>>>
<br>>> Nothing in the current spec requires that the data() function =
return the
<br>>> same value for distinct default-constructed string_view instan=
ces. So use
<br>>> the following data members:
<br>>>
<br>>> const charT * m_ptr;
<br>>> union {
<br>>> size_t m_len;
<br>>> charT m_nul;
<br>>> };
<br>>>
<br>>> and have the default constructor set m_ptr to &m_nul and m=
_len to 0. The
<br>>> result is a (unique) empty string reference.
<br>>>
<br>>> I've tested this by modifying Boost's implementation and it wo=
rks fine.
<br>>> Note that only the m_len data member is actually used and is a=
lways zero
<br>>> for the default-constructed value. There's no issue abou=
t accessing the
<br>>> other union member because when size() is zero you can't legit=
imately
<br>>> dereference data() unless you know from construction that it's=
pointing
<br>>> into a non-empty range (and in this case it doesn't).
<br>> I have thought in a similar direction, but the problem is if you h=
ave two
<br>> string_view's, s1 and s2. Assume that s1 i empty, does the stateme=
nt
<br>> s2 =3D s1; imply that s2.data() =3D=3D s1.data()?
<br>>
<br>> Then what happens if s1 is deallocated and it's memory is returned=
to the
<br>> system, won't s2.m_ptr then hold an illegal pointer value, one of =
those
<br>> where even loading it could trigger a hardware trap on some archit=
ectures.
<br>>
<br>> /MF
<br>>
<br>
<br>If s1 and s2 are empty, only access to the metadata is rational. Using=
=20
<br>operator[], front(), back(), etc. will produce undefined behavior.
<br>s1.data() and s2.data() are irrelevant because, it points to the=20
<br>beginning of a range of zero length. One could just as easily set=
=20
<br>data() to null or some random value, when the string_view becomes empty=
=20
<br>but, such actions are unneeded. The equality comparison is based =
on the=20
<br>equality of the two ordered sets of characters from s1 and s2. Al=
l=20
<br>empty views are equally empty and does not imply ( s2.data() =3D=3D=20
<br>s1.data() ), just as ( s1 =3D=3D s2 ) does not imply that ( &s1 =3D=
=3D &s2 ).
<br>
<br>If &s1 is deallocated and falls into a protected segment, any acces=
s to=20
<br>it will trap, just like any other object. If both s1 and s2 where=
=20
<br>referencing a string that was deallocated before they both became empty=
=20
<br>then, both would trap, unless data() is randomized or set to some safe=
=20
<br>location as I mentioned above but, this would be pointless as accessing=
=20
<br>the referenced string of an empty view is undefined behavior.
<br>
<br>
<br>To me the prevention of null being returned by data() is just an=20
<br>artifact inherited from std::string. It seem like an early and=20
<br>incomplete error check. You could also argue that all unreachable=
=20
<br>segments be restricted.
<br>
<br>If string_view was only a range of a std:string, forwarding all=20
<br>std::string's warts through the interface would not be completely=20
<br>unexpected. Especially when the wrapper is such a lightweight cla=
ss.=20
<br>Yet, string_view serves a wider purpose therefore, those warts should=
=20
<br>ignored. I argue that std::string's interface should be relaxed and, no=
t=20
<br>that string_view's be restricted.
<br>
<br>Consider std::array< char, 0 >. It's data() will return nul=
l, and the=20
<br>rest of it's members behave as rationally. </blockquote><div><br>=
</div><div>This is not correct. I just looked it up in N3797:</div><div>23.=
3.2.8. says "<font face=3D"courier new, monospace">begin() =3D=3D end() =3D=
=3D</font> unique value. The return value of <font face=3D"courier new, mon=
ospace">data()</font> is unspecified"<br></div><div> </div><blockquote=
class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1=
px #ccc solid;padding-left: 1ex;">I see no reason for=20
<br>string_view not to behave in a similar fashion. While std:string =
may=20
<br>never return null for it's data(), it is inconsequential as string_view=
=20
<br>maybe constructed from other sources.
<br>
<br>Having a is_null() seems excessive. data() should be allowed to be null=
,=20
<br>as this seems the simplest solution. Following the behavior of=20
<br>std::array< char, 0 > seems to solve many of the other problems i=
n the=20
<br>interface being unable to handle data() and begin() being null.
<br>
<br>While string_view is modeled after std::string's interface, the newer=
=20
<br>std::array interface seems more flexible and also solves the default=20
<br>empty initialization problem. Besides, any object that behaves=20
<br>rationally when zeroed out, say by memset, is a plus.
<br>
<br>
<br></blockquote></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_346_17237154.1390163879753--
.
Author: Nevin Liber <nevin@eviloverlord.com>
Date: Sun, 19 Jan 2014 14:37:28 -0600
Raw View
--001a11c3841ad0128e04f058c04f
Content-Type: text/plain; charset=ISO-8859-1
On 19 January 2014 14:31, Alexander Bolz <abolz.lists@gmail.com> wrote:
> Ok. But an unspecialized optional<string_view> is very different from a
> nullable string_view.
> And a specialized optional<string_view> would be very different from an
> optional<T>.
>
Which would be enough for me to vote strongly against this. Learn from
vector<bool>... (bad name for a useful class)
>
> --
Nevin ":-)" Liber <mailto:nevin@eviloverlord.com> (847) 691-1404
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a11c3841ad0128e04f058c04f
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On 19 January 2014 14:31, Alexander Bolz <span dir=3D"ltr"=
><<a href=3D"mailto:abolz.lists@gmail.com" target=3D"_blank">abolz.lists=
@gmail.com</a>></span> wrote:<br><div class=3D"gmail_extra"><div class=
=3D"gmail_quote">
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Ok. But an unspecializ=
ed optional<string_view> is very different from a nullable string_vie=
w.</div>
<div>And a specialized optional<string_view> would be very different =
from an optional<T>.</div></div></blockquote><div><br></div><div>Whic=
h would be enough for me to vote strongly against this. =A0Learn from vecto=
r<bool>... (bad name for a useful class)</div>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><br></div></div></bloc=
kquote></div>-- <br>=A0Nevin ":-)" Liber=A0 <mailto:<a href=3D=
"mailto:nevin@eviloverlord.com" target=3D"_blank">nevin@eviloverlord.com</a=
>>=A0 (847) 691-1404
</div></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--001a11c3841ad0128e04f058c04f--
.
Author: Miro Knejp <miro@knejp.de>
Date: Sun, 19 Jan 2014 22:08:39 +0100
Raw View
This is a multi-part message in MIME format.
--------------010900020006080609010601
Content-Type: text/plain; charset=UTF-8; format=flowed
> Ok. But an unspecialized optional<string_view> is very different from
> a nullable string_view.
> And a specialized optional<string_view> would be very different from
> an optional<T>.
What is the difference between a "nullable string_view" and an
"optional<string_view>"? Not in terms of syntax but semantics. That's
what must be the same. Both give you means of marking the string_view as
*null* and both cause errors/UB if accessing such a string.
If done properly the only difference between optional<T> and
optional<string_view> is sizeof() by optimizing away a bool member and
use .data() == nullptr for determining whether the optional is engaged
or not. As long as string_view does not accept null this distinction can
be made.
> I need to make sure that the specialized version is constructible from
> a nullptr and
> and then constructing a disengaged optional.
Do the null check before constructing the optional. If the string_view
constructor does not accept nullptr neither does
optional<string_view>(in_place_t, ...). Just like for any other T.
> What should the relational operators of this specialization look like?
> I would like to be
> able to write something like
>
> void f(optional<string_view> s)
> {
> if (s == "abc") {}
> if (s < "abc") {}
> }
Since it's an optional<T> you still have to use it like an optional<T>.
If "s" is disengaged both comparsions return false, which is correct and
I would expect the same for a null string_view. Just like with any other T.
Instead of using "if(s.data())" use "if(s)" or "if(!s)" to check for null.
I don't see why there should be a difference between specialized and
unspecialized optional<string_view>. I also don't see how it is
different from a "null string_view". As far as I can see the semantics
are equivalent. As long as string_view does not accept nullptr the
specialization is nothing but a sizeof() optimizing implementation detail.
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--------------010900020006080609010601
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<meta content=3D"text/html; charset=3DUTF-8" http-equiv=3D"Content-Type=
">
</head>
<body text=3D"#000000" bgcolor=3D"#FFFFFF">
<br>
<blockquote
cite=3D"mid:53d0e0c3-7eee-4853-886d-624bf4b22fb4@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<div>
<div>Ok. But an unspecialized optional<string_view> is
very different from a nullable string_view.</div>
<div>And a specialized optional<string_view> would be
very different from an optional<T>.</div>
</div>
</div>
</blockquote>
What is the difference between a "nullable string_view" and an
"optional<string_view>"? Not in terms of syntax but semantics.
That's what must be the same. Both give you means of marking the
string_view as *null* and both cause errors/UB if accessing such a
string. <br>
<br>
If done properly the only difference between optional<T> and
optional<string_view> is sizeof() by optimizing away a bool
member and use .data() =3D=3D nullptr for determining whether the
optional is engaged or not. As long as string_view does not accept
null this distinction can be made.<br>
<blockquote
cite=3D"mid:53d0e0c3-7eee-4853-886d-624bf4b22fb4@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<div>
<div>I need to make sure that the specialized version is
constructible from a nullptr and</div>
<div>and then constructing a disengaged optional.</div>
</div>
</div>
</blockquote>
Do the null check before constructing the optional. If the
string_view constructor does not accept nullptr neither does
optional<string_view>(in_place_t, ...). Just like for any
other T.<br>
<blockquote
cite=3D"mid:53d0e0c3-7eee-4853-886d-624bf4b22fb4@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<div>What should the relational operators of this specialization
look like? I would like to be</div>
<div>able to write something like</div>
<div><br>
</div>
<div><font face=3D"courier new, monospace">void
f(optional<string_view> s)</font></div>
<div><font face=3D"courier new, monospace">{</font></div>
<div><font face=3D"courier new, monospace">=C2=A0 if (s =3D=3D "abc=
") {}</font></div>
<div><font face=3D"courier new, monospace">=C2=A0 if (s < "abc")=
{}</font></div>
<div><font face=3D"courier new, monospace">}</font></div>
</div>
</blockquote>
Since it's an optional<T> you still have to use it like an
optional<T>. If "s" is disengaged both comparsions return
false, which is correct and I would expect the same for a null
string_view. Just like with any other T.<br>
<br>
Instead of using "if(s.data())" use "if(s)" or "if(!s)" to check for
null.<br>
<br>
I don't see why there should be a difference between specialized and
unspecialized optional<string_view>. I also don't see how it
is different from a "null string_view". As far as I can see the
semantics are equivalent. As long as string_view does not accept
nullptr the specialization is nothing but a sizeof() optimizing
implementation detail.<br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--------------010900020006080609010601--
.
Author: Nevin Liber <nevin@eviloverlord.com>
Date: Sun, 19 Jan 2014 15:15:07 -0600
Raw View
--001a11c3841a698d5504f05947b7
Content-Type: text/plain; charset=ISO-8859-1
On 19 January 2014 15:08, Miro Knejp <miro@knejp.de> wrote:
>
> I don't see why there should be a difference between specialized and
> unspecialized optional<string_view>. I also don't see how it is different
> from a "null string_view". As far as I can see the semantics are
> equivalent. As long as string_view does not accept nullptr the
> specialization is nothing but a sizeof() optimizing implementation detail.
>
In which case it is just a Quality of Implementation issue and need not be
addressed by the Standard.
--
Nevin ":-)" Liber <mailto:nevin@eviloverlord.com> (847) 691-1404
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a11c3841a698d5504f05947b7
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On 19 January 2014 15:08, Miro Knejp <span dir=3D"ltr"><=
;<a href=3D"mailto:miro@knejp.de" target=3D"_blank">miro@knejp.de</a>></=
span> wrote:<br><div class=3D"gmail_extra"><div class=3D"gmail_quote"><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #cc=
c solid;padding-left:1ex">
=20
=20
=20
<div text=3D"#000000" bgcolor=3D"#FFFFFF"><div class=3D"im"><br></div>
I don't see why there should be a difference between specialized an=
d
unspecialized optional<string_view>. I also don't see how it
is different from a "null string_view". As far as I can see t=
he
semantics are equivalent. As long as string_view does not accept
nullptr the specialization is nothing but a sizeof() optimizing
implementation detail.</div></blockquote></div><div><br></div><div>In w=
hich case it is just a Quality of Implementation issue and need not be addr=
essed by the Standard.</div>-- <br>=A0Nevin ":-)" Liber=A0 <ma=
ilto:<a href=3D"mailto:nevin@eviloverlord.com" target=3D"_blank">nevin@evil=
overlord.com</a>>=A0 (847) 691-1404
</div></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--001a11c3841a698d5504f05947b7--
.
Author: Miro Knejp <miro@knejp.de>
Date: Sun, 19 Jan 2014 22:23:17 +0100
Raw View
This is a multi-part message in MIME format.
--------------050305000202030103060604
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Am 19.01.2014 22:15, schrieb Nevin Liber:
> On 19 January 2014 15:08, Miro Knejp <miro@knejp.de
> <mailto:miro@knejp.de>> wrote:
>
>
> I don't see why there should be a difference between specialized
> and unspecialized optional<string_view>. I also don't see how it
> is different from a "null string_view". As far as I can see the
> semantics are equivalent. As long as string_view does not accept
> nullptr the specialization is nothing but a sizeof() optimizing
> implementation detail.
>
>
> In which case it is just a Quality of Implementation issue and need
> not be addressed by the Standard.
Yes, that was basically my point.
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--------------050305000202030103060604
Content-Type: text/html; charset=ISO-8859-1
<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<br>
<div class="moz-cite-prefix">Am 19.01.2014 22:15, schrieb Nevin
Liber:<br>
</div>
<blockquote
cite="mid:CAGg_6+MYduAHPOrY=Mk8sOux8+YPXKNPwhAFEXRH3n4-qfaPvg@mail.gmail.com"
type="cite">
<div dir="ltr">On 19 January 2014 15:08, Miro Knejp <span
dir="ltr"><<a moz-do-not-send="true"
href="mailto:miro@knejp.de" target="_blank">miro@knejp.de</a>></span>
wrote:<br>
<div class="gmail_extra">
<div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex">
<div text="#000000" bgcolor="#FFFFFF">
<div class="im"><br>
</div>
I don't see why there should be a difference between
specialized and unspecialized
optional<string_view>. I also don't see how it is
different from a "null string_view". As far as I can see
the semantics are equivalent. As long as string_view
does not accept nullptr the specialization is nothing
but a sizeof() optimizing implementation detail.</div>
</blockquote>
</div>
<div><br>
</div>
<div>In which case it is just a Quality of Implementation
issue and need not be addressed by the Standard.</div>
</div>
</div>
</blockquote>
Yes, that was basically my point.<br>
<br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href="http://groups.google.com/a/isocpp.org/group/std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/</a>.<br />
--------------050305000202030103060604--
.
Author: "Paul A. Tessier" <phernost@gmail.com>
Date: Sun, 19 Jan 2014 16:52:29 -0500
Raw View
This is a multi-part message in MIME format.
--------------040806000801000106030406
Content-Type: text/plain; charset=UTF-8; format=flowed
On 01/19/2014 03:37 PM, Alexander Bolz wrote:
> Am Sonntag, 19. Januar 2014 20:00:43 UTC+1 schrieb Paul Tessier:
>
> On 01/19/2014 12:44 PM, Magnus Fromreide wrote:
> > On Sun, Jan 19, 2014 at 07:55:32AM -0800, Peter Bigot wrote:
> >> On Friday, January 17, 2014 10:19:07 PM UTC-6, Marshall wrote:
> >>> On Jan 17, 2014, at 6:13 PM, Miro Knejp <mi...@knejp.de
> <javascript:>>
> >>> wrote:
> >>>
> >>>>> - both of these methods are impossible if the presumptions
> stated above
> >>> "begin() should never return nullptr" and "we don't need a
> special
> >>> is_null()". Well, not entirely. Of course you could create
> some bogus
> >>> object and use its address instead of nullptr.
> >>>> Why not set the string_view to "" in the default constructor?
> >>> I believe that this is the current proposal.
> >>>
> >>> However, this requires creating a global variable (which some
> >>> implementations will put in the code segment) for each default
> constructed
> >>> string_view (yes, some implementations will merge them
> together in the same
> >>> translation unit).
> >>>
> >> I thought somebody had proposed a "will-probably-work" solution
> involving
> >> casts of non-zero values to a pointer to avoid the global
> variable, but
> >> here's another solution I believe is safe and well-defined:
> >>
> >> Nothing in the current spec requires that the data() function
> return the
> >> same value for distinct default-constructed string_view
> instances. So use
> >> the following data members:
> >>
> >> const charT * m_ptr;
> >> union {
> >> size_t m_len;
> >> charT m_nul;
> >> };
> >>
> >> and have the default constructor set m_ptr to &m_nul and m_len
> to 0. The
> >> result is a (unique) empty string reference.
> >>
> >> I've tested this by modifying Boost's implementation and it
> works fine.
> >> Note that only the m_len data member is actually used and is
> always zero
> >> for the default-constructed value. There's no issue about
> accessing the
> >> other union member because when size() is zero you can't
> legitimately
> >> dereference data() unless you know from construction that it's
> pointing
> >> into a non-empty range (and in this case it doesn't).
> > I have thought in a similar direction, but the problem is if you
> have two
> > string_view's, s1 and s2. Assume that s1 i empty, does the
> statement
> > s2 = s1; imply that s2.data() == s1.data()?
> >
> > Then what happens if s1 is deallocated and it's memory is
> returned to the
> > system, won't s2.m_ptr then hold an illegal pointer value, one
> of those
> > where even loading it could trigger a hardware trap on some
> architectures.
> >
> > /MF
> >
>
> If s1 and s2 are empty, only access to the metadata is rational.
> Using
> operator[], front(), back(), etc. will produce undefined behavior.
> s1.data() and s2.data() are irrelevant because, it points to the
> beginning of a range of zero length. One could just as easily set
> data() to null or some random value, when the string_view becomes
> empty
> but, such actions are unneeded. The equality comparison is based
> on the
> equality of the two ordered sets of characters from s1 and s2. All
> empty views are equally empty and does not imply ( s2.data() ==
> s1.data() ), just as ( s1 == s2 ) does not imply that ( &s1 == &s2 ).
>
> If &s1 is deallocated and falls into a protected segment, any
> access to
> it will trap, just like any other object. If both s1 and s2 where
> referencing a string that was deallocated before they both became
> empty
> then, both would trap, unless data() is randomized or set to some
> safe
> location as I mentioned above but, this would be pointless as
> accessing
> the referenced string of an empty view is undefined behavior.
>
>
> To me the prevention of null being returned by data() is just an
> artifact inherited from std::string. It seem like an early and
> incomplete error check. You could also argue that all unreachable
> segments be restricted.
>
> If string_view was only a range of a std:string, forwarding all
> std::string's warts through the interface would not be completely
> unexpected. Especially when the wrapper is such a lightweight class.
> Yet, string_view serves a wider purpose therefore, those warts should
> ignored. I argue that std::string's interface should be relaxed
> and, not
> that string_view's be restricted.
>
> Consider std::array< char, 0 >. It's data() will return null, and
> the
> rest of it's members behave as rationally.
>
>
> This is not correct. I just looked it up in N3797:
> 23.3.2.8. says "begin() == end() == unique value. The return value of
> data() is unspecified"
>
> I see no reason for
> string_view not to behave in a similar fashion. While std:string may
> never return null for it's data(), it is inconsequential as
> string_view
> maybe constructed from other sources.
>
> Having a is_null() seems excessive. data() should be allowed to be
> null,
> as this seems the simplest solution. Following the behavior of
> std::array< char, 0 > seems to solve many of the other problems in
> the
> interface being unable to handle data() and begin() being null.
>
> While string_view is modeled after std::string's interface, the newer
> std::array interface seems more flexible and also solves the default
> empty initialization problem. Besides, any object that behaves
> rationally when zeroed out, say by memset, is a plus.
>
>
> --
>
> ---
> 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.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
Ah, that is correct, of which null is a unique value. My original point
still stands though. Preventing null as an allowable value only adds
complexity, and allowing null can be handled in a rational fashion as is
demonstrated by new interfaces.
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--------------040806000801000106030406
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<meta content=3D"text/html; charset=3DUTF-8" http-equiv=3D"Content-Type=
">
</head>
<body bgcolor=3D"#FFFFFF" text=3D"#000000">
<div class=3D"moz-cite-prefix">On 01/19/2014 03:37 PM, Alexander Bolz
wrote:<br>
</div>
<blockquote
cite=3D"mid:1e1da13e-663f-4f98-8f54-595b8f75591e@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">Am Sonntag, 19. Januar 2014 20:00:43 UTC+1 schrieb
Paul Tessier:<br>
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On
01/19/2014 12:44 PM, Magnus Fromreide wrote:
<br>
> On Sun, Jan 19, 2014 at 07:55:32AM -0800, Peter Bigot
wrote:
<br>
>> On Friday, January 17, 2014 10:19:07 PM UTC-6,
Marshall wrote:
<br>
>>> On Jan 17, 2014, at 6:13 PM, Miro Knejp <<a
moz-do-not-send=3D"true">mi...@knejp.de</a>
<javascript:>>
<br>
>>> wrote:
<br>
>>>
<br>
>>>>> - both of these methods are impossible if
the presumptions stated above
<br>
>>> "begin() should never return nullptr" and "we
don't need a special
<br>
>>> is_null()". Well, not entirely. Of course you
could create some bogus
<br>
>>> object and use its address instead of nullptr.
<br>
>>>> Why not set the string_view to "" in the
default constructor?
<br>
>>> I believe that this is the current proposal.
<br>
>>>
<br>
>>> However, this requires creating a global variable
(which some
<br>
>>> implementations will put in the code segment) for
each default constructed
<br>
>>> string_view (yes, some implementations will merge
them together in the same
<br>
>>> translation unit).
<br>
>>>
<br>
>> I thought somebody had proposed a
"will-probably-work" solution involving
<br>
>> casts of non-zero values to a pointer to avoid the
global variable, but
<br>
>> here's another solution I believe is safe and
well-defined:
<br>
>>
<br>
>> Nothing in the current spec requires that the data()
function return the
<br>
>> same value for distinct default-constructed
string_view instances. =C2=A0So use
<br>
>> the following data members:
<br>
>>
<br>
>> =C2=A0 =C2=A0const charT * m_ptr;
<br>
>> =C2=A0 =C2=A0union {
<br>
>> =C2=A0 =C2=A0 =C2=A0 size_t m_len;
<br>
>> =C2=A0 =C2=A0 =C2=A0 charT m_nul;
<br>
>> =C2=A0 =C2=A0};
<br>
>>
<br>
>> and have the default constructor set m_ptr to
&m_nul and m_len to 0. =C2=A0The
<br>
>> result is a (unique) empty string reference.
<br>
>>
<br>
>> I've tested this by modifying Boost's implementation
and it works fine.
<br>
>> Note that only the m_len data member is actually used
and is always zero
<br>
>> for the default-constructed value. =C2=A0There's no issu=
e
about accessing the
<br>
>> other union member because when size() is zero you
can't legitimately
<br>
>> dereference data() unless you know from construction
that it's pointing
<br>
>> into a non-empty range (and in this case it doesn't).
<br>
> I have thought in a similar direction, but the problem is
if you have two
<br>
> string_view's, s1 and s2. Assume that s1 i empty, does
the statement
<br>
> s2 =3D s1; imply that s2.data() =3D=3D s1.data()?
<br>
>
<br>
> Then what happens if s1 is deallocated and it's memory is
returned to the
<br>
> system, won't s2.m_ptr then hold an illegal pointer
value, one of those
<br>
> where even loading it could trigger a hardware trap on
some architectures.
<br>
>
<br>
> /MF
<br>
>
<br>
<br>
If s1 and s2 are empty, only access to the metadata is
rational. Using <br>
operator[], front(), back(), etc. will produce undefined
behavior.
<br>
s1.data() and s2.data() are irrelevant because, it points to
the <br>
beginning of a range of zero length. =C2=A0One could just as easi=
ly
set <br>
data() to null or some random value, when the string_view
becomes empty <br>
but, such actions are unneeded. =C2=A0The equality comparison is
based on the <br>
equality of the two ordered sets of characters from s1 and s2.
=C2=A0All <br>
empty views are equally empty and does not imply ( s2.data()
=3D=3D <br>
s1.data() ), just as ( s1 =3D=3D s2 ) does not imply that (
&s1 =3D=3D &s2 ).
<br>
<br>
If &s1 is deallocated and falls into a protected segment,
any access to <br>
it will trap, just like any other object. =C2=A0If both s1 and s2
where <br>
referencing a string that was deallocated before they both
became empty <br>
then, both would trap, unless data() is randomized or set to
some safe <br>
location as I mentioned above but, this would be pointless as
accessing <br>
the referenced string of an empty view is undefined behavior.
<br>
<br>
<br>
To me the prevention of null being returned by data() is just
an <br>
artifact inherited from std::string. =C2=A0It seem like an early
and <br>
incomplete error check. =C2=A0You could also argue that all
unreachable <br>
segments be restricted.
<br>
<br>
If string_view was only a range of a std:string, forwarding
all <br>
std::string's warts through the interface would not be
completely <br>
unexpected. =C2=A0Especially when the wrapper is such a lightweig=
ht
class. <br>
Yet, string_view serves a wider purpose therefore, those warts
should <br>
ignored. I argue that std::string's interface should be
relaxed and, not <br>
that string_view's be restricted.
<br>
<br>
Consider std::array< char, 0 >. =C2=A0It's data() will retu=
rn
null, and the <br>
rest of it's members behave as rationally. =C2=A0</blockquote>
<div><br>
</div>
<div>This is not correct. I just looked it up in N3797:</div>
<div>23.3.2.8. says "<font face=3D"courier new, monospace">begin()
=3D=3D end() =3D=3D</font> unique value. The return value of <f=
ont
face=3D"courier new, monospace">data()</font> is unspecified"<b=
r>
</div>
<div>=C2=A0</div>
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">I see no
reason for <br>
string_view not to behave in a similar fashion. =C2=A0While
std:string may <br>
never return null for it's data(), it is inconsequential as
string_view <br>
maybe constructed from other sources.
<br>
<br>
Having a is_null() seems excessive. data() should be allowed
to be null, <br>
as this seems the simplest solution. =C2=A0Following the behavior
of <br>
std::array< char, 0 > seems to solve many of the other
problems in the <br>
interface being unable to handle data() and begin() being
null.
<br>
<br>
While string_view is modeled after std::string's interface,
the newer <br>
std::array interface seems more flexible and also solves the
default <br>
empty initialization problem. =C2=A0Besides, any object that
behaves <br>
rationally when zeroed out, say by memset, is a plus.
<br>
<br>
<br>
</blockquote>
</div>
-- <br>
=C2=A0<br>
--- <br>
You received this message because you are subscribed to the Google
Groups "ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it,
send an email to <a class=3D"moz-txt-link-abbreviated" href=3D"mailto=
:std-proposals+unsubscribe@isocpp.org">std-proposals+unsubscribe@isocpp.org=
</a>.<br>
To post to this group, send email to <a class=3D"moz-txt-link-abbrevi=
ated" href=3D"mailto:std-proposals@isocpp.org">std-proposals@isocpp.org</a>=
..<br>
Visit this group at <a moz-do-not-send=3D"true"
href=3D"http://groups.google.com/a/isocpp.org/group/std-proposals/"=
>http://groups.google.com/a/isocpp.org/group/std-proposals/</a>.<br>
</blockquote>
<br>
Ah, that is correct, of which null is a unique value.=C2=A0 My original
point still stands though.=C2=A0 Preventing null as an allowable value
only adds complexity, and allowing null can be handled in a rational
fashion as is demonstrated by new interfaces.<br>
<br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--------------040806000801000106030406--
.
Author: Alexander Bolz <abolz.lists@gmail.com>
Date: Sun, 19 Jan 2014 22:56:45 +0100
Raw View
--90e6ba3fcd17f137df04f059d99d
Content-Type: text/plain; charset=ISO-8859-1
2014/1/19 Miro Knejp <miro@knejp.de>
>
> Ok. But an unspecialized optional<string_view> is very different from a
> nullable string_view.
> And a specialized optional<string_view> would be very different from an
> optional<T>.
>
> What is the difference between a "nullable string_view" and an
> "optional<string_view>"? Not in terms of syntax but semantics. That's what
> must be the same. Both give you means of marking the string_view as *null*
> and both cause errors/UB if accessing such a string.
>
Yes, and that's almost the only thing both have in common. With "nullable"
I mean that it
should be possible to construct a string_view from a nullptr and -- for
consistency -- data()
should be allowed to return nullptr. Any operation on string_view would
assume that a null
string_view is equal to an empty string_view.
The current proposal requires data != null. Ok. But IMHO there is no reason
for this. It just
restricts the cases where a string_view would be useful.
Now the caller has to do a null check even if a function could handle null
pointers.
>
> If done properly the only difference between optional<T> and
> optional<string_view> is sizeof() by optimizing away a bool member and use
> .data() == nullptr for determining whether the optional is engaged or not.
> As long as string_view does not accept null this distinction can be made.
>
If data() == nullptr ever returns true, string_view is already nullable.
>
> I need to make sure that the specialized version is constructible from
> a nullptr and
> and then constructing a disengaged optional.
>
> Do the null check before constructing the optional. If the string_view
> constructor does not accept nullptr neither does
> optional<string_view>(in_place_t, ...). Just like for any other T.
>
I just don't want to do that. I have a function like
void f(char const* s) {
if (s == nullptr)
dothis();
else
dothat();
}
and I want to replace char const* with string_view to make it accept a
std::string so I can save some std::string.c_str()
calls.
>
> What should the relational operators of this specialization look like? I
> would like to be
> able to write something like
>
> void f(optional<string_view> s)
> {
> if (s == "abc") {}
> if (s < "abc") {}
> }
>
> Since it's an optional<T> you still have to use it like an optional<T>. If
> "s" is disengaged both comparsions return false, which is correct and I
> would expect the same for a null string_view. Just like with any other T.
>
> Instead of using "if(s.data())" use "if(s)" or "if(!s)" to check for null.
>
> I don't see why there should be a difference between specialized and
> unspecialized optional<string_view>. I also don't see how it is different
> from a "null string_view". As far as I can see the semantics are
> equivalent. As long as string_view does not accept nullptr the
> specialization is nothing but a sizeof() optimizing implementation detail.
>
> --
>
> ---
> 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.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--
Alex
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--90e6ba3fcd17f137df04f059d99d
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_default" style=3D"font-family:arial,he=
lvetica,sans-serif"><span style=3D"font-family:arial">2014/1/19 Miro Knejp =
</span><span dir=3D"ltr" style=3D"font-family:arial"><<a href=3D"mailto:=
miro@knejp.de" target=3D"_blank">miro@knejp.de</a>></span><br>
</div><div class=3D"gmail_extra"><div class=3D"gmail_quote"><blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;pa=
dding-left:1ex">
=20
=20
=20
<div text=3D"#000000" bgcolor=3D"#FFFFFF"><div class=3D"im">
<br>
<blockquote type=3D"cite">
<div dir=3D"ltr">
<div>
<div>Ok. But an unspecialized optional<string_view> is
very different from a nullable string_view.</div>
<div>And a specialized optional<string_view> would be
very different from an optional<T>.</div>
</div>
</div>
</blockquote></div>
What is the difference between a "nullable string_view" and a=
n
"optional<string_view>"? Not in terms of syntax but sem=
antics.
That's what must be the same. Both give you means of marking the
string_view as *null* and both cause errors/UB if accessing such a
string.<br></div></blockquote><div><br></div><div><div class=3D"gmail_d=
efault" style=3D"font-family:arial,helvetica,sans-serif">Yes, and that'=
s almost the only thing both have in common. With "nullable" I me=
an that it</div>
<div class=3D"gmail_default" style=3D"font-family:arial,helvetica,sans-seri=
f">should be possible to construct a string_view from a nullptr and -- for =
consistency -- data()</div><div class=3D"gmail_default" style=3D"font-famil=
y:arial,helvetica,sans-serif">
should be allowed to return nullptr. Any operation on string_view would ass=
ume that a null</div></div><div class=3D"gmail_default" style=3D"font-famil=
y:arial,helvetica,sans-serif">string_view is equal to an empty string_view.=
</div>
<div class=3D"gmail_default" style=3D"font-family:arial,helvetica,sans-seri=
f"><br></div><div class=3D"gmail_default" style=3D"font-family:arial,helvet=
ica,sans-serif">The current proposal requires data !=3D null. Ok. But IMHO =
there is no reason for this. It just</div>
<div class=3D"gmail_default" style=3D"font-family:arial,helvetica,sans-seri=
f">restricts the cases where a string_view would be useful.</div><div class=
=3D"gmail_default" style=3D"font-family:arial,helvetica,sans-serif"><br></d=
iv><div class=3D"gmail_default" style=3D"font-family:arial,helvetica,sans-s=
erif">
Now the caller has to do a null check even if a function could handle null =
pointers.</div><div>=A0</div><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div text=3D"#0=
00000" bgcolor=3D"#FFFFFF">
<br>
If done properly the only difference between optional<T> and
optional<string_view> is sizeof() by optimizing away a bool
member and use .data() =3D=3D nullptr for determining whether the
optional is engaged or not. As long as string_view does not accept
null this distinction can be made.</div></blockquote><div><br></div><di=
v><div class=3D"gmail_default" style=3D"font-family:arial,helvetica,sans-se=
rif">If data() =3D=3D nullptr ever returns true, string_view is already nul=
lable.</div>
<br></div><div>=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0=
0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div text=3D"#000000=
" bgcolor=3D"#FFFFFF"><div class=3D"im"><br>
<blockquote type=3D"cite">
<div dir=3D"ltr">
<div>
<div>I need to make sure that the specialized version is
constructible from a nullptr and</div>
<div>and then constructing a disengaged optional.</div>
</div>
</div>
</blockquote></div>
Do the null check before constructing the optional. If the
string_view constructor does not accept nullptr neither does
optional<string_view>(in_place_t, ...). Just like for any
other T.</div></blockquote><div><br></div><div><div class=3D"gmail_defa=
ult" style=3D"font-family:arial,helvetica,sans-serif">I just don't want=
to do that. I have a function like</div><div class=3D"gmail_default" style=
=3D"font-family:arial,helvetica,sans-serif">
<br></div><div class=3D"gmail_default"><font face=3D"courier new, monospace=
">void f(char const* s) {</font></div><div class=3D"gmail_default"><font fa=
ce=3D"courier new, monospace">=A0 if (s =3D=3D nullptr)</font></div><div cl=
ass=3D"gmail_default">
<font face=3D"courier new, monospace">=A0 =A0 dothis();</font></div><div cl=
ass=3D"gmail_default"><font face=3D"courier new, monospace">=A0 else</font>=
</div><div class=3D"gmail_default"><font face=3D"courier new, monospace">=
=A0 =A0 dothat();</font></div>
<div class=3D"gmail_default"><font face=3D"courier new, monospace">}</font>=
</div><div class=3D"gmail_default" style=3D"font-family:arial,helvetica,san=
s-serif"><br></div><div class=3D"gmail_default" style=3D"font-family:arial,=
helvetica,sans-serif">
and I want to replace char const* with string_view to make it accept a std:=
:string so I can save some std::string.c_str()</div><div class=3D"gmail_def=
ault" style=3D"font-family:arial,helvetica,sans-serif">calls.</div><br></di=
v>
<div>=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;=
border-left:1px #ccc solid;padding-left:1ex"><div text=3D"#000000" bgcolor=
=3D"#FFFFFF"><div class=3D"im"><br>
<blockquote type=3D"cite">
<div dir=3D"ltr">
<div>What should the relational operators of this specialization
look like? I would like to be</div>
<div>able to write something like</div>
<div><br>
</div>
<div><font face=3D"courier new, monospace">void
f(optional<string_view> s)</font></div>
<div><font face=3D"courier new, monospace">{</font></div>
<div><font face=3D"courier new, monospace">=A0 if (s =3D=3D "a=
bc") {}</font></div>
<div><font face=3D"courier new, monospace">=A0 if (s < "abc=
") {}</font></div>
<div><font face=3D"courier new, monospace">}</font></div>
</div>
</blockquote></div>
Since it's an optional<T> you still have to use it like an
optional<T>. If "s" is disengaged both comparsions retu=
rn
false, which is correct and I would expect the same for a null
string_view. Just like with any other T.</div></blockquote><blockquote =
class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid=
;padding-left:1ex"><div text=3D"#000000" bgcolor=3D"#FFFFFF">
<br>
Instead of using "if(s.data())" use "if(s)" or &quo=
t;if(!s)" to check for
null.<br>
<br>
I don't see why there should be a difference between specialized an=
d
unspecialized optional<string_view>. I also don't see how it
is different from a "null string_view". As far as I can see t=
he
semantics are equivalent. As long as string_view does not accept
nullptr the specialization is nothing but a sizeof() optimizing
implementation detail.<br>
</div><div class=3D"HOEnZb"><div class=3D"h5">
<p></p>
-- <br>
=A0<br>
--- <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%2Bunsubscribe@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>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br><br clear=3D"all"><div><br></div>-- <br>=
<div dir=3D"ltr">Alex</div>
</div></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--90e6ba3fcd17f137df04f059d99d--
.
Author: Miro Knejp <miro@knejp.de>
Date: Sun, 19 Jan 2014 23:53:53 +0100
Raw View
This is a multi-part message in MIME format.
--------------050600080705010905060701
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
>
> I just don't want to do that. I have a function like
>
> void f(char const* s) {
> if (s == nullptr)
> dothis();
> else
> dothat();
> }
>
> and I want to replace char const* with string_view to make it accept a
> std::string so I can save some std::string.c_str()
> calls.
>
Saving some string.c_str() calls isn't a very convincing argument. Not
for me at least. When I have to chose between safety/robustness or
convenience the former wins. Knowing a std::string_view cannot be null
just as std::string cannot be is a valuable quality of life improvement.
I would assume the number of times one needs a nullable string is only a
fraction of the actual uses of string_view.
string_view has as far as I can remember always been described as a
drop-in replacement for string. Discussing the possibility of a nullable
std::string_view should equally raise a discussion about the possibility
of a nullable std::string. If it is not possible to replace functions
taking (const string&) with (string_view) and have the same semantics
it's far less usefull and only works against the trend of making things
safer and more intuitive. (const char*) methods should always ring alarm
bells.
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--------------050600080705010905060701
Content-Type: text/html; charset=ISO-8859-1
<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<br>
<blockquote
cite="mid:CAM0iMhwJXMamGN94_-hU_0fO3Cnk3aJgVexsjgHz45wEo-eWhA@mail.gmail.com"
type="cite">
<div dir="ltr">
<div class="gmail_extra">
<div class="gmail_quote">
<div><br>
</div>
<div>
<div class="gmail_default"
style="font-family:arial,helvetica,sans-serif">I just
don't want to do that. I have a function like</div>
<div class="gmail_default"
style="font-family:arial,helvetica,sans-serif">
<br>
</div>
<div class="gmail_default"><font face="courier new,
monospace">void f(char const* s) {</font></div>
<div class="gmail_default"><font face="courier new,
monospace"> if (s == nullptr)</font></div>
<div class="gmail_default">
<font face="courier new, monospace"> dothis();</font></div>
<div class="gmail_default"><font face="courier new,
monospace"> else</font></div>
<div class="gmail_default"><font face="courier new,
monospace"> dothat();</font></div>
<div class="gmail_default"><font face="courier new,
monospace">}</font></div>
<div class="gmail_default"
style="font-family:arial,helvetica,sans-serif"><br>
</div>
<div class="gmail_default"
style="font-family:arial,helvetica,sans-serif">
and I want to replace char const* with string_view to
make it accept a std::string so I can save some
std::string.c_str()</div>
<div class="gmail_default"
style="font-family:arial,helvetica,sans-serif">calls.</div>
<br>
</div>
</div>
</div>
</div>
</blockquote>
Saving some string.c_str() calls isn't a very convincing argument.
Not for me at least. When I have to chose between safety/robustness
or convenience the former wins. Knowing a std::string_view cannot be
null just as std::string cannot be is a valuable quality of life
improvement. I would assume the number of times one needs a nullable
string is only a fraction of the actual uses of string_view.<br>
<br>
string_view has as far as I can remember always been described as a
drop-in replacement for string. Discussing the possibility of a
nullable std::string_view should equally raise a discussion about
the possibility of a nullable std::string. If it is not possible to
replace functions taking (const string&) with (string_view) and
have the same semantics it's far less usefull and only works against
the trend of making things safer and more intuitive. (const char*)
methods should always ring alarm bells.<br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href="http://groups.google.com/a/isocpp.org/group/std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/</a>.<br />
--------------050600080705010905060701--
.
Author: gornishanov@gmail.com
Date: Sun, 19 Jan 2014 14:55:24 -0800 (PST)
Raw View
------=_Part_837_23178409.1390172124703
Content-Type: text/plain; charset=UTF-8
Alexander:
The current proposal requires data != null. Ok. But IMHO there is no reason
for this. It just
> restricts the cases where a string_view would be useful.
>
I see, would replacing
constexpr basic_string_view(const charT* str, size_type len);
*Requires*: str is not a null pointer and [str,str + len) is a valid range.
with
constexpr basic_string_view(const charT* str, size_type len);
*Requires*: str is not a null pointer and [str,str + len) is a valid range
or str == nullptr and len == 0.
address your concerns?
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_837_23178409.1390172124703
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Alexander:</div><div><br></div><div>The current propo=
sal requires data !=3D null. Ok. But IMHO there is no reason for this. It j=
ust</div><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8=
ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-w=
idth: 1px; border-left-style: solid;"><div dir=3D"ltr"><div><div class=3D"g=
mail_quote">
<div style=3D"font-family: arial,helvetica,sans-serif;">restricts the cases=
where a string_view would be useful.</div></div></div></div></blockquote><=
div><br></div><div>I see, would replacing</div><div><br></div><div><pre><co=
de>constexpr basic_string_view(const charT* str, size_type len);</code></pr=
e><div class=3D"attributes"><p><i>Requires</i>: str is not a null pointer a=
nd [str,str + len) is a valid range.</p><p>with</p></div></div><div><pre><c=
ode>constexpr basic_string_view(const charT* str, size_type len);</code></p=
re><div class=3D"attributes"><p><i>Requires</i>: str is not a null pointer =
and [str,str + len) is a valid range<br>or str =3D=3D nullptr and len =3D=
=3D 0.</p><p>address your concerns?</p><p><br></p><p><br></p></div></div>
</div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_837_23178409.1390172124703--
.
Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Sun, 19 Jan 2014 16:11:32 -0800 (PST)
Raw View
------=_Part_753_31806092.1390176692321
Content-Type: text/plain; charset=UTF-8
Op zondag 19 januari 2014 19:31:19 UTC+1 schreef Peter Bigot:
>
> On further reflection it'd better to store a null pointer in m_ptr to
> represent a default-constructed value but to return &m_nul from data() when
> m_ptr is null.
>
Having such conditionals in data() doesn't seem like a good idea. data()
should be as simple (and as fast) as possible.
> constexpr basic_string_view(const charT* str, size_type len);
*> Requires*: str is not a null pointer and [str,str + len) is a valid
range.
What's the rationale for the not-null requirement? I don't like it, one
should be able to construct a string_view from a NULL, 0 pair.
vector::data() could return NULL (AFAIK), so that'd mean I couldn't
construct a string_view from v.data(), v.size()
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_753_31806092.1390176692321
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Op zondag 19 januari 2014 19:31:19 UTC+1 schreef Peter Big=
ot:<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><div =
class=3D"gmail_quote"><div>On further reflection it'd better to store a nul=
l pointer in m_ptr to represent a default-constructed value but to return &=
amp;m_nul from data() when m_ptr is null. </div></div></div></div></b=
lockquote><div><br></div><div>Having such conditionals in data() doesn't se=
em like a good idea. data() should be as simple (and as fast) as possible.<=
/div><div><br></div><div>> <span style=3D"white-space: inherit; col=
or: rgb(0, 0, 0);">constexpr basic_string_view(const charT* str, size_type =
len);</span></div><div><i style=3D"line-height: 18px; color: rgb(0, 0, 0); =
font-family: 'Times New Roman';">> Requires</i><span style=3D"line-heigh=
t: 18px; color: rgb(0, 0, 0); font-family: 'Times New Roman';">:</span><spa=
n style=3D"line-height: 18px; color: rgb(0, 0, 0); font-family: 'Times New =
Roman';"> </span><code style=3D"line-height: 18px; color: rgb(0, 0, 0)=
; white-space: nowrap;">str</code><span style=3D"line-height: 18px; color: =
rgb(0, 0, 0); font-family: 'Times New Roman';"> </span><span style=3D"=
line-height: 18px; color: rgb(0, 0, 0); font-family: 'Times New Roman';">is=
not a null pointer and [</span><code style=3D"line-height: 18px; color: rg=
b(0, 0, 0); white-space: nowrap;">str</code><span style=3D"line-height: 18p=
x; color: rgb(0, 0, 0); font-family: 'Times New Roman';">,</span><code styl=
e=3D"line-height: 18px; color: rgb(0, 0, 0); white-space: nowrap;">str + le=
n</code><span style=3D"line-height: 18px; color: rgb(0, 0, 0); font-family:=
'Times New Roman';">) is a valid range.</span> </div><div><br></div><=
div>What's the rationale for the not-null requirement? I don't like it, one=
should be able to construct a string_view from a NULL, 0 pair.</div><div>v=
ector::data() could return NULL (AFAIK), so that'd mean I couldn't construc=
t a string_view from v.data(), v.size()</div></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_753_31806092.1390176692321--
.
Author: Alexander Bolz <abolz.lists@gmail.com>
Date: Sun, 19 Jan 2014 16:35:11 -0800 (PST)
Raw View
------=_Part_1440_13224426.1390178111886
Content-Type: text/plain; charset=UTF-8
Am Sonntag, 19. Januar 2014 23:53:53 UTC+1 schrieb Miro Knejp:
>
> I just don't want to do that. I have a function like
>
> void f(char const* s) {
> if (s == nullptr)
> dothis();
> else
> dothat();
> }
>
> and I want to replace char const* with string_view to make it accept a
> std::string so I can save some std::string.c_str()
> calls.
>
> Saving some string.c_str() calls isn't a very convincing argument. Not
> for me at least. When I have to chose between safety/robustness or
> convenience the former wins. Knowing a std::string_view cannot be null just
> as std::string cannot be is a valuable quality of life improvement. I would
> assume the number of times one needs a nullable string is only a fraction
> of the actual uses of string_view.
>
> string_view has as far as I can remember always been described as a
> drop-in replacement for string. Discussing the possibility of a nullable
> std::string_view should equally raise a discussion about the possibility of
> a nullable std::string. If it is not possible to replace functions taking
> (const string&) with (string_view) and have the same semantics it's far
> less usefull and only works against the trend of making things safer and
> more intuitive. (const char*) methods should always ring alarm bells.
>
For a function like
void print(string const& s) {
}
there is an implicit precondition: a string can not be constructed from a
nullptr.
So you have to check this before calling. When replacing string const& with
string_view,
you just need to make the precondition explicit. Then in both cases data()
!= null.
If you use string.data(), you can't simply replace func(string const&) with
func(string_view)
even if data() returns non-null, since data() might not be null terminated.
void print(string const& s) {
printf("%s", s.data());
}
If yyou don't use data() then, well... its not important if data() returns
nullptr or not.
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_1440_13224426.1390178111886
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Am Sonntag, 19. Januar 2014 23:53:53 UTC+1 schrieb Miro Kn=
ejp:<br><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0=
..8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
=20
=20
=20
<div text=3D"#000000" bgcolor=3D"#FFFFFF">
=20
<blockquote type=3D"cite">
<div dir=3D"ltr">
<div>
<div class=3D"gmail_quote">
<div><br>
</div>
<div>
<div style=3D"font-family:arial,helvetica,sans-serif">I just
don't want to do that. I have a function like</div>
<div style=3D"font-family:arial,helvetica,sans-serif">
<br>
</div>
<div><font face=3D"courier new,
monospace">void f(char const* s) {</font></div>
<div><font face=3D"courier new,
monospace"> if (s =3D=3D nullptr)</font></div>
<div>
<font face=3D"courier new, monospace"> dothis(=
);</font></div>
<div><font face=3D"courier new,
monospace"> else</font></div>
<div><font face=3D"courier new,
monospace"> dothat();</font></div>
<div><font face=3D"courier new,
monospace">}</font></div>
<div style=3D"font-family:arial,helvetica,sans-serif"><br>
</div>
<div style=3D"font-family:arial,helvetica,sans-serif">
and I want to replace char const* with string_view to
make it accept a std::string so I can save some
std::string.c_str()</div>
<div style=3D"font-family:arial,helvetica,sans-serif">calls.<=
/div>
<br>
</div>
</div>
</div>
</div>
</blockquote>
Saving some string.c_str() calls isn't a very convincing argument.
Not for me at least. When I have to chose between safety/robustness
or convenience the former wins. Knowing a std::string_view cannot be
null just as std::string cannot be is a valuable quality of life
improvement. I would assume the number of times one needs a nullable
string is only a fraction of the actual uses of string_view.<br>
<br>
string_view has as far as I can remember always been described as a
drop-in replacement for string. Discussing the possibility of a
nullable std::string_view should equally raise a discussion about
the possibility of a nullable std::string. If it is not possible to
replace functions taking (const string&) with (string_view) and
have the same semantics it's far less usefull and only works against
the trend of making things safer and more intuitive. (const char*)
methods should always ring alarm bells.<br></div></blockquote><div><br>=
</div><div>For a function like<br></div><div><br></div><div><font face=3D"c=
ourier new, monospace">void print(string const& s) {</font></div><div><=
font face=3D"courier new, monospace">}</font></div><div><br></div><div>ther=
e is an implicit precondition: a string can not be constructed from a nullp=
tr.</div><div>So you have to check this before calling. When replacing stri=
ng const& with string_view,</div><div>you just need to make the precond=
ition explicit. Then in both cases data() !=3D null.</div><div><br></div><d=
iv>If you use string.data(), you can't simply replace func(string const&=
;) with func(string_view)</div><div>even if data() returns non-null, since =
data() might not be null terminated.</div><div><br></div><div><font face=3D=
"courier new, monospace">void print(string const& s) {</font></div><div=
><font face=3D"courier new, monospace"> printf("%s", s.data());</font=
></div><div><font face=3D"courier new, monospace">}</font></div><div><br></=
div><div>If yyou don't use data() then, well... its not important if data()=
returns nullptr or not.</div><div><br></div></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_1440_13224426.1390178111886--
.
Author: Miro Knejp <miro@knejp.de>
Date: Mon, 20 Jan 2014 02:36:40 +0100
Raw View
This is a multi-part message in MIME format.
--------------060100090409090202030703
Content-Type: text/plain; charset=UTF-8; format=flowed
>
> For a function like
>
> void print(string const& s) {
> }
>
> there is an implicit precondition: a string can not be constructed
> from a nullptr.
> So you have to check this before calling. When replacing string const&
> with string_view,
> you just need to make the precondition explicit. Then in both cases
> data() != null.
Yes, I as author of print have the implicit precondition enforced by
std::string that it's always called with a valid string. That is
something I can rely on. That is a good thing. Changing the signature to
accept (nullable) string_view suddenly breaks this guarantee and I
either have to add asserts or some other kinds of checks and document it
somewhere and needlessly complexify every method relying on this
guarantee. That is a bad thing. And suddenly you need to create new test
cases for print even though it was working perfectly. That is also a bad
thing.
>
> If you use string.data(), you can't simply replace func(string const&)
> with func(string_view)
> even if data() returns non-null, since data() might not be null
> terminated.
>
> void print(string const& s) {
> printf("%s", s.data());
> }
>
> If yyou don't use data() then, well... its not important if data()
> returns nullptr or not.
If one used .data() to pass it to (const char*) methods (which should
ring a bell and make you pay *very good attention* to what you're doing)
before C++11 then it was already calling for disaster as .data() was not
guaranteed to be null terminated. Then there are the methods which take
a pointer and a length. There it doesn't matter but they might crash if
passed in null (even if the length is 0). Seen it happen more often than
I like. I always tell people to use .c_str() because it is more
explicitly stating intentions and it is backwards compatible.
null always makes things more complicated than necessary. Just notice
how the library is evolving to gradually remove the word and value
"null" from our everyday usage. That's a good thing. Think in
abstractions, not null. Throwing null at everyone only to enable a few
edge cases seems wrong. One can always come up with situations where a
nullable string_view might be useful, as is the case with many other
things deemed "bad", but in the end it matters how common that scenario
is compared to where a non-null guarantee makes code safer, simpler and
more robust.
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--------------060100090409090202030703
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<meta content=3D"text/html; charset=3DUTF-8" http-equiv=3D"Content-Type=
">
</head>
<body text=3D"#000000" bgcolor=3D"#FFFFFF">
<br>
<blockquote
cite=3D"mid:975e038a-8ae2-48d4-ba5b-3b6d7d67cea7@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<div><br>
</div>
<div>For a function like<br>
</div>
<div><br>
</div>
<div><font face=3D"courier new, monospace">void print(string
const& s) {</font></div>
<div><font face=3D"courier new, monospace">}</font></div>
<div><br>
</div>
<div>there is an implicit precondition: a string can not be
constructed from a nullptr.</div>
<div>So you have to check this before calling. When replacing
string const& with string_view,</div>
<div>you just need to make the precondition explicit. Then in
both cases data() !=3D null.</div>
</div>
</blockquote>
Yes, I as author of print have the implicit precondition enforced by
std::string that it's always called with a valid string. That is
something I can rely on. That is a good thing. Changing the
signature to accept (nullable) string_view suddenly breaks this
guarantee and I either have to add asserts or some other kinds of
checks and document it somewhere and needlessly complexify every
method relying on this guarantee. That is a bad thing. And suddenly
you need to create new test cases for print even though it was
working perfectly. That is also a bad thing.<br>
<blockquote
cite=3D"mid:975e038a-8ae2-48d4-ba5b-3b6d7d67cea7@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<div><br>
</div>
<div>If you use string.data(), you can't simply replace
func(string const&) with func(string_view)</div>
<div>even if data() returns non-null, since data() might not be
null terminated.</div>
<div><br>
</div>
<div><font face=3D"courier new, monospace">void print(string
const& s) {</font></div>
<div><font face=3D"courier new, monospace">=C2=A0 printf("%s",
s.data());</font></div>
<div><font face=3D"courier new, monospace">}</font></div>
<div><br>
</div>
<div>If yyou don't use data() then, well... its not important if
data() returns nullptr or not.<br>
</div>
</div>
</blockquote>
If one used .data() to pass it to (const char*) methods (which
should ring a bell and make you pay *very good attention* to what
you're doing) before C++11 then it was already calling for disaster
as .data() was not guaranteed to be null terminated. Then there are
the methods which take a pointer and a length. There it doesn't
matter but they might crash if passed in null (even if the length is
0). Seen it happen more often than I like. I always tell people to
use .c_str() because it is more explicitly stating intentions and it
is backwards compatible.<br>
<br>
null always makes things more complicated than necessary. Just
notice how the library is evolving to gradually remove the word and
value "null" from our everyday usage. That's a good thing. Think in
abstractions, not null. Throwing null at everyone only to enable a
few edge cases seems wrong. One can always come up with situations
where a nullable string_view might be useful, as is the case with
many other things deemed "bad", but in the end it matters how common
that scenario is compared to where a non-null guarantee makes code
safer, simpler and more robust.<br>
<br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--------------060100090409090202030703--
.
Author: Peter Bigot <bigotp@acm.org>
Date: Sun, 19 Jan 2014 17:54:32 -0800 (PST)
Raw View
------=_Part_598_24792908.1390182872735
Content-Type: text/plain; charset=UTF-8
On Sunday, January 19, 2014 1:22:40 PM UTC-6, Magnus Fromreide wrote:
>
> On Sun, Jan 19, 2014 at 12:31:19PM -0600, Peter Bigot wrote:
> > On Sun, Jan 19, 2014 at 11:44 AM, Magnus Fromreide <ma...@lysator.liu.se<javascript:>>wrote:
>
> >
> > > On Sun, Jan 19, 2014 at 07:55:32AM -0800, Peter Bigot wrote:
> > > > On Friday, January 17, 2014 10:19:07 PM UTC-6, Marshall wrote:
> > > > >
> > >
> > > I have thought in a similar direction, but the problem is if you have
> two
> > > string_view's, s1 and s2. Assume that s1 i empty, does the statement
> > > s2 = s1; imply that s2.data() == s1.data()?
> > >
> > > Then what happens if s1 is deallocated and it's memory is returned to
> the
> > > system, won't s2.m_ptr then hold an illegal pointer value, one of
> those
> > > where even loading it could trigger a hardware trap on some
> architectures.
> > >
> >
> > In my approach I detect in the assignment operator and copy constructor
> > whether the RHS is default-constructed, and if so invoke clear() on the
> > LHS/new instance. So in all cases either the reference is to a sequence
> > outside the instance, or it's an empty default-constructed (cleared)
> > instance where data() is a non-dereferenceable pointer to an internal
> charT
> > object: no cross-object pointers.
> >
> > Now that you point it out, this does result in behavior non-conformant
> with
> > the current draft specification for the copy constructor and operator=
> > which are specified as =default.
> >
> > On further reflection it'd better to store a null pointer in m_ptr to
> > represent a default-constructed value but to return &m_nul from data()
> when
> > m_ptr is null. Then the default implementations are retained. This
> still
> > means that data() will be always be non-null, but sv1.data() will not
> > compare equal to sv2.data() if one or both of the instances have been
> > cleared/default-constructed. (sv1 == sv2 will still hold, of course.)
> >
> > Does that address the objection?
>
> The check at copy time seems to solve the problem.
>
> The use of null as a flag value seems to interfere with the "allow null
> string_views"
Yes. I am not in favor of string_view supporting null values as well as
empty values; absence of a value is a distinct concept that should be
treated independently as with std::optional. I think string_view should
support the intersection, not the union, of the information provided by its
underlying concepts (a) std::string and (b) a pair (const charT * ptr,
size_t len). Only the latter is capable of expressing absence-of-a-value
as distinct from empty-string. (In fact it expresses multiple
absence-of-a-value as you could wish to encode information in a non-zero
size() paired with a null data(). Madness that way lies. Just say no to
null data().)
I do think that string_view is more a reference type than a collection type
(thought it is both), so there may be an argument in support of being able
to detect whether an instance holds a valid reference (i.e. does not have a
default-constructed value, including a value equivalent to
default-construction due to invocation of clear()). If this is desirable,
it can be detected easily by adding a member function has_reference() that
returns !!m_ptr.
> and "have an optimized optional<string_view>" proposals
> as both allow null's for other purposes.
>
I can't speak to that question.
Peter
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_598_24792908.1390182872735
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Sunday, January 19, 2014 1:22:40 PM UTC-6, Magn=
us Fromreide wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Sun, Jan=
19, 2014 at 12:31:19PM -0600, Peter Bigot wrote:
<br>> On Sun, Jan 19, 2014 at 11:44 AM, Magnus Fromreide <<a href=3D"=
javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"W_8XQ94iSXwJ" onmou=
sedown=3D"this.href=3D'javascript:';return true;" onclick=3D"this.href=3D'j=
avascript:';return true;">ma...@lysator.liu.se</a>>wrote:
<br>>=20
<br>> > On Sun, Jan 19, 2014 at 07:55:32AM -0800, Peter Bigot wrote:
<br>> > > On Friday, January 17, 2014 10:19:07 PM UTC-6, Marshall =
wrote:
<br>> > > >
<br>> >
<br>> > I have thought in a similar direction, but the problem is if =
you have two
<br>> > string_view's, s1 and s2. Assume that s1 i empty, does the st=
atement
<br>> > s2 =3D s1; imply that s2.data() =3D=3D s1.data()?
<br>> >
<br>> > Then what happens if s1 is deallocated and it's memory is ret=
urned to the
<br>> > system, won't s2.m_ptr then hold an illegal pointer value, on=
e of those
<br>> > where even loading it could trigger a hardware trap on some a=
rchitectures.
<br>> >
<br>>=20
<br>> In my approach I detect in the assignment operator and copy constr=
uctor
<br>> whether the RHS is default-constructed, and if so invoke clear() o=
n the
<br>> LHS/new instance. So in all cases either the reference is to=
a sequence
<br>> outside the instance, or it's an empty default-constructed (cleare=
d)
<br>> instance where data() is a non-dereferenceable pointer to an inter=
nal charT
<br>> object: no cross-object pointers.
<br>>=20
<br>> Now that you point it out, this does result in behavior non-confor=
mant with
<br>> the current draft specification for the copy constructor and opera=
tor=3D
<br>> which are specified as =3Ddefault.
<br>>=20
<br>> On further reflection it'd better to store a null pointer in m_ptr=
to
<br>> represent a default-constructed value but to return &m_nul fro=
m data() when
<br>> m_ptr is null. Then the default implementations are retained=
.. This still
<br>> means that data() will be always be non-null, but sv1.data() will =
not
<br>> compare equal to sv2.data() if one or both of the instances have b=
een
<br>> cleared/default-constructed. (sv1 =3D=3D sv2 will still hold=
, of course.)
<br>>=20
<br>> Does that address the objection?
<br>
<br>The check at copy time seems to solve the problem.
<br>
<br>The use of null as a flag value seems to interfere with the "allow null
<br>string_views" </blockquote><div><br>Yes. I am not in favor of str=
ing_view supporting null values as well as empty values; absence of a value=
is a distinct concept that should be treated independently as with std::op=
tional. I think string_view should support the intersection, not the =
union, of the information provided by its underlying concepts (a) std::stri=
ng and (b) a pair (const charT * ptr, size_t len). Only the latter is=
capable of expressing absence-of-a-value as distinct from empty-string.&nb=
sp; (In fact it expresses multiple absence-of-a-value as you could wish to =
encode information in a non-zero size() paired with a null data(). Ma=
dness that way lies. Just say no to null data().)<br><br>I do think t=
hat string_view is more a reference type than a collection type (thought it=
is both), so there may be an argument in support of being able to detect w=
hether an instance holds a valid reference (i.e. does not have a default-co=
nstructed value, including a value equivalent to default-construction due t=
o invocation of clear()). If this is desirable, it can be detected ea=
sily by adding a member function has_reference() that returns !!m_ptr.<br>&=
nbsp;</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">and "have an optimi=
zed optional<string_view>" proposals
<br>as both allow null's for other purposes.
<br></blockquote><div><br>I can't speak to that question.<br></div><br>Pete=
r<br></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_598_24792908.1390182872735--
.
Author: Paul Tessier <phernost@gmail.com>
Date: Sun, 19 Jan 2014 19:39:14 -0800 (PST)
Raw View
------=_Part_1689_8595788.1390189155087
Content-Type: text/plain; charset=UTF-8
On Sunday, January 19, 2014 8:36:40 PM UTC-5, Miro Knejp wrote:
>
>
>
> For a function like
>
> void print(string const& s) {
> }
>
> there is an implicit precondition: a string can not be constructed from
> a nullptr.
> So you have to check this before calling. When replacing string const&
> with string_view,
> you just need to make the precondition explicit. Then in both cases data()
> != null.
>
> Yes, I as author of print have the implicit precondition enforced by
> std::string that it's always called with a valid string. That is something
> I can rely on. That is a good thing. Changing the signature to accept
> (nullable) string_view suddenly breaks this guarantee and I either have to
> add asserts or some other kinds of checks and document it somewhere and
> needlessly complexify every method relying on this guarantee. That is a bad
> thing. And suddenly you need to create new test cases for print even though
> it was working perfectly. That is also a bad thing.
>
How is that true. If a string_view is null, how is it not valid. All null
views are empty views. No additionally complexity or coding is required.
Calling other members with an empty view is for the most part undefined
behaviour. If data(), begin(), etc. return null or not is irrelevant, and
an arbitrary restriction.
>
> If you use string.data(), you can't simply replace func(string const&)
> with func(string_view)
> even if data() returns non-null, since data() might not be null terminated.
>
> void print(string const& s) {
> printf("%s", s.data());
> }
>
> If yyou don't use data() then, well... its not important if data()
> returns nullptr or not.
>
> If one used .data() to pass it to (const char*) methods (which should ring
> a bell and make you pay *very good attention* to what you're doing) before
> C++11 then it was already calling for disaster as .data() was not
> guaranteed to be null terminated. Then there are the methods which take a
> pointer and a length. There it doesn't matter but they might crash if
> passed in null (even if the length is 0). Seen it happen more often than I
> like. I always tell people to use .c_str() because it is more explicitly
> stating intentions and it is backwards compatible.
>
> null always makes things more complicated than necessary. Just notice how
> the library is evolving to gradually remove the word and value "null" from
> our everyday usage. That's a good thing. Think in abstractions, not null.
> Throwing null at everyone only to enable a few edge cases seems wrong. One
> can always come up with situations where a nullable string_view might be
> useful, as is the case with many other things deemed "bad", but in the end
> it matters how common that scenario is compared to where a non-null
> guarantee makes code safer, simpler and more robust.
>
A legacy interface's poorly handled parameters should not be used as an
excuse for a design argument.
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_1689_8595788.1390189155087
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Sunday, January 19, 2014 8:36:40 PM UTC-5, Miro=
Knejp wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
=20
=20
=20
<div text=3D"#000000" bgcolor=3D"#FFFFFF">
<br>
<blockquote type=3D"cite">
<div dir=3D"ltr">
<div><br>
</div>
<div>For a function like<br>
</div>
<div><br>
</div>
<div><font face=3D"courier new, monospace">void print(string
const& s) {</font></div>
<div><font face=3D"courier new, monospace">}</font></div>
<div><br>
</div>
<div>there is an implicit precondition: a string can not be
constructed from a nullptr.</div>
<div>So you have to check this before calling. When replacing
string const& with string_view,</div>
<div>you just need to make the precondition explicit. Then in
both cases data() !=3D null.</div>
</div>
</blockquote>
Yes, I as author of print have the implicit precondition enforced by
std::string that it's always called with a valid string. That is
something I can rely on. That is a good thing. Changing the
signature to accept (nullable) string_view suddenly breaks this
guarantee and I either have to add asserts or some other kinds of
checks and document it somewhere and needlessly complexify every
method relying on this guarantee. That is a bad thing. And suddenly
you need to create new test cases for print even though it was
working perfectly. That is also a bad thing.<br></div></blockquote><div=
><br>How is that true. If a string_view is null, how is it not valid.=
All null views are empty views. No additionally complexity or =
coding is required. Calling other members with an empty view is for t=
he most part undefined behaviour. If data(), begin(), etc. return nul=
l or not is irrelevant, and an arbitrary restriction.<br></div><blockquote =
class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1p=
x #ccc solid;padding-left: 1ex;"><div text=3D"#000000" bgcolor=3D"#FFFFFF">
<blockquote type=3D"cite">
<div dir=3D"ltr">
<div><br>
</div>
<div>If you use string.data(), you can't simply replace
func(string const&) with func(string_view)</div>
<div>even if data() returns non-null, since data() might not be
null terminated.</div>
<div><br>
</div>
<div><font face=3D"courier new, monospace">void print(string
const& s) {</font></div>
<div><font face=3D"courier new, monospace"> printf("%s",
s.data());</font></div>
<div><font face=3D"courier new, monospace">}</font></div>
<div><br>
</div>
<div>If yyou don't use data() then, well... its not important if
data() returns nullptr or not.<br>
</div>
</div>
</blockquote>
If one used .data() to pass it to (const char*) methods (which
should ring a bell and make you pay *very good attention* to what
you're doing) before C++11 then it was already calling for disaster
as .data() was not guaranteed to be null terminated. Then there are
the methods which take a pointer and a length. There it doesn't
matter but they might crash if passed in null (even if the length is
0). Seen it happen more often than I like. I always tell people to
use .c_str() because it is more explicitly stating intentions and it
is backwards compatible.<br>
</div></blockquote><div> </div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-le=
ft: 1ex;"><div text=3D"#000000" bgcolor=3D"#FFFFFF">null always makes thing=
s more complicated than necessary. Just
notice how the library is evolving to gradually remove the word and
value "null" from our everyday usage. That's a good thing. Think in
abstractions, not null. Throwing null at everyone only to enable a
few edge cases seems wrong. One can always come up with situations
where a nullable string_view might be useful, as is the case with
many other things deemed "bad", but in the end it matters how common
that scenario is compared to where a non-null guarantee makes code
safer, simpler and more robust.<br></div></blockquote><div><br></div><d=
iv>A legacy interface's poorly handled parameters should not be used as an =
excuse for a design argument.<br></div></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_1689_8595788.1390189155087--
.
Author: Paul Tessier <phernost@gmail.com>
Date: Sun, 19 Jan 2014 20:07:45 -0800 (PST)
Raw View
------=_Part_1627_22142613.1390190865793
Content-Type: text/plain; charset=UTF-8
On Sunday, January 19, 2014 8:54:32 PM UTC-5, Peter Bigot wrote:
>
>
>
> On Sunday, January 19, 2014 1:22:40 PM UTC-6, Magnus Fromreide wrote:
>>
>> On Sun, Jan 19, 2014 at 12:31:19PM -0600, Peter Bigot wrote:
>> > On Sun, Jan 19, 2014 at 11:44 AM, Magnus Fromreide <
>> ma...@lysator.liu.se>wrote:
>> >
>> > > On Sun, Jan 19, 2014 at 07:55:32AM -0800, Peter Bigot wrote:
>> > > > On Friday, January 17, 2014 10:19:07 PM UTC-6, Marshall wrote:
>> > > > >
>> > >
>> > > I have thought in a similar direction, but the problem is if you have
>> two
>> > > string_view's, s1 and s2. Assume that s1 i empty, does the statement
>> > > s2 = s1; imply that s2.data() == s1.data()?
>> > >
>> > > Then what happens if s1 is deallocated and it's memory is returned to
>> the
>> > > system, won't s2.m_ptr then hold an illegal pointer value, one of
>> those
>> > > where even loading it could trigger a hardware trap on some
>> architectures.
>> > >
>> >
>> > In my approach I detect in the assignment operator and copy constructor
>> > whether the RHS is default-constructed, and if so invoke clear() on the
>> > LHS/new instance. So in all cases either the reference is to a
>> sequence
>> > outside the instance, or it's an empty default-constructed (cleared)
>> > instance where data() is a non-dereferenceable pointer to an internal
>> charT
>> > object: no cross-object pointers.
>> >
>> > Now that you point it out, this does result in behavior non-conformant
>> with
>> > the current draft specification for the copy constructor and operator=
>> > which are specified as =default.
>> >
>> > On further reflection it'd better to store a null pointer in m_ptr to
>> > represent a default-constructed value but to return &m_nul from data()
>> when
>> > m_ptr is null. Then the default implementations are retained. This
>> still
>> > means that data() will be always be non-null, but sv1.data() will not
>> > compare equal to sv2.data() if one or both of the instances have been
>> > cleared/default-constructed. (sv1 == sv2 will still hold, of course.)
>> >
>> > Does that address the objection?
>>
>> The check at copy time seems to solve the problem.
>>
>> The use of null as a flag value seems to interfere with the "allow null
>> string_views"
>
>
> Yes. I am not in favor of string_view supporting null values as well as
> empty values; absence of a value is a distinct concept that should be
> treated independently as with std::optional. I think string_view should
> support the intersection, not the union, of the information provided by its
> underlying concepts (a) std::string and (b) a pair (const charT * ptr,
> size_t len). Only the latter is capable of expressing absence-of-a-value
> as distinct from empty-string. (In fact it expresses multiple
> absence-of-a-value as you could wish to encode information in a non-zero
> size() paired with a null data(). Madness that way lies. Just say no to
> null data().)
>
Why would ( nullptr, 3 ) be considered an empty view? It's garbage in
almost all use cases but, so is ( (char*)1, 3 ). Defending against one
single bad pointer and ignoring all the rest, solves one out of a myriad of
similar problems. A null view ( null, 0 ) is no different than an empty
view ( (char*)rand(), 0 ). Although, is_null seems pointless if it can be
guaranteed that the following be true.
For any empty string_view N constructed as ( string_view N{ P, 0 } ), that
N.data(), N.begin(), N.end(), etc. all return P.
Currently P is banned from being null. Which seems to solve one corner
case and, creates problems for other, otherwise logical, use cases.
>
> I do think that string_view is more a reference type than a collection
> type (thought it is both), so there may be an argument in support of being
> able to detect whether an instance holds a valid reference (i.e. does not
> have a default-constructed value, including a value equivalent to
> default-construction due to invocation of clear()). If this is desirable,
> it can be detected easily by adding a member function has_reference() that
> returns !!m_ptr.
>
>
All references can become dangling by one way or another. What you
described is a smart pointer with a string interface, which if that's what
you want, I can argue against. It may solve many use cases but, seems
overkill at least considering the current stated goal of string_view.
> and "have an optimized optional<string_view>" proposals
>> as both allow null's for other purposes.
>>
>
> I can't speak to that question.
>
> Peter
>
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_1627_22142613.1390190865793
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Sunday, January 19, 2014 8:54:32 PM UTC-5, Pete=
r Bigot wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"=
><br><br>On Sunday, January 19, 2014 1:22:40 PM UTC-6, Magnus Fromreide wro=
te:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bo=
rder-left:1px #ccc solid;padding-left:1ex">On Sun, Jan 19, 2014 at 12:31:19=
PM -0600, Peter Bigot wrote:
<br>> On Sun, Jan 19, 2014 at 11:44 AM, Magnus Fromreide <<a>ma...@ly=
sator.liu.se</a>>wrote:
<br>>=20
<br>> > On Sun, Jan 19, 2014 at 07:55:32AM -0800, Peter Bigot wrote:
<br>> > > On Friday, January 17, 2014 10:19:07 PM UTC-6, Marshall =
wrote:
<br>> > > >
<br>> >
<br>> > I have thought in a similar direction, but the problem is if =
you have two
<br>> > string_view's, s1 and s2. Assume that s1 i empty, does the st=
atement
<br>> > s2 =3D s1; imply that s2.data() =3D=3D s1.data()?
<br>> >
<br>> > Then what happens if s1 is deallocated and it's memory is ret=
urned to the
<br>> > system, won't s2.m_ptr then hold an illegal pointer value, on=
e of those
<br>> > where even loading it could trigger a hardware trap on some a=
rchitectures.
<br>> >
<br>>=20
<br>> In my approach I detect in the assignment operator and copy constr=
uctor
<br>> whether the RHS is default-constructed, and if so invoke clear() o=
n the
<br>> LHS/new instance. So in all cases either the reference is to=
a sequence
<br>> outside the instance, or it's an empty default-constructed (cleare=
d)
<br>> instance where data() is a non-dereferenceable pointer to an inter=
nal charT
<br>> object: no cross-object pointers.
<br>>=20
<br>> Now that you point it out, this does result in behavior non-confor=
mant with
<br>> the current draft specification for the copy constructor and opera=
tor=3D
<br>> which are specified as =3Ddefault.
<br>>=20
<br>> On further reflection it'd better to store a null pointer in m_ptr=
to
<br>> represent a default-constructed value but to return &m_nul fro=
m data() when
<br>> m_ptr is null. Then the default implementations are retained=
.. This still
<br>> means that data() will be always be non-null, but sv1.data() will =
not
<br>> compare equal to sv2.data() if one or both of the instances have b=
een
<br>> cleared/default-constructed. (sv1 =3D=3D sv2 will still hold=
, of course.)
<br>>=20
<br>> Does that address the objection?
<br>
<br>The check at copy time seems to solve the problem.
<br>
<br>The use of null as a flag value seems to interfere with the "allow null
<br>string_views" </blockquote><div><br>Yes. I am not in favor of str=
ing_view supporting null values as well as empty values; absence of a value=
is a distinct concept that should be treated independently as with std::op=
tional. I think string_view should support the intersection, not the =
union, of the information provided by its underlying concepts (a) std::stri=
ng and (b) a pair (const charT * ptr, size_t len). Only the latter is=
capable of expressing absence-of-a-value as distinct from empty-string.&nb=
sp; (In fact it expresses multiple absence-of-a-value as you could wish to =
encode information in a non-zero size() paired with a null data(). Ma=
dness that way lies. Just say no to null data().)<br></div></div></bl=
ockquote><div><br>Why would ( nullptr, 3 ) be considered an empty view?&nbs=
p; It's garbage in almost all use cases but, so is ( (char*)1, 3 ). D=
efending against one single bad pointer and ignoring all the rest, solves o=
ne out of a myriad of similar problems. A null view ( null, 0 ) is no=
different than an empty view ( (char*)rand(), 0 ). Although, is_null=
seems pointless if it can be guaranteed that the following be true.<br><br=
>For any empty string_view N constructed as ( string_view N{ P, 0 } ), that=
N.data(), N.begin(), N.end(), etc. all return P.<br><br>Currently P is ban=
ned from being null. Which seems to solve one corner case and, create=
s problems for other, otherwise logical, use cases.<br> <br></div><blo=
ckquote 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><br>I do thi=
nk that string_view is more a reference type than a collection type (though=
t it is both), so there may be an argument in support of being able to dete=
ct whether an instance holds a valid reference (i.e. does not have a defaul=
t-constructed value, including a value equivalent to default-construction d=
ue to invocation of clear()). If this is desirable, it can be detecte=
d easily by adding a member function has_reference() that returns !!m_ptr.<=
br> </div></div></blockquote><div><br>All references can become dangli=
ng by one way or another. What you described is a smart pointer with =
a string interface, which if that's what you want, I can argue against.&nbs=
p; It may solve many use cases but, seems overkill at least considering the=
current stated goal of string_view.<br> </div><blockquote class=3D"gm=
ail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc soli=
d;padding-left: 1ex;"><div dir=3D"ltr"><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1=
ex">and "have an optimized optional<string_view>" proposals
<br>as both allow null's for other purposes.
<br></blockquote><div><br>I can't speak to that question.<br></div><br>Pete=
r<br></div></blockquote></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_1627_22142613.1390190865793--
.
Author: Nevin Liber <nevin@eviloverlord.com>
Date: Mon, 20 Jan 2014 00:01:16 -0600
Raw View
--f46d0421a6391fae4f04f060a164
Content-Type: text/plain; charset=ISO-8859-1
On 19 January 2014 22:07, Paul Tessier <phernost@gmail.com> wrote:
> Why would ( nullptr, 3 ) be considered an empty view?
>
It would be undefined behavior.
My personal preference for all this is that string_view(nullptr, 0) be
allowed, and it is a Quality of Implementation issue whether or not
sv.data() can ever return a nullptr; i.e., it would be allowed to return
any legal pointer it wants for an empty string_view.
> --
>
Nevin ":-)" Liber <mailto:nevin@eviloverlord.com> (847) 691-1404
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--f46d0421a6391fae4f04f060a164
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On 19 January 2014 22:07, Paul Tessier <span dir=3D"ltr">&=
lt;<a href=3D"mailto:phernost@gmail.com" target=3D"_blank">phernost@gmail.c=
om</a>></span> wrote:<br><div class=3D"gmail_extra"><div class=3D"gmail_=
quote"><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><div class=3D"h5"><span style=3D"color:rgb(34,34,34)"=
>Why would ( nullptr, 3 ) be considered an empty view?</span><br></div></di=
v></div></blockquote><div><br></div><div>It would be undefined behavior.</d=
iv>
<div><br></div><div>My personal preference for all this is that string_view=
(nullptr, 0) be allowed, and it is a Quality of Implementation issue whethe=
r or not sv.data() can ever return a nullptr; i.e., it would be allowed to =
return any legal pointer it wants for an empty string_view.</div>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>--=A0<br></div></div><=
/blockquote></div>=A0Nevin ":-)" Liber=A0 <mailto:<a href=3D"m=
ailto:nevin@eviloverlord.com" target=3D"_blank">nevin@eviloverlord.com</a>&=
gt;=A0 (847) 691-1404
</div></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--f46d0421a6391fae4f04f060a164--
.
Author: Jeffrey Yasskin <jyasskin@google.com>
Date: Sun, 19 Jan 2014 22:12:55 -0800
Raw View
On Sun, Jan 19, 2014 at 10:01 PM, Nevin Liber <nevin@eviloverlord.com> wrote:
> On 19 January 2014 22:07, Paul Tessier <phernost@gmail.com> wrote:
>>
>> Why would ( nullptr, 3 ) be considered an empty view?
>
>
> It would be undefined behavior.
>
> My personal preference for all this is that string_view(nullptr, 0) be
> allowed, and it is a Quality of Implementation issue whether or not
> sv.data() can ever return a nullptr; i.e., it would be allowed to return any
> legal pointer it wants for an empty string_view.
That's interesting. It's easier to both specify and implement to just
say that string_view(x, y).data()==x and string_view(x, y).size()==y,
assuming [x, x+y) is a valid range. Why would you special-case data()
to return arbitrary things when y==0?
Thanks,
Jeffrey (who's adding the data()==nullptr option to the paper as we speak)
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Nevin Liber <nevin@eviloverlord.com>
Date: Mon, 20 Jan 2014 00:25:58 -0600
Raw View
--f46d043c7de66b9a3f04f060f977
Content-Type: text/plain; charset=ISO-8859-1
On 20 January 2014 00:12, Jeffrey Yasskin <jyasskin@google.com> wrote:
> > My personal preference for all this is that string_view(nullptr, 0) be
> > allowed, and it is a Quality of Implementation issue whether or not
> > sv.data() can ever return a nullptr; i.e., it would be allowed to return
> any
> > legal pointer it wants for an empty string_view.
>
> That's interesting. It's easier to both specify and implement to just
> say that string_view(x, y).data()==x and string_view(x, y).size()==y,
> assuming [x, x+y) is a valid range. Why would you special-case data()
> to return arbitrary things when y==0?
>
A debugging implementation may want to ensure that developers aren't
dependent on "knowing" that a nullptr was passed in.
--
Nevin ":-)" Liber <mailto:nevin@eviloverlord.com> (847) 691-1404
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--f46d043c7de66b9a3f04f060f977
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On 20 January 2014 00:12, Jeffrey Yasskin <span dir=3D"ltr=
"><<a href=3D"mailto:jyasskin@google.com" target=3D"_blank">jyasskin@goo=
gle.com</a>></span> wrote:<br><div class=3D"gmail_extra"><div class=3D"g=
mail_quote">
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div class=3D"im">> My personal preferenc=
e for all this is that string_view(nullptr, 0) be<br>
> allowed, and it is a Quality of Implementation issue whether or not<br=
>
> sv.data() can ever return a nullptr; i.e., it would be allowed to retu=
rn any<br>
> legal pointer it wants for an empty string_view.<br>
<br>
</div>That's interesting. It's easier to both specify and implement=
to just<br>
say that string_view(x, y).data()=3D=3Dx and string_view(x, y).size()=3D=3D=
y,<br>
assuming [x, x+y) is a valid range. Why would you special-case data()<br>
to return arbitrary things when y=3D=3D0?<br></blockquote><div><br></div><d=
iv>A debugging implementation may want to ensure that developers aren't=
dependent on "knowing" that a nullptr was passed in.</div></div>
-- <br>=A0Nevin ":-)" Liber=A0 <mailto:<a href=3D"mailto:nevin=
@eviloverlord.com" target=3D"_blank">nevin@eviloverlord.com</a>>=A0 (847=
) 691-1404
</div></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--f46d043c7de66b9a3f04f060f977--
.
Author: Jeffrey Yasskin <jyasskin@google.com>
Date: Sun, 19 Jan 2014 23:36:00 -0800
Raw View
--001a113a54d6b4530004f061f22b
Content-Type: text/plain; charset=ISO-8859-1
On Sun, Jan 19, 2014 at 10:25 PM, Nevin Liber <nevin@eviloverlord.com> wrote:
> On 20 January 2014 00:12, Jeffrey Yasskin <jyasskin@google.com> wrote:
>>
>> > My personal preference for all this is that string_view(nullptr, 0) be
>> > allowed, and it is a Quality of Implementation issue whether or not
>> > sv.data() can ever return a nullptr; i.e., it would be allowed to return
>> > any
>> > legal pointer it wants for an empty string_view.
>>
>> That's interesting. It's easier to both specify and implement to just
>> say that string_view(x, y).data()==x and string_view(x, y).size()==y,
>> assuming [x, x+y) is a valid range. Why would you special-case data()
>> to return arbitrary things when y==0?
>
>
> A debugging implementation may want to ensure that developers aren't
> dependent on "knowing" that a nullptr was passed in.
Thanks. I think I don't personally want that, but I've added your
reason to the "if we want data()==nullptr" section in the attached
draft. I plan to send this to Clark tomorrow (Monday) morning.
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a113a54d6b4530004f061f22b
Content-Type: text/html; charset=UTF-8; name="string_view.html"
Content-Disposition: attachment; filename="string_view.html"
Content-Transfer-Encoding: base64
X-Attachment-Id: f_hqnf6cjp0
PCFET0NUWVBFIGh0bWw+CjxodG1sIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1s
Ij4KICA8aGVhZD4KICAgIDxtZXRhIGNvbnRlbnQ9InRleHQvaHRtbDtjaGFyc2V0PVVURi04IiBo
dHRwLWVxdWl2PSJDb250ZW50LVR5cGUiLz4KICAgIDxtZXRhIGNoYXJzZXQ9IlVURi04Ii8+CiAg
ICA8dGl0bGU+c3RyaW5nX3ZpZXc6IGEgbm9uLW93bmluZyByZWZlcmVuY2UgdG8gYSBzdHJpbmcs
IHJldmlzaW9uIDY8L3RpdGxlPgo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgpib2R5IHtjb2xvcjog
IzAwMDAwMDsgYmFja2dyb3VuZC1jb2xvcjogI0ZGRkZGRjt9CgpkZWwge3RleHQtZGVjb3JhdGlv
bjogbGluZS10aHJvdWdoOyBjb2xvcjogIzhCMDA0MDt9CmlucyB7dGV4dC1kZWNvcmF0aW9uOiB1
bmRlcmxpbmU7IGNvbG9yOiAjMDA1MTAwO30KCnByZSBjb2RlIHtkaXNwbGF5OiBpbmxpbmUtYmxv
Y2s7IHdoaXRlLXNwYWNlOiBpbmhlcml0fQpjb2RlIHt3aGl0ZS1zcGFjZTogbm93cmFwfQpjb2Rl
IHdiciB7d2hpdGUtc3BhY2U6IG5vcm1hbH0KCi8qCi53b3JkaW5nIHsgbWF4LXdpZHRoOiA5MGV4
OyB9Ci53b3JkaW5nIC5zZWN0bnVtIHsgbWFyZ2luLXJpZ2h0OiAxZW07IH0KLndvcmRpbmcgLnNl
Y3RuYW1lIHsgZGlzcGxheTogYmxvY2s7IGZsb2F0OiByaWdodDsgIH0KCnNlY3Rpb24ubnVtYmVy
ZWQgeyBjb3VudGVyLXJlc2V0OiBwYXItbnVtOyB9Ci53b3JkaW5nIHA6YmVmb3JlLCAud29yZGlu
ZyBkdDpiZWZvcmUgewogICAgY29udGVudDogY291bnRlcihwYXItbnVtKSAiICI7IGNvdW50ZXIt
aW5jcmVtZW50OiBwYXItbnVtOwogICAgZm9udC1zaXplOiA4MCU7IHBvc2l0aW9uOiBhYnNvbHV0
ZTsgbGVmdDogMmVtfQoqLwoud29yZGluZyB0ZCB7IGJvcmRlci10b3A6IHRoaW4gc29saWQgYmxh
Y2s7IGJvcmRlci1ib3R0b206IHRoaW4gc29saWQgYmxhY2s7IH0KCnNlY3Rpb24uZnVuY3Rpb24g
eyBjbGVhcjogYm90aDsgfQouYXR0cmlidXRlcywgLmF0dHJpYnV0ZSB7bWFyZ2luLWxlZnQ6IDJl
bX0KCi5kb2NpbmZvIHtmbG9hdDogcmlnaHR9Ci5kb2NpbmZvIHAge21hcmdpbjogMDsgdGV4dC1h
bGlnbjpyaWdodDsgZm9udC1zdHlsZTogaXRhbGljfQoKc2VjdGlvbiB7cGFkZGluZy1sZWZ0OiAx
NnB4fQpzZWN0aW9uIGgyLCBzZWN0aW9uIGgzLCBzZWN0aW9uIGg0LCBzZWN0aW9uIGg1LCBzZWN0
aW9uIGg2IHttYXJnaW4tbGVmdDogLTE2cHh9CgpoMiwgaDMsIGg0LCBoNSwgaDYgeyBtYXJnaW4t
Ym90dG9tOiAuNzVlbSB9Cmg1LCBoNiB7IGZvbnQtc2l6ZTogMWVtOyB9Ci53b3JkaW5nIGg0IHsg
Zm9udC1zaXplOiAxLjE3ZW0gfQpwIHttYXJnaW4tdG9wOiAuNWVtOyBtYXJnaW4tYm90dG9tOiAu
NWVtfQpwOmZpcnN0LWNoaWxkLCB1bCwgb2wge21hcmdpbi10b3A6IDB9Ci50b2RvIGR0Om5vdCg6
Zmlyc3QtY2hpbGQpIHttYXJnaW4tdG9wOiAuNWVtfQpwLCBsaSwgZGQsIHRhYmxlIHttYXgtd2lk
dGg6IDgwZXh9Cgp0YWJsZSB7IG1hcmdpbjogMWVtOyBib3JkZXItY29sbGFwc2U6IGNvbGxhcHNl
OyAgYm9yZGVyOiB0aGluIHNvbGlkIGJsYWNrfQouc3RyYXdwb2xsIHRkIHt0ZXh0LWFsaWduOiBj
ZW50ZXJ9Ci53b3JkaW5nIHRhYmxlIHsgYm9yZGVyOiBkb3VibGU7IH0KY2FwdGlvbiB7IHdoaXRl
LXNwYWNlOiBwcmU7IH0KLndvcmRpbmcgdGQgeyB0ZXh0LWFsaWduOiBsZWZ0OyB9CgoKLmV4YW1w
bGUge2Rpc3BsYXk6IGlubGluZS1ibG9jazsgY2xlYXI6IGJvdGg7IG1hcmdpbi1sZWZ0OiAxZXg7
CiAgICAgICAgICBib3JkZXI6IHRoaW4gc29saWQgIzBlMDsgYmFja2dyb3VuZC1jb2xvcjogI2Y4
ZjhmODsgcGFkZGluZzogMWV4fQoKLmVkbm90ZSB7ZGlzcGxheTogaW5saW5lLWJsb2NrOyBjbGVh
cjogYm90aDsgbWFyZ2luLWxlZnQ6IDFleDsKICAgICAgICAgYm9yZGVyOiB0aGluIHNvbGlkICMw
ZTA7IGJhY2tncm91bmQtY29sb3I6ICNmOGY4Zjg7IHBhZGRpbmc6IDFleH0KCmRpdi5lZG5vdGUg
PiAqOmZpcnN0LWNoaWxkOjpiZWZvcmUge2NvbnRlbnQ6ICJOb3RlOiAiOyBkaXNwbGF5OiBpbmxp
bmU7IGZvbnQtd2VpZ2h0OiBib2xkfQpkaXYuZWRub3RlIHtkaXNwbGF5OiBpbmxpbmUtYmxvY2s7
IG1hcmdpbi1sZWZ0OiAxZXg7IGJvcmRlcjogdGhpbiBzb2xpZCAjZmI2OwogICAgICAgICAgICBw
YWRkaW5nOiAxZXg7IGJhY2tncm91bmQtY29sb3I6ICNmZmY0ZGR9Cgo6dGFyZ2V0IHtiYWNrZ3Jv
dW5kLWNvbG9yOiAjZmVkfQo8L3N0eWxlPgoKPC9oZWFkPgo8Ym9keT4KICA8aGVhZGVyPgogICAg
PGRpdiBjbGFzcz0iZG9jaW5mbyI+CiAgICAgIDxwPklTTy9JRUMgSlRDMSBTQzIyIFdHMjEgRDM4
NDk8L3A+CiAgICAgIDxwPkRhdGU6IDx0aW1lIHB1YmRhdGU9IiI+MjAxNC0wMS0xOTwvdGltZT48
L3A+CiAgICAgIDxhZGRyZXNzPgogICAgICAgIDxwPkplZmZyZXkgWWFzc2tpbiAmbHQ7PGEgaHJl
Zj0ibWFpbHRvOmp5YXNza2luQGdvb2dsZS5jb20iPmp5YXNza2luQGdvb2dsZS5jb208L2E+Jmd0
OzwvcD4KICAgICAgPC9hZGRyZXNzPgogICAgPC9kaXY+CiAgICA8aDE+PGNvZGU+c3RyaW5nX3Zp
ZXc8L2NvZGU+OiBhIG5vbi1vd25pbmcgcmVmZXJlbmNlIHRvIGEgc3RyaW5nLCByZXZpc2lvbiA2
PC9oMT4KICA8L2hlYWRlcj4KICA8cD48c21hbGw+PGEgaHJlZj0iI21haW5jb250ZW50Ij5Ta2lw
IHRhYmxlIG9mIGNvbnRlbnRzPC9hPjwvc21hbGw+PC9wPgogIDxuYXYgaWQ9InRvYyI+PC9uYXY+
CiAgPGEgaWQ9Im1haW5jb250ZW50Ij48L2E+CiAgPHNlY3Rpb24+CiAgICA8aDIgaWQ9Im92ZXJ2
aWV3Ij5PdmVydmlldzwvaDI+CiAgICA8cD5SZWZlcmVuY2VzIHRvIHN0cmluZ3MgYXJlIHZlcnkg
Y29tbW9uIGluIEMrKyBwcm9ncmFtcywgYnV0CiAgICBvZnRlbiB0aGUgY2FsbGVlIGRvZXNuJ3Qg
Y2FyZSBhYm91dCB0aGUgZXhhY3QgdHlwZSBvZiB0aGUgb2JqZWN0CiAgICB0aGF0IG93bnMgdGhl
IGRhdGEuIDMgdGhpbmdzIGdlbmVyYWxseSBoYXBwZW4gaW4gdGhpcyBjYXNlOjwvcD4KICAgIDxv
bD4KICAgICAgPGxpPlRoZSBjYWxsZWUgdGFrZXMgPGNvZGU+Y29uc3Qgc3RkOjpzdHJpbmcmPC9j
b2RlPiBhbmQgaW5zaXN0cwogICAgICB0aGF0IGNhbGxlcnMgY29weSB0aGUgZGF0YSBpZiBpdCB3
YXMgb3JpZ2luYWxseSBvd25lZCBieSBhbm90aGVyCiAgICAgIHR5cGUuPC9saT4KCiAgICAgIDxs
aT5UaGUgY2FsbGVlIHRha2VzIHR3byBwYXJhbWV0ZXJzJiM4MjEyO2EgPGNvZGU+Y2hhcio8L2Nv
ZGU+IGFuZAogICAgICBhIGxlbmd0aCAob3IganVzdCA8Y29kZT5jaGFyKjwvY29kZT4gYW5kIGFz
c3VtZXMKICAgICAgMC10ZXJtaW5hdGlvbikmIzgyMTI7YW5kIHJlZHVjZXMgdGhlIHJlYWRhYmls
aXR5IGFuZCBzYWZldHkgb2YKICAgICAgY2FsbHMgYW5kIGxvc2VzIGFueSBoZWxwZXIgZnVuY3Rp
b25zIHRoZSBvcmlnaW5hbCB0eXBlCiAgICAgIHByb3ZpZGVkLjwvbGk+CgogICAgICA8bGk+VGhl
IGNhbGxlZSBpcyByZXdyaXR0ZW4gYXMgYSB0ZW1wbGF0ZSBhbmQgaXRzIGltcGxlbWVudGF0aW9u
CiAgICAgIGlzIG1vdmVkIHRvIGEgaGVhZGVyIGZpbGUuIFRoaXMgY2FuIGluY3JlYXNlIGZsZXhp
YmlsaXR5IGlmIHRoZQogICAgICBhdXRob3IgdGFrZXMgdGhlIHRpbWUgdG8gY29kZSB0byBhIHdl
YWtlciBpdGVyYXRvciBjb25jZXB0LCBidXQgaXQKICAgICAgY2FuIGFsc28gaW5jcmVhc2UgY29t
cGlsZSB0aW1lIGFuZCBjb2RlIHNpemUsIGFuZCBjYW4gZXZlbgogICAgICBpbnRyb2R1Y2UgYnVn
cyBpZiB0aGUgYXV0aG9yIG1pc3NlcyBhbiBhc3N1bXB0aW9uIHRoYXQgdGhlCiAgICAgIGFyZ3Vt
ZW50J3MgY29udGVudHMgYXJlIGNvbnRpZ3VvdXMuPC9saT4KICAgIDwvb2w+CgogICAgPHA+R29v
Z2xlLCBMTFZNLCBhbmQgQmxvb21iZXJnIGhhdmUgaW5kZXBlbmRlbnRseSBpbXBsZW1lbnRlZCBh
CiAgICBzdHJpbmctcmVmZXJlbmNlIHR5cGUgdG8gZW5jYXBzdWxhdGUgdGhpcyBraW5kIG9mIGFy
Z3VtZW50LiA8YQogICAgaHJlZj0iI2Jhc2ljLnN0cmluZy52aWV3Ij48Y29kZT5zdHJpbmdfdmll
dzwvY29kZT48L2E+IGlzIGltcGxpY2l0bHkKICAgIGNvbnN0cnVjdGlibGUgZnJvbSA8Y29kZT5j
b25zdCBjaGFyKjwvY29kZT4gYW5kIDxjb2RlPnN0ZDo6c3RyaW5nPC9jb2RlPi4gSXQKICAgIHBy
b3ZpZGVzIHRoZSA8Y29kZT5jb25zdDwvY29kZT4gbWVtYmVyIG9wZXJhdGlvbnMgZnJvbQogICAg
PGNvZGU+c3RkOjpzdHJpbmc8L2NvZGU+IHRvIGVhc2UgY29udmVyc2lvbi4gVGhpcyBwYXBlciBm
b2xsb3dzIDxhCiAgICBocmVmPSJodHRwOi8vc3JjLmNocm9taXVtLm9yZy92aWV3dmMvY2hyb21l
L3RydW5rL3NyYy9iYXNlL3N0cmluZ3Mvc3RyaW5nX3BpZWNlLmg/dmlldz1tYXJrdXAiPkNocm9t
aXVtPC9hPgogICAgYW5kIDxhCiAgICBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vYmxvb21iZXJn
L2JzbC9ibG9iL21hc3Rlci9ncm91cHMvYnNsL2JzbHN0bC9ic2xzdGxfc3RyaW5ncmVmLmgiPkJs
b29tYmVyZzwvYT4KICAgIGluIGV4dGVuZGluZyA8Y29kZT5zdHJpbmdfdmlldzwvY29kZT4gdG8g
PGNvZGU+PGEKICAgIGhyZWY9IiNiYXNpYy5zdHJpbmcudmlldyI+YmFzaWNfc3RyaW5nX3ZpZXc8
L2E+Jmx0O2NoYXJUJmd0OzwvY29kZT4sIGFuZAogICAgZnVydGhlciBleHRlbmRzIGl0IHRvIGlu
Y2x1ZGUgYSA8Y29kZT50cmFpdHM8L2NvZGU+IHBhcmFtZXRlciB0byBtYXRjaAogICAgPGNvZGU+
YmFzaWNfc3RyaW5nPC9jb2RlPi4gV2UgcHJvdmlkZSB0eXBlZGVmcyB0byBwYXJhbGxlbCB0aGUg
NAogICAgPGNvZGU+YmFzaWNfc3RyaW5nPC9jb2RlPiB0eXBlZGVmcy48L3A+CgogICAgPHA+Qm90
aCBHb29nbGUncyBhbmQgTExWTSdzIDxjb2RlPnN0cmluZ192aWV3PC9jb2RlPiB0eXBlcyAoYnV0
IG5vdAogICAgQmxvb21iZXJnJ3MpIGV4dGVuZCB0aGUgaW50ZXJmYWNlIGZyb20gPGNvZGU+c3Rk
OjpzdHJpbmc8L2NvZGU+IHRvIHByb3ZpZGUKICAgIHNvbWUgaGVscGZ1bCB1dGlsaXR5IGZ1bmN0
aW9uczo8L3A+CiAgICA8dWw+CiAgICAgIDxsaT5zdGFydHNfd2l0aDwvbGk+CiAgICAgIDxsaT5l
bmRzX3dpdGg8L2xpPgogICAgICA8bGk+PGEgaHJlZj0iI3N0cmluZy52aWV3Lm1vZGlmaWVycyI+
cmVtb3ZlX3ByZWZpeDwvYT48L2xpPgogICAgICA8bGk+PGEgaHJlZj0iI3N0cmluZy52aWV3Lm1v
ZGlmaWVycyI+cmVtb3ZlX3N1ZmZpeDwvYT48L2xpPgogICAgICA8bGk+c3BsaXQ8L2xpPgogICAg
ICA8bGk+dHJpbTwvbGk+CiAgICAgIDxsaT5jb25zdW1lX3ByZWZpeDwvbGk+CiAgICAgIDxsaT5j
b3VudDwvbGk+CiAgICA8L3VsPgoKICAgIDxwPlZlcnNpb25zIG9mIDxjb2RlPnN0ZDo6c3RyaW5n
PC9jb2RlPiBvcGVyYXRpb25zIHRoYXQgdGFrZQogICAgPGNvZGU+c3RyaW5nX3ZpZXc8L2NvZGU+
IGluc3RlYWQgYWxzbyBnaXZlIHRoZSBzdGFuZGFyZCBhIHdheSB0byBwcm92aWRlCiAgICBpbi1w
bGFjZSBvcGVyYXRpb25zIG9uIG5vbi1udWxsLXRlcm1pbmF0ZWQgYnl0ZS9jaGFyYWN0ZXIgc2Vx
dWVuY2VzOjwvcD4KICAgIDx1bD4KICAgICAgPGxpPjxhIGhyZWY9IiNiYXNpYy5zdHJpbmcuaGFz
aCI+aGFzaDwvYT4sIGFzIHJlcXVlc3RlZCBieSBjKytzdGQtbGliLTMxOTM1PC9saT4KICAgICAg
PGxpPkluIGEgZnV0dXJlIGFkZGl0aW9uLCBudW1lcmljIGNvbnZlcnNpb25zPC9saT4KICAgIDwv
dWw+CiAgPC9zZWN0aW9uPgoKICA8c2VjdGlvbj4KICAgIDxoMiBpZD0iaW52ZW50aW9ucyI+SW52
ZW50aW9ucyBpbiB0aGlzIHBhcGVyPC9oMj4KCiAgICA8cD5Hb29nbGUncyA8Y29kZT5TdHJpbmdQ
aWVjZTwvY29kZT4gcHJvdmlkZXMgPGNvZGU+YXNfc3RyaW5nPC9jb2RlPiBhbmQKICAgIDxjb2Rl
PlRvU3RyaW5nPC9jb2RlPiBtZXRob2RzIHRvIGNvbnZlcnQgdG8gPGNvZGU+c3RkOjpzdHJpbmc8
L2NvZGU+LiBMTFZNJ3MKICAgIDxjb2RlPlN0cmluZ1JlZjwvY29kZT4gcHJvdmlkZXMgYm90aCBh
IDxjb2RlPnN0cigpPC9jb2RlPiBleHBsaWNpdAogICAgY29udmVyc2lvbiBhbmQgYW4gaW1wbGlj
aXQgPGNvZGU+b3BlcmF0b3Igc3RkOjpzdHJpbmcoKTwvY29kZT4uIFNpbmNlIHRoaXMKICAgIHBh
cGVyIGJ1aWxkcyBvbiB0b3Agb2YgQysrMTEsIHdlIHByb3ZpZGUgYW4gPGEKICAgIGhyZWY9IiNz
dHJpbmcuY29ucyI+PGVtPjxjb2RlPmV4cGxpY2l0PC9jb2RlPjwvZW0+IGNvbnZlcnNpb24KICAg
IGNvbnN0cnVjdG9yPC9hPiBhcyB3ZWxsIGFzIGEgbGVzcyB2ZXJib3NlIDxhCiAgICBocmVmPSIj
c3RyaW5nLnZpZXcubm9ubWVtIj48Y29kZT50b19zdHJpbmc8L2NvZGU+IGZ1bmN0aW9uPC9hPi48
L3A+CgogICAgPHA+Tm9uZSBvZiB0aGUgZXhpc3RpbmcgY2xhc3NlcyBoYXZlIDxjb2RlPmNvbnN0
ZXhwcjwvY29kZT4gbWV0aG9kcy48L3A+CiAgPC9zZWN0aW9uPgoKICA8c2VjdGlvbj4KICAgIDxo
MiBpZD0iYmlrZXNoZWQiPkJpa2VzaGVkITwvaDI+CgogICAgPHA+V2UgZm91bmQgcm91Z2ggPGEK
ICAgIGhyZWY9Imh0dHBzOi8vZ3JvdXBzLmdvb2dsZS5jb20vYS9pc29jcHAub3JnL2QvdG9waWMv
c3RkLXByb3Bvc2Fscy81c1c4eXA1aThtby9kaXNjdXNzaW9uIj5jb25zZW5zdXMKICAgIGFyb3Vu
ZCByZW5hbWluZyB0aGlzIGNsYXNzIHRvIDxjb2RlPnN0cmluZ192aWV3PC9jb2RlPjwvYT4uIE90
aGVyIG9wdGlvbnMKICAgIGluY2x1ZGVkOjwvcD4KCiAgICA8dWw+CiAgICAgIDxsaT5iYXNpY19z
dHJpbmdfcmFuZ2UgKG1lYW5pbmcgYSB0ZW1wbGF0ZWQgaXRlcmF0b3IgcmFuZ2UpPC9saT4KICAg
ICAgPGxpPmNoYXJfcmFuZ2U8L2xpPgogICAgICA8bGk+Y29uc3Rfc3RyaW5nX2ZhY2FkZTwvbGk+
CiAgICAgIDxsaT5leHRfc3RyaW5nPC9saT4KICAgICAgPGxpPmV4dGVybmFsX3N0cmluZzwvbGk+
CiAgICAgIDxsaT5zdHJfcmVmPC9saT4KICAgICAgPGxpPnN0cmluZ19jcmVmIChhbmQgc3RyaW5n
X3JlZiBmb3Igbm9uLWNvbnN0KTwvbGk+CiAgICAgIDxsaT5zdHJpbmdfcGllY2U8L2xpPgogICAg
ICA8bGk+c3RyaW5nX3JhbmdlPC9saT4KICAgICAgPGxpPnN0cmluZ19yZWY8L2xpPgogICAgICA8
bGk+PHN0cm9uZz5zdHJpbmdfdmlldzwvc3Ryb25nPjwvbGk+CiAgICAgIDxsaT5zdWJfc3RyaW5n
PC9saT4KICAgIDwvdWw+CiAgPC9zZWN0aW9uPgoKICA8c2VjdGlvbj4KICAgIDxoMiBpZD0ibW9k
aWZpY2F0aW9ucyI+TW9kaWZpY2F0aW9ucyB2cyBzdGQ6OnN0cmluZzwvaDI+CgogICAgPHA+VGhl
IGludGVyZmFjZSBvZiA8Y29kZT5zdHJpbmdfdmlldzwvY29kZT4gaXMgc2ltaWxhciB0bywgYnV0
IG5vdCBleGFjdGx5CiAgICB0aGUgc2FtZSBhcyB0aGUgaW50ZXJmYWNlIG9mIDxjb2RlPnN0ZDo6
c3RyaW5nPC9jb2RlPi4gIEluIGdlbmVyYWwsIHdlIHdhbnQKICAgIHRvIG1pbmltaXplIGRpZmZl
cmVuY2VzIGJldHdlZW4gPGNvZGU+c3RkOjpzdHJpbmc8L2NvZGU+IGFuZAogICAgPGNvZGU+c3Ry
aW5nX3ZpZXc8L2NvZGU+IHNvIHRoYXQgdXNlcnMgY2FuIGdvIGJhY2sgYW5kIGZvcnRoIGJldHdl
ZW4gdGhlIHR3bwogICAgb2Z0ZW4uICBUaGlzIHNlY3Rpb24ganVzdGlmaWVzIHRoZSBkaWZmZXJl
bmNlcyB3aG9zZSB1dGlsaXR5IHdlIHRoaW5rCiAgICBvdmVyY29tZXMgdGhhdCBnZW5lcmFsIHJ1
bGUuPC9wPgoKICAgIDxoMyBpZD0iYWRkaXRpb25zIj5BZGRpdGlvbjwvaDM+CiAgICA8dWw+CiAg
ICAgIDxsaT48Y29kZT48YQogICAgICBocmVmPSIjc3RyaW5nLnZpZXcubW9kaWZpZXJzIj5yZW1v
dmVfcHJlZml4KCk8L2E+PC9jb2RlPiBhbmQKICAgICAgPGNvZGU+PGEKICAgICAgaHJlZj0iI3N0
cmluZy52aWV3Lm1vZGlmaWVycyI+cmVtb3ZlX3N1ZmZpeCgpPC9hPjwvY29kZT4gbWFrZQogICAg
ICBpdCBlYXN5IHRvIHBhcnNlIHN0cmluZ3MgdXNpbmcgPGNvZGU+c3RyaW5nX3ZpZXc8L2NvZGU+
LiAgVGhleSBjb3VsZCBib3RoCiAgICAgIGJlIGltcGxlbWVudGVkIGFzIG5vbi1tZW1iZXIgZnVu
Y3Rpb25zIChlLmcuIDxjb2RlPnN0ci5yZW1vdmVfcHJlZml4KG4pCiAgICAgIDx3YnIvPj09PTx3
YnIvPiBzdHIgPSBzdHIuc3Vic3RyKG4pPC9jb2RlPiksIGJ1dCBpdCBzZWVtcyB1c2VmdWwgdG8K
ICAgICAgcHJvdmlkZSB0aGUgc2ltcGxlc3QgbXV0YXRvcnMgYXMgbWVtYmVyIGZ1bmN0aW9ucy4g
IE5vdGUgdGhhdCBvdGhlcgogICAgICB0cmF2ZXJzYWwgcHJpbWl0aXZlcyBuZWVkIHRvIGJlIG5v
bi1tZW1iZXJzIHNvIHRoYXQgdGhleSdyZQogICAgICBleHRlbnNpYmxlLCB3aGljaCBtYXkgYXJn
dWUgZm9yIHB1bGxpbmcgdGhlc2Ugb3V0IHRvby48L2xpPgogICAgPC91bD4KICA8L3NlY3Rpb24+
CgogIDxzZWN0aW9uPgogICAgPGgyIGlkPSJ3aHktbm90Ij5XaHkgbm90IGNoYW5nZSAmbHQ7bXkt
cGV0LWZlYXR1cmU+PzwvaDI+CiAgICA8cD5JIGhhdmVuJ3QgdGFrZW4gZXZlcnkgc3VnZ2VzdGlv
biB0byBjaGFuZ2UgPGNvZGU+c3RyaW5nX3ZpZXc8L2NvZGU+LiAgVGhpcwogICAgc2VjdGlvbiBl
eHBsYWlucyB0aGUgcmF0aW9uYWxlcy48L3A+CgogICAgPHNlY3Rpb24+CiAgICAgIDxoMyBpZD0i
cmVtb3ZlLWZpbmQiPlJlbW92ZSB0aGUgZmluZCooKSBtZXRob2RzPC9oMz4KCiAgICAgIDxwPk1h
bnkgcGVvcGxlIGhhdmUgYXNrZWQgd2h5IHdlIGFyZW4ndCByZW1vdmluZyBhbGwgb2YgdGhlCiAg
ICAgIDxjb2RlPmZpbmQ8dmFyPio8L3Zhcj48L2NvZGU+IG1ldGhvZHMsIHNpbmNlIHRoZXkncmUg
d2lkZWx5IGNvbnNpZGVyZWQgYQogICAgICB3YXJ0IG9uIDxjb2RlPnN0ZDo6c3RyaW5nPC9jb2Rl
Pi4gIEZpcnN0LCB3ZSdkIGxpa2UgdG8gbWFrZSBpdCBhcyBlYXN5IGFzCiAgICAgIHBvc3NpYmxl
IHRvIGNvbnZlcnQgY29kZSB0byB1c2UgPGNvZGU+c3RyaW5nX3ZpZXc8L2NvZGU+LCBzbyBpdCdz
IHVzZWZ1bCB0bwogICAgICBrZWVwIHRoZSBpbnRlcmZhY2UgYXMgc2ltaWxhciBhcyByZWFzb25h
YmxlIHRvIDxjb2RlPnN0ZDo6c3RyaW5nPC9jb2RlPi4KICAgICAgU2Vjb25kLCByZXBsYWNpbmcg
dGhlc2UgdGhlc2UgbWV0aG9kcyB3aXRoIHVzZXMgb2YgdGhlIHN0YW5kYXJkIGFsZ29yaXRobXMK
ICAgICAgbGlicmFyeSByZXF1aXJlcyBzd2l0Y2hpbmcgZnJvbSBpbmRpY2VzIHRvIGl0ZXJhdG9y
cywgd3JpdGluZwogICAgICBzb21ld2hhdC1jb21wbGljYXRlZCBjb252ZXJzaW9uIGNvZGUsIGFu
ZC9vciBwYXNzaW5nIGN1c3RvbSBsYW1iZGFzIHRvCiAgICAgIDxjb2RlPmZpbmRfaWY8L2NvZGU+
LiAgTGV0J3MgbG9vayBhdCB0aGUgcmVwbGFjZW1lbnQgY29kZSBmb3IgZWFjaCBvZiB0aGUKICAg
ICAgcmVtYWluaW5nIG1ldGhvZHM6PC9wPgoKICAgICAgPGRsPgogICAgICAgIDxkdD48Y29kZT5o
YXlzdGFjay5maW5kKG5lZWRsZSk8L2NvZGU+PC9kdD4KICAgICAgICA8ZGQ+UmVwbGFjZWQgYnk6
CiAgICAgICAgPHByZSBjbGFzcz0iZXhhbXBsZSI+PGNvZGU+YXV0byBpdGVyID0gc3RkOjpzZWFy
Y2goaGF5c3RhY2suYmVnaW4oKSwgaGF5c3RhY2suZW5kKCksCiAgICAgICAgICAgICAgICAgICAg
ICAgIG5lZWRsZS5iZWdpbigpLCBuZWVkbGUuZW5kKCkpOwpyZXR1cm4gaXRlciA9PSBoYXlzdGFj
ay5lbmQoKSA/IHN0ZDo6c3RyaW5nOjpucG9zIDogaXRlciAtIGhheXN0YWNrLmJlZ2luKCk7PC9j
b2RlPjwvcHJlPjwvZGQ+CgogICAgICAgIDxkdD48Y29kZT5oYXlzdGFjay5yZmluZChuZWVkbGUp
PC9jb2RlPjwvZHQ+CiAgICAgICAgPGRkPlJlcGxhY2VkIGJ5OgogICAgICAgIDxwcmUgY2xhc3M9
ImV4YW1wbGUiPjxjb2RlPmF1dG8gaXRlciA9IHN0ZDo6ZmluZF9lbmQoaGF5c3RhY2suYmVnaW4o
KSwgaGF5c3RhY2suZW5kKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgbmVlZGxlLmJlZ2lu
KCksIG5lZWRsZS5lbmQoKSk7CnJldHVybiBpdGVyID09IGhheXN0YWNrLmVuZCgpID8gc3RkOjpz
dHJpbmc6Om5wb3MgOiBpdGVyIC0gaGF5c3RhY2suYmVnaW4oKTs8L2NvZGU+PC9wcmU+PC9kZD4K
CiAgICAgICAgPGR0Pjxjb2RlPmhheXN0YWNrLmZpbmRfZmlyc3Rfb2YobmVlZGxlcyk8L2NvZGU+
PC9kdD4KICAgICAgICA8ZGQ+UmVwbGFjZWQgYnk6CiAgICAgICAgPHByZSBjbGFzcz0iZXhhbXBs
ZSI+PGNvZGU+YXV0byBpdGVyID0gc3RkOjpmaW5kX2ZpcnN0X29mKGhheXN0YWNrLmJlZ2luKCks
IGhheXN0YWNrLmVuZCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmVlZGxlcy5i
ZWdpbigpLCBuZWVkbGVzLmVuZCgpKTsKcmV0dXJuIGl0ZXIgPT0gaGF5c3RhY2suZW5kKCkgPyBz
dGQ6OnN0cmluZzo6bnBvcyA6IGl0ZXIgLSBoYXlzdGFjay5iZWdpbigpOzwvY29kZT48L3ByZT48
L2RkPgoKICAgICAgICA8ZHQ+PGNvZGU+aGF5c3RhY2suZmluZF9sYXN0X29mKG5lZWRsZXMpPC9j
b2RlPjwvZHQ+CiAgICAgICAgPGRkPlJlcGxhY2VkIGJ5OgogICAgICAgIDxwcmUgY2xhc3M9ImV4
YW1wbGUiPjxjb2RlPmF1dG8gaXRlciA9IHN0ZDo6ZmluZF9maXJzdF9vZihoYXlzdGFjay48c3Ry
b25nPnI8L3N0cm9uZz5iZWdpbigpLCBoYXlzdGFjay48c3Ryb25nPnI8L3N0cm9uZz5lbmQoKSwK
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5lZWRsZXMuYmVnaW4oKSwgbmVlZGxlcy5l
bmQoKSk7CnJldHVybiBpdGVyID09IGhheXN0YWNrLjxzdHJvbmc+cjwvc3Ryb25nPmVuZCgpID8g
c3RkOjpzdHJpbmc6Om5wb3MgOiBpdGVyPHN0cm9uZz4uYmFzZSgpIC0gMTwvc3Ryb25nPiAtIGhh
eXN0YWNrLmJlZ2luKCk7PC9jb2RlPjwvcHJlPjwvZGQ+CgogICAgICAgIDxkdD48Y29kZT5oYXlz
dGFjay5maW5kX2ZpcnN0X25vdF9vZihzdHJhdyk8L2NvZGU+PC9kdD4KICAgICAgICA8ZGQ+UmVw
bGFjZWQgYnk6CiAgICAgICAgPHByZSBjbGFzcz0iZXhhbXBsZSI+PGNvZGU+YXV0byBpdGVyID0g
c3RkOjpmaW5kX2lmKGhheXN0YWNrLmJlZ2luKCksIGhheXN0YWNrLmVuZCgpLCBbJmFtcDtdKGNo
YXIgYykgewogIHJldHVybiBzdGQ6OmZpbmQoc3RyYXcuYmVnaW4oKSwgc3RyYXcuZW5kKCksIGMp
ID09IHN0cmF3LmVuZCgpOwp9KTsKcmV0dXJuIGl0ZXIgPT0gaGF5c3RhY2suZW5kKCkgPyBzdGQ6
OnN0cmluZzo6bnBvcyA6IGl0ZXIgLSBoYXlzdGFjay5iZWdpbigpOzwvY29kZT48L3ByZT48L2Rk
PgoKICAgICAgICA8ZHQ+PGNvZGU+aGF5c3RhY2suZmluZF9sYXN0X25vdF9vZihzdHJhdyk8L2Nv
ZGU+PC9kdD4KICAgICAgICA8ZGQ+UmVwbGFjZWQgYnk6CiAgICAgICAgPHByZSBjbGFzcz0iZXhh
bXBsZSI+PGNvZGU+YXV0byBpdGVyID0gc3RkOjpmaW5kX2lmKGhheXN0YWNrLjxzdHJvbmc+cjwv
c3Ryb25nPmJlZ2luKCksIGhheXN0YWNrLjxzdHJvbmc+cjwvc3Ryb25nPmVuZCgpLCBbJmFtcDtd
KGNoYXIgYykgewogIHJldHVybiBzdGQ6OmZpbmQoc3RyYXcuYmVnaW4oKSwgc3RyYXcuZW5kKCks
IGMpID09IHN0cmF3LmVuZCgpOwp9KTsKcmV0dXJuIGl0ZXIgPT0gaGF5c3RhY2suPHN0cm9uZz5y
PC9zdHJvbmc+ZW5kKCkgPyBzdGQ6OnN0cmluZzo6bnBvcyA6IGl0ZXI8c3Ryb25nPi5iYXNlKCkg
LSAxPC9zdHJvbmc+IC0gaGF5c3RhY2suYmVnaW4oKTs8L2NvZGU+PC9wcmU+PC9kZD4KICAgICAg
PC9kbD4KCiAgICAgIDxwPjxjb2RlPmZpbmQ8L2NvZGU+LCA8Y29kZT5yZmluZDwvY29kZT4sIGFu
ZCA8Y29kZT5maW5kX2ZpcnN0X29mPC9jb2RlPgogICAgICBhcmUgc3RyYWlnaHRmb3J3YXJkLCBh
bHRob3VnaCB0aGUgY29udmVyc2lvbiBmcm9tIGluZGljZXMgdG8gaXRlcmF0b3JzCiAgICAgIHdv
dWxkIHByZXZlbnQgbWFueSB1c2VycyBmcm9tIHN3aXRjaGluZyBldmVuIHRvIHRoZW0uCiAgICAg
IDxjb2RlPmZpbmRfbGFzdF9vZjwvY29kZT4sIDxjb2RlPmZpbmRfZmlyc3Rfbm90X29mPC9jb2Rl
PiwgYW5kCiAgICAgIDxjb2RlPmZpbmRfbGFzdF9ub3Rfb2Y8L2NvZGU+IGdldCBwcm9ncmVzc2l2
ZWx5IHdvcnNlIHRvIGhhbmRsZSBldmVuIGluIGFuCiAgICAgIGl0ZXJhdG9yLWJhc2VkIGZ1bmN0
aW9uLjwvcD4KCiAgICAgIDxwPkRpc2N1c3Npb24gaW4gQnJpc3RvbCBjb25jbHVkZWQgdGhhdCA8
Y29kZT5zdHJpbmdfdmlldzwvY29kZT4gc2hvdWxkCiAgICAgIGluY2x1ZGUgYWxsIG9mIHRoZSBj
b25zdCBzaWduYXR1cmVzIGZyb20gPGNvZGU+c3RyaW5nPC9jb2RlPi48L3A+CgogICAgICA8dGFi
bGUgY2xhc3M9InN0cmF3cG9sbCI+CiAgICAgICAgPGNhcHRpb24+QnJpc3RvbCBzdHJhdyBwb2xs
IG9uICJTaG91bGQgd2Uga2VlcCB0aGUgcG9zL24gYXJndW1lbnRzIHRvIGZpbmQsIGV0Yz8iPC9j
YXB0aW9uPgogICAgICAgIDx0cj48dGQ+U0Y8L3RkPjx0ZD5XRjwvdGQ+PHRkPk48L3RkPjx0ZD5X
QTwvdGQ+PHRkPlNBPC90ZD48L3RyPgogICAgICAgIDx0cj48dGQ+NTwvdGQ+PHRkPjQ8L3RkPjx0
ZD4xPC90ZD48dGQ+MjwvdGQ+PHRkPjA8L3RkPjwvdHI+CiAgICAgIDwvdGFibGU+CiAgICAgIDx0
YWJsZSBjbGFzcz0ic3RyYXdwb2xsIj4KICAgICAgICA8Y2FwdGlvbj5CcmlzdG9sIHN0cmF3IHBv
bGwgb24gIlNob3VsZCB3ZSBrZWVwIHRoZSBjb3B5KCkgbWV0aG9kPyI8L2NhcHRpb24+CiAgICAg
ICAgPHRyPjx0ZD5TRjwvdGQ+PHRkPldGPC90ZD48dGQ+TjwvdGQ+PHRkPldBPC90ZD48dGQ+U0E8
L3RkPjwvdHI+CiAgICAgICAgPHRyPjx0ZD40PC90ZD48dGQ+MjwvdGQ+PHRkPjI8L3RkPjx0ZD4z
PC90ZD48dGQ+MjwvdGQ+PC90cj4KICAgICAgPC90YWJsZT4KICAgIDwvc2VjdGlvbj4KCiAgICA8
c2VjdGlvbj4KICAgICAgPGgzIGlkPSJtdXRhYmxlIj5NYWtlIDxjb2RlPmJhc2ljX3N0cmluZ192
aWV3Jmx0O2NoYXI+PC9jb2RlPiBtdXRhYmxlPC9oMz4KCiAgICAgIDxwPuKApiBhbmQgdXNlIDxj
b2RlPmJhc2ljX3N0cmluZ192aWV3Jmx0O2NvbnN0IGNoYXI+PC9jb2RlPiBmb3IgdGhlIGNvbnN0
YW50CiAgICAgIGNhc2UuICBUaGUgY29uc3RhbnQgY2FzZSBpcyBlbm91Z2ggbW9yZSBjb21tb24g
dGhhbiB0aGUgbXV0YWJsZSBjYXNlIHRoYXQKICAgICAgaXQgbmVlZHMgdG8gYmUgdGhlIGRlZmF1
bHQuICBNYWtpbmcgdGhlIG11dGFibGUgY2FzZSB0aGUgZGVmYXVsdCB3b3VsZAogICAgICBwcmV2
ZW50IHBhc3Npbmcgc3RyaW5nIGxpdGVyYWxzIGludG8gPGNvZGU+c3RyaW5nX3ZpZXc8L2NvZGU+
IHBhcmFtZXRlcnMsCiAgICAgIHdoaWNoIHdvdWxkIGRlZmVhdCBhIHNpZ25pZmljYW50IHVzZSBj
YXNlIGZvciA8Y29kZT5zdHJpbmdfdmlldzwvY29kZT4uICBJbgogICAgICBhIHNvbWV3aGF0IGFu
YWxvZ291cyBzaXRhdGlvbiwgTExWTSBkZWZpbmVkIGFuIDxhCiAgICAgIGhyZWY9Imh0dHA6Ly9s
bHZtLm9yZy92aWV3dmMvbGx2bS1wcm9qZWN0L2xsdm0vdHJ1bmsvaW5jbHVkZS9sbHZtL0FEVC9B
cnJheVJlZi5oP3ZpZXc9bG9nIj48Y29kZT5BcnJheVJlZjwvY29kZT4KICAgICAgY2xhc3M8L2E+
IGluIEZlYiAyMDExLCBhbmQgZGlkbid0IGZpbmQgYSBuZWVkIGZvciB0aGUgbWF0Y2hpbmcKICAg
ICAgPGNvZGU+TXV0YWJsZUFycmF5UmVmPC9jb2RlPiB1bnRpbCBKYW4gMjAxMi4gIFRoZXkgc3Rp
bGwgaGF2ZW4ndCBuZWVkZWQgYQogICAgICBtdXRhYmxlIHZlcnNpb24gb2YgPGEKICAgICAgaHJl
Zj0iaHR0cDovL2xsdm0ub3JnL3ZpZXd2Yy9sbHZtLXByb2plY3QvbGx2bS90cnVuay9pbmNsdWRl
L2xsdm0vQURUL1N0cmluZ1JlZi5oP3ZpZXc9bWFya3VwIj48Y29kZT5TdHJpbmdSZWY8L2NvZGU+
PC9hPi4KICAgICAgT25lIHBvc3NpYmxlIHJlYXNvbiBmb3IgdGhpcyBpcyB0aGF0IG1vc3QgdXNl
cyB0aGF0IG5lZWQgdG8gbW9kaWZ5IGEKICAgICAgc3RyaW5nIGFsc28gbmVlZCB0byBiZSBhYmxl
IHRvIGNoYW5nZSBpdHMgbGVuZ3RoLCBhbmQgdGhhdCdzIGltcG9zc2libGUKICAgICAgdGhyb3Vn
aCBldmVuIGEgbXV0YWJsZSB2ZXJzaW9uIG9mIDxjb2RlPnN0cmluZ192aWV3PC9jb2RlPi48L3A+
CgogICAgICA8cD5XZSA8ZW0+Y291bGQ8L2VtPiB1c2UgPGNvZGU+dHlwZWRlZiBiYXNpY19zdHJp
bmdfdmlldyZsdDtjb25zdCBjaGFyPgogICAgICBzdHJpbmdfdmlldzwvY29kZT4gdG8gbWFrZSB0
aGUgaW1tdXRhYmxlIGNhc2UgdGhlIGRlZmF1bHQgd2hpbGUgc3RpbGwKICAgICAgc3VwcG9ydGlu
ZyB0aGUgbXV0YWJsZSBjYXNlIHVzaW5nIHRoZSBzYW1lIHRlbXBsYXRlLiAgSSBoYXZlbid0IGdv
bmUgdGhpcwogICAgICB3YXkgYmVjYXVzZSBpdCB3b3VsZCBjb21wbGljYXRlIHRoZSB0ZW1wbGF0
ZSdzIGRlZmluaXRpb24gd2l0aG91dAogICAgICBzaWduaWZpY2FudGx5IGhlbHBpbmcgdXNlcnMu
PC9wPgogICAgPC9zZWN0aW9uPgoKICAgIDxzZWN0aW9uPgogICAgICA8aDMgaWQ9Im9wZXJhdG9y
LWJvb2wiPkFkZCBhbiA8Y29kZT5leHBsaWNpdCBvcGVyYXRvciBib29sPC9jb2RlPjwvaDM+Cgog
ICAgICA8cD5UaGlzIHdvdWxkIGJlIGFuIGFiYnJldmlhdGlvbiBmb3IgPGNvZGU+IWVtcHR5KCk8
L2NvZGU+LCB1c2FibGUgZm9yCiAgICAgIGluaXRpYWxpemF0aW9uIGluIDxjb2RlPmlmPC9jb2Rl
PiBzdGF0ZW1lbnRzLiAgPGEKICAgICAgaHJlZj0iaHR0cDovL3d3dy5vcGVuLXN0ZC5vcmcvanRj
MS9zYzIyL3dnMjEvZG9jcy9wYXBlcnMvMjAxMy9uMzUwOS5odG0iPk4zNTA5PC9hPgogICAgICBj
YW1lIHRvIFNHOSBpbiBCcmlzdG9sIGFuZCB3YXMgbm90IGFjY2VwdGVkLjwvcD4KCiAgICAgIDx0
YWJsZSBjbGFzcz0ic3RyYXdwb2xsIj4KICAgICAgICA8Y2FwdGlvbj5CcmlzdG9sIHN0cmF3IHBv
bGwgb24gIkRvIHdlIHdhbnQgdG8gcHVyc3VlIFtOMzUwOV0/IjwvY2FwdGlvbj4KICAgICAgICA8
dHI+PHRkPlNGPC90ZD48dGQ+V0Y8L3RkPjx0ZD5XQTwvdGQ+PHRkPlNBPC90ZD48L3RyPgogICAg
ICAgIDx0cj48dGQ+MDwvdGQ+PHRkPjE8L3RkPjx0ZD4zPC90ZD48dGQ+NTwvdGQ+PC90cj4KICAg
ICAgPC90YWJsZT4KCiAgICA8L3NlY3Rpb24+CgogICAgPHNlY3Rpb24+CiAgICAgIDxoMyBpZD0i
YXZvaWQtc3RybGVuIj5Bdm9pZCA8Y29kZT5zdHJsZW4oInN0cmluZyBsaXRlcmFsIik8L2NvZGU+
PC9oMz4KCiAgICAgIDxwPldpdGggYSBjb25zdHJ1Y3RvciBvZiB0aGUgZm9ybTo8L3A+CiAgICAg
IDxwcmUgY2xhc3M9ImV4YW1wbGUiPjxjb2RlPnRlbXBsYXRlJmx0O3NpemVfdCBOPgpiYXNpY19z
dHJpbmdfdmlldyhjb25zdCBjaGFyVCAoJmFtcDtzdHIpW05dKTs8L2NvZGU+PC9wcmU+CiAgICAg
IDxwPndlIGNvdWxkIGF2b2lkIGEgPGNvZGU+c3RybGVuKCk8L2NvZGU+IGNhbGwgd2hlbiBhCiAg
ICAgIDxjb2RlPmJhc2ljX3N0cmluZ192aWV3PC9jb2RlPiBpcyBjb25zdHJ1Y3RlZCBmcm9tIGEg
c3RyaW5nIGxpdGVyYWwuCiAgICAgIFVuZm9ydHVuYXRlbHksIHRoaXMgY29uc3RydWN0b3IgZG9l
cyBjb21wbGV0ZWx5IHRoZSB3cm9uZyB0aGluZyB3aGVuCiAgICAgIGNhbGxlZCBsaWtlOjwvcD4K
ICAgICAgPHByZSBjbGFzcz0iZXhhbXBsZSI+PGNvZGU+Y2hhciBzcGFjZVtQQVRIX01BWF07CnNu
cHJpbnRmKHNwYWNlLCBzaXplb2Yoc3BhY2UpLCAic29tZSBzdHJpbmciKTsKc3RyaW5nX3ZpZXcg
c3RyKHNwYWNlKTs8L2NvZGU+PC9wcmU+CiAgICAgIDxwPkl0IHdvdWxkIGJlIHBvc3NpYmxlIHRv
IGF2b2lkIHRoYXQgcHJvYmxlbSBieSBkZWZpbmluZyBhCiAgICAgIDxjb2RlPmJhc2ljX3N0cmlu
Z192aWV3KGNoYXIqIHN0cik8L2NvZGU+IHRoYXQgdXNlcyA8Y29kZT5zdHJsZW4oKTwvY29kZT4K
ICAgICAgYWdhaW4sIGJ1dCB0aGlzIGFkZHMgY29tcGxleGl0eS4gIFNvbWUgcGVvcGxlIGhhdmUg
c3VnZ2VzdGVkIGEKICAgICAgPGNvZGU+c3RyaW5nX3ZpZXc6OmZyb21fbGl0ZXJhbDwvY29kZT4g
bWV0aG9kLCBidXQgSSBjb25zaWRlciB0aGF0IHRvbwogICAgICB2ZXJib3NlLjwvcD4KICAgICAg
PHA+RXZlbiB0aGUgb3JpZ2luYWwgd29ycnkgaXMgb2Jzb2xldGUgZ2l2ZW4gbW9kZXJuIG9wdGlt
aXplcnM6IGJvdGggZ2NjCiAgICAgIGFuZCBjbGFuZyBvcHRpbWl6ZSA8Y29kZT5zdHJsZW4oIkxp
dGVyYWwiKTwvY29kZT4gaW50byBhIGNvbnN0YW50LCBtYWtpbmcKICAgICAgdGhlIHNpbXBsZSwg
c2FmZSBjb2RlIGFzIGVmZmljaWVudCBhcyB0aGUgdGVtcGxhdGUuICBPdGhlciBpbXBsZW1lbnRh
dGlvbnMKICAgICAgc2hvdWxkIHByb3ZpZGUgdGhlIHNhbWUgb3B0aW1pemF0aW9uIGFzIGEgUW9J
IGlzc3VlLjwvcD4KICAgIDwvc2VjdGlvbj4KCiAgICA8c2VjdGlvbj4KICAgICAgPGgzIGlkPSJ0
cmVhdC1hcy1wb2ludGVyIj5EZWZpbmUgY29tcGFyaXNvbiBvbiA8Y29kZT5iZWdpbjwvY29kZT4v
PGNvZGU+ZW5kPC9jb2RlPiBpbnN0ZWFkIG9mIHRoZSBlbGVtZW50czwvaDM+CgogICAgICA8cD5P
cGVyYXRpb25zIG9uIDxjb2RlPnN0cmluZ192aWV3PC9jb2RlPiBhcHBseSB0byB0aGUgY2hhcmFj
dGVycyBpbiB0aGUKICAgICAgc3RyaW5nLCBhbmQgbm90IHRoZSBwb2ludGVycyB0aGF0IHJlZmVy
IHRvIHRoZSBjaGFyYWN0ZXJzLiAgVGhpcwogICAgICBpbnRyb2R1Y2VzIHRoZSBwb3NzaWJpbGl0
eSB0aGF0IHRoZSB1bmRlcmx5aW5nIGNoYXJhY3RlcnMgbWlnaHQgY2hhbmdlCiAgICAgIHdoaWxl
IGEgPGNvZGU+c3RyaW5nX3ZpZXc8L2NvZGU+IHJlZmVycmluZyB0byB0aGVtIGlzIGluIGFuIGFz
c29jaWF0aXZlCiAgICAgIGNvbnRhaW5lciwgd2hpY2ggd291bGQgYnJlYWsgdGhlIGNvbnRhaW5l
ciwgYnV0IHdlIGJlbGlldmUgdGhpcyByaXNrIGlzCiAgICAgIHdvcnRod2hpbGUgYmVjYXVzZSBp
dCBtYXRjaGVzIGV4aXN0aW5nIHByYWN0aWNlIGFuZCBtYXRjaGVzIHVzZXIKICAgICAgaW50ZW50
aW9ucyBtb3JlIG9mdGVuLjwvcD4KICAgIDwvc2VjdGlvbj4KCiAgICA8c2VjdGlvbj4KICAgICAg
PGgzIGlkPSJjb250aWd1b3VzLXJhbmdlIj5XYWl0IGZvciA8Y29kZT5jb250aWd1b3VzX3Jhbmdl
Jmx0O2NoYXJUPjwvY29kZT48L2gzPgoKICAgICAgPHA+PGNvZGU+Y29udGlndW91c19yYW5nZSZs
dDtUPjwvY29kZT4gYWxvbmcgd2l0aCBhbgogICAgICA8Y29kZT5pc19jb250aWd1b3VzJmx0O0l0
ZXJhdG9yT3JSYW5nZT48L2NvZGU+IHRyYWl0IHdvdWxkIGJlIHVzZWZ1bCBmb3IKICAgICAgbWFu
eSBwdXJwb3Nlcy4gIEhvd2V2ZXIsIGEgcmVmZXJlbmNlIGNsYXNzIHRoYXQncyBzcGVjaWZpY2Fs
bHkgZm9yIHN0cmluZ3MKICAgICAgcHJvdmlkZXMgYSBjb3VwbGUgZXh0cmEgYmVuZWZpdHM6PC9w
PgogICAgICA8dWw+CiAgICAgICAgPGxpPjxjb2RlPnN0cmluZ192aWV3PC9jb2RlPiBjYW4gaGF2
ZSBhbiBpbXBsaWNpdCBjb252ZXJzaW9uIGZyb20KICAgICAgICA8Y29kZT5jb25zdCBjaGFyKjwv
Y29kZT4sIHdoaWxlIGl0IHdvdWxkIGJlIGEgc3VycHJpc2luZyBzcGVjaWFsIGNhc2UgdG8KICAg
ICAgICBwcm92aWRlIHRoYXQgb24gPGNvZGU+Y29udGlndW91c19yYW5nZSZsdDtjb25zdCBjaGFy
Kj48L2NvZGU+LjwvbGk+CiAgICAgICAgPGxpPldlIGNhbiBwcm92aWRlIGEgc3Vic2V0IG9mIDxj
b2RlPmJhc2ljX3N0cmluZzwvY29kZT4ncyBpbnRlcmZhY2UgdG8KICAgICAgICBlYXNlIHRyYW5z
aXRpb25zIHRvIGFuZCBmcm9tIG93bmVyc2hpcCwgd2hpbGUgc3VjaCBtZXRob2RzIHdvdWxkIGJl
IHZlcnkKICAgICAgICBzdHJhbmdlIG9uIDxjb2RlPmNvbnRpZ3VvdXNfcmFuZ2U8L2NvZGU+Ljwv
bGk+CiAgICAgICAgPGxpPjxjb2RlPmJhc2ljX3N0cmluZ192aWV3PC9jb2RlPiB0YWtlcyBhIDxj
b2RlPmNoYXJfdHJhaXRzPC9jb2RlPgogICAgICAgIGFyZ3VtZW50IGFsbG93aW5nIGN1c3RvbWl6
YXRpb24gb2YgY29tcGFyaXNvbi4KICAgICAgICA8Y29kZT5jb250aWd1b3VzX3JhbmdlPC9jb2Rl
PiBsaWtlbHkgd291bGRuJ3QuPC9saT4KICAgICAgICA8bGk+V2UgY29tcGFyZSBhbmQgaGFzaCA8
Y29kZT5zdHJpbmdfdmlldzwvY29kZT5zIHVzaW5nIHRoZSBlbGVtZW50cyB0aGV5CiAgICAgICAg
cmVmZXIgdG8uICBUaGVyZSdzIGEgc3Ryb25nZXIgYXJndW1lbnQgdG8gY29tcGFyZSBhCiAgICAg
ICAgPGNvZGU+Y29udGlndW91c19yYW5nZTwvY29kZT4gdXNpbmcgdGhlIHBvaW50ZXJzIGluc2lk
ZSBpdCwgbWVhbmluZyB0d28KICAgICAgICA8Y29kZT5jb250aWd1b3VzX3JhbmdlJmx0O2NoYXI+
PC9jb2RlPnMgb2YgdGhlIHNhbWUgY2hhcmFjdGVycyBtaWdodAogICAgICAgIGNvbXBhcmUgdW5l
cXVhbC48L2xpPgogICAgICAgIDxsaT5UaGUgbm90aW9uIG9mIGEgInN0cmluZyIgaXMgZGlmZmVy
ZW50IGZyb20gdGhlIG5vdGlvbiBvZiBhIHJhbmdlIG9mCiAgICAgICAgY2hhcmFjdGVycywgd2hp
Y2ggaXMgb25lIHJlYXNvbiB3ZSBoYXZlIDxjb2RlPnN0ZDo6c3RyaW5nPC9jb2RlPiBpbgogICAg
ICAgIGFkZGl0aW9uIHRvIDxjb2RlPnN0ZDo6dmVjdG9yJmx0O2NoYXI+PC9jb2RlPi4gIFVzZXJz
IGJlbmVmaXQgZnJvbQogICAgICAgIHNheWluZyB3aGljaCB0aGV5IG1lYW4gaW4gaW50ZXJmYWNl
cy48L2xpPgogICAgICA8L3VsPgogICAgPC9zZWN0aW9uPgoKICAgIDxzZWN0aW9uPgogICAgICA8
aDMgaWQ9Im51bGwtdGVybWluYXRpb24iPk1ha2UgPGNvZGU+c3RyaW5nX3ZpZXc8L2NvZGU+IG51
bGwtdGVybWluYXRlZDwvaDM+CgogICAgICA8cD5Eb2luZyB0aGlzIG5haXZlbHkgbWFrZXMgPGNv
ZGU+c3Vic3RyPC9jb2RlPiBpbXBvc3NpYmxlIHRvIGltcGxlbWVudAogICAgICB3aXRob3V0IGEg
Y29weS4gIFdlIGNvdWxkIGltYWdpbmUgaW52ZW50aW5nIGEgbW9yZSBjb21wbGV4IGludGVyZmFj
ZSB0aGF0CiAgICAgIHJlY29yZHMgd2hldGhlciB0aGUgaW5wdXQgc3RyaW5nIHdhcyBudWxsLXRl
cm1pbmF0ZWQsIGdpdmluZyB0aGUgdXNlciB0aGUKICAgICAgb3B0aW9uIHRvIHVzZSB0aGF0IHN0
cmluZyB3aGVuIHRyeWluZyB0byBwYXNzIGEgPGNvZGU+c3RyaW5nX3ZpZXc8L2NvZGU+IHRvCiAg
ICAgIGEgbGVnYWN5IG9yIEMgZnVuY3Rpb24gZXhwZWN0aW5nIGEgbnVsbC10ZXJtaW5hdGVkIDxj
b2RlPmNvbnN0CiAgICAgIGNoYXIqPC9jb2RlPi4gIFRoaXMgcHJvcG9zYWwgZG9lc24ndCBpbmNs
dWRlIHN1Y2ggYW4gaW50ZXJmYWNlIGJlY2F1c2UgaXQKICAgICAgd291bGQgbWFrZSA8Y29kZT5z
dHJpbmdfdmlldzwvY29kZT4gYmlnZ2VyIG9yIG1vcmUgZXhwZW5zaXZlLCBhbmQgYmVjYXVzZQog
ICAgICB0aGVyZSdzIG5vIGV4aXN0aW5nIHByYWN0aWNlIHRvIGd1aWRlIHVzIHRvd2FyZCB0aGUg
cmlnaHQgaW50ZXJmYWNlLjwvcD4KCiAgICAgIDxwPkFub3RoZXIgb3B0aW9uIHdvdWxkIGJlIHRv
IGRlZmluZSBhIHNlcGFyYXRlIDxjb2RlPnpzdHJpbmdfdmlldzwvY29kZT4KICAgICAgY2xhc3Mg
dG8gcmVwcmVzZW50IG51bGwtdGVybWluYXRlZCBzdHJpbmdzIGFuZCBsZXQgaXQgZGVjYXkgdG8K
ICAgICAgPGNvZGU+c3RyaW5nX3ZpZXc8L2NvZGU+IHdoZW4gbmVjZXNzYXJ5LiAgVGhhdCdzIHBs
YXVzaWJsZSBidXQgbm90IHBhcnQgb2YKICAgICAgdGhpcyBwcm9wb3NhbC48L3A+CiAgICA8L3Nl
Y3Rpb24+CgogICAgPHNlY3Rpb24+CiAgICAgIDxoMyBpZD0icG9wLWZyb250Ij5zL3JlbW92ZV9w
cmVmaXgvcG9wX2Zyb250LywgZXRjLjwvaDM+CgogICAgICA8cD5JbiA8YQogICAgICBocmVmPSJo
dHRwOi8vd2lraS5lZGcuY29tL3R3aWtpL2Jpbi92aWV3L1dnMjFrb25hMjAxMi9MaWJyYXJ5V29y
a2luZ0dyb3VwI1Rvd2FyZF9SYW5nZV9vYmplY3RzIj5Lb25hCiAgICAgIDIwMTI8L2E+LCBJIHBy
b3Bvc2VkIGEgPGNvZGU+cmFuZ2UmbHQ7PjwvY29kZT4gY2xhc3Mgd2l0aAogICAgICA8Y29kZT5w
b3BfZnJvbnQ8L2NvZGU+LCBldGMuIG1lbWJlcnMgdGhhdCBhZGp1c3RlZCB0aGUgYm91bmRzIG9m
IHRoZQogICAgICByYW5nZS4gIERpc2N1c3Npb24gdGhlcmUgaW5kaWNhdGVkIHRoYXQgY29tbWl0
dGVlIG1lbWJlcnMgd2VyZQogICAgICB1bmNvbWZvcnRhYmxlIHVzaW5nIHRoZSBzYW1lIG5hbWVz
IGZvciBsaWdodHdlaWdodCByYW5nZSBvcGVyYXRpb25zIGFzCiAgICAgIGNvbnRhaW5lciBvcGVy
YXRpb25zLiAgRXhpc3RpbmcgcHJhY3RpY2UgZG9lc24ndCBhZ3JlZSBvbiBhIG5hbWUgZm9yIHRo
aXMKICAgICAgb3BlcmF0aW9uLCBzbyBJJ3ZlIGtlcHQgdGhlIG5hbWUgdXNlZCBieSBHb29nbGUn
cwogICAgICA8Y29kZT5TdHJpbmdQaWVjZTwvY29kZT4uPC9wPgogICAgPC9zZWN0aW9uPgoKICAg
IDxzZWN0aW9uPgogICAgICA8aDMgaWQ9ImRhdGEtc2l6ZS1jb25zdHJ1Y3RvciI+QWxsb3cgaW1w
bGljaXQgY29udmVyc2lvbiBmcm9tIG1vcmUgdHlwZXMuPC9oMz4KCiAgICAgIDxwPjxhCiAgICAg
IGhyZWY9Imh0dHBzOi8vZ3JvdXBzLmdvb2dsZS5jb20vYS9pc29jcHAub3JnL2QvbXNnL3N0ZC1w
cm9wb3NhbHMvOHQ1RUZKZkxuMEkvbXM3R1hfV3Q0QzhKIj5CZW1hbgogICAgICBEYXdlcyBzdWdn
ZXN0ZWQ8L2E+IGRlZmluaW5nIDxjb2RlPnN0ZDo6c3RyaW5nX3ZpZXdfe2JlZ2luLGVuZH08L2Nv
ZGU+IGFuZAogICAgICBhbGxvd2luZyB1c2VycyB0byBhZGQgb3ZlcmxvYWRzIHdpdGhpbiA8Y29k
ZT5zdGQ8L2NvZGU+LiAgVXNpbmcgQURMIGlzIGEKICAgICAgc2xpZ2h0IHZhcmlhbnQuICBXZSBj
b3VsZCBhbHNvIGFsbG93IGNvbnZlcnNpb24gZnJvbSBhbnkgdHlwZSB3aXRoCiAgICAgIDxjb2Rl
Pi5kYXRhKCk8L2NvZGU+IGFuZCA8Y29kZT4uc2l6ZSgpPC9jb2RlPiBtZW1iZXJzIHJldHVybmlu
ZyB0aGUgcmlnaHQKICAgICAgdHlwZXMuPC9wPgoKICAgICAgPHA+VWx0aW1hdGVseSwgSSB0aGlu
ayB3ZSB3YW50IHRvIGFsbG93IHRoaXMgY29udmVyc2lvbiBiYXNlZCBvbiBkZXRlY3RpbmcKICAg
ICAgY29udGlndW91cyByYW5nZXMuICBBbnkgY29uc3RydWN0b3Igd2UgYWRkIHRvIHdvcmsgYXJv
dW5kIHRoYXQgaXMgZ29pbmcgdG8KICAgICAgbG9vayBsaWtlIGEgd2FydCBpbiBhIGNvdXBsZSB5
ZWFycy4gIEkgdGhpbmsgd2UnbGwgYmUgYmV0dGVyIG9mZiBtYWtpbmcKICAgICAgdXNlcnMgZXhw
bGljaXRseSBjb252ZXJ0IHdoZW4gdGhleSBjYW4ndCBhZGQgYW4gYXBwcm9wcmlhdGUgY29udmVy
c2lvbgogICAgICBvcGVyYXRvciwgYW5kIHRoZW4gd2UgY2FuIGFkZCB0aGUgb3B0aW1hbCBjb25z
dHJ1Y3RvciB3aGVuIGNvbnRpZ3VvdXMKICAgICAgaXRlcmF0b3JzIG1ha2UgaXQgaW50byB0aGUg
bGlicmFyeS48L3A+CgogICAgICA8dGFibGUgY2xhc3M9InN0cmF3cG9sbCI+CiAgICAgICAgPGNh
cHRpb24+QnJpc3RvbCBzdHJhdyBwb2xsIG9uICJTaG91bGQgd2UgcHJvdmlkZSB0aGlzIGFkYXB0
YXRpb24gbWV0aG9kPyI8L2NhcHRpb24+CiAgICAgICAgPHRyPjx0ZD5TRjwvdGQ+PHRkPldGPC90
ZD48dGQ+TjwvdGQ+PHRkPldBPC90ZD48dGQ+U0E8L3RkPjwvdHI+CiAgICAgICAgPHRyPjx0ZD4w
PC90ZD48dGQ+MDwvdGQ+PHRkPjE8L3RkPjx0ZD41PC90ZD48dGQ+NjwvdGQ+PC90cj4KICAgICAg
PC90YWJsZT4KICAgIDwvc2VjdGlvbj4KCiAgICA8c2VjdGlvbj4KICAgICAgPGgzIGlkPSJudWxs
LWRhdGEiPjxjb2RlPnN0cmluZ192aWV3KCkuZGF0YSgpID09IG51bGxwdHI8L2NvZGU+PzwvaDM+
CgogICAgICA8cD5UaGUgb2J2aW91cyB3YXkgdG8gaW5pdGlhbGl6ZSBhIGRlZmF1bHQgY29uc3Ry
dWN0ZWQKICAgICAgPGNvZGU+c3RyaW5nX3ZpZXc8L2NvZGU+IGlzIHdpdGggPGNvZGU+LmRhdGEo
KSA9PSBudWxscHRyPC9jb2RlPiBhbmQKICAgICAgPGNvZGU+LnNpemUoKSA9PSAwPC9jb2RlPi4g
SG93ZXZlciwgdGhhdCB2aW9sYXRlcyBhbiBpbnZhcmlhbnQgb2YgPGEKICAgICAgaHJlZj0iI3N0
cmluZy52aWV3LmRhdGEiPjxjb2RlPmRhdGEoKTwvY29kZT48L2E+LCB0aGF0IGl0IG5ldmVyIHJl
dHVybnMKICAgICAgPGNvZGU+bnVsbHB0cjwvY29kZT4uICBJbnN0ZWFkLCBpbXBsZW1lbnRhdGlv
bnMgbXVzdCBpbml0aWFsaXplCiAgICAgIDxjb2RlPmRhdGEoKTwvY29kZT4gd2l0aCBhbiBhcmJp
dHJhcnkgcG9pbnRlciB2YWx1ZSBzdWNoIHRoYXQKICAgICAgWzxjb2RlPmRhdGEoKTwvY29kZT4s
PGNvZGU+ZGF0YSgpPC9jb2RlPikgaXMgYSB2YWxpZCByYW5nZS4gKE9uIG1hbnkKICAgICAgcGxh
dGZvcm1zLCBhbiBhcmJpdHJhcnkgdmFsdWUgbWlnaHQgc3VmZmljZSwgYnV0IG9uIHNvbWUgcGxh
dGZvcm1zLCB0aGlzCiAgICAgIG1pZ2h0IG5lZWQgdG8gYmUgYSBkZXJlZmVyZW5jZWFibGUgb3Ig
b25lLXBhc3QtdGhlLWVuZCBhZGRyZXNzIGxpa2UKICAgICAgPGNvZGU+dGhpczwvY29kZT4gb3Ig
PGNvZGU+IiI8L2NvZGU+Lik8L3A+CgogICAgICA8cD5XZSBjb3VsZCBpbWFnaW5lIGF2b2lkaW5n
IHRoaXMgY29tcGxpY2F0aW9uIGJ5IGFsbG93aW5nCiAgICAgIDxjb2RlPmRhdGEoKTwvY29kZT4g
dG8gcmV0dXJuIDxjb2RlPm51bGxwdHI8L2NvZGU+LCB3aGljaCB3b3VsZCBhbHNvIGFsbG93CiAg
ICAgIHVzIHRvIHJlbGF4IHRoZSBwcmVjb25kaXRpb24gb24gPGNvZGU+c3RyaW5nX3ZpZXcoY29u
c3QgY2hhciosCiAgICAgIHNpemVfdCk8L2NvZGU+LiAgSG93ZXZlciwgaW4gR29vZ2xlJ3MgaW1w
bGVtZW50YXRpb24sIHdlIGZvdW5kIHRoYXQKICAgICAgcHJvZ3JhbW1lcnMgdGVuZGVkIHRvIHVz
ZSA8Y29kZT5kYXRhKCk9PW51bGxwdHI8L2NvZGU+IHRvIHNpZ25hbAogICAgICBjb25kaXRpb25z
IHRoYXQgZGlmZmVyZWQgZnJvbSBzaW1wbHkgPGNvZGU+ZW1wdHkoKTwvY29kZT4uIFRoaXMgd2Fz
IGEKICAgICAgc291cmNlIG9mIGNvbmZ1c2lvbiBpbiBpbnRlcmZhY2VzLCBhbmQgaXQgZ2l2ZXMg
PGNvZGU+c3RyaW5nX3ZpZXc8L2NvZGU+CiAgICAgIG9uZSBtb3JlIHBvc3NpYmxlIHZhbHVlIHRo
YW4gPGNvZGU+Y29uc3Qgc3RkOjpzdHJpbmcmPC9jb2RlPiwgc28gdGhpcwogICAgICBwcm9wb3Nh
bCBmb3JiaWRzIHRoZSBwb3NzaWJpbGl0eS48L3A+CgogICAgICA8cD5FdmVuIHdpdGhvdXQgcmVs
YXhpbmcgdGhlIHByZWNvbmRpdGlvbiBvbiA8Y29kZT5zdHJpbmdfdmlldyhjb25zdAogICAgICBj
aGFyKiwgc2l6ZV90KTwvY29kZT4sIGFsbG93aW5nIGltcGxlbWVudGF0aW9ucyB0byByZXR1cm4g
YSBudWxsCiAgICAgIDxjb2RlPmRhdGEoKTwvY29kZT4gZnJvbSA8Y29kZT5zdHJpbmdfdmlldygp
PC9jb2RlPiB3aXRob3V0IHJlcXVpcmluZyBpdCwKICAgICAgd291bGQgY2F1c2UgcG9ydGFiaWxp
dHkgcHJvYmxlbXM6IHNvbWUgdXNlcnMgd291bGQgdGVzdCBmb3IKICAgICAgPGNvZGU+ZGF0YSgp
PT1udWxscHRyPC9jb2RlPiB0byBpZGVudGlmeSBhIGRlZmF1bHQtY29uc3RydWN0ZWQKICAgICAg
PGNvZGU+c3RyaW5nX3ZpZXc8L2NvZGU+IG9uIHRoYXQgaW1wbGVtZW50YXRpb24sIGFuZCB3b3Vs
ZCB0aGVuIGJlIHVuYWJsZQogICAgICB0byB1c2UgYW5vdGhlciBpbXBsZW1lbnRhdGlvbi48L3A+
CgogICAgICA8cD5Ib3dldmVyLCA8Y29kZT5zdGQ6OnZlY3Rvcjo6ZGF0YSgpPC9jb2RlPiBtYXkg
cmV0dXJuCiAgICAgIDxjb2RlPm51bGxwdHI8L2NvZGU+LCBhbmQgd2UgZG9uJ3QgaGF2ZQogICAg
ICA8Y29kZT5jb250aWd1b3VzX2l0ZXJhdG9yX3RhZzwvY29kZT4gYXZhaWxhYmxlIHlldCB0byBh
bGxvdyB1c2VycyB0byBwYXNzCiAgICAgIGEgPGNvZGU+dmVjdG9yPC9jb2RlPidzIDxjb2RlPmJl
Z2luKCk8L2NvZGU+IGFuZCA8Y29kZT5lbmQoKTwvY29kZT4gdG8KICAgICAgPGNvZGU+c3RyaW5n
X3ZpZXcoKTwvY29kZT4sIHNvIHRoaXMgcmVxdWlyZW1lbnQgbWF5IHJlcXVpcmUgZXh0cmEKICAg
ICAgY29uZGl0aW9ucyBpbiB1c2VyIGNvZGUuIFRoaXMgYW5kIHN0cm9uZyBpbnRlcmVzdCBvbiB0
aGUgc3RkLXByb3Bvc2FscwogICAgICBtYWlsaW5nIGxpc3QgZW5jb3VyYWdlZCBtZSB0byBhZGQg
YW4gPGEKICAgICAgaHJlZj0iI2FsdGVybmF0ZS1udWxscHRyLXdvcmRpbmciPmFsdGVybmF0ZSB3
b3JkaW5nPC9hPiBzZWN0aW9uIGJlbG93LjwvcD4KICAgIDwvc2VjdGlvbj4KICA8L3NlY3Rpb24+
CgogIDxzZWN0aW9uPgogICAgPGgyIGlkPSJmdXR1cmUiPlBsYW5zIGZvciBmdXR1cmUgY2hhbmdl
czwvaDI+CgogICAgPHVsPgogICAgICA8bGk+VGhlcmUgYXJlIG1hbnkgZnVuY3Rpb25zIG91dHNp
ZGUgb2YgdGhlIHN0cmluZ3MgY2hhcHRlciB0aGF0IHNob3VsZAogICAgICBpbmNvcnBvcmF0ZSA8
Y29kZT5zdHJpbmdfdmlldzwvY29kZT4uICBJJ2xsIHByb3Bvc2UgdGhvc2UgY2hhbmdlcyBpbiBh
CiAgICAgIHN1YnNlcXVlbnQgcGFwZXIgYmFzZWQgb24gdGhlIDxhCiAgICAgIGhyZWY9Imh0dHA6
Ly93d3cub3Blbi1zdGQub3JnL2p0YzEvc2MyMi93ZzIxL2RvY3MvcGFwZXJzLzIwMTMvbjM2ODUu
aHRtbCN3b3JkaW5nLXJlc3QiPnBhcnQKICAgICAgb2YgTjM2ODU8L2E+IHRoYXQgaXNuJ3QgaW4g
dGhpcyBwYXBlci48L2xpPgogICAgICA8bGk+V2Ugd2FudCBhIGxpdGVyYWwgb3BlcmF0b3IgdG8g
cHJvZHVjZSA8Y29kZT5zdHJpbmdfdmlldzwvY29kZT4sIG1heWJlIDxjb2RlPiIic3Y8L2NvZGU+
LjwvbGk+CiAgICA8L3VsPgogIDwvc2VjdGlvbj4KCiAgPHNlY3Rpb24+CiAgICA8aDIgaWQ9InJl
dmlzaW9uLWhpc3RvcnkiPlBhcGVyIHJldmlzaW9uIGhpc3Rvcnk8L2gyPgogICAgPHA+VGhpcyBw
YXBlciB1cGRhdGVzIE4zNzYyIGJ5OjwvcD4KICAgIDx1bD4KICAgICAgPGxpPkV4cGxhaW5pbmcg
d2h5IDxjb2RlPnN0cmluZ192aWV3KCkuZGF0YSgpICE9IG51bGxwdHI8L2NvZGU+IGFuZCBhZGRp
bmcKICAgICAgYW4gYWx0ZXJuYXRlIHdvcmRpbmcgc2VjdGlvbiBpbiBjYXNlIHdlIGRlY2lkZSB0
aGF0IHNob3VsZCBiZQogICAgICBwb3NzaWJsZSw8L2xpPgogICAgICA8bGk+Rml4aW5nIHVwIHJl
ZmVyZW5jZXMgYW5kIG5hbWVzcGFjZXMgdG8gbWF0Y2ggdGhlIEZ1bmRhbWVudGFscyBUUyw8L2xp
PgogICAgICA8bGk+RGVjbGFyaW5nIGV2ZXJ5IGZ1bmN0aW9uIGFzIDxjb2RlPmNvbnN0ZXhwcjwv
Y29kZT4gdGhhdAogICAgICBjb3VsZCBiZSBhIGNvbnN0YW50IGV4cHJlc3Npb24gaWYgdGhlIDxj
b2RlPnRyYWl0czwvY29kZT4gY2xhc3MKICAgICAgaXMgc3VpdGFibGUsIGFuZDwvbGk+CiAgICAg
IDxsaT5BZGRpbmcgZXhwb3NpdGlvbi1vbmx5IDxjb2RlPmRhdGFfPC9jb2RlPiBhbmQgPGNvZGU+
c2l6ZV88L2NvZGU+IG1lbWJlcnMsIGFuZCByZS1leHBsYWluaW5nIHNldmVyYWwgbWVtYmVycyBp
biB0ZXJtcyBvZiB0aGVtLjwvbGk+CiAgICA8L3VsPgoKICAgIDxwPjxhIGhyZWY9Imh0dHA6Ly93
d3cub3Blbi1zdGQub3JnL2p0YzEvc2MyMi93ZzIxL2RvY3MvcGFwZXJzLzIwMTMvbjM3NjIuaHRt
bCI+TjM3NjI8L2E+IHVwZGF0ZWQgTjM2ODUgYnkgcmVtb3Zpbmcgb3RoZXIgc3RhbmRhcmQgbGli
cmFyeSB1cGRhdGVzIHNvCiAgICB0aGF0IHRoZSBjb3JlIDxjb2RlPnN0cmluZ192aWV3PC9jb2Rl
PiBjbGFzcyBjYW4gYmUgYWNjZXB0ZWQgaW5kZXBlbmRlbnRseS4KICAgIEkndmUgYWxzbzo8L3A+
CiAgICA8dWw+CiAgICAgIDxsaT5GaXhlZCBzb21lIGJ1Z3MgaW4gdGhlIDxjb2RlPnBvczwvY29k
ZT4gYW5kIDxjb2RlPm48L2NvZGU+IHBhcmFtZXRlcnMsPC9saT4KICAgICAgPGxpPkFkZGVkIDxj
b2RlPmNvcHkoKTwvY29kZT4gYmFjayw8L2xpPgogICAgICA8bGk+UmVtb3ZlZCB0aGUgYXNzdW1w
dGlvbiB0aGF0IDxhCiAgICAgIGhyZWY9Imh0dHA6Ly93d3cub3Blbi1zdGQub3JnL2p0YzEvc2My
Mi93ZzIxL2RvY3MvcGFwZXJzLzIwMTMvbjM2ODcuaHRtbCMyMjMyIj5MV0cKICAgICAgaXNzdWUg
MjIzMjwvYT4gd2lsbCBiZSBmaXhlZCw8L2xpPgogICAgICA8bGk+QWRkZWQgYSBtZW1iZXIgPGNv
ZGU+c3dhcCgpPC9jb2RlPiBzaW5jZSBpdCdzIGNvbnN0YW50IHRpbWUsPC9saT4KICAgICAgPGxp
PkVuc3VyZWQgdGhhdCA8Y29kZT5zdGQ6OnN3YXA8L2NvZGU+IGFuZCB0aGUgcmFuZ2UgYWNjZXNz
IGZ1bmN0aW9ucyBhcmUKICAgICAgYXZhaWxhYmxlIHdoZW4gPGNvZGU+Jmx0O3N0cmluZ192aWV3
PjwvY29kZT4gaXMgaW5jbHVkZWQsIGFuZDwvbGk+CiAgICAgIDxsaT5GaXhlZCB1cCBzb21lIDxj
b2RlPm5vZXhjZXB0PC9jb2RlPnMuPC9saT4KICAgIDwvdWw+CgogICAgPHA+PGEgaHJlZj0iaHR0
cDovL3d3dy5vcGVuLXN0ZC5vcmcvanRjMS9zYzIyL3dnMjEvZG9jcy9wYXBlcnMvMjAxMy9uMzY4
NS5odG1sIj5OMzY4NTwvYT4gdXBkYXRlZCBOMzYwOSB3aXRoIHRoZSByZXN1bHRzIG9mIHRoZSA8
YQogICAgaHJlZj0iaHR0cDovL3dpa2kuZWRnLmNvbS90d2lraS9iaW4vdmlldy9XZzIxYnJpc3Rv
bC9MaWJyYXJ5RXZvbHV0aW9uV29ya2luZ0dyb3VwI04zNjA5Ij5MRVdHCiAgICBkaXNjdXNzaW9u
IGluIEJyaXN0b2w8L2E+LiAgU2lnbmlmaWNhbnQgY2hhbmdlcyBpbmNsdWRlOjwvcD4KICAgIDx1
bD4KICAgICAgPGxpPlJlZGlyZWN0ZWQgZm9yIGEgVFMgaW5zdGVhZCBvZiBDKysxNDwvbGk+CiAg
ICAgIDxsaT5Nb3ZlZCBpbnRvIGEgPGNvZGU+Jmx0O3N0cmluZ192aWV3PjwvY29kZT4gaGVhZGVy
LjwvbGk+CiAgICAgIDxsaT5BZGRlZCB0aGUgPGNvZGU+cG9zPC9jb2RlPiBhbmQgPGNvZGU+bjwv
Y29kZT4gcGFyYW1ldGVycyBiYWNrIHRvIDxjb2RlPnN0cmluZ192aWV3PC9jb2RlPiBtZXRob2Rz
LjwvbGk+CiAgICAgIDxsaT5SZW1vdmVkIDxjb2RlPnN0YXJ0c193aXRoPC9jb2RlPiBhbmQgPGNv
ZGU+ZW5kc193aXRoPC9jb2RlPi48L2xpPgogICAgPC91bD4KCiAgICA8cD48YSBocmVmPSJodHRw
Oi8vd3d3Lm9wZW4tc3RkLm9yZy9qdGMxL3NjMjIvd2cyMS9kb2NzL3BhcGVycy8yMDEzL24zNjA5
Lmh0bWwiPk4zNjA5PC9hPiB3YXMgYSBtaW5vciB1cGRhdGUgdG8gTjM1MTIgdGhhdCByZW5hbWVk
IHRoZSBwcm9wb3NlZCBjbGFzcyB0bwogICAgPGNvZGU+YmFzaWNfc3RyaW5nX3ZpZXc8L2NvZGU+
IGFuZCBmaXhlZCBzb21lIHdvcmRpbmcgbWlzdGFrZXMuPC9wPgoKICAgIDxwPjxhIGhyZWY9Imh0
dHA6Ly93d3cub3Blbi1zdGQub3JnL2p0YzEvc2MyMi93ZzIxL2RvY3MvcGFwZXJzLzIwMTMvbjM1
MTIuaHRtbCI+TjM1MTI8L2E+CiAgICB1cGRhdGVkIE4zNDQyIHdpdGggd29yZGluZyBmb3IgdGhl
IDxhCiAgICBocmVmPSJodHRwOi8vd3d3Lm9wZW4tc3RkLm9yZy9qdGMxL3NjMjIvd2cyMS9kb2Nz
L3BhcGVycy8yMDEyL24zNDg1LnBkZiI+ZHJhZnQKICAgIEMrKzE0IHN0YW5kYXJkPC9hPi4gIE5v
dGUgdGhhdCB3ZSBzdGlsbCBhcmVuJ3Qgc3VyZSB3aGV0aGVyIHdlJ3JlIGFpbWluZyBmb3IKICAg
IGEgVFMgb3IgQysrMTQuPC9wPgoKICAgIDxwPjxhIGhyZWY9Imh0dHA6Ly93d3cub3Blbi1zdGQu
b3JnL2p0YzEvc2MyMi93ZzIxL2RvY3MvcGFwZXJzLzIwMTIvbjM0NDIuaHRtbCI+TjM0NDI8L2E+
CiAgICB3YXMgYWltZWQgYXQgYSBUUyBhbmQgdXBkYXRlZAogICAgPGEgaHJlZj0iaHR0cDovL3d3
dy5vcGVuLXN0ZC5vcmcvanRjMS9zYzIyL3dnMjEvZG9jcy9wYXBlcnMvMjAxMi9uMzMzNC5odG1s
Ij5OMzMzNDwvYT4KICAgIGJ5IHJlbW92aW5nIDxjb2RlPmFycmF5X3JlZjwvY29kZT4uPC9wPgoK
ICAgIDxwPlRoZSA8YQogICAgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9jeHgtc3Rk
LWRyYWZ0L2Jsb2Ivc3RyaW5nLXJlZi1wYXBlci9zdHJpbmdfdmlldy5odG1sIj5tb3N0CiAgICBy
ZWNlbnQgdmVyc2lvbiBvZiB0aGlzIHBhcGVyPC9hPiBpcyBtYWludGFpbmVkIG9uIEdpdEh1Yi48
L3A+CiAgPC9zZWN0aW9uPgoKCiAgPGhyLz4KCiAgPHNlY3Rpb24gY2xhc3M9IndvcmRpbmciPgog
ICAgPGgyIGlkPSJ3b3JkaW5nIj5Xb3JkaW5nIGZvciB0aGUgRnVuZGFtZW50YWxzIFRTPC9oMj4K
CiAgICA8IS0tPHA+V29yZGluZyBjaGFuZ2VzIGFyZSBiZWluZyBtYWludGFpbmVkIGF0IDxhCiAg
ICBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2N4eC1zdGQtZHJhZnQvY29tcGFyZS9z
dHJpbmctcmVmIj5odHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2N4eC1zdGQtZHJhZnQvY29tcGFy
ZS9zdHJpbmctcmVmPC9hPgogICAgYW5kIGEgc25hcHNob3Qgb2YgdGhlIGNoYW5nZXMgaXMgY29w
aWVkIGJlbG93LiAgQSB2ZXJ5IGVhcmx5IGltcGxlbWVudGF0aW9uCiAgICBpcyBhdCA8YQogICAg
aHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9saWJjeHgvY29tcGFyZS9zdHJpbmctcmVm
Ij5odHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2xpYmN4eC9jb21wYXJlL3N0cmluZy1yZWY8L2E+
LgogICAgUGF0Y2hlcyBhbmQgcHVsbCByZXF1ZXN0cyBhcmUgd2VsY29tZSBhZ2FpbnN0IGJvdGgu
PC9wPi0tPgoKICAgIDxoMyBpZD0ic3RyaW5ncyI+Q2xhdXNlIHgsIHN0cmluZ192aWV3PC9oMz4K
CiAgICA8cD5UaGUgY2xhc3MgdGVtcGxhdGUgPGNvZGU+YmFzaWNfc3RyaW5nX3ZpZXc8L2NvZGU+
IGRlc2NyaWJlcyBvYmplY3RzIHRoYXQKICAgIGNhbiByZWZlciB0byBhIGNvbnN0YW50IGNvbnRp
Z3VvdXMgc2VxdWVuY2Ugb2YgY2hhci1saWtlIChDKysxMVtzdHJpbmdzLmdlbmVyYWxdKSBvYmpl
Y3RzCiAgICB3aXRoIHRoZSBmaXJzdCBlbGVtZW50IG9mCiAgICB0aGUgc2VxdWVuY2UgYXQgcG9z
aXRpb24gemVyby4gSW4gdGhlIHJlc3Qgb2YgdGhpcyBDbGF1c2UsIHRoZSB0eXBlIG9mIHRoZQog
ICAgY2hhci1saWtlIG9iamVjdHMgaGVsZCBpbiBhIDxjb2RlPmJhc2ljX3N0cmluZ192aWV3PC9j
b2RlPgogICAgb2JqZWN0IGlzIGRlc2lnbmF0ZWQgYnkgPGNvZGU+Y2hhclQ8L2NvZGU+LjwvcD4K
CiAgICA8cD5bTm90ZTogVGhlIGxpYnJhcnkgcHJvdmlkZXMgaW1wbGljaXQgY29udmVyc2lvbnMg
ZnJvbSA8Y29kZT5jb25zdAogICAgY2hhclQqPC9jb2RlPiBhbmQgPGNvZGU+c3RkOjpiYXNpY19z
dHJpbmcmbHQ7Y2hhclQsIC4uLj48L2NvZGU+IHRvCiAgICA8Y29kZT5zdGQ6OmJhc2ljX3N0cmlu
Z192aWV3Jmx0O2NoYXJULCAuLi4+PC9jb2RlPiBzbyB0aGF0IHVzZXIgY29kZSBjYW4KICAgIGFj
Y2VwdCBqdXN0IDxjb2RlPnN0ZDo6YmFzaWNfc3RyaW5nX3ZpZXcmbHQ7Y2hhclQ+PC9jb2RlPiBh
cyBhIG5vbi10ZW1wbGF0ZWQKICAgIHBhcmFtZXRlciB3aGVyZXZlciBhIHNlcXVlbmNlIG9mIGNo
YXJhY3RlcnMgaXMgZXhwZWN0ZWQuIFVzZXItZGVmaW5lZCB0eXBlcwogICAgc2hvdWxkIGRlZmlu
ZSB0aGVpciBvd24gaW1wbGljaXQgY29udmVyc2lvbnMgdG8KICAgIDxjb2RlPnN0ZDo6YmFzaWNf
c3RyaW5nX3ZpZXc8L2NvZGU+IGluCiAgICBvcmRlciB0byBpbnRlcm9wZXJhdGUgd2l0aCB0aGVz
ZSBmdW5jdGlvbnMuIOKAlCBlbmQgbm90ZSBdPC9wPgoKICAgIDxwPlRoZSBjb21wbGV4aXR5IG9m
IG1lbWJlciBmdW5jdGlvbnMgaXMgTygxKSB1bmxlc3Mgb3RoZXJ3aXNlCiAgICBzcGVjaWZpZWQu
PC9wPgoKICAgIDxoND5BZGQgYSAiSGVhZGVyICZsdDtzdHJpbmdfdmlldz4gc3lub3BzaXMiPC9o
ND4KCiAgICA8cHJlPjxjb2RlPm5hbWVzcGFjZSBzdGQgewpuYW1lc3BhY2UgZXhwZXJpbWVudGFs
IHsKaW5saW5lIG5hbWVzcGFjZSBmdW5kYW1lbnRhbHNfdjEgewogIC8vIFtiYXNpYy5zdHJpbmcu
dmlld10sIGJhc2ljX3N0cmluZ192aWV3OgogIHRlbXBsYXRlJmx0O2NsYXNzIGNoYXJULCBjbGFz
cyB0cmFpdHMgPSBjaGFyX3RyYWl0cyZsdDtjaGFyVD4+CiAgICAgIGNsYXNzIGJhc2ljX3N0cmlu
Z192aWV3OwoKICAvLyBbc3RyaW5nLnZpZXcuY29tcGFyaXNvbl0sIG5vbi1tZW1iZXIgYmFzaWNf
c3RyaW5nX3ZpZXcgY29tcGFyaXNvbiBmdW5jdGlvbnMKICB0ZW1wbGF0ZSZsdDtjbGFzcyBjaGFy
VCwgY2xhc3MgdHJhaXRzPgogIGNvbnN0ZXhwciBib29sIG9wZXJhdG9yPT0oYmFzaWNfc3RyaW5n
X3ZpZXcmbHQ7Y2hhclQsIHRyYWl0cz4geCwgYmFzaWNfc3RyaW5nX3ZpZXcmbHQ7Y2hhclQsIHRy
YWl0cz4geSkgbm9leGNlcHQ7CiAgdGVtcGxhdGUmbHQ7Y2xhc3MgY2hhclQsIGNsYXNzIHRyYWl0
cz4KICBjb25zdGV4cHIgYm9vbCBvcGVyYXRvciE9KGJhc2ljX3N0cmluZ192aWV3Jmx0O2NoYXJU
LCB0cmFpdHM+IHgsIGJhc2ljX3N0cmluZ192aWV3Jmx0O2NoYXJULCB0cmFpdHM+IHkpIG5vZXhj
ZXB0OwogIHRlbXBsYXRlJmx0O2NsYXNzIGNoYXJULCBjbGFzcyB0cmFpdHM+CiAgY29uc3RleHBy
IGJvb2wgb3BlcmF0b3ImbHQ7IChiYXNpY19zdHJpbmdfdmlldyZsdDtjaGFyVCwgdHJhaXRzPiB4
LCBiYXNpY19zdHJpbmdfdmlldyZsdDtjaGFyVCwgdHJhaXRzPiB5KSBub2V4Y2VwdDsKICB0ZW1w
bGF0ZSZsdDtjbGFzcyBjaGFyVCwgY2xhc3MgdHJhaXRzPgogIGNvbnN0ZXhwciBib29sIG9wZXJh
dG9yPiAoYmFzaWNfc3RyaW5nX3ZpZXcmbHQ7Y2hhclQsIHRyYWl0cz4geCwgYmFzaWNfc3RyaW5n
X3ZpZXcmbHQ7Y2hhclQsIHRyYWl0cz4geSkgbm9leGNlcHQ7CiAgdGVtcGxhdGUmbHQ7Y2xhc3Mg
Y2hhclQsIGNsYXNzIHRyYWl0cz4KICBjb25zdGV4cHIgYm9vbCBvcGVyYXRvciZsdDs9KGJhc2lj
X3N0cmluZ192aWV3Jmx0O2NoYXJULCB0cmFpdHM+IHgsIGJhc2ljX3N0cmluZ192aWV3Jmx0O2No
YXJULCB0cmFpdHM+IHkpIG5vZXhjZXB0OwogIHRlbXBsYXRlJmx0O2NsYXNzIGNoYXJULCBjbGFz
cyB0cmFpdHM+CiAgY29uc3RleHByIGJvb2wgb3BlcmF0b3I+PShiYXNpY19zdHJpbmdfdmlldyZs
dDtjaGFyVCwgdHJhaXRzPiB4LCBiYXNpY19zdHJpbmdfdmlldyZsdDtjaGFyVCwgdHJhaXRzPiB5
KSBub2V4Y2VwdDsKICAvLyBbc3RyaW5nLnZpZXcuY29tcGFyaXNvbl0sIHN1ZmZpY2llbnQgYWRk
aXRpb25hbCBvdmVybG9hZHMgb2YgY29tcGFyaXNvbiBmdW5jdGlvbnMKCiAgLy8gW3N0cmluZy52
aWV3Lm5vbm1lbV0sIG90aGVyIG5vbi1tZW1iZXIgYmFzaWNfc3RyaW5nX3ZpZXcgZnVuY3Rpb25z
CiAgdGVtcGxhdGUmbHQ7Y2xhc3MgY2hhclQsIGNsYXNzIHRyYWl0cyA9IGNoYXJfdHJhaXRzJmx0
O2NoYXJUPiwKICAgICAgICAgICBjbGFzcyBBbGxvY2F0b3IgPSBhbGxvY2F0b3ImbHQ7Y2hhclQ+
ID4KICAgIGJhc2ljX3N0cmluZyZsdDtjaGFyVCwgdHJhaXRzLCBBbGxvY2F0b3I+IHRvX3N0cmlu
ZygKICAgICAgYmFzaWNfc3RyaW5nX3ZpZXcmbHQ7Y2hhclQsIHRyYWl0cz4sCiAgICAgIGNvbnN0
IEFsbG9jYXRvciYgYSA9IEFsbG9jYXRvcigpKTsKCiAgdGVtcGxhdGUmbHQ7Y2xhc3MgY2hhclQs
IGNsYXNzIHRyYWl0cz4KICAgIGJhc2ljX29zdHJlYW0mbHQ7Y2hhclQsIHRyYWl0cz4mCiAgICAg
IG9wZXJhdG9yJmx0OyZsdDsoYmFzaWNfb3N0cmVhbSZsdDtjaGFyVCwgdHJhaXRzPiYgb3MsCiAg
ICAgICAgICAgICAgICAgYmFzaWNfc3RyaW5nX3ZpZXcmbHQ7Y2hhclQsdHJhaXRzPiBzdHIpOwoK
ICAvLyBiYXNpY19zdHJpbmdfdmlldyB0eXBlZGVmIG5hbWVzCiAgdHlwZWRlZiBiYXNpY19zdHJp
bmdfdmlldyZsdDtjaGFyPiBzdHJpbmdfdmlldzsKICB0eXBlZGVmIGJhc2ljX3N0cmluZ192aWV3
Jmx0O2NoYXIxNl90PiB1MTZzdHJpbmdfdmlldzsKICB0eXBlZGVmIGJhc2ljX3N0cmluZ192aWV3
Jmx0O2NoYXIzMl90PiB1MzJzdHJpbmdfdmlldzsKICB0eXBlZGVmIGJhc2ljX3N0cmluZ192aWV3
Jmx0O3djaGFyX3Q+IHdzdHJpbmdfdmlldzsKCn0gIC8vIG5hbWVzcGFjZSBmdW5kYW1lbnRhbHNf
djEKfSAgLy8gbmFtZXNwYWNlIGV4cGVyaW1lbnRhbAoKICAvLyBbc3RyaW5nLnZpZXcuaGFzaF0s
IGhhc2ggc3VwcG9ydDoKICB0ZW1wbGF0ZSAmbHQ7Y2xhc3MgVD4gc3RydWN0IGhhc2g7CiAgdGVt
cGxhdGUgJmx0Oz4gc3RydWN0IGhhc2gmbHQ7ZXhwZXJpbWVudGFsOjpzdHJpbmdfdmlldz47CiAg
dGVtcGxhdGUgJmx0Oz4gc3RydWN0IGhhc2gmbHQ7ZXhwZXJpbWVudGFsOjp1MTZzdHJpbmdfdmll
dz47CiAgdGVtcGxhdGUgJmx0Oz4gc3RydWN0IGhhc2gmbHQ7ZXhwZXJpbWVudGFsOjp1MzJzdHJp
bmdfdmlldz47CiAgdGVtcGxhdGUgJmx0Oz4gc3RydWN0IGhhc2gmbHQ7ZXhwZXJpbWVudGFsOjp3
c3RyaW5nX3ZpZXc+Owp9ICAvLyBuYW1lc3BhY2Ugc3RkPC9jb2RlPjwvcHJlPgoKICAgIDxwPlRo
ZSBmdW5jdGlvbiB0ZW1wbGF0ZXMgZGVmaW5lZCBpbiBDKysxMVt1dGlsaXR5LnN3YXBdIGFuZCBD
KysxMVtpdGVyYXRvci5yYW5nZV0gYXJlCiAgICBhdmFpbGFibGUgd2hlbiA8Y29kZT4mbHQ7c3Ry
aW5nX3ZpZXc+PC9jb2RlPiBpcyBpbmNsdWRlZC48L3A+CgogICAgPGRpdiBjbGFzcz0iZWRub3Rl
Ij48cD5Ob3JtYWxseSBJIHdvdWxkIHVwZGF0ZSB0aGUgbGlzdCBpbiBDKysxMVtpdGVyYXRvci5y
YW5nZV0sIGJ1dCB3ZSdyZSBub3QgeWV0IHN1cmUgaG93IHRvIGRvIHRoYXQgaW4gYSBUUywgc28g
SSBwaWNrZWQgdGhlIG1vcmUgc2VsZi1jb250YWluZWQgb3B0aW9uLjwvcD48L2Rpdj4KCiAgICAg
PHByZT48Y29kZT5uYW1lc3BhY2Ugc3RkIHsKbmFtZXNwYWNlIGV4cGVyaW1lbnRhbCB7Cm5hbWVz
cGFjZSBmdW5kYW1lbnRhbHNfdjEgewogIHRlbXBsYXRlJmx0O2NsYXNzIGNoYXJULCBjbGFzcyB0
cmFpdHMgPSBjaGFyX3RyYWl0cyZsdDtjaGFyVD4+CiAgY2xhc3MgYmFzaWNfc3RyaW5nX3ZpZXcg
ewogICAgcHVibGljOgogICAgLy8gdHlwZXMKICAgIHR5cGVkZWYgdHJhaXRzIHRyYWl0c190eXBl
OwogICAgdHlwZWRlZiBjaGFyVCB2YWx1ZV90eXBlOwogICAgdHlwZWRlZiBjb25zdCBjaGFyVCog
cG9pbnRlcjsKICAgIHR5cGVkZWYgY29uc3QgY2hhclQqIGNvbnN0X3BvaW50ZXI7CiAgICB0eXBl
ZGVmIGNvbnN0IGNoYXJUJiByZWZlcmVuY2U7CiAgICB0eXBlZGVmIGNvbnN0IGNoYXJUJiBjb25z
dF9yZWZlcmVuY2U7CiAgICB0eXBlZGVmIDx2YXI+aW1wbGVtZW50YXRpb24tZGVmaW5lZDwvdmFy
PiBjb25zdF9pdGVyYXRvcjsgLy8gU2VlIFtzdHJpbmcudmlldy5pdGVyYXRvcnNdCiAgICB0eXBl
ZGVmIGNvbnN0X2l0ZXJhdG9yIGl0ZXJhdG9yOyAgLy8gW0Zvb3Rub3RlOiBCZWNhdXNlIGJhc2lj
X3N0cmluZ192aWV3IHJlZmVycyB0byBhIGNvbnN0YW50IHNlcXVlbmNlLCBpdGVyYXRvciBhbmQg
Y29uc3RfaXRlcmF0b3IgYXJlIHRoZSBzYW1lIHR5cGUuIC0tZW5kIGZvb3Rub3RlXQogICAgdHlw
ZWRlZiByZXZlcnNlX2l0ZXJhdG9yJmx0O2NvbnN0X2l0ZXJhdG9yPiBjb25zdF9yZXZlcnNlX2l0
ZXJhdG9yOwogICAgdHlwZWRlZiBjb25zdF9yZXZlcnNlX2l0ZXJhdG9yIHJldmVyc2VfaXRlcmF0
b3I7CiAgICB0eXBlZGVmIHNpemVfdCBzaXplX3R5cGU7CiAgICB0eXBlZGVmIHB0cmRpZmZfdCBk
aWZmZXJlbmNlX3R5cGU7CiAgICBzdGF0aWMgY29uc3RleHByIHNpemVfdHlwZSBucG9zID0gc2l6
ZV90eXBlKC0xKTsKCiAgICAvLyBbc3RyaW5nLnZpZXcuY29uc10sIGNvbnN0cnVjdC9jb3B5CiAg
ICBjb25zdGV4cHIgYmFzaWNfc3RyaW5nX3ZpZXcoKSBub2V4Y2VwdDsKICAgIGNvbnN0ZXhwciBi
YXNpY19zdHJpbmdfdmlldyhjb25zdCBiYXNpY19zdHJpbmdfdmlldyYpIG5vZXhjZXB0ID0gZGVm
YXVsdDsKICAgIGJhc2ljX3N0cmluZ192aWV3JiBvcGVyYXRvcj0oY29uc3QgYmFzaWNfc3RyaW5n
X3ZpZXcmKSBub2V4Y2VwdCA9IGRlZmF1bHQ7CiAgICB0ZW1wbGF0ZSZsdDtjbGFzcyBBbGxvY2F0
b3I+CiAgICBiYXNpY19zdHJpbmdfdmlldyhjb25zdCBiYXNpY19zdHJpbmcmbHQ7Y2hhclQsIHRy
YWl0cywgQWxsb2NhdG9yPiYgc3RyKSBub2V4Y2VwdDsKICAgIGNvbnN0ZXhwciBiYXNpY19zdHJp
bmdfdmlldyhjb25zdCBjaGFyVCogc3RyKTs8L2NvZGU+PC9wcmU+CiAgICA8ZGl2IGNsYXNzPSJl
ZG5vdGUiPjxwPlRoZSBhYm92ZSBjb25zdHJ1Y3RvciBpcyBjb25zdGV4cHIgdG8gdGFrZSBhZHZh
bnRhZ2Ugb2YgdXNlci13cml0dGVuIHRyYWl0cyBjbGFzc2VzIHRoYXQgbWlnaHQgcHJvdmlkZSBh
IGNvbnN0ZXhwciA8Y29kZT5sZW5ndGgoKTwvY29kZT4gZnVuY3Rpb24uICBJdCBjYW4ndCBiZSBw
YXJ0IG9mIGEgY29uc3RhbnQgZXhwcmVzc2lvbiB3aXRoIDxjb2RlPnN0ZDo6Y2hhcl90cmFpdHMm
bHQ7Y2hhcj48L2NvZGU+IHdpdGhvdXQgY2hhbmdlcyB0byB0aGF0IGNsYXNzLjwvcD48L2Rpdj4K
PHByZT48Y29kZT4gICAgY29uc3RleHByIGJhc2ljX3N0cmluZ192aWV3KGNvbnN0IGNoYXJUKiBz
dHIsIHNpemVfdHlwZSBsZW4pOzwvY29kZT48L3ByZT4KICAgIDxkaXYgY2xhc3M9ImVkbm90ZSI+
PHA+Tm8gaW5pdGlhbGl6ZXJfbGlzdCBjb25zdHJ1Y3RvciBiZWNhdXNlIEMrKzExW2RjbC5pbml0
Lmxpc3RdcDYgc2F5cyBpdCB3b3VsZCBsaWtlbHkgc3RvcmUgYSBkYW5nbGluZyByZWZlcmVuY2Ug
aW50byB0aGUgPGNvZGU+YmFzaWNfc3RyaW5nX3ZpZXc8L2NvZGU+LjwvcD48L2Rpdj4KCjxwcmU+
PGNvZGU+ICAgIC8vIFtzdHJpbmcudmlldy5pdGVyYXRvcnNdLCBpdGVyYXRvcnMKICAgIGNvbnN0
ZXhwciBjb25zdF9pdGVyYXRvciBiZWdpbigpIGNvbnN0IG5vZXhjZXB0OwogICAgY29uc3RleHBy
IGNvbnN0X2l0ZXJhdG9yIGVuZCgpIGNvbnN0IG5vZXhjZXB0OwogICAgY29uc3RleHByIGNvbnN0
X2l0ZXJhdG9yIGNiZWdpbigpIGNvbnN0IG5vZXhjZXB0OwogICAgY29uc3RleHByIGNvbnN0X2l0
ZXJhdG9yIGNlbmQoKSBjb25zdCBub2V4Y2VwdDs8L2NvZGU+PC9wcmU+CiAgICA8ZGl2IGNsYXNz
PSJlZG5vdGUiPjxwPnJldmVyc2VfaXRlcmF0b3IgbWV0aG9kcyBhcmVu4oCZdCBjb25zdGV4cHIg
YmVjYXVzZSByZXZlcnNlX2l0ZXJhdG9yIGlzbuKAmXQgYSBsaXRlcmFsIHR5cGUuIFNlZSA8YSBo
cmVmPSJodHRwOi8vd3d3Lm9wZW4tc3RkLm9yZy9qdGMxL3NjMjIvd2cyMS9kb2NzL3BhcGVycy8y
MDEyL24zNDczLmh0bWwjMjIwOCI+TFdHIElzc3VlIDIyMDg8L2E+LjwvcD48L2Rpdj4KPHByZT48
Y29kZT4gICAgY29uc3RfcmV2ZXJzZV9pdGVyYXRvciByYmVnaW4oKSBjb25zdCBub2V4Y2VwdDsK
ICAgIGNvbnN0X3JldmVyc2VfaXRlcmF0b3IgcmVuZCgpIGNvbnN0IG5vZXhjZXB0OwogICAgY29u
c3RfcmV2ZXJzZV9pdGVyYXRvciBjcmJlZ2luKCkgY29uc3Qgbm9leGNlcHQ7CiAgICBjb25zdF9y
ZXZlcnNlX2l0ZXJhdG9yIGNyZW5kKCkgY29uc3Qgbm9leGNlcHQ7CgogICAgLy8gW3N0cmluZy52
aWV3LmNhcGFjaXR5XSwgY2FwYWNpdHkKICAgIGNvbnN0ZXhwciBzaXplX3R5cGUgc2l6ZSgpIGNv
bnN0IG5vZXhjZXB0OwogICAgY29uc3RleHByIHNpemVfdHlwZSBsZW5ndGgoKSBjb25zdCBub2V4
Y2VwdDsKICAgIGNvbnN0ZXhwciBzaXplX3R5cGUgbWF4X3NpemUoKSBjb25zdCBub2V4Y2VwdDsK
ICAgIGNvbnN0ZXhwciBib29sIGVtcHR5KCkgY29uc3Qgbm9leGNlcHQ7CgogICAgLy8gW3N0cmlu
Zy52aWV3LmFjY2Vzc10sIGVsZW1lbnQgYWNjZXNzCiAgICBjb25zdGV4cHIgY29uc3QgY2hhclQm
IG9wZXJhdG9yW10oc2l6ZV90eXBlIHBvcykgY29uc3Q7CiAgICBjb25zdGV4cHIgY29uc3QgY2hh
clQmIGF0KHNpemVfdHlwZSBwb3MpIGNvbnN0OwogICAgY29uc3RleHByIGNvbnN0IGNoYXJUJiBm
cm9udCgpIGNvbnN0OwogICAgY29uc3RleHByIGNvbnN0IGNoYXJUJiBiYWNrKCkgY29uc3Q7CiAg
ICBjb25zdGV4cHIgY29uc3QgY2hhclQqIGRhdGEoKSBjb25zdCBub2V4Y2VwdDsKCiAgICAvLyBb
c3RyaW5nLnZpZXcubW9kaWZpZXJzXSwgbW9kaWZpZXJzOgogICAgdm9pZCBjbGVhcigpIG5vZXhj
ZXB0OwogICAgdm9pZCByZW1vdmVfcHJlZml4KHNpemVfdHlwZSBuKTsKICAgIHZvaWQgcmVtb3Zl
X3N1ZmZpeChzaXplX3R5cGUgbik7CiAgICB2b2lkIHN3YXAoYmFzaWNfc3RyaW5nX3ZpZXcmIHMp
IG5vZXhjZXB0OwoKICAgIC8vIFtzdHJpbmcudmlldy5vcHNdLCBzdHJpbmcgb3BlcmF0aW9uczoK
ICAgIHRlbXBsYXRlJmx0O2NsYXNzIEFsbG9jYXRvcj4KICAgIGV4cGxpY2l0IG9wZXJhdG9yIGJh
c2ljX3N0cmluZyZsdDtjaGFyVCwgdHJhaXRzLCBBbGxvY2F0b3I+KCkgY29uc3Q7CgogICAgc2l6
ZV90eXBlIGNvcHkoY2hhclQqIHMsIHNpemVfdHlwZSBuLCBzaXplX3R5cGUgcG9zID0gMCkgY29u
c3Q7CgogICAgY29uc3RleHByIGJhc2ljX3N0cmluZ192aWV3IHN1YnN0cihzaXplX3R5cGUgcG9z
PTAsIHNpemVfdHlwZSBuPW5wb3MpIGNvbnN0OwogICAgY29uc3RleHByIGludCBjb21wYXJlKGJh
c2ljX3N0cmluZ192aWV3IHMpIGNvbnN0IG5vZXhjZXB0OwogICAgY29uc3RleHByIGludCBjb21w
YXJlKHNpemVfdHlwZSBwb3MxLCBzaXplX3R5cGUgbjEsIGJhc2ljX3N0cmluZ192aWV3IHMpIGNv
bnN0OwogICAgY29uc3RleHByIGludCBjb21wYXJlKHNpemVfdHlwZSBwb3MxLCBzaXplX3R5cGUg
bjEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgYmFzaWNfc3RyaW5nX3ZpZXcgcywgc2l6ZV90
eXBlIHBvczIsIHNpemVfdHlwZSBuMikgY29uc3Q7CiAgICBjb25zdGV4cHIgaW50IGNvbXBhcmUo
Y29uc3QgY2hhclQqIHMpIGNvbnN0OwogICAgY29uc3RleHByIGludCBjb21wYXJlKHNpemVfdHlw
ZSBwb3MxLCBzaXplX3R5cGUgbjEsIGNvbnN0IGNoYXJUKiBzKSBjb25zdDsKICAgIGNvbnN0ZXhw
ciBpbnQgY29tcGFyZShzaXplX3R5cGUgcG9zMSwgc2l6ZV90eXBlIG4xLAogICAgICAgICAgICAg
ICAgICAgICAgICAgIGNvbnN0IGNoYXJUKiBzLCBzaXplX3R5cGUgbjIpIGNvbnN0OwogICAgY29u
c3RleHByIHNpemVfdHlwZSBmaW5kKGJhc2ljX3N0cmluZ192aWV3IHMsIHNpemVfdHlwZSBwb3M9
MCkgY29uc3Qgbm9leGNlcHQ7CiAgICBjb25zdGV4cHIgc2l6ZV90eXBlIGZpbmQoY2hhclQgYywg
c2l6ZV90eXBlIHBvcz0wKSBjb25zdCBub2V4Y2VwdDsKICAgIGNvbnN0ZXhwciBzaXplX3R5cGUg
ZmluZChjb25zdCBjaGFyVCogcywgc2l6ZV90eXBlIHBvcywgc2l6ZV90eXBlIG4pIGNvbnN0Owog
ICAgY29uc3RleHByIHNpemVfdHlwZSBmaW5kKGNvbnN0IGNoYXJUKiBzLCBzaXplX3R5cGUgcG9z
PTApIGNvbnN0OwogICAgY29uc3RleHByIHNpemVfdHlwZSByZmluZChiYXNpY19zdHJpbmdfdmll
dyBzLCBzaXplX3R5cGUgcG9zPW5wb3MpIGNvbnN0IG5vZXhjZXB0OwogICAgY29uc3RleHByIHNp
emVfdHlwZSByZmluZChjaGFyVCBjLCBzaXplX3R5cGUgcG9zPW5wb3MpIGNvbnN0IG5vZXhjZXB0
OwogICAgY29uc3RleHByIHNpemVfdHlwZSByZmluZChjb25zdCBjaGFyVCogcywgc2l6ZV90eXBl
IHBvcywgc2l6ZV90eXBlIG4pIGNvbnN0OwogICAgY29uc3RleHByIHNpemVfdHlwZSByZmluZChj
b25zdCBjaGFyVCogcywgc2l6ZV90eXBlIHBvcz1ucG9zKSBjb25zdDsKICAgIGNvbnN0ZXhwciBz
aXplX3R5cGUgZmluZF9maXJzdF9vZihiYXNpY19zdHJpbmdfdmlldyBzLCBzaXplX3R5cGUgcG9z
PTApIGNvbnN0IG5vZXhjZXB0OwogICAgY29uc3RleHByIHNpemVfdHlwZSBmaW5kX2ZpcnN0X29m
KGNoYXJUIGMsIHNpemVfdHlwZSBwb3M9MCkgY29uc3Qgbm9leGNlcHQ7CiAgICBjb25zdGV4cHIg
c2l6ZV90eXBlIGZpbmRfZmlyc3Rfb2YoY29uc3QgY2hhclQqIHMsIHNpemVfdHlwZSBwb3MsIHNp
emVfdHlwZSBuKSBjb25zdDsKICAgIGNvbnN0ZXhwciBzaXplX3R5cGUgZmluZF9maXJzdF9vZihj
b25zdCBjaGFyVCogcywgc2l6ZV90eXBlIHBvcz0wKSBjb25zdDsKICAgIGNvbnN0ZXhwciBzaXpl
X3R5cGUgZmluZF9sYXN0X29mKGJhc2ljX3N0cmluZ192aWV3IHMsIHNpemVfdHlwZSBwb3M9bnBv
cykgY29uc3Qgbm9leGNlcHQ7CiAgICBjb25zdGV4cHIgc2l6ZV90eXBlIGZpbmRfbGFzdF9vZihj
aGFyVCBjLCBzaXplX3R5cGUgcG9zPW5wb3MpIGNvbnN0IG5vZXhjZXB0OwogICAgY29uc3RleHBy
IHNpemVfdHlwZSBmaW5kX2xhc3Rfb2YoY29uc3QgY2hhclQqIHMsIHNpemVfdHlwZSBwb3MsIHNp
emVfdHlwZSBuKSBjb25zdDsKICAgIGNvbnN0ZXhwciBzaXplX3R5cGUgZmluZF9sYXN0X29mKGNv
bnN0IGNoYXJUKiBzLCBzaXplX3R5cGUgcG9zPW5wb3MpIGNvbnN0OwogICAgY29uc3RleHByIHNp
emVfdHlwZSBmaW5kX2ZpcnN0X25vdF9vZihiYXNpY19zdHJpbmdfdmlldyBzLCBzaXplX3R5cGUg
cG9zPTApIGNvbnN0IG5vZXhjZXB0OwogICAgY29uc3RleHByIHNpemVfdHlwZSBmaW5kX2ZpcnN0
X25vdF9vZihjaGFyVCBjLCBzaXplX3R5cGUgcG9zPTApIGNvbnN0IG5vZXhjZXB0OwogICAgY29u
c3RleHByIHNpemVfdHlwZSBmaW5kX2ZpcnN0X25vdF9vZihjb25zdCBjaGFyVCogcywgc2l6ZV90
eXBlIHBvcywgc2l6ZV90eXBlIG4pIGNvbnN0OwogICAgY29uc3RleHByIHNpemVfdHlwZSBmaW5k
X2ZpcnN0X25vdF9vZihjb25zdCBjaGFyVCogcywgc2l6ZV90eXBlIHBvcz0wKSBjb25zdDsKICAg
IGNvbnN0ZXhwciBzaXplX3R5cGUgZmluZF9sYXN0X25vdF9vZihiYXNpY19zdHJpbmdfdmlldyBz
LCBzaXplX3R5cGUgcG9zPW5wb3MpIGNvbnN0IG5vZXhjZXB0OwogICAgY29uc3RleHByIHNpemVf
dHlwZSBmaW5kX2xhc3Rfbm90X29mKGNoYXJUIGMsIHNpemVfdHlwZSBwb3M9bnBvcykgY29uc3Qg
bm9leGNlcHQ7CiAgICBjb25zdGV4cHIgc2l6ZV90eXBlIGZpbmRfbGFzdF9ub3Rfb2YoY29uc3Qg
Y2hhclQqIHMsIHNpemVfdHlwZSBwb3MsIHNpemVfdHlwZSBuKSBjb25zdDsKICAgIGNvbnN0ZXhw
ciBzaXplX3R5cGUgZmluZF9sYXN0X25vdF9vZihjb25zdCBjaGFyVCogcywgc2l6ZV90eXBlIHBv
cz1ucG9zKSBjb25zdDsKCiAgIHByaXZhdGU6CiAgICBjb25zdCBjaGFyVCogZGF0YV87ICAvLyA8
ZW0+ZXhwb3NpdGlvbiBvbmx5PC9lbT4KICAgIHNpemVfdHlwZSAgICBzaXplXzsgIC8vIDxlbT5l
eHBvc2l0aW9uIG9ubHk8L2VtPgogIH07Cn0gIC8vIG5hbWVzcGFjZSBmdW5kYW1lbnRhbHNfdjEK
fSAgLy8gbmFtZXNwYWNlIGV4cGVyaW1lbnRhbAp9ICAvLyBuYW1lc3BhY2Ugc3RkPC9jb2RlPjwv
cHJlPgoKICAgIDxwPkluIGV2ZXJ5IHNwZWNpYWxpemF0aW9uIDxjb2RlPmJhc2ljX3N0cmluZ192
aWV3Jmx0O2NoYXJULCB0cmFpdHM+PC9jb2RlPiwKICAgIHRoZSB0eXBlIDxjb2RlPnRyYWl0czwv
Y29kZT4gc2hhbGwgc2F0aXNmeSB0aGUgY2hhcmFjdGVyIHRyYWl0cwogICAgcmVxdWlyZW1lbnRz
IChDKysxMVtjaGFyLnRyYWl0c10pLCBhbmQgdGhlIHR5cGUgPGNvZGU+dHJhaXRzOjpjaGFyX3R5
cGU8L2NvZGU+CiAgICBzaGFsbCBuYW1lIHRoZSBzYW1lIHR5cGUgYXMgPGNvZGU+Y2hhclQ8L2Nv
ZGU+LjwvcD4KCiAgICA8aDQ+QWRkIGEgc3ViY2xhdXNlICJ4LjEgYmFzaWNfc3RyaW5nX3ZpZXcg
Y29uc3RydWN0b3JzIGFuZCBhc3NpZ25tZW50IG9wZXJhdG9ycyAgW3N0cmluZy52aWV3LmNvbnNd
IjwvaDQ+CgogICAgPHByZT48Y29kZT5jb25zdGV4cHIgYmFzaWNfc3RyaW5nX3ZpZXcoKSBub2V4
Y2VwdDs8L2NvZGU+PC9wcmU+CiAgICA8ZGl2IGNsYXNzPSJhdHRyaWJ1dGVzIj4KICAgICAgPHA+
PGk+RWZmZWN0czwvaT46IENvbnN0cnVjdHMgYW4gZW1wdHkgPGNvZGU+YmFzaWNfc3RyaW5nX3Zp
ZXc8L2NvZGU+LjwvcD4KICAgICAgPHA+PGk+UG9zdGNvbmRpdGlvbjwvaT46IDxjb2RlPnNpemVf
ID09IDA8L2NvZGU+LCBhbmQgPGNvZGU+ZGF0YV88L2NvZGU+IGhhcyBhbiB1bnNwZWNpZmllZCwg
bm9uLW51bGwgdmFsdWUgc3VjaCB0aGF0IFs8Y29kZT5kYXRhXzwvY29kZT4sPGNvZGU+ZGF0YV88
L2NvZGU+KSBpcyBhIHZhbGlkIHJhbmdlLjwvcD4KICAgIDwvZGl2PgoKICAgIDxwcmU+PGNvZGU+
dGVtcGxhdGUmbHQ7Y2xhc3MgQWxsb2NhdG9yPgpiYXNpY19zdHJpbmdfdmlldyhjb25zdCBiYXNp
Y19zdHJpbmcmbHQ7Y2hhclQsIHRyYWl0cywgQWxsb2NhdG9yPiYgc3RyKSBub2V4Y2VwdDs8L2Nv
ZGU+PC9wcmU+CiAgICA8ZGl2IGNsYXNzPSJhdHRyaWJ1dGVzIj4KICAgICAgPHA+PGk+RWZmZWN0
czwvaT46IENvbnN0cnVjdHMgYSA8Y29kZT5iYXNpY19zdHJpbmdfdmlldzwvY29kZT4sIHdpdGgg
dGhlIHBvc3Rjb25kaXRpb25zIGluIFRhYmxlIFt0YWI6c3RyaW5nLnZpZXcuY3RyLjFdPC9wPgog
ICAgICA8cD48aT5SZW1hcmtzPC9pPjogVGhlIHByb2dyYW0gc2hhbGwgbm90IGFsdGVyIGFueSBv
ZiB0aGUgdmFsdWVzIHN0b3JlZCBpbiB0aGUgY2hhcmFjdGVyIGFycmF5LiBbRm9vdG5vdGU6IFRo
aXMgaXMgdGhlIHNhbWUgcmVxdWlyZW1lbnQgYXMgb24gPGNvZGU+c3RyLmRhdGEoKTwvY29kZT4g
LS0gZW5kIGZvb3Rub3RlXTwvcD4KICAgICAgPHRhYmxlPjxjYXB0aW9uPlRhYmxlIFt0YWI6c3Ry
aW5nLnZpZXcuY3RyLjFdIOKAlCBiYXNpY19zdHJpbmdfdmlldyhjb25zdCBiYXNpY19zdHJpbmcm
KSBlZmZlY3RzPC9jYXB0aW9uPgogICAgICA8dHI+PHRoPkVsZW1lbnQ8L3RoPjx0aD5WYWx1ZTwv
dGg+PC90cj4KICAgICAgPHRyPjx0ZD48Y29kZT5kYXRhXzwvY29kZT48L3RkPjx0ZD48Y29kZT5z
dHIuZGF0YSgpPC9jb2RlPjwvdGQ+PC90cj4KICAgICAgPHRyPjx0ZD48Y29kZT5zaXplXzwvY29k
ZT48L3RkPjx0ZD48Y29kZT5zdHIuc2l6ZSgpPC9jb2RlPjwvdGQ+PC90cj4KICAgICAgPC90YWJs
ZT4KICAgIDwvZGl2PgoKICAgIDxwcmU+PGNvZGU+YmFzaWNfc3RyaW5nX3ZpZXcoY29uc3QgY2hh
clQqIHN0cik7PC9jb2RlPjwvcHJlPgogICAgPGRpdiBjbGFzcz0iYXR0cmlidXRlcyI+CiAgICAg
IDxwPjxpPlJlcXVpcmVzPC9pPjogWzxjb2RlPnN0cjwvY29kZT4sPGNvZGU+c3RyICsgdHJhaXRz
OjpsZW5ndGgoc3RyKTwvY29kZT4pIGlzIGEgdmFsaWQgcmFuZ2UuPC9wPgogICAgICA8cD48aT5F
ZmZlY3RzPC9pPjogQ29uc3RydWN0cyBhIDxjb2RlPmJhc2ljX3N0cmluZ192aWV3PC9jb2RlPiBy
ZWZlcnJpbmcgdG8gdGhlIHNhbWUgc3RyaW5nIGFzIDxjb2RlPnN0cjwvY29kZT4sIHdpdGggdGhl
IHBvc3Rjb25kaXRpb25zCiAgICAgIGluIFRhYmxlIFt0YWI6c3RyaW5nLnZpZXcuY3RyLjJdPC9w
PgoKICAgICAgPHRhYmxlPjxjYXB0aW9uPlRhYmxlIFt0YWI6c3RyaW5nLnZpZXcuY3RyLjJdIOKA
lCBiYXNpY19zdHJpbmdfdmlldyhjb25zdCBjaGFyVCopIGVmZmVjdHM8L2NhcHRpb24+CiAgICAg
IDx0cj48dGg+RWxlbWVudDwvdGg+PHRoPlZhbHVlPC90aD48L3RyPgogICAgICA8dHI+PHRkPjxj
b2RlPmRhdGFfPC9jb2RlPjwvdGQ+PHRkPjxjb2RlPnN0cjwvY29kZT48L3RkPjwvdHI+CiAgICAg
IDx0cj48dGQ+PGNvZGU+c2l6ZV88L2NvZGU+PC90ZD48dGQ+PGNvZGU+dHJhaXRzOjpsZW5ndGgo
c3RyKTwvY29kZT48L3RkPjwvdHI+CiAgICAgIDwvdGFibGU+CgogICAgICA8cD48aT5Db21wbGV4
aXR5PC9pPjogTyg8Y29kZT50cmFpdHM6Omxlbmd0aChzdHIpPC9jb2RlPik8L3A+CiAgICA8L2Rp
dj4KCiAgICA8cHJlPjxjb2RlPmNvbnN0ZXhwciBiYXNpY19zdHJpbmdfdmlldyhjb25zdCBjaGFy
VCogc3RyLCBzaXplX3R5cGUgbGVuKTs8L2NvZGU+PC9wcmU+CiAgICA8ZGl2IGNsYXNzPSJhdHRy
aWJ1dGVzIj4KICAgICAgPHA+PGk+UmVxdWlyZXM8L2k+OiA8Y29kZT5zdHI8L2NvZGU+IGlzIG5v
dCBhIG51bGwgcG9pbnRlciBhbmQgWzxjb2RlPnN0cjwvY29kZT4sPGNvZGU+c3RyICsgbGVuPC9j
b2RlPikgaXMgYSB2YWxpZCByYW5nZS48L3A+CiAgICAgIDxwPjxpPkVmZmVjdHM8L2k+OiBDb25z
dHJ1Y3RzIGEgPGNvZGU+YmFzaWNfc3RyaW5nX3ZpZXc8L2NvZGU+LCB3aXRoIHRoZSBwb3N0Y29u
ZGl0aW9ucyBpbiBUYWJsZSBbdGFiOnN0cmluZy52aWV3LmN0ci4zXTwvcD4KICAgICAgPHRhYmxl
PjxjYXB0aW9uPlRhYmxlIFt0YWI6c3RyaW5nLnZpZXcuY3RyLjNdIOKAlCBiYXNpY19zdHJpbmdf
dmlldyhjb25zdCBjaGFyVCosIHNpemVfdHlwZSkgZWZmZWN0czwvY2FwdGlvbj4KICAgICAgPHRy
Pjx0aD5FbGVtZW50PC90aD48dGg+VmFsdWU8L3RoPjwvdHI+CiAgICAgIDx0cj48dGQ+PGNvZGU+
ZGF0YV88L2NvZGU+PC90ZD48dGQ+PGNvZGU+c3RyPC9jb2RlPjwvdGQ+PC90cj4KICAgICAgPHRy
Pjx0ZD48Y29kZT5zaXplXzwvY29kZT48L3RkPjx0ZD48Y29kZT5sZW48L2NvZGU+PC90ZD48L3Ry
PgogICAgICA8L3RhYmxlPgogICAgPC9kaXY+CgoKICAgIDxoND5BZGQgYSBzdWJjbGF1c2UgIngu
MiBiYXNpY19zdHJpbmdfdmlldyBpdGVyYXRvciBzdXBwb3J0IFtzdHJpbmcudmlldy5pdGVyYXRv
cnNdIjwvaDQ+CgogICAgPHByZT48Y29kZT50eXBlZGVmIGltcGxlbWVudGF0aW9uLWRlZmluZWQg
Y29uc3RfaXRlcmF0b3I7PC9jb2RlPjwvcHJlPgogICAgPGRpdiBjbGFzcz0iYXR0cmlidXRlcyI+
CiAgICAgIDxwPkEgY29uc3RhbnQgcmFuZG9tLWFjY2VzcyBpdGVyYXRvciB0eXBlIHN1Y2ggdGhh
dCwgZm9yIGEgPGNvZGU+Y29uc3RfaXRlcmF0b3IgaXQ8L2NvZGU+LAogICAgICBpZiA8Y29kZT4m
YW1wOyooaXQrTik8L2NvZGU+IGlzIHZhbGlkLCB0aGVuIGl0IGlzIGVxdWFsIHRvIDxjb2RlPigm
YW1wOyppdCkrTjwvY29kZT4uPC9wPgogICAgICA8cD5Gb3IgYSA8Y29kZT5iYXNpY19zdHJpbmdf
dmlldyBzdHI8L2NvZGU+LCBhbnkgb3BlcmF0aW9uIHRoYXQgaW52YWxpZGF0ZXMgYSBwb2ludGVy
IGluCiAgICAgIHRoZSByYW5nZSBbPGNvZGU+c3RyLmRhdGEoKTwvY29kZT4sIDxjb2RlPnN0ci5k
YXRhKCkrc3RyLnNpemUoKTwvY29kZT4pIGludmFsaWRhdGVzIHBvaW50ZXJzLAogICAgICBpdGVy
YXRvcnMsIGFuZCByZWZlcmVuY2VzIHJldHVybmVkIGZyb20gPGNvZGU+c3RyPC9jb2RlPidzIG1l
dGhvZHMuPC9wPgogICAgICA8cD5BbGwgcmVxdWlyZW1lbnRzIG9uIGNvbnRhaW5lciBpdGVyYXRv
cnMgKEMrKzExW2NvbnRhaW5lci5yZXF1aXJlbWVudHNdKQogICAgICBhcHBseSB0byA8Y29kZT5i
YXNpY19zdHJpbmdfdmlldzo6Y29uc3RfaXRlcmF0b3I8L2NvZGU+IGFzIHdlbGwuPC9wPgogICAg
PC9kaXY+CgoKICAgIDxwcmU+PGNvZGU+Y29uc3RleHByIGNvbnN0X2l0ZXJhdG9yIGJlZ2luKCkg
Y29uc3Qgbm9leGNlcHQ7CmNvbnN0ZXhwciBjb25zdF9pdGVyYXRvciBjYmVnaW4oKSBjb25zdCBu
b2V4Y2VwdDs8L2NvZGU+PC9wcmU+CiAgICA8cCBjbGFzcz0iYXR0cmlidXRlIj48aT5SZXR1cm5z
PC9pPjogQW4gaXRlcmF0b3Igc3VjaCB0aGF0IDxjb2RlPiYqYmVnaW4oKSA9PSBkYXRhXzwvY29k
ZT4gaWYgPGNvZGU+KmRhdGFfPC9jb2RlPiBpcyBhIHZhbGlkIGV4cHJlc3Npb24gYW5kIDxjb2Rl
PiFlbXB0eSgpPC9jb2RlPiwgb3IgZWxzZSBhbiB1bnNwZWNpZmllZCB2YWx1ZSBzdWNoIHRoYXQg
Wzxjb2RlPmJlZ2luKCk8L2NvZGU+LDxjb2RlPmVuZCgpPC9jb2RlPikgaXMgYSB2YWxpZCByYW5n
ZS48L3A+CgogICAgPHByZT48Y29kZT5jb25zdGV4cHIgY29uc3RfaXRlcmF0b3IgZW5kKCkgY29u
c3Qgbm9leGNlcHQ7CmNvbnN0ZXhwciBjb25zdF9pdGVyYXRvciBjZW5kKCkgY29uc3Qgbm9leGNl
cHQ7PC9jb2RlPjwvcHJlPgogICAgPHAgY2xhc3M9ImF0dHJpYnV0ZSI+PGk+UmV0dXJuczwvaT46
IDxjb2RlPmJlZ2luKCkgKyBzaXplKCk8L2NvZGU+PC9wPgoKICAgIDxwcmU+PGNvZGU+Y29uc3Rf
cmV2ZXJzZV9pdGVyYXRvciByYmVnaW4oKSBjb25zdCBub2V4Y2VwdDsKY29uc3RfcmV2ZXJzZV9p
dGVyYXRvciBjcmJlZ2luKCkgY29uc3Qgbm9leGNlcHQ7PC9jb2RlPjwvcHJlPgogICAgPHAgY2xh
c3M9ImF0dHJpYnV0ZSI+PGk+UmV0dXJuczwvaT46IEFuIGl0ZXJhdG9yIHdoaWNoIGlzIHNlbWFu
dGljYWxseSBlcXVpdmFsZW50IHRvIDxjb2RlPnJldmVyc2VfaXRlcmF0b3IoZW5kKCkpPC9jb2Rl
Pi48L3A+CgogICAgPHByZT48Y29kZT5jb25zdF9yZXZlcnNlX2l0ZXJhdG9yIHJlbmQoKSBjb25z
dCBub2V4Y2VwdDsKY29uc3RfcmV2ZXJzZV9pdGVyYXRvciBjcmVuZCgpIGNvbnN0IG5vZXhjZXB0
OzwvY29kZT48L3ByZT4KICAgIDxwIGNsYXNzPSJhdHRyaWJ1dGUiPjxpPlJldHVybnM8L2k+OiBB
biBpdGVyYXRvciB3aGljaCBpcyBzZW1hbnRpY2FsbHkgZXF1aXZhbGVudCB0byA8Y29kZT5yZXZl
cnNlX2l0ZXJhdG9yKGJlZ2luKCkpPC9jb2RlPi48L3A+CgogICAgPGg0PkFkZCBhIHN1YmNsYXVz
ZSAieC4zIGJhc2ljX3N0cmluZ192aWV3IGNhcGFjaXR5IFtzdHJpbmcudmlldy5jYXBhY2l0eV0i
PC9oND4KCiAgICA8cHJlPjxjb2RlPmNvbnN0ZXhwciBzaXplX3R5cGUgc2l6ZSgpIGNvbnN0IG5v
ZXhjZXB0OzwvY29kZT48L3ByZT4KICAgIDxkaXYgY2xhc3M9ImF0dHJpYnV0ZXMiPgogICAgICA8
cD48aT5SZXR1cm5zPC9pPjogPGNvZGU+c2l6ZV88L2NvZGU+PC9wPgogICAgPC9kaXY+CgogICAg
PHByZT48Y29kZT5jb25zdGV4cHIgc2l6ZV90eXBlIGxlbmd0aCgpIGNvbnN0IG5vZXhjZXB0Ozwv
Y29kZT48L3ByZT4KICAgIDxwIGNsYXNzPSJhdHRyaWJ1dGUiPjxpPlJldHVybnM8L2k+OiA8Y29k
ZT5zaXplXzwvY29kZT4uPC9wPgoKICAgIDxwcmU+PGNvZGU+Y29uc3RleHByIHNpemVfdHlwZSBt
YXhfc2l6ZSgpIGNvbnN0IG5vZXhjZXB0OzwvY29kZT48L3ByZT4KICAgIDxwIGNsYXNzPSJhdHRy
aWJ1dGUiPjxpPlJldHVybnM8L2k+OiBUaGUgbGFyZ2VzdCBwb3NzaWJsZSBudW1iZXIgb2YgY2hh
ci1saWtlIG9iamVjdHMgdGhhdCBjYW4gYmUgcmVmZXJyZWQgdG8gYnkgYSA8Y29kZT5iYXNpY19z
dHJpbmdfdmlldzwvY29kZT4uPC9wPgoKICAgIDxwcmU+PGNvZGU+Y29uc3RleHByIGJvb2wgZW1w
dHkoKSBjb25zdCBub2V4Y2VwdDs8L2NvZGU+PC9wcmU+CiAgICA8cCBjbGFzcz0iYXR0cmlidXRl
Ij48aT5SZXR1cm5zPC9pPjogPGNvZGU+c2l6ZV8gPT0gMDwvY29kZT4uPC9wPgoKCiAgICA8aDQg
aWQ9InN0cmluZy52aWV3LmFjY2VzcyI+QWRkIGEgc3ViY2xhdXNlICJ4LjQgYmFzaWNfc3RyaW5n
X3ZpZXcgZWxlbWVudCBhY2Nlc3MgW3N0cmluZy52aWV3LmFjY2Vzc10iPC9oND4KCiAgICA8cHJl
Pjxjb2RlPmNvbnN0ZXhwciBjb25zdF9yZWZlcmVuY2Ugb3BlcmF0b3JbXShzaXplX3R5cGUgcG9z
KSBjb25zdDs8L2NvZGU+PC9wcmU+CiAgICA8ZGl2IGNsYXNzPSJhdHRyaWJ1dGVzIj4KICAgICAg
PHA+PGk+UmVxdWlyZXM8L2k+OiA8Y29kZT5wb3MgJmx0OyBzaXplKCk8L2NvZGU+LjwvcD4KICAg
ICAgPHA+PGk+UmV0dXJuczwvaT46IDxjb2RlPmRhdGFfW3Bvc108L2NvZGU+PC9wPgogICAgICA8
cD48aT5UaHJvd3M8L2k+OiBOb3RoaW5nLjwvcD4KICAgICAgPHA+WyBOb3RlOiBVbmxpa2UgPGNv
ZGU+YmFzaWNfc3RyaW5nOjpvcGVyYXRvcltdPC9jb2RlPiwKICAgICAgPGNvZGU+YmFzaWNfc3Ry
aW5nX3ZpZXc6Om9wZXJhdG9yW10oc2l6ZSgpKTwvY29kZT4gaGFzIHVuZGVmaW5lZCBiZWhhdmlv
ciBpbnN0ZWFkIG9mCiAgICAgIHJldHVybmluZyA8Y29kZT5jaGFyVCgpPC9jb2RlPi4g4oCUIGVu
ZCBub3RlIF08L3A+CiAgICA8L2Rpdj4KCiAgICA8cHJlPjxjb2RlPmNvbnN0ZXhwciBjb25zdF9y
ZWZlcmVuY2UgYXQoc2l6ZV90eXBlIHBvcykgY29uc3Q7PC9jb2RlPjwvcHJlPgogICAgPGRpdiBj
bGFzcz0iYXR0cmlidXRlcyI+CiAgICAgIDxwPjxpPlRocm93czwvaT46IDxjb2RlPm91dF9vZl9y
YW5nZTwvY29kZT4gaWYgPGNvZGU+cG9zID49IHNpemUoKTwvY29kZT4uPC9wPgogICAgICA8cD48
aT5SZXR1cm5zPC9pPjogPGNvZGU+b3BlcmF0b3JbXShwb3MpPC9jb2RlPi48L3A+CiAgICA8L2Rp
dj4KCiAgICA8cHJlPjxjb2RlPmNvbnN0ZXhwciBjb25zdCBjaGFyVCYgZnJvbnQoKSBjb25zdDs8
L2NvZGU+PC9wcmU+CiAgICA8ZGl2IGNsYXNzPSJhdHRyaWJ1dGVzIj4KICAgICAgPHA+PGk+UmVx
dWlyZXM8L2k+OiA8Y29kZT4hZW1wdHkoKTwvY29kZT48L3A+CiAgICAgIDxwPjxpPkVmZmVjdHM8
L2k+OiBFcXVpdmFsZW50IHRvIDxjb2RlPnJldHVybiBvcGVyYXRvcltdKDApPC9jb2RlPi48L3A+
CiAgICA8L2Rpdj4KCiAgICA8cHJlPjxjb2RlPmNvbnN0ZXhwciBjb25zdCBjaGFyVCYgYmFjaygp
IGNvbnN0OzwvY29kZT48L3ByZT4KICAgIDxkaXYgY2xhc3M9ImF0dHJpYnV0ZXMiPgogICAgICA8
cD48aT5SZXF1aXJlczwvaT46IDxjb2RlPiFlbXB0eSgpPC9jb2RlPjwvcD4KICAgICAgPHA+PGk+
RWZmZWN0czwvaT46IEVxdWl2YWxlbnQgdG8gPGNvZGU+cmV0dXJuIG9wZXJhdG9yW10oc2l6ZSgp
IC0gMSk8L2NvZGU+LjwvcD4KICAgIDwvZGl2PgoKICAgIDxwcmUgaWQ9InN0cmluZy52aWV3LmRh
dGEiPjxjb2RlPmNvbnN0ZXhwciBjb25zdCBjaGFyVCogZGF0YSgpIGNvbnN0IG5vZXhjZXB0Ozwv
Y29kZT48L3ByZT4KICAgIDxkaXYgY2xhc3M9ImF0dHJpYnV0ZXMiPgogICAgICA8cD48aT5SZXR1
cm5zPC9pPjogPGNvZGU+ZGF0YV88L2NvZGU+PC9wPgogICAgICA8cD5bIE5vdGU6IFVubGlrZSA8
Y29kZT5zdGQ6OnN0cmluZzo6ZGF0YSgpPC9jb2RlPiBhbmQgc3RyaW5nIGxpdGVyYWxzLCA8Y29k
ZT5kYXRhKCk8L2NvZGU+IG1heQogICAgICByZXR1cm4gYSBwb2ludGVyIHRvIGEgYnVmZmVyIHRo
YXQgaXMgbm90IG51bGwtdGVybWluYXRlZC4gVGhlcmVmb3JlIGl0IGlzCiAgICAgIHR5cGljYWxs
eSBhIG1pc3Rha2UgdG8gcGFzcyA8Y29kZT5kYXRhKCk8L2NvZGU+IHRvIGEgcm91dGluZSB0aGF0
IHRha2VzIGp1c3QgYQogICAgICA8Y29kZT5jb25zdCBjaGFyVCo8L2NvZGU+IGFuZCBleHBlY3Rz
IGEgbnVsbC10ZXJtaW5hdGVkIHN0cmluZy4g4oCUIGVuZCBub3RlIF08L3A+CiAgICA8L2Rpdj4K
CiAgICA8aDQgaWQ9InN0cmluZy52aWV3Lm1vZGlmaWVycyI+QWRkIGEgc3ViY2xhdXNlICJ4LjUg
YmFzaWNfc3RyaW5nX3ZpZXcgbW9kaWZpZXJzIFtzdHJpbmcudmlldy5tb2RpZmllcnNdIjwvaDQ+
CgogICAgPHByZT48Y29kZT52b2lkIGNsZWFyKCkgbm9leGNlcHQ7PC9jb2RlPjwvcHJlPgogICAg
PHAgY2xhc3M9ImF0dHJpYnV0ZSI+PGk+RWZmZWN0czwvaT46IEVxdWl2YWxlbnQgdG8gPGNvZGU+
KnRoaXMgPSBiYXNpY19zdHJpbmdfdmlldygpPC9jb2RlPjwvcD4KCiAgICA8cHJlPjxjb2RlPnZv
aWQgcmVtb3ZlX3ByZWZpeChzaXplX3R5cGUgbik7PC9jb2RlPjwvcHJlPgogICAgPGRpdiBjbGFz
cz0iYXR0cmlidXRlcyI+CiAgICAgIDxwPjxpPlJlcXVpcmVzPC9pPjogPGNvZGU+biAmbHQ7PSBz
aXplKCk8L2NvZGU+PC9wPgogICAgICA8cD48aT5FZmZlY3RzPC9pPjogRXF1aXZhbGVudCB0byA8
Y29kZT5kYXRhXyArPSBuOyBzaXplXyAtPSBuOzwvY29kZT48L3A+CiAgICA8L2Rpdj4KCiAgICA8
cHJlPjxjb2RlPnZvaWQgcmVtb3ZlX3N1ZmZpeChzaXplX3R5cGUgbik7PC9jb2RlPjwvcHJlPgog
ICAgPGRpdiBjbGFzcz0iYXR0cmlidXRlcyI+CiAgICAgIDxwPjxpPlJlcXVpcmVzPC9pPjogPGNv
ZGU+biAmbHQ7PSBzaXplKCk8L2NvZGU+PC9wPgogICAgICA8cD48aT5FZmZlY3RzPC9pPjogRXF1
aXZhbGVudCB0byA8Y29kZT5zaXplXyAtPSBuOzwvY29kZT48L3A+CiAgICA8L2Rpdj4KCiAgICA8
cHJlPjxjb2RlPnZvaWQgc3dhcChiYXNpY19zdHJpbmdfdmlldyYgcykgbm9leGNlcHQ8L2NvZGU+
PC9wcmU+CiAgICA8ZGl2IGNsYXNzPSJhdHRyaWJ1dGVzIj4KICAgICAgPHA+PGk+RWZmZWN0czwv
aT46IEV4Y2hhbmdlcyB0aGUgdmFsdWVzIG9mIDxjb2RlPip0aGlzPC9jb2RlPiBhbmQgPGNvZGU+
czwvY29kZT4uPC9wPgogICAgPC9kaXY+CgoKICAgIDxoNCBpZD0ic3RyaW5nLnZpZXcub3BzIj5B
ZGQgYSBzdWJjbGF1c2UgInguNiBiYXNpY19zdHJpbmdfdmlldyBzdHJpbmcgb3BlcmF0aW9ucyBb
c3RyaW5nLnZpZXcub3BzXSI8L2g0PgoKICAgIDxwcmU+PGNvZGU+dGVtcGxhdGUmbHQ7Y2xhc3Mg
QWxsb2NhdG9yPgpleHBsaWNpdCAgLy8gRm9vdG5vdGU6IFRoaXMgY29udmVyc2lvbiBpcyBleHBs
aWNpdCB0byBhdm9pZCBhY2NpZGVudGFsIE8oTikgb3BlcmF0aW9ucyBvbiB0eXBlIG1pc21hdGNo
ZXMuIC0tZW5kIGZvb3Rub3RlCm9wZXJhdG9yIGJhc2ljX3N0cmluZyZsdDtjaGFyVCwgdHJhaXRz
LCBBbGxvY2F0b3I+KCkgY29uc3Q7PC9jb2RlPjwvcHJlPgogICAgPGRpdiBjbGFzcz0iYXR0cmli
dXRlcyI+CiAgICAgIDxwPjxpPkVmZmVjdHM8L2k+OiBFcXVpdmFsZW50IHRvIDxjb2RlPnJldHVy
biBiYXNpY19zdHJpbmcmbHQ7Y2hhclQsIHRyYWl0cywgQWxsb2NhdG9yPihzdHIuYmVnaW4oKSwg
c3RyLmVuZCgpKS48L2NvZGU+PC9wPgogICAgICA8cD5bIE5vdGU6IFVzZXJzIHdobyB3YW50IHRv
IGNvbnRyb2wgdGhlIGFsbG9jYXRvciBpbnN0YW5jZSBzaG91bGQgY2FsbCA8Y29kZT5iYXNpY19z
dHJpbmcoc3RyLmJlZ2luKCksIHN0ci5lbmQoKSwgYWxsb2NhdG9yKTwvY29kZT4gZGlyZWN0bHku
IC0tIGVuZCBub3RlIF08L3A+CiAgICA8L2Rpdj4KCiAgICA8cHJlPjxjb2RlPnNpemVfdHlwZSBj
b3B5KGNoYXJUKiBzLCBzaXplX3R5cGUgbiwgc2l6ZV90eXBlIHBvcyA9IDApIGNvbnN0OzwvY29k
ZT48L3ByZT4KICAgIDxkaXYgY2xhc3M9ImF0dHJpYnV0ZXMiPgogICAgICA8cD48aT5UaHJvd3M8
L2k+OiA8Y29kZT5vdXRfb2ZfcmFuZ2U8L2NvZGU+IGlmIDxjb2RlPnBvcyA+IHNpemUoKTwvY29k
ZT4uPC9wPgogICAgICA8cD48aT5SZW1hcmtzPC9pPjogTGV0IDxjb2RlPjx2YXI+cmxlbjwvdmFy
PjwvY29kZT4gYmUgdGhlIHNtYWxsZXIgb2YgPGNvZGU+bjwvY29kZT4gYW5kIDxjb2RlPnNpemUo
KSAtIHBvczwvY29kZT4uPC9wPgogICAgICA8cD48aT5SZXF1aXJlczwvaT46IFs8Y29kZT5zPC9j
b2RlPiwgPGNvZGU+cys8dmFyPnJsZW48L3Zhcj48L2NvZGU+KSBpcyBhIHZhbGlkIHJhbmdlLjwv
cD4KICAgICAgPHA+PGk+RWZmZWN0czwvaT46IEVxdWl2YWxlbnQgdG8gPGNvZGU+c3RkOjpjb3B5
X24oYmVnaW4oKSArIHBvcywgPHZhcj5ybGVuPC92YXI+LCBzKS48L2NvZGU+PC9wPgogICAgICA8
cD48aT5SZXR1cm5zPC9pPjogPGNvZGU+PHZhcj5ybGVuPC92YXI+PC9jb2RlPi48L3A+CiAgICA8
L2Rpdj4KCiAgICA8cHJlPjxjb2RlPmNvbnN0ZXhwciBiYXNpY19zdHJpbmdfdmlldyBzdWJzdHIo
c2l6ZV90eXBlIHBvcyA9IDAsIHNpemVfdHlwZSBuID0gbnBvcykgY29uc3Q7PC9jb2RlPjwvcHJl
PgogICAgPGRpdiBjbGFzcz0iYXR0cmlidXRlcyI+CiAgICAgIDxwPjxpPlRocm93czwvaT46IDxj
b2RlPm91dF9vZl9yYW5nZTwvY29kZT4gaWYgPGNvZGU+cG9zID4gc2l6ZSgpPC9jb2RlPi48L3A+
CiAgICAgIDxwPjxpPkVmZmVjdHM8L2k+OiBEZXRlcm1pbmVzIHRoZSBlZmZlY3RpdmUgbGVuZ3Ro
IDxjb2RlPjx2YXI+cmxlbjwvdmFyPjwvY29kZT4gb2YgdGhlIHN0cmluZyB0byByZWZlcmVuY2Ug
YXMgdGhlIHNtYWxsZXIgb2YgPGNvZGU+bjwvY29kZT4gYW5kIDxjb2RlPnNpemUoKSAtIHBvczwv
Y29kZT4uPC9wPgogICAgICA8cD48aT5SZXR1cm5zPC9pPjogPGNvZGU+YmFzaWNfc3RyaW5nX3Zp
ZXcoZGF0YSgpK3BvcywgPHZhcj5ybGVuPC92YXI+KTwvY29kZT4uPC9wPgogICAgPC9kaXY+Cgog
ICAgPHByZT48Y29kZT5jb25zdGV4cHIgaW50IGNvbXBhcmUoYmFzaWNfc3RyaW5nX3ZpZXcgc3Ry
KSBjb25zdCBub2V4Y2VwdDs8L2NvZGU+PC9wcmU+CiAgICA8ZGl2IGNsYXNzPSJhdHRyaWJ1dGVz
Ij4KICAgICAgPHA+PGk+RWZmZWN0czwvaT46IERldGVybWluZXMgdGhlIGVmZmVjdGl2ZSBsZW5n
dGgKICAgICAgPGNvZGU+PHZhcj5ybGVuPC92YXI+PC9jb2RlPiBvZiB0aGUgc3RyaW5ncyB0byBj
b21wYXJlIGFzIHRoZQogICAgICBzbWFsbGVzdCBvZiA8Y29kZT5zaXplKCk8L2NvZGU+IGFuZCA8
Y29kZT5zdHIuc2l6ZSgpPC9jb2RlPi4gVGhlCiAgICAgIGZ1bmN0aW9uIHRoZW4gY29tcGFyZXMg
dGhlIHR3byBzdHJpbmdzIGJ5IGNhbGxpbmcKICAgICAgPGNvZGU+dHJhaXRzOjpjb21wYXJlKGRh
dGEoKSwgc3RyLmRhdGEoKSwgPHZhcj5ybGVuPC92YXI+KTwvY29kZT4uPC9wPgogICAgICA8cD48
aT5Db21wbGV4aXR5PC9pPjogTyg8Y29kZT48dmFyPnJsZW48L3Zhcj48L2NvZGU+KTwvcD4KICAg
ICAgPHA+PGk+UmV0dXJuczwvaT46IFRoZSBub256ZXJvIHJlc3VsdCBpZiB0aGUgcmVzdWx0IG9m
IHRoZSBjb21wYXJpc29uIGlzIG5vbnplcm8uIE90aGVyd2lzZSwgcmV0dXJucyBhIHZhbHVlIGFz
CiAgICAgIGluZGljYXRlZCBpbiBUYWJsZSBbdGFiOnN0cmluZy52aWV3LmNvbXBhcmVdLjwvcD4K
ICAgICAgPHRhYmxlPjxjYXB0aW9uPlRhYmxlIFt0YWI6c3RyaW5nLnZpZXcuY29tcGFyZV0g4oCU
IGNvbXBhcmUoKSByZXN1bHRzPC9jYXB0aW9uPgogICAgICA8dHI+PHRoPkNvbmRpdGlvbjwvdGg+
PHRoPlJldHVybiBWYWx1ZTwvdGg+PC90cj4KICAgICAgPHRyPjx0ZD48Y29kZT5zaXplKCkgJmx0
OyBzdHIuc2l6ZSgpPC9jb2RlPjwvdGQ+PHRkPjxjb2RlPiZsdDsgMDwvY29kZT48L3RkPjwvdHI+
CiAgICAgIDx0cj48dGQ+PGNvZGU+c2l6ZSgpID09IHN0ci5zaXplKCk8L2NvZGU+PC90ZD48dGQ+
PGNvZGU+MDwvY29kZT48L3RkPjwvdHI+CiAgICAgIDx0cj48dGQ+PGNvZGU+c2l6ZSgpID4gIHN0
ci5zaXplKCk8L2NvZGU+PC90ZD48dGQ+PGNvZGU+PiAwPC9jb2RlPjwvdGQ+PC90cj4KICAgICAg
PC90YWJsZT4KICAgIDwvZGl2PgoKICAgIDxwcmU+PGNvZGU+Y29uc3RleHByIGludCBjb21wYXJl
KHNpemVfdHlwZSBwb3MxLCBzaXplX3R5cGUgbjEsIGJhc2ljX3N0cmluZ192aWV3IHN0cikgY29u
c3Q7PC9jb2RlPjwvcHJlPgogICAgPHAgY2xhc3M9ImF0dHJpYnV0ZSI+PGk+RWZmZWN0czwvaT46
IEVxdWl2YWxlbnQgdG8gPGNvZGU+cmV0dXJuIHN1YnN0cihwb3MxLCBuMSkuY29tcGFyZShzdHIp
PC9jb2RlPi48L3A+CgogICAgPHByZT48Y29kZT5jb25zdGV4cHIgaW50IGNvbXBhcmUoc2l6ZV90
eXBlIHBvczEsIHNpemVfdHlwZSBuMSwgYmFzaWNfc3RyaW5nX3ZpZXcgc3RyLAogICAgICAgICAg
ICAgICAgICAgICAgc2l6ZV90eXBlIHBvczIsIHNpemVfdHlwZSBuMikgY29uc3Q7PC9jb2RlPjwv
cHJlPgogICAgPHAgY2xhc3M9ImF0dHJpYnV0ZSI+PGk+RWZmZWN0czwvaT46IEVxdWl2YWxlbnQg
dG8gPGNvZGU+cmV0dXJuIHN1YnN0cihwb3MxLCBuMSkuY29tcGFyZShzdHIuc3Vic3RyKHBvczIs
IG4yKSk8L2NvZGU+LjwvcD4KICAgIDxwcmU+PGNvZGU+Y29uc3RleHByIGludCBjb21wYXJlKGNv
bnN0IGNoYXJUKiBzKSBjb25zdDs8L2NvZGU+PC9wcmU+CiAgICA8cCBjbGFzcz0iYXR0cmlidXRl
Ij48aT5FZmZlY3RzPC9pPjogRXF1aXZhbGVudCB0byA8Y29kZT5yZXR1cm4gY29tcGFyZShiYXNp
Y19zdHJpbmdfdmlldyhzKSk8L2NvZGU+LjwvcD4KICAgIDxwcmU+PGNvZGU+Y29uc3RleHByIGlu
dCBjb21wYXJlKHNpemVfdHlwZSBwb3MxLCBzaXplX3R5cGUgbjEsIGNvbnN0IGNoYXJUKiBzKSBj
b25zdDs8L2NvZGU+PC9wcmU+CiAgICA8cCBjbGFzcz0iYXR0cmlidXRlIj48aT5FZmZlY3RzPC9p
PjogRXF1aXZhbGVudCB0byA8Y29kZT5yZXR1cm4gc3Vic3RyKHBvczEsIG4xKS5jb21wYXJlKGJh
c2ljX3N0cmluZ192aWV3KHMpKTwvY29kZT4uPC9wPgogICAgPHByZT48Y29kZT5jb25zdGV4cHIg
aW50IGNvbXBhcmUoc2l6ZV90eXBlIHBvczEsIHNpemVfdHlwZSBuMSwKICAgICAgICAgICAgICAg
ICAgICAgIGNvbnN0IGNoYXJUKiBzLCBzaXplX3R5cGUgbjIpIGNvbnN0OzwvY29kZT48L3ByZT4K
ICAgIDxwIGNsYXNzPSJhdHRyaWJ1dGUiPjxpPkVmZmVjdHM8L2k+OiBFcXVpdmFsZW50IHRvIDxj
b2RlPnJldHVybiBzdWJzdHIocG9zMSwgbjEpLmNvbXBhcmUoYmFzaWNfc3RyaW5nX3ZpZXcocywg
bjIpKTwvY29kZT4uPC9wPgoKICAgIDxoNT5BZGQgYSBzdWItc3ViY2xhdXNlICJ4LjYuMSBTZWFy
Y2hpbmcgYmFzaWNfc3RyaW5nX3ZpZXcgW3N0cmluZy52aWV3LmZpbmRdIjwvaDU+CgogICAgPHA+
TWVtYmVyIGZ1bmN0aW9ucyBpbiB0aGlzIHNlY3Rpb24gaGF2ZSBjb21wbGV4aXR5IE8oPGNvZGU+
c2l6ZSgpICogYXJndW1lbnQuc2l6ZSgpPC9jb2RlPikKICAgIGF0IHdvcnN0LCBhbHRob3VnaCBp
bXBsZW1lbnRhdGlvbnMgYXJlIGVuY291cmFnZWQgdG8gZG8gYmV0dGVyLjwvcD4KCiAgICA8cD5F
YWNoIG1lbWJlciBmdW5jdGlvbiBvZiB0aGUgZm9ybTwvcD4KICAgIDxwcmU+PGNvZGU+Y29uc3Rl
eHByIDx2YXI+cmV0dXJuLXR5cGUgZngxPC92YXI+KGNvbnN0IGNoYXJUKiBzLCBzaXplX3R5cGUg
cG9zKTs8L2NvZGU+PC9wcmU+CiAgICA8cD5pcyBlcXVpdmFsZW50IHRvIDxjb2RlPnJldHVybiA8
dmFyPmZ4MTwvdmFyPihiYXNpY19zdHJpbmdfdmlldyhzKSwgcG9zKTwvY29kZT4uPC9wPgoKICAg
IDxwPkVhY2ggbWVtYmVyIGZ1bmN0aW9uIG9mIHRoZSBmb3JtPC9wPgogICAgPHByZT48Y29kZT5j
b25zdGV4cHIgPHZhcj5yZXR1cm4tdHlwZSBmeDE8L3Zhcj4oY29uc3QgY2hhclQqIHMsIHNpemVf
dHlwZSBwb3MsIHNpemVfdHlwZSBuKTsgLy8gZmluZCgpIHZhcmlhbnRzPC9jb2RlPjwvcHJlPgog
ICAgPHA+aXMgZXF1aXZhbGVudCB0byA8Y29kZT5yZXR1cm4gPHZhcj5meDE8L3Zhcj4oYmFzaWNf
c3RyaW5nX3ZpZXcocywgbiksIHBvcyk8L2NvZGU+LjwvcD4KCiAgICA8cD5FYWNoIG1lbWJlciBm
dW5jdGlvbiBvZiB0aGUgZm9ybTwvcD4KICAgIDxwcmU+PGNvZGU+Y29uc3RleHByIDx2YXI+cmV0
dXJuLXR5cGUgZngyPC92YXI+KGNoYXJUIGMsIHNpemVfdHlwZSBwb3MpOyAvLyBmaW5kKCkgdmFy
aWFudHM8L2NvZGU+PC9wcmU+CiAgICA8cD5pcyBlcXVpdmFsZW50IHRvIDxjb2RlPnJldHVybiA8
dmFyPmZ4MjwvdmFyPihiYXNpY19zdHJpbmdfdmlldygmYywgMSksIHBvcyk8L2NvZGU+LjwvcD4K
CiAgICA8cHJlPjxjb2RlPmNvbnN0ZXhwciBzaXplX3R5cGUgZmluZChiYXNpY19zdHJpbmdfdmll
dyBzdHIsIHNpemVfdHlwZSBwb3M9MCkgY29uc3Qgbm9leGNlcHQ7PC9jb2RlPjwvcHJlPgogICAg
PGRpdiBjbGFzcz0iYXR0cmlidXRlcyI+CiAgICAgIDxwPjxpPkVmZmVjdHM8L2k+OiBEZXRlcm1p
bmVzIHRoZSBsb3dlc3QgcG9zaXRpb24gPGNvZGU+PHZhcj54cG9zPC92YXI+PC9jb2RlPiwgaWYg
cG9zc2libGUsIHN1Y2ggdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgb2J0YWluOjwvcD4K
ICAgICAgPHVsPjxsaT48Y29kZT5wb3MgJmx0Oz0gPHZhcj54cG9zPC92YXI+PC9jb2RlPjwvbGk+
CiAgICAgIDxsaT48Y29kZT48dmFyPnhwb3M8L3Zhcj4gKyBzdHIuc2l6ZSgpICZsdDs9IHNpemUo
KTwvY29kZT48L2xpPgogICAgICA8bGk+PGNvZGU+dHJhaXRzOjplcShhdCg8dmFyPnhwb3M8L3Zh
cj4rSSksIHN0ci5hdChJKSk8L2NvZGU+IGZvciBhbGwgZWxlbWVudHMgPGNvZGU+STwvY29kZT4g
b2YgdGhlIHN0cmluZyByZWZlcmVuY2VkIGJ5IDxjb2RlPnN0cjwvY29kZT4uPC9saT4KICAgICAg
PC91bD4KICAgICAgPHA+PGk+UmV0dXJuczwvaT46IDxjb2RlPjx2YXI+eHBvczwvdmFyPjwvY29k
ZT4gaWYgdGhlIGZ1bmN0aW9uIGNhbiBkZXRlcm1pbmUgc3VjaCBhIHZhbHVlIGZvciA8Y29kZT48
dmFyPnhwb3M8L3Zhcj48L2NvZGU+LiBPdGhlcndpc2UsIHJldHVybnMgPGNvZGU+bnBvczwvY29k
ZT4uPC9wPgogICAgICA8cD48aT5SZW1hcmtzPC9pPjogVXNlcyA8Y29kZT50cmFpdHM6OmVxKCk8
L2NvZGU+LjwvcD4KICAgIDwvZGl2PgoKICAgIDxwcmU+PGNvZGU+Y29uc3RleHByIHNpemVfdHlw
ZSByZmluZChiYXNpY19zdHJpbmdfdmlldyBzdHIsIHNpemVfdHlwZSBwb3M9bnBvcykgY29uc3Qg
bm9leGNlcHQ7PC9jb2RlPjwvcHJlPgogICAgPGRpdiBjbGFzcz0iYXR0cmlidXRlcyI+CiAgICAg
IDxwPjxpPkVmZmVjdHM8L2k+OiBEZXRlcm1pbmVzIHRoZSBoaWdoZXN0IHBvc2l0aW9uIDxjb2Rl
Pnhwb3M8L2NvZGU+LCBpZiBwb3NzaWJsZSwgc3VjaCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0
aW9ucyBvYnRhaW46PC9wPgogICAgICA8dWw+PGxpPjxjb2RlPnhwb3MgJmx0Oz0gcG9zPC9jb2Rl
PjwvbGk+CiAgICAgIDxsaT48Y29kZT54cG9zICsgc3RyLnNpemUoKSAmbHQ7PSBzaXplKCk8L2Nv
ZGU+PC9saT4KICAgICAgPGxpPjxjb2RlPnRyYWl0czo6ZXEoYXQoeHBvcytJKSwgc3RyLmF0KEkp
KTwvY29kZT4gZm9yIGFsbCBlbGVtZW50cyA8Y29kZT5JPC9jb2RlPiBvZiB0aGUgc3RyaW5nIHJl
ZmVyZW5jZWQgYnkgPGNvZGU+c3RyPC9jb2RlPi48L2xpPjwvdWw+CiAgICAgIDxwPjxpPlJldHVy
bnM8L2k+OiA8Y29kZT54cG9zPC9jb2RlPiBpZiB0aGUgZnVuY3Rpb24gY2FuIGRldGVybWluZSBz
dWNoIGEgdmFsdWUgZm9yIDxjb2RlPnhwb3M8L2NvZGU+LiBPdGhlcndpc2UsIHJldHVybnMgPGNv
ZGU+bnBvczwvY29kZT4uPC9wPgogICAgICA8cD48aT5SZW1hcmtzPC9pPjogVXNlcyA8Y29kZT50
cmFpdHM6OmVxKCk8L2NvZGU+LjwvcD4KICAgIDwvZGl2PgoKICAgIDxwcmU+PGNvZGU+Y29uc3Rl
eHByIHNpemVfdHlwZSBmaW5kX2ZpcnN0X29mKGJhc2ljX3N0cmluZ192aWV3IHN0ciwgc2l6ZV90
eXBlIHBvcz0wKSBjb25zdCBub2V4Y2VwdDs8L2NvZGU+PC9wcmU+CiAgICA8ZGl2IGNsYXNzPSJh
dHRyaWJ1dGVzIj4KICAgICAgPHA+PGk+RWZmZWN0czwvaT46IERldGVybWluZXMgdGhlIGxvd2Vz
dCBwb3NpdGlvbiA8Y29kZT54cG9zPC9jb2RlPiwgaWYgcG9zc2libGUsIHN1Y2ggdGhhdCB0aGUg
Zm9sbG93aW5nIGNvbmRpdGlvbnMgb2J0YWluOjwvcD4KICAgICAgPHVsPjxsaT48Y29kZT5wb3Mg
Jmx0Oz0geHBvczwvY29kZT48L2xpPgogICAgICA8bGk+PGNvZGU+eHBvcyAmbHQ7IHNpemUoKTwv
Y29kZT48L2xpPgogICAgICA8bGk+PGNvZGU+dHJhaXRzOjplcShhdCh4cG9zKSwgc3RyLmF0KEkp
KTwvY29kZT4gZm9yIHNvbWUgZWxlbWVudCA8Y29kZT5JPC9jb2RlPiBvZiB0aGUgc3RyaW5nIHJl
ZmVyZW5jZWQgYnkgPGNvZGU+c3RyPC9jb2RlPi48L2xpPjwvdWw+CiAgICAgIDxwPjxpPlJldHVy
bnM8L2k+OiA8Y29kZT54cG9zPC9jb2RlPiBpZiB0aGUgZnVuY3Rpb24gY2FuIGRldGVybWluZSBz
dWNoIGEgdmFsdWUgZm9yIDxjb2RlPnhwb3M8L2NvZGU+LiBPdGhlcndpc2UsIHJldHVybnMgPGNv
ZGU+bnBvczwvY29kZT4uPC9wPgogICAgICA8cD48aT5SZW1hcmtzPC9pPjogVXNlcyA8Y29kZT50
cmFpdHM6OmVxKCk8L2NvZGU+LjwvcD4KICAgIDwvZGl2PgoKICAgIDxwcmU+PGNvZGU+Y29uc3Rl
eHByIHNpemVfdHlwZSBmaW5kX2xhc3Rfb2YoYmFzaWNfc3RyaW5nX3ZpZXcgc3RyLCBzaXplX3R5
cGUgcG9zPW5wb3MpIGNvbnN0IG5vZXhjZXB0OzwvY29kZT48L3ByZT4KICAgIDxkaXYgY2xhc3M9
ImF0dHJpYnV0ZXMiPgogICAgICA8cD48aT5FZmZlY3RzPC9pPjogRGV0ZXJtaW5lcyB0aGUgaGln
aGVzdCBwb3NpdGlvbiA8Y29kZT54cG9zPC9jb2RlPiwgaWYgcG9zc2libGUsIHN1Y2ggdGhhdCB0
aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgb2J0YWluOjwvcD4KICAgICAgPHVsPjxsaT48Y29kZT54
cG9zICZsdDs9IHBvczwvY29kZT48L2xpPgogICAgICA8bGk+PGNvZGU+eHBvcyAmbHQ7IHNpemUo
KTwvY29kZT48L2xpPgogICAgICA8bGk+PGNvZGU+dHJhaXRzOjplcShhdCh4cG9zKSwgc3RyLmF0
KEkpKTwvY29kZT4gZm9yIHNvbWUgZWxlbWVudCA8Y29kZT5JPC9jb2RlPiBvZiB0aGUgc3RyaW5n
IHJlZmVyZW5jZWQgYnkgPGNvZGU+c3RyPC9jb2RlPi48L2xpPjwvdWw+CiAgICAgIDxwPjxpPlJl
dHVybnM8L2k+OiA8Y29kZT54cG9zPC9jb2RlPiBpZiB0aGUgZnVuY3Rpb24gY2FuIGRldGVybWlu
ZSBzdWNoIGEgdmFsdWUgZm9yIDxjb2RlPnhwb3M8L2NvZGU+LiBPdGhlcndpc2UsIHJldHVybnMg
PGNvZGU+bnBvczwvY29kZT4uPC9wPgogICAgICA8cD48aT5SZW1hcmtzPC9pPjogVXNlcyA8Y29k
ZT50cmFpdHM6OmVxKCk8L2NvZGU+LjwvcD4KICAgIDwvZGl2PgoKICAgIDxwcmU+PGNvZGU+Y29u
c3RleHByIHNpemVfdHlwZSBmaW5kX2ZpcnN0X25vdF9vZihiYXNpY19zdHJpbmdfdmlldyBzdHIs
IHNpemVfdHlwZSBwb3M9MCkgY29uc3Qgbm9leGNlcHQ7PC9jb2RlPjwvcHJlPgogICAgPGRpdiBj
bGFzcz0iYXR0cmlidXRlcyI+CiAgICAgIDxwPjxpPkVmZmVjdHM8L2k+OiBEZXRlcm1pbmVzIHRo
ZSBsb3dlc3QgcG9zaXRpb24gPGNvZGU+eHBvczwvY29kZT4sIGlmIHBvc3NpYmxlLCBzdWNoIHRo
YXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIG9idGFpbjo8L3A+CiAgICAgIDx1bD48bGk+PGNv
ZGU+cG9zICZsdDs9IHhwb3M8L2NvZGU+PC9saT4KICAgICAgPGxpPjxjb2RlPnhwb3MgJmx0OyBz
aXplKCk8L2NvZGU+PC9saT4KICAgICAgPGxpPjxjb2RlPnRyYWl0czo6ZXEoYXQoeHBvcyksIHN0
ci5hdChJKSk8L2NvZGU+IGZvciBubyBlbGVtZW50IDxjb2RlPkk8L2NvZGU+IG9mIHRoZSBzdHJp
bmcgcmVmZXJlbmNlZCBieSA8Y29kZT5zdHI8L2NvZGU+LjwvbGk+PC91bD4KICAgICAgPHA+PGk+
UmV0dXJuczwvaT46IDxjb2RlPnhwb3M8L2NvZGU+IGlmIHRoZSBmdW5jdGlvbiBjYW4gZGV0ZXJt
aW5lIHN1Y2ggYSB2YWx1ZSBmb3IgPGNvZGU+eHBvczwvY29kZT4uIE90aGVyd2lzZSwgcmV0dXJu
cyA8Y29kZT5ucG9zPC9jb2RlPi48L3A+CiAgICAgIDxwPjxpPlJlbWFya3M8L2k+OiBVc2VzIDxj
b2RlPnRyYWl0czo6ZXEoKTwvY29kZT4uPC9wPgogICAgPC9kaXY+CgogICAgPHByZT48Y29kZT5j
b25zdGV4cHIgc2l6ZV90eXBlIGZpbmRfbGFzdF9ub3Rfb2YoYmFzaWNfc3RyaW5nX3ZpZXcgc3Ry
LCBzaXplX3R5cGUgcG9zPW5wb3MpIGNvbnN0IG5vZXhjZXB0OzwvY29kZT48L3ByZT4KICAgIDxk
aXYgY2xhc3M9ImF0dHJpYnV0ZXMiPgogICAgICA8cD48aT5FZmZlY3RzPC9pPjogRGV0ZXJtaW5l
cyB0aGUgaGlnaGVzdCBwb3NpdGlvbiA8Y29kZT54cG9zPC9jb2RlPiwgaWYgcG9zc2libGUsIHN1
Y2ggdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgb2J0YWluOjwvcD4KICAgICAgPHVsPjxs
aT48Y29kZT54cG9zICZsdDs9IHBvczwvY29kZT48L2xpPgogICAgICA8bGk+PGNvZGU+eHBvcyAm
bHQ7IHNpemUoKTwvY29kZT48L2xpPgogICAgICA8bGk+PGNvZGU+dHJhaXRzOjplcShhdCh4cG9z
KSwgc3RyLmF0KEkpKTwvY29kZT4gZm9yIG5vIGVsZW1lbnQgPGNvZGU+STwvY29kZT4gb2YgdGhl
IHN0cmluZyByZWZlcmVuY2VkIGJ5IDxjb2RlPnN0cjwvY29kZT4uPC9saT48L3VsPgogICAgICA8
cD48aT5SZXR1cm5zPC9pPjogPGNvZGU+eHBvczwvY29kZT4gaWYgdGhlIGZ1bmN0aW9uIGNhbiBk
ZXRlcm1pbmUgc3VjaCBhIHZhbHVlIGZvciA8Y29kZT54cG9zPC9jb2RlPi4gT3RoZXJ3aXNlLCBy
ZXR1cm5zIDxjb2RlPm5wb3M8L2NvZGU+LjwvcD4KICAgICAgPHA+PGk+UmVtYXJrczwvaT46IFVz
ZXMgPGNvZGU+dHJhaXRzOjplcSgpPC9jb2RlPi48L3A+CiAgICA8L2Rpdj4KCgogICAgPGg0PkFk
ZCBhIHN1YmNsYXVzZSAieC43IGJhc2ljX3N0cmluZ192aWV3IG5vbi1tZW1iZXIgY29tcGFyaXNv
biBmdW5jdGlvbnMgW3N0cmluZy52aWV3LmNvbXBhcmlzb25dIjwvaDQ+CgogICAgPHA+SW1wbGVt
ZW50YXRpb25zIHNoYWxsIHByb3ZpZGUgc3VmZmljaWVudCBhZGRpdGlvbmFsIG92ZXJsb2FkcyBz
byB0aGF0IGFuCiAgICBvYmplY3QgPGNvZGU+PHZhcj50PC92YXI+PC9jb2RlPiB3aXRoIGFuIGlt
cGxpY2l0IGNvbnZlcnNpb24gdG8KICAgIDxjb2RlPmJhc2ljX3N0cmluZ192aWV3Jmx0O2NoYXJU
LCB0cmFpdHM+PC9jb2RlPiBjYW4gYmUgY29tcGFyZWQgYWNjb3JkaW5nIHRvCiAgICBUYWJsZSBb
dGFiOnN0cmluZy52aWV3LmNvbXBhcmlzb24ub3ZlcmxvYWRzXSwgd2hlcmUKICAgIDxjb2RlPjx2
YXI+c3A8L3Zhcj48L2NvZGU+IGlzIGFuIGluc3RhbmNlIG9mCiAgICA8Y29kZT5iYXNpY19zdHJp
bmdfdmlldyZsdDtjaGFyVCwgdHJhaXRzPjwvY29kZT4uPC9wPgoKICAgIDx0YWJsZT48Y2FwdGlv
bj5UYWJsZSBbdGFiOnN0cmluZy52aWV3LmNvbXBhcmlzb24ub3ZlcmxvYWRzXSDigJQ8d2JyLz4g
QWRkaXRpb25hbCBiYXNpY19zdHJpbmdfdmlldyBjb21wYXJpc29uIG92ZXJsb2FkczwvY2FwdGlv
bj4KICAgIDx0cj48dGg+RXhwcmVzc2lvbjwvdGg+PHRoPkVxdWl2YWxlbnQgdG88L3RoPjwvdHI+
CiAgICA8dHI+PHRkPjxjb2RlPnQgPT0gc3A8L2NvZGU+PC90ZD48dGQ+PGNvZGU+YmFzaWNfc3Ry
aW5nX3ZpZXcmbHQ7Y2hhclQsIHRyYWl0cz4odCkgPT0gc3A8L2NvZGU+PC90ZD48L3RyPgogICAg
PHRyPjx0ZD48Y29kZT5zcCA9PSB0PC9jb2RlPjwvdGQ+PHRkPjxjb2RlPnNwID09IGJhc2ljX3N0
cmluZ192aWV3Jmx0O2NoYXJULCB0cmFpdHM+KHQpPC9jb2RlPjwvdGQ+PC90cj4KICAgIDx0cj48
dGQ+PGNvZGU+dCAhPSBzcDwvY29kZT48L3RkPjx0ZD48Y29kZT5iYXNpY19zdHJpbmdfdmlldyZs
dDtjaGFyVCwgdHJhaXRzPih0KSAhPSBzcDwvY29kZT48L3RkPjwvdHI+CiAgICA8dHI+PHRkPjxj
b2RlPnNwICE9IHQ8L2NvZGU+PC90ZD48dGQ+PGNvZGU+c3AgIT0gYmFzaWNfc3RyaW5nX3ZpZXcm
bHQ7Y2hhclQsIHRyYWl0cz4odCk8L2NvZGU+PC90ZD48L3RyPgogICAgPHRyPjx0ZD48Y29kZT50
ICZsdDsgc3A8L2NvZGU+PC90ZD48dGQ+PGNvZGU+YmFzaWNfc3RyaW5nX3ZpZXcmbHQ7Y2hhclQs
IHRyYWl0cz4odCkgJmx0OyBzcDwvY29kZT48L3RkPjwvdHI+CiAgICA8dHI+PHRkPjxjb2RlPnNw
ICZsdDsgdDwvY29kZT48L3RkPjx0ZD48Y29kZT5zcCAmbHQ7IGJhc2ljX3N0cmluZ192aWV3Jmx0
O2NoYXJULCB0cmFpdHM+KHQpPC9jb2RlPjwvdGQ+PC90cj4KICAgIDx0cj48dGQ+PGNvZGU+dCA+
IHNwPC9jb2RlPjwvdGQ+PHRkPjxjb2RlPmJhc2ljX3N0cmluZ192aWV3Jmx0O2NoYXJULCB0cmFp
dHM+KHQpID4gc3A8L2NvZGU+PC90ZD48L3RyPgogICAgPHRyPjx0ZD48Y29kZT5zcCA+IHQ8L2Nv
ZGU+PC90ZD48dGQ+PGNvZGU+c3AgPiBiYXNpY19zdHJpbmdfdmlldyZsdDtjaGFyVCwgdHJhaXRz
Pih0KTwvY29kZT48L3RkPjwvdHI+CiAgICA8dHI+PHRkPjxjb2RlPnQgJmx0Oz0gc3A8L2NvZGU+
PC90ZD48dGQ+PGNvZGU+YmFzaWNfc3RyaW5nX3ZpZXcmbHQ7Y2hhclQsIHRyYWl0cz4odCkgJmx0
Oz0gc3A8L2NvZGU+PC90ZD48L3RyPgogICAgPHRyPjx0ZD48Y29kZT5zcCAmbHQ7PSB0PC9jb2Rl
PjwvdGQ+PHRkPjxjb2RlPnNwICZsdDs9IGJhc2ljX3N0cmluZ192aWV3Jmx0O2NoYXJULCB0cmFp
dHM+KHQpPC9jb2RlPjwvdGQ+PC90cj4KICAgIDx0cj48dGQ+PGNvZGU+dCA+PSBzcDwvY29kZT48
L3RkPjx0ZD48Y29kZT5iYXNpY19zdHJpbmdfdmlldyZsdDtjaGFyVCwgdHJhaXRzPih0KSA+PSBz
cDwvY29kZT48L3RkPjwvdHI+CiAgICA8dHI+PHRkPjxjb2RlPnNwID49IHQ8L2NvZGU+PC90ZD48
dGQ+PGNvZGU+c3AgPj0gYmFzaWNfc3RyaW5nX3ZpZXcmbHQ7Y2hhclQsIHRyYWl0cz4odCk8L2Nv
ZGU+PC90ZD48L3RyPgogICAgPC90YWJsZT4KCiAgICA8cD5bIEV4YW1wbGU6IEEgc2FtcGxlIGNv
bmZvcm1pbmcgaW1wbGVtZW50YXRpb24gZm9yIG9wZXJhdG9yPT0gd291bGQgYmU6PC9wPgo8cHJl
Pjxjb2RlPiAgdGVtcGxhdGUmbHQ7Y2xhc3MgVD4gc3RydWN0IF9faWRlbnRpdHkgeyB0eXBlZGVm
IFQgdHlwZTsgfTsKICB0ZW1wbGF0ZSZsdDtjbGFzcyBjaGFyVCwgY2xhc3MgdHJhaXRzPgogIGNv
bnN0ZXhwciBib29sIG9wZXJhdG9yPT0oCiAgICAgIGJhc2ljX3N0cmluZ192aWV3Jmx0O2NoYXJU
LCB0cmFpdHM+IGxocywKICAgICAgYmFzaWNfc3RyaW5nX3ZpZXcmbHQ7Y2hhclQsIHRyYWl0cz4g
cmhzKSBub2V4Y2VwdCB7CiAgICByZXR1cm4gbGhzLmNvbXBhcmUocmhzKSA9PSAwOwogIH0KICB0
ZW1wbGF0ZSZsdDtjbGFzcyBjaGFyVCwgY2xhc3MgdHJhaXRzPgogIGNvbnN0ZXhwciBib29sIG9w
ZXJhdG9yPT0oCiAgICAgIGJhc2ljX3N0cmluZ192aWV3Jmx0O2NoYXJULCB0cmFpdHM+IGxocywK
ICAgICAgdHlwZW5hbWUgX19pZGVudGl0eSZsdDtiYXNpY19zdHJpbmdfdmlldyZsdDtjaGFyVCwg
dHJhaXRzPj46OnR5cGUgcmhzKSBub2V4Y2VwdCB7CiAgICByZXR1cm4gbGhzLmNvbXBhcmUocmhz
KSA9PSAwOwogIH0KICB0ZW1wbGF0ZSZsdDtjbGFzcyBjaGFyVCwgY2xhc3MgdHJhaXRzPgogIGNv
bnN0ZXhwciBib29sIG9wZXJhdG9yPT0oCiAgICAgIHR5cGVuYW1lIF9faWRlbnRpdHkmbHQ7YmFz
aWNfc3RyaW5nX3ZpZXcmbHQ7Y2hhclQsIHRyYWl0cz4+Ojp0eXBlIGxocywKICAgICAgYmFzaWNf
c3RyaW5nX3ZpZXcmbHQ7Y2hhclQsIHRyYWl0cz4gcmhzKSBub2V4Y2VwdCB7CiAgICByZXR1cm4g
bGhzLmNvbXBhcmUocmhzKSA9PSAwOwp9PC9jb2RlPjwvcHJlPgogICAgPHA+4oCUIGVuZCBleGFt
cGxlIF08L3A+Cgo8cHJlPjxjb2RlPnRlbXBsYXRlJmx0O2NsYXNzIGNoYXJULCBjbGFzcyB0cmFp
dHM+CiAgY29uc3RleHByIGJvb2wgb3BlcmF0b3I9PShiYXNpY19zdHJpbmdfdmlldyZsdDtjaGFy
VCx0cmFpdHM+IGxocywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhc2ljX3N0cmluZ192
aWV3Jmx0O2NoYXJULHRyYWl0cz4gcmhzKSBub2V4Y2VwdDs8L2NvZGU+PC9wcmU+CiAgICA8cCBj
bGFzcz0iYXR0cmlidXRlIj48aT5SZXR1cm5zPC9pPjogPGNvZGU+bGhzLmNvbXBhcmUocmhzKSA9
PSAwPC9jb2RlPi48L3A+Cgo8cHJlPjxjb2RlPnRlbXBsYXRlJmx0O2NsYXNzIGNoYXJULCBjbGFz
cyB0cmFpdHM+CiAgY29uc3RleHByIGJvb2wgb3BlcmF0b3IhPShiYXNpY19zdHJpbmdfdmlldyZs
dDtjaGFyVCx0cmFpdHM+IGxocywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhc2ljX3N0
cmluZ192aWV3Jmx0O2NoYXJULHRyYWl0cz4gcmhzKSBub2V4Y2VwdDs8L2NvZGU+PC9wcmU+CiAg
ICA8cCBjbGFzcz0iYXR0cmlidXRlIj48aT5SZXR1cm5zPC9pPjogPGNvZGU+IShsaHMgPT0gcmhz
KTwvY29kZT4uPC9wPgoKPHByZT48Y29kZT50ZW1wbGF0ZSZsdDtjbGFzcyBjaGFyVCwgY2xhc3Mg
dHJhaXRzPgogIGNvbnN0ZXhwciBib29sIG9wZXJhdG9yJmx0OyAoYmFzaWNfc3RyaW5nX3ZpZXcm
bHQ7Y2hhclQsdHJhaXRzPiBsaHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXNpY19z
dHJpbmdfdmlldyZsdDtjaGFyVCx0cmFpdHM+IHJocykgbm9leGNlcHQ7PC9jb2RlPjwvcHJlPgog
ICAgPHAgY2xhc3M9ImF0dHJpYnV0ZSI+PGk+UmV0dXJuczwvaT46IDxjb2RlPmxocy5jb21wYXJl
KHJocykgJmx0OyAwPC9jb2RlPi48L3A+Cgo8cHJlPjxjb2RlPnRlbXBsYXRlJmx0O2NsYXNzIGNo
YXJULCBjbGFzcyB0cmFpdHM+CiAgY29uc3RleHByIGJvb2wgb3BlcmF0b3I+IChiYXNpY19zdHJp
bmdfdmlldyZsdDtjaGFyVCx0cmFpdHM+IGxocywKICAgICAgICAgICAgICAgICAgICAgICAgICAg
IGJhc2ljX3N0cmluZ192aWV3Jmx0O2NoYXJULHRyYWl0cz4gcmhzKSBub2V4Y2VwdDs8L2NvZGU+
PC9wcmU+CiAgICA8cCBjbGFzcz0iYXR0cmlidXRlIj48aT5SZXR1cm5zPC9pPjogPGNvZGU+bGhz
LmNvbXBhcmUocmhzKSA+IDA8L2NvZGU+LjwvcD4KCjxwcmU+PGNvZGU+dGVtcGxhdGUmbHQ7Y2xh
c3MgY2hhclQsIGNsYXNzIHRyYWl0cz4KICBjb25zdGV4cHIgYm9vbCBvcGVyYXRvciZsdDs9KGJh
c2ljX3N0cmluZ192aWV3Jmx0O2NoYXJULHRyYWl0cz4gbGhzLAogICAgICAgICAgICAgICAgICAg
ICAgICAgICAgYmFzaWNfc3RyaW5nX3ZpZXcmbHQ7Y2hhclQsdHJhaXRzPiByaHMpIG5vZXhjZXB0
OzwvY29kZT48L3ByZT4KICAgIDxwIGNsYXNzPSJhdHRyaWJ1dGUiPjxpPlJldHVybnM8L2k+OiA8
Y29kZT5saHMuY29tcGFyZShyaHMpICZsdDs9IDA8L2NvZGU+LjwvcD4KCjxwcmU+PGNvZGU+dGVt
cGxhdGUmbHQ7Y2xhc3MgY2hhclQsIGNsYXNzIHRyYWl0cz4KICBjb25zdGV4cHIgYm9vbCBvcGVy
YXRvcj49KGJhc2ljX3N0cmluZ192aWV3Jmx0O2NoYXJULHRyYWl0cz4gbGhzLAogICAgICAgICAg
ICAgICAgICAgICAgICAgICAgYmFzaWNfc3RyaW5nX3ZpZXcmbHQ7Y2hhclQsdHJhaXRzPiByaHMp
IG5vZXhjZXB0OzwvY29kZT48L3ByZT4KICAgIDxwIGNsYXNzPSJhdHRyaWJ1dGUiPjxpPlJldHVy
bnM8L2k+OiA8Y29kZT5saHMuY29tcGFyZShyaHMpID49IDA8L2NvZGU+LjwvcD4KCiAgICA8aDQg
aWQ9InN0cmluZy52aWV3Lm5vbm1lbSI+QWRkIGEgc3ViY2xhdXNlICJ4LjggT3RoZXIgYmFzaWNf
c3RyaW5nX3ZpZXcgbm9uLW1lbWJlciBmdW5jdGlvbnMgW3N0cmluZy52aWV3Lm5vbm1lbV0iPC9o
ND4KCiAgICA8cHJlPjxjb2RlPnRlbXBsYXRlJmx0O2NsYXNzIGNoYXJULCBjbGFzcyB0cmFpdHMg
PSBjaGFyX3RyYWl0cyZsdDtjaGFyVD4sCiAgICAgICAgIGNsYXNzIEFsbG9jYXRvciA9IGFsbG9j
YXRvciZsdDtjaGFyVD4gPgogIGJhc2ljX3N0cmluZyZsdDtjaGFyVCwgdHJhaXRzLCBBbGxvY2F0
b3I+IHRvX3N0cmluZygKICAgIGJhc2ljX3N0cmluZ192aWV3Jmx0O2NoYXJULCB0cmFpdHM+IHN0
ciwKICAgIGNvbnN0IEFsbG9jYXRvciYgYSA9IEFsbG9jYXRvcigpKTs8L2NvZGU+PC9wcmU+CiAg
ICA8ZGl2IGNsYXNzPSJhdHRyaWJ1dGVzIj4KICAgICAgPHA+PGk+Q29tcGxleGl0eTwvaT46IE8o
PGNvZGU+c3RyLnNpemUoKTwvY29kZT4pPC9wPgogICAgICA8cD48aT5SZXR1cm5zPC9pPjogPGNv
ZGU+YmFzaWNfc3RyaW5nJmx0O2NoYXJULCB0cmFpdHMsIEFsbG9jYXRvcj4oc3RyLmJlZ2luKCks
IHN0ci5lbmQoKSwgYSk8L2NvZGU+LjwvcD4KICAgIDwvZGl2PgoKICAgIDxoND5BZGQgYSBzdWJj
bGF1c2UgInguOSBJbnNlcnRlcnMgYW5kIGV4dHJhY3RvcnMgW3N0cmluZy52aWV3LmlvXTwvaDQ+
CgogICAgPHByZT48Y29kZT50ZW1wbGF0ZSZsdDtjbGFzcyBjaGFyVCwgY2xhc3MgdHJhaXRzPgog
IGJhc2ljX29zdHJlYW0mbHQ7Y2hhclQsIHRyYWl0cz4mCiAgICBvcGVyYXRvciZsdDsmbHQ7KGJh
c2ljX29zdHJlYW0mbHQ7Y2hhclQsIHRyYWl0cz4mIG9zLAogICAgICAgICAgICAgICBiYXNpY19z
dHJpbmdfdmlldyZsdDtjaGFyVCx0cmFpdHM+IHN0cik7PC9jb2RlPjwvcHJlPgogICAgPGRpdiBj
bGFzcz0iYXR0cmlidXRlcyI+CiAgICAgIDxwPjxpPkVmZmVjdHM8L2k+OiBCZWhhdmVzIGFzIGEg
Zm9ybWF0dGVkIG91dHB1dCBmdW5jdGlvbgogICAgICAoQysrMTFbb3N0cmVhbS5mb3JtYXR0ZWQu
cmVxbXRzXSkgb2YgPGNvZGU+b3M8L2NvZGU+LiBGb3JtcyBhIGNoYXJhY3RlcgogICAgICBzZXF1
ZW5jZSA8Y29kZT5zZXE8L2NvZGU+LCBpbml0aWFsbHkgY29uc2lzdGluZyBvZiB0aGUgZWxlbWVu
dHMgZGVmaW5lZCBieQogICAgICB0aGUgcmFuZ2UgPGNvZGU+W3N0ci5iZWdpbigpLCBzdHIuZW5k
KCkpPC9jb2RlPi4gRGV0ZXJtaW5lcyBwYWRkaW5nIGZvcgogICAgICA8Y29kZT5zZXE8L2NvZGU+
IGFzIGRlc2NyaWJlZCBpbiBDKysxMVtvc3RyZWFtLmZvcm1hdHRlZC5yZXFtdHNdLiBUaGVuIGlu
c2VydHMKICAgICAgPGNvZGU+c2VxPC9jb2RlPiBhcyBpZiBieSBjYWxsaW5nIDxjb2RlPm9zLnJk
YnVmKCktPnNwdXRuKHNlcSwgbik8L2NvZGU+LAogICAgICB3aGVyZSA8Y29kZT5uPC9jb2RlPiBp
cyB0aGUgbGFyZ2VyIG9mIDxjb2RlPm9zLndpZHRoKCk8L2NvZGU+IGFuZAogICAgICA8Y29kZT5z
dHIuc2l6ZSgpPC9jb2RlPjsgdGhlbiBjYWxscyA8Y29kZT5vcy53aWR0aCgwKTwvY29kZT4uPC9w
PgogICAgICA8cD48aT5SZXR1cm5zPC9pPjogb3M8L3A+CiAgICA8L2Rpdj4KCgogICAgPGg0IGlk
PSJiYXNpYy5zdHJpbmcuaGFzaCI+QWRkIGEgc3ViY2xhdXNlICJ4LjEwIEhhc2ggc3VwcG9ydCBb
c3RyaW5nLnZpZXcuaGFzaF0iPC9oND4KCiAgICA8cHJlPjxjb2RlPnRlbXBsYXRlICZsdDs+IHN0
cnVjdCBoYXNoJmx0O2V4cGVyaW1lbnRhbDo6c3RyaW5nX3ZpZXc+Owp0ZW1wbGF0ZSAmbHQ7PiBz
dHJ1Y3QgaGFzaCZsdDtleHBlcmltZW50YWw6OnUxNnN0cmluZ192aWV3PjsKdGVtcGxhdGUgJmx0
Oz4gc3RydWN0IGhhc2gmbHQ7ZXhwZXJpbWVudGFsOjp1MzJzdHJpbmdfdmlldz47CnRlbXBsYXRl
ICZsdDs+IHN0cnVjdCBoYXNoJmx0O2V4cGVyaW1lbnRhbDo6d3N0cmluZ192aWV3Pjs8L2NvZGU+
PC9wcmU+CiAgICA8cCBjbGFzcz0iYXR0cmlidXRlIj48aT5SZXF1aXJlczwvaT46IHRoZSB0ZW1w
bGF0ZSBzcGVjaWFsaXphdGlvbnMgc2hhbGwKICAgIG1lZXQgdGhlIHJlcXVpcmVtZW50cyBvZiBj
bGFzcyB0ZW1wbGF0ZSBoYXNoIChDKysxMVt1bm9yZC5oYXNoXSkuPC9wPgoKICA8L3NlY3Rpb24+
CgogIDxzZWN0aW9uIGNsYXNzPSJ3b3JkaW5nIj4KICAgIDxoMiBpZD0iYWx0ZXJuYXRlLW51bGxw
dHItd29yZGluZyI+QWx0ZXJuYXRlIHdvcmRpbmcgaWYgPGNvZGU+ZGF0YSgpPC9jb2RlPiBtYXkg
YmUgPGNvZGU+bnVsbHB0cjwvY29kZT48L2gyPgogICAgPHA+VGhpcyBzZWN0aW9uIGxpc3RzIGNo
YW5nZXMgdG8gdGhlIDxhIGhyZWY9IiN3b3JkaW5nIj5wcm9wb3NlZCB3b3JkaW5nPC9hPgogICAg
aWYgdGhlIExXRyBwcmVmZXJzIHRvIGFsbG93ICJudWxsIiA8Y29kZT5zdHJpbmdfdmlldzwvY29k
ZT5zLjwvcD4KCiAgICA8aDM+SW4gc3ViY2xhdXNlICJ4LjEgYmFzaWNfc3RyaW5nX3ZpZXcgY29u
c3RydWN0b3JzIGFuZCBhc3NpZ25tZW50IG9wZXJhdG9ycyAgW3N0cmluZy52aWV3LmNvbnNdIjwv
aDM+CgogICAgPHByZT48Y29kZT5jb25zdGV4cHIgYmFzaWNfc3RyaW5nX3ZpZXcoKSBub2V4Y2Vw
dDs8L2NvZGU+PC9wcmU+CiAgICA8ZGl2IGNsYXNzPSJhdHRyaWJ1dGVzIj4KICAgICAgPHA+PGk+
RWZmZWN0czwvaT46IENvbnN0cnVjdHMgYW4gZW1wdHkgPGNvZGU+YmFzaWNfc3RyaW5nX3ZpZXc8
L2NvZGU+LjwvcD4KICAgICAgPHA+PGk+UG9zdGNvbmRpdGlvbjwvaT46IDxjb2RlPnNpemVfID09
IDA8L2NvZGU+LCBhbmQgPGlucz48Y29kZT5kYXRhXyA9PSBudWxscHRyPC9jb2RlPi48L2lucz48
ZGVsPjxjb2RlPmRhdGFfPC9jb2RlPiBoYXMgYW4gdW5zcGVjaWZpZWQsIG5vbi1udWxsIHZhbHVl
IHN1Y2ggdGhhdCBbPGNvZGU+ZGF0YV88L2NvZGU+LDxjb2RlPmRhdGFfPC9jb2RlPikgaXMgYSB2
YWxpZCByYW5nZS48L2RlbD48L3A+CiAgICAgIDxkaXYgY2xhc3M9ImVkbm90ZSI+PHA+QWx0ZXJu
YXRlbHksIHdlIGNvdWxkIGxlYXZlIDxjb2RlPmRhdGFfPC9jb2RlPgogICAgICB1bnNwZWNpZmll
ZC1idXQtdmFsaWQsIGJ1dCBJIHdvcnJ5IGFib3V0IHBvcnRhYmlsaXR5IGluIHRoYXQKICAgICAg
Y2FzZS48L3A+PC9kaXY+CiAgICA8L2Rpdj4KCiAgICA8cHJlPjxjb2RlPmNvbnN0ZXhwciBiYXNp
Y19zdHJpbmdfdmlldyhjb25zdCBjaGFyVCogc3RyLCBzaXplX3R5cGUgbGVuKTs8L2NvZGU+PC9w
cmU+CiAgICA8ZGl2IGNsYXNzPSJhdHRyaWJ1dGVzIj4KICAgICAgPHA+PGk+UmVxdWlyZXM8L2k+
OiA8ZGVsPjxjb2RlPnN0cjwvY29kZT4gaXMgbm90IGEgbnVsbCBwb2ludGVyIGFuZCA8L2RlbD5b
PGNvZGU+c3RyPC9jb2RlPiw8Y29kZT5zdHIgKyBsZW48L2NvZGU+KSBpcyBhIHZhbGlkIHJhbmdl
LjwvcD4KICAgICAgPHA+PGk+RWZmZWN0czwvaT46IENvbnN0cnVjdHMgYSA8Y29kZT5iYXNpY19z
dHJpbmdfdmlldzwvY29kZT4sIHdpdGggdGhlIHBvc3Rjb25kaXRpb25zIGluIFRhYmxlIFt0YWI6
c3RyaW5nLnZpZXcuY3RyLjNdPC9wPgogICAgICA8dGFibGU+PGNhcHRpb24+VGFibGUgW3RhYjpz
dHJpbmcudmlldy5jdHIuM10g4oCUIGJhc2ljX3N0cmluZ192aWV3KGNvbnN0IGNoYXJUKiwgc2l6
ZV90eXBlKSBlZmZlY3RzPC9jYXB0aW9uPgogICAgICA8dHI+PHRoPkVsZW1lbnQ8L3RoPjx0aD5W
YWx1ZTwvdGg+PC90cj4KICAgICAgPHRyPjx0ZD48Y29kZT5kYXRhXzwvY29kZT48L3RkPjx0ZD48
Y29kZT5zdHI8L2NvZGU+PC90ZD48L3RyPgogICAgICA8dHI+PHRkPjxjb2RlPnNpemVfPC9jb2Rl
PjwvdGQ+PHRkPjxjb2RlPmxlbjwvY29kZT48L3RkPjwvdHI+CiAgICAgIDwvdGFibGU+CiAgICA8
L2Rpdj4KCiAgICA8aDM+SW4gc3ViY2xhdXNlICJ4LjQgYmFzaWNfc3RyaW5nX3ZpZXcgZWxlbWVu
dCBhY2Nlc3MgW3N0cmluZy52aWV3LmFjY2Vzc10iPC9oMz4KCiAgICA8cHJlPjxjb2RlPmNvbnN0
ZXhwciBjb25zdCBjaGFyVCogZGF0YSgpIGNvbnN0IG5vZXhjZXB0OzwvY29kZT48L3ByZT4KICAg
IDxkaXYgY2xhc3M9ImF0dHJpYnV0ZXMiPgogICAgICA8cD48aT5SZXR1cm5zPC9pPjogPGNvZGU+
ZGF0YV88L2NvZGU+PC9wPgogICAgICA8cD5bIE5vdGU6IFVubGlrZSA8Y29kZT5zdGQ6OnN0cmlu
Zzo6ZGF0YSgpPC9jb2RlPiBhbmQgc3RyaW5nIGxpdGVyYWxzLCA8Y29kZT5kYXRhKCk8L2NvZGU+
IG1heQogICAgICByZXR1cm4gYSBwb2ludGVyIHRvIGEgYnVmZmVyIHRoYXQgaXMgbm90IG51bGwt
dGVybWluYXRlZC4gVGhlcmVmb3JlIGl0IGlzCiAgICAgIHR5cGljYWxseSBhIG1pc3Rha2UgdG8g
cGFzcyA8Y29kZT5kYXRhKCk8L2NvZGU+IHRvIGEgcm91dGluZSB0aGF0IHRha2VzIGp1c3QgYQog
ICAgICA8Y29kZT5jb25zdCBjaGFyVCo8L2NvZGU+IGFuZCBleHBlY3RzIGEgbnVsbC10ZXJtaW5h
dGVkIHN0cmluZy4g4oCUIGVuZCBub3RlIF08L3A+CiAgICAgIDxkaXYgY2xhc3M9ImVkbm90ZSI+
PHA+V2UgY291bGQgc3BlY2lmeSB0aGF0IGlmIDxjb2RlPnNpemVfPT0wPC9jb2RlPiB0aGVuCiAg
ICAgIDxjb2RlPmRhdGEoKTwvY29kZT4gc2ltcGx5IHJldHVybnMgYSB2YWxpZCBwb2ludGVyIHZh
bHVlLCBhbmQgbm90CiAgICAgIG5lY2Vzc2FyaWx5IDxjb2RlPmRhdGFfPC9jb2RlPi4gIFRoaXMg
d291bGQgbGV0IGRlYnVnZ2luZyBpbXBsZW1lbnRhdGlvbnMKICAgICAgcHJldmVudCBkZXZlbG9w
ZXJzIGZyb20gZGVwZW5kaW5nIG9uIGEgcGFzc2VkLXRocm91Z2ggbnVsbCB2YWx1ZSwgYnV0CiAg
ICAgIHdvdWxkIHByZXZlbnQgPGEKICAgICAgaHJlZj0iaHR0cDovL3d3dy5vcGVuLXN0ZC5vcmcv
anRjMS9zYzIyL3dnMjEvZG9jcy9wYXBlcnMvMjAxMy9uMzU5My5odG1sI2RlbGltaXRlcnMiPnRo
ZQogICAgICA8Y29kZT5zdGQ6OnNwbGl0KCk8L2NvZGU+IHByb3Bvc2FsJ3MgRGVsaW1pdGVyczwv
YT4gZnJvbSB1c2luZwogICAgICA8Y29kZT5zdHJpbmdfdmlldzwvY29kZT4gdG8gcmVwcmVzZW50
IGEgMC1sZW5ndGggcG9zaXRpb24gd2l0aGluIGEgc3RyaW5nCiAgICAgIGF0IHdoaWNoIHRvIHNw
bGl0LjwvcD48L2Rpdj4KICAgIDwvZGl2PgogIDwvc2VjdGlvbj4KCiAgPHNlY3Rpb24+CiAgICA8
aDIgaWQ9ImFja25vd2xlZGdlbWVudHMiPkFja25vd2xlZGdlbWVudHM8L2gyPgoKICAgIDxwPkkn
ZCBsaWtlIHRvIHRoYW5rIE1hcnNoYWxsIENsb3csIE9sYWYgdmFuIGRlciBTcGVrLCB0aGUgQm9v
c3QgYW5kCiAgICBzdGQtcHJvcG9zYWxzIG1haWxpbmcgbGlzdHMsIENoYW5kbGVyIENhcnJ1dGgs
IEJlbWFuIERhd2VzLCBBbGlzZGFpcgogICAgTWVyZWRpdGgsIGFuZCBlc3BlY2lhbGx5IERhbmll
bCBLcsO8Z2xlciBmb3IgaGVscCwgYWR2aWNlLCBhbmQgd29yZGluZyBpbgogICAgdGhpcyBwYXBl
ci48L3A+CiAgPC9zZWN0aW9uPgoKICA8c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCI+PCEt
LQovKioKICogVGhpcyBjb2RlIGlzIGNvbXBpbGVkIGZyb20gaDVvLCB3aXRoIHRoZSBwYXRjaGVz
IGluIGlzc3VlcyAxOCwgMTksIGFuZCAyCiAqIChodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL2g1
by9pc3N1ZXMvbGlzdCkuCiAqCiAqIFRoaXMgY29kZSBjb250YWlucyBhbiBpbXBsZW1lbnRhdGlv
biBvZiBIVE1MNSBvdXRsaW5pbmcgYWxnb3JpdGhtLCBhcyBkZXNjcmliZWQgYnkgV0hBVFdHIGF0
IFsxXQogKgogKiBUaGUgY29weXJpZ2h0IG5vdGljZSBhdCBbMl0gc2F5czoKICogICAgICAgICAg
ICAgIChjKSBDb3B5cmlnaHQgMjAwNC0yMDExIEFwcGxlIENvbXB1dGVyLCBJbmMuLCBNb3ppbGxh
IEZvdW5kYXRpb24sIGFuZCBPcGVyYSBTb2Z0d2FyZSBBU0EuCiAqICAgICAgICAgICAgICBZb3Ug
YXJlIGdyYW50ZWQgYSBsaWNlbnNlIHRvIHVzZSwgcmVwcm9kdWNlIGFuZCBjcmVhdGUgZGVyaXZh
dGl2ZSB3b3JrcyBvZiB0aGlzIGRvY3VtZW50LgogKgogKiBbMV0gaHR0cDovL3d3dy53aGF0d2cu
b3JnL3NwZWNzL3dlYi1hcHBzL2N1cnJlbnQtd29yay9tdWx0aXBhZ2Uvc2VjdGlvbnMuaHRtbCNv
dXRsaW5lcwogKiBbMl0gaHR0cDovL3d3dy53aGF0d2cub3JnL3NwZWNzL3dlYi1hcHBzL2N1cnJl
bnQtd29yay9tdWx0aXBhZ2UvaW5kZXguaHRtbAogKi8KKGZ1bmN0aW9uKCl7dmFyIGo9ZnVuY3Rp
b24oYil7dGhpcy5zZWN0aW9ucz1bXTt0aGlzLnN0YXJ0aW5nTm9kZT1ifTtqLnByb3RvdHlwZT17
aGVhZGluZzohMSxhcHBlbmQ6ZnVuY3Rpb24oYil7Yi5jb250YWluZXI9dGhpczt0aGlzLnNlY3Rp
b25zLnB1c2goYil9LGFzSFRNTDpmdW5jdGlvbihiKXsib2JqZWN0IiE9dHlwZW9mIGImJihiPXtj
cmVhdGVMaW5rczpifSk7dmFyIGE7YT10aGlzLmhlYWRpbmc7ZyhhKT8oIkhHUk9VUCI9PWEudGFn
TmFtZS50b1VwcGVyQ2FzZSgpJiYoYT1hLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJoIistayhhKSlb
MF0pLGE9YS50ZXh0Q29udGVudHx8YS5pbm5lclRleHR8fCI8aT5ObyB0ZXh0IGNvbnRlbnQgaW5z
aWRlICIrYS5ub2RlTmFtZSsiPC9pPiIpOmE9IiIrYTtpZihiLmNyZWF0ZUxpbmtzKXt2YXIgZTth
OntlPXRoaXMuc3RhcnRpbmdOb2RlO2Zvcih2YXIgZCxjPWU7Oyl7aWYoZD1jLmdldEF0dHJpYnV0
ZSgiaWQiKSl7ZT1kO2JyZWFrIGF9Zm9yKGM9CmMuZmlyc3RDaGlsZDtjJiYzPT1jLm5vZGVUeXBl
JiYhL1xTLy50ZXN0KGMuZGF0YSk7KWM9Yy5uZXh0U2libGluZztpZighZyhjKSlicmVha31kbyBk
PSJoNW8tIisgKytxO3doaWxlKHIuZ2V0RWxlbWVudEJ5SWQoZCkpO2Uuc2V0QXR0cmlidXRlKCJp
ZCIsZCk7ZT1kfWE9JzxhIGhyZWY9IiMnK2UrJyI+JythKyI8L2E+In1yZXR1cm4gYStuKHRoaXMu
c2VjdGlvbnMsYil9fTt2YXIgbj1mdW5jdGlvbihiLGEpe2lmKGEuc2tpcFRvcEhlYWRlcilyZXR1
cm4gYS5za2lwVG9wSGVhZGVyPSExLG4oYlswXS5zZWN0aW9ucyxhKTtmb3IodmFyIGM9IiIsZD0w
O2Q8Yi5sZW5ndGg7ZCsrKXt2YXIgZj1iW2RdO2Euc2tpcFVudGl0bGVkJiYic3RyaW5nIj09dHlw
ZW9mIGYuaGVhZGluZ3x8KGMrPSI8bGk+IitmLmFzSFRNTChhKSsiPC9saT4iKX1yZXR1cm4iIj09
Yz9jOiI8b2w+IitjKyI8L29sPiJ9LHM9ZnVuY3Rpb24oYil7Yj1iLmhlYWRpbmc7cmV0dXJuIGco
Yik/ayhiKToxfSxjLGQsZiwKcSxyLHQ9ZnVuY3Rpb24oYil7aWYoIWcoZltmLmxlbmd0aC0xXSkp
aWYobChiKXx8bShiKSludWxsIT1jJiZmLnB1c2goYyksYz1iLGQ9bmV3IGooYiksYy5vdXRsaW5l
PXtzZWN0aW9uczpbZF0sc3RhcnRpbmdOb2RlOmIsYXNIVE1MOmZ1bmN0aW9uKGEpe3JldHVybiBu
KHRoaXMuc2VjdGlvbnMsYSl9fTtlbHNlIGlmKG51bGwhPWMmJmcoYikpe2lmKGQuaGVhZGluZylp
ZihrKGIpPj1zKGMub3V0bGluZS5zZWN0aW9uc1tjLm91dGxpbmUuc2VjdGlvbnMubGVuZ3RoLTFd
KSl7dmFyIGE9bmV3IGooYik7Yy5vdXRsaW5lLnNlY3Rpb25zLnB1c2goYSk7ZD1hO2QuaGVhZGlu
Zz1ifWVsc2V7dmFyIGE9ITEsZT1kO2RvIGsoYik8cyhlKSYmKGE9bmV3IGooYiksZS5hcHBlbmQo
YSksZD1hLGQuaGVhZGluZz1iLGE9ITApLGU9ZS5jb250YWluZXI7d2hpbGUoIWEpfWVsc2UgZC5o
ZWFkaW5nPWI7Zi5wdXNoKGIpfX0scD1mdW5jdGlvbihiKXtyZXR1cm4gZnVuY3Rpb24oYSl7cmV0
dXJuIGEmJgphLnRhZ05hbWUmJlJlZ0V4cChiLCJpIikudGVzdChhLnRhZ05hbWUudG9VcHBlckNh
c2UoKSl9fSxtPXAoIl5CTE9DS1FVT1RFfEJPRFl8REVUQUlMU3xGSUVMRFNFVHxGSUdVUkV8VEQk
IiksbD1wKCJeQVJUSUNMRXxBU0lERXxOQVZ8U0VDVElPTiQiKSxnPXAoIl5IWzEtNl18SEdST1VQ
JCIpLGs9ZnVuY3Rpb24oYil7dmFyIGE9Yi50YWdOYW1lLnRvVXBwZXJDYXNlKCk7aWYoIkhHUk9V
UCI9PWEpZm9yKGE9MTs2Pj1hO2ErKyl7aWYoMDxiLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJIIith
KS5sZW5ndGgpcmV0dXJuLWF9ZWxzZSByZXR1cm4tcGFyc2VJbnQoYS5zdWJzdHIoMSkpfTtIVE1M
NU91dGxpbmU9ZnVuY3Rpb24oYil7cT0wO3I9Yi5vd25lckRvY3VtZW50fHx3aW5kb3cuZG9jdW1l
bnQ7ZD1jPW51bGw7Zj1bXTt2YXIgYT1iO2E6Zm9yKDthOyl7dChhKTtpZihhLmZpcnN0Q2hpbGQp
e2E9YS5maXJzdENoaWxkO2NvbnRpbnVlIGF9Zm9yKDthOyl7dmFyIGU9YSxoPWZbZi5sZW5ndGgt
CjFdO2lmKGcoaCkpaD09ZSYmZi5wb3AoKTtlbHNle2lmKChsKGUpfHxtKGUpKSYmIWQuaGVhZGlu
ZylkLmhlYWRpbmc9IjxpPlVudGl0bGVkICIrZS50YWdOYW1lLnRvVXBwZXJDYXNlKCkrIjwvaT4i
O2lmKGwoZSkmJjA8Zi5sZW5ndGgpe2M9Zi5wb3AoKTtkPWMub3V0bGluZS5zZWN0aW9uc1tjLm91
dGxpbmUuc2VjdGlvbnMubGVuZ3RoLTFdO2ZvcihoPTA7aDxlLm91dGxpbmUuc2VjdGlvbnMubGVu
Z3RoO2grKylkLmFwcGVuZChlLm91dGxpbmUuc2VjdGlvbnNbaF0pfWVsc2UgaWYobShlKSYmMDxm
Lmxlbmd0aCl7Yz1mLnBvcCgpO2ZvcihkPWMub3V0bGluZS5zZWN0aW9uc1tjLm91dGxpbmUuc2Vj
dGlvbnMubGVuZ3RoLTFdOzA8ZC5zZWN0aW9ucy5sZW5ndGg7KWQ9ZC5zZWN0aW9uc1tkLnNlY3Rp
b25zLmxlbmd0aC0xXX1lbHNlIGlmKGwoZSl8fG0oZSkpZD1jLm91dGxpbmUuc2VjdGlvbnNbMF19
aWYoYS5uZXh0U2libGluZyl7YT1hLm5leHRTaWJsaW5nO2NvbnRpbnVlIGF9YT0KYT09Yj9udWxs
OmEucGFyZW50Tm9kZX19cmV0dXJuIG51bGwhPWM/Yy5vdXRsaW5lOm51bGx9fSkoKTsKCgogICAg
dmFyIG91dGxpbmUgPSBIVE1MNU91dGxpbmUoZG9jdW1lbnQuYm9keSk7CiAgICBkb2N1bWVudC5n
ZXRFbGVtZW50QnlJZCgndG9jJykuaW5uZXJIVE1MID0KICAgICAgICBvdXRsaW5lLmFzSFRNTCh7
Y3JlYXRlTGlua3M6IHRydWUsIHNraXBUb3BIZWFkZXI6IHRydWUsIHNraXBVbnRpdGxlZDogdHJ1
ZX0pOwogIC8vLS0+PC9zY3JpcHQ+CjwvYm9keT4KPC9odG1sPgo=
--001a113a54d6b4530004f061f22b--
.
Author: Alexander Bolz <abolz.lists@gmail.com>
Date: Mon, 20 Jan 2014 04:15:16 -0800 (PST)
Raw View
------=_Part_1968_22086388.1390220116661
Content-Type: text/plain; charset=UTF-8
Please let me summarize why I think string_view should be constructible
from a nullptr (and a zero length) and and data() should return the
pointer passed to the constructor. Please, if I got anything wrong, let me
know! I really don't understand the reason for data() != null.
The only reason presented here that data() should always return non-null is
that "nullptrs are bad". I'm not convinced. If there are other arguments,
I really would like to hear them.
Since it's not null terminated, string_view's data() is not a replacement
for string's data() and since it might contain null characters, string's
data() is not a replacement for C-strings. When using data() I have to
be careful anyway.
data() == null (which implies size() == 0) doesn't force the user
to write additional null checks. The standard _explicitly_ allows
nullptr + 0 and nullptr - nullptr. So if I use any standard algorithm
like find, I can write
find(sv.data(), sv.data() + sv.size(), 'x')
or
find(sv.begin(), sv.end(), 'x').
If a function f takes an iterator and and a length I could also write
f(sv.begin(), sv.end() - sv.begin()).
For all these algorithms using iterators, a null string_view is exactly
the same as an empty string_view.
Actually, allowing data() == null frees the user from performing null
checks.
So I think allowing data() == null makes working with C-strings more safe
and working with std::string's more efficient. And of course I can directly
use any other contiguous range of characters as a (sub-)string.
And if there are situations where I need/want to know whether a string_view
was constructed from a nullptr, I can get this information, too.
This would not (directly) be possible if string_view were constructible from
a nullptr, but the return value of data() is unspecified. It actually
would introduce UB if I don't pay extra attention to this.
void f(char const* ptr, size_t len)
{
auto s = string_view(ptr, len);
// ...
g(ptr, s.data() - ptr);
}
Summary: I pay for what I don't use: a non-null ptr.
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_1968_22086388.1390220116661
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Please let me summarize why I think string_view shoul=
d be constructible</div><div>from a nullptr (and a zero length) and and dat=
a() should return the</div><div>pointer passed to the constructor. Please, =
if I got anything wrong, let me</div><div>know! I really don't understand t=
he reason for data() !=3D null.</div><div><br></div><div>The only reason pr=
esented here that data() should always return non-null is</div><div>that "n=
ullptrs are bad". I'm not convinced. If there are other arguments,</div><di=
v>I really would like to hear them.</div><div><br></div><div>Since it's not=
null terminated, string_view's data() is not a replacement</div><div>for s=
tring's data() and since it might contain null characters, string's</div><d=
iv>data() is not a replacement for C-strings. When using data() I have to</=
div><div>be careful anyway.</div><div><br></div><div>data() =3D=3D null (wh=
ich implies size() =3D=3D 0) doesn't force the user</div><div>to write addi=
tional null checks. The standard _explicitly_ allows</div><div>nullptr + 0 =
and nullptr - nullptr. So if I use any standard algorithm</div><div>like fi=
nd, I can write</div><div><br></div><div><font face=3D"courier new, monospa=
ce">find(sv.data(), sv.data() + sv.size(), 'x')</font></div><div><br></div>=
<div>or</div><div><br></div><div><font face=3D"courier new, monospace">find=
(sv.begin(), sv.end(), 'x').</font></div><div><br></div><div>If a function =
f takes an iterator and and a length I could also write</div><div><br></div=
><div><font face=3D"courier new, monospace">f(sv.begin(), sv.end() - sv.beg=
in()).</font></div><div><br></div><div>For all these algorithms using itera=
tors, a null string_view is exactly</div><div>the same as an empty string_v=
iew.</div><div><br></div><div>Actually, allowing data() =3D=3D null frees t=
he user from performing null checks.</div><div><br></div><div>So I think al=
lowing data() =3D=3D null makes working with C-strings more safe</div><div>=
and working with std::string's more efficient. And of course I can directly=
</div><div>use any other contiguous range of characters as a (sub-)string.<=
/div><div><br></div><div>And if there are situations where I need/want to k=
now whether a string_view</div><div>was constructed from a nullptr, I can g=
et this information, too.</div><div><br></div><div>This would not (directly=
) be possible if string_view were constructible from</div><div>a nullptr, b=
ut the return value of data() is unspecified. It actually</div><div>would i=
ntroduce UB if I don't pay extra attention to this.</div><div><br></div><di=
v><font face=3D"courier new, monospace">void f(char const* ptr, size_t len)=
</font></div><div><font face=3D"courier new, monospace">{</font></div><div>=
<font face=3D"courier new, monospace"> auto s =3D string_view(=
ptr, len);</font></div><div><font face=3D"courier new, monospace"> &n=
bsp; // ...</font></div><div><font face=3D"courier new, monospace"> &=
nbsp; g(ptr, s.data() - ptr);</font></div><div><font face=3D"courier new, m=
onospace">}</font></div><div><br></div><div>Summary: I pay for what I don't=
use: a non-null ptr.</div><div><br></div></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_1968_22086388.1390220116661--
.
Author: Peter Bigot <bigotp@acm.org>
Date: Mon, 20 Jan 2014 05:13:11 -0800 (PST)
Raw View
------=_Part_699_2367907.1390223591514
Content-Type: text/plain; charset=UTF-8
On Monday, January 20, 2014 1:36:00 AM UTC-6, Jeffrey Yasskin wrote:
>
> On Sun, Jan 19, 2014 at 10:25 PM, Nevin Liber <ne...@eviloverlord.com<javascript:>>
> wrote:
> > On 20 January 2014 00:12, Jeffrey Yasskin <jyas...@google.com<javascript:>>
> wrote:
> >>
> >> > My personal preference for all this is that string_view(nullptr, 0)
> be
> >> > allowed, and it is a Quality of Implementation issue whether or not
> >> > sv.data() can ever return a nullptr; i.e., it would be allowed to
> return
> >> > any
> >> > legal pointer it wants for an empty string_view.
> >>
> >> That's interesting. It's easier to both specify and implement to just
> >> say that string_view(x, y).data()==x and string_view(x, y).size()==y,
> >> assuming [x, x+y) is a valid range. Why would you special-case data()
> >> to return arbitrary things when y==0?
> >
> >
> > A debugging implementation may want to ensure that developers aren't
> > dependent on "knowing" that a nullptr was passed in.
>
> Thanks. I think I don't personally want that, but I've added your
> reason to the "if we want data()==nullptr" section in the attached
> draft. I plan to send this to Clark tomorrow (Monday) morning.
>
I believe your alternative section also needs something like:
In subclause "x.1 basic_string_view constructors and assignment operators
[string.view.cons]"
basic_string_view(const charT* str);
Requires: [str,str + traits::length(str)) is a valid range, or that str
is a null pointer value
along with setting the size() to zero in the added case, if I'm correct in
my understanding that traits::length(str) is undefined when str is null.
Peter
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_699_2367907.1390223591514
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Monday, January 20, 2014 1:36:00 AM UTC-6, Jeff=
rey Yasskin wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Sun, Jan =
19, 2014 at 10:25 PM, Nevin Liber <<a href=3D"javascript:" target=3D"_bl=
ank" gdf-obfuscated-mailto=3D"pimK0eE3_H0J" onmousedown=3D"this.href=3D'jav=
ascript:';return true;" onclick=3D"this.href=3D'javascript:';return true;">=
ne...@eviloverlord.com</a>> wrote:
<br>> On 20 January 2014 00:12, Jeffrey Yasskin <<a href=3D"javascrip=
t:" target=3D"_blank" gdf-obfuscated-mailto=3D"pimK0eE3_H0J" onmousedown=3D=
"this.href=3D'javascript:';return true;" onclick=3D"this.href=3D'javascript=
:';return true;">jyas...@google.com</a>> wrote:
<br>>>
<br>>> > My personal preference for all this is that string_view(n=
ullptr, 0) be
<br>>> > allowed, and it is a Quality of Implementation issue whet=
her or not
<br>>> > sv.data() can ever return a nullptr; i.e., it would be al=
lowed to return
<br>>> > any
<br>>> > legal pointer it wants for an empty string_view.
<br>>>
<br>>> That's interesting. It's easier to both specify and implement =
to just
<br>>> say that string_view(x, y).data()=3D=3Dx and string_view(x, y)=
..size()=3D=3Dy,
<br>>> assuming [x, x+y) is a valid range. Why would you special-case=
data()
<br>>> to return arbitrary things when y=3D=3D0?
<br>>
<br>>
<br>> A debugging implementation may want to ensure that developers aren=
't
<br>> dependent on "knowing" that a nullptr was passed in.
<br>
<br>Thanks. I think I don't personally want that, but I've added your
<br>reason to the "if we want data()=3D=3Dnullptr" section in the attached
<br>draft. I plan to send this to Clark tomorrow (Monday) morning.
<br></blockquote><div> <br>I believe your alternative section also nee=
ds something like:<br><br>In subclause "x.1 basic_string_view constructors =
and assignment operators [string.view.cons]" <br><br> bas=
ic_string_view(const charT* str);<br> Requires: [str,str =
+ traits::length(str)) is a valid range, or that str is a null pointer valu=
e<br><br>along with setting the size() to zero in the added case, if I'm co=
rrect in my understanding that traits::length(str) is undefined when str is=
null.<br><br>Peter<br></div></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_699_2367907.1390223591514--
.
Author: Peter Bigot <bigotp@acm.org>
Date: Mon, 20 Jan 2014 05:30:32 -0800 (PST)
Raw View
------=_Part_8_1283287.1390224632687
Content-Type: text/plain; charset=UTF-8
On Monday, January 20, 2014 6:15:16 AM UTC-6, Alexander Bolz wrote:
>
> Please let me summarize why I think string_view should be constructible
> from a nullptr (and a zero length) and and data() should return the
> pointer passed to the constructor. Please, if I got anything wrong, let me
> know! I really don't understand the reason for data() != null.
>
> The only reason presented here that data() should always return non-null is
> that "nullptrs are bad". I'm not convinced. If there are other arguments,
> I really would like to hear them.
>
> Since it's not null terminated, string_view's data() is not a replacement
> for string's data() and since it might contain null characters, string's
> data() is not a replacement for C-strings. When using data() I have to
> be careful anyway.
>
> data() == null (which implies size() == 0) doesn't force the user
> to write additional null checks. The standard _explicitly_ allows
> nullptr + 0 and nullptr - nullptr. So if I use any standard algorithm
> like find, I can write
>
> find(sv.data(), sv.data() + sv.size(), 'x')
>
> or
>
> find(sv.begin(), sv.end(), 'x').
>
> If a function f takes an iterator and and a length I could also write
>
> f(sv.begin(), sv.end() - sv.begin()).
>
> For all these algorithms using iterators, a null string_view is exactly
> the same as an empty string_view.
>
> Actually, allowing data() == null frees the user from performing null
> checks.
>
> So I think allowing data() == null makes working with C-strings more safe
> and working with std::string's more efficient. And of course I can directly
> use any other contiguous range of characters as a (sub-)string.
>
> And if there are situations where I need/want to know whether a string_view
> was constructed from a nullptr, I can get this information, too.
>
> This would not (directly) be possible if string_view were constructible
> from
> a nullptr, but the return value of data() is unspecified. It actually
> would introduce UB if I don't pay extra attention to this.
>
> void f(char const* ptr, size_t len)
> {
> auto s = string_view(ptr, len);
> // ...
> g(ptr, s.data() - ptr);
> }
>
> Summary: I pay for what I don't use: a non-null ptr.
>
>
Thanks; that's a clear statement. In return, here's my reasoning for the
other perspective:
In addition to that it expresses something std::string cannot express, my
main objection to allowing string_view(p) where p is a null pointer value
is the assumption that this should be implicitly treated as identical to
construction from an empty string. I believe emptiness comes from
size()==0, not from data()==nullptr in conjunction with an inference that
therefore size() must also be zero because that's necessary to allow data()
to be the basis of a valid range.
E.g., when getenv(3) returns a null pointer it means something very
different from when it returns a non-null pointer to an empty string. The
argument that allowing null frees you from null checks only works when
those two pointers signify the same thing and all uses of data() involve
range operations. It's equally true that disallowing null frees you from
null checks because if you have a string_view at all you know data() cannot
be null, and this becomes important when data() is being used as an
iterator in its own right.
My strongest objection is to any line of reasoning that leads to:
const std::string base("ABCDE");
string_view sv(base);
ASSERT_EQ(base.data(), sv.data());
sv.remove_prefix(2);
ASSERT_EQ(base.data()+2, sv.data());
sv.remove_suffix(3);
ASSERT_EQ(0, sv.size());
ASSERT_EQ(nullptr, sv.data());
passing in a conforming implementation due to an expectation that all empty
ranges are equivalent.
Would it be acceptable to everybody if language were added to the proposal
to the effect that all mutating string_view operations ensure that [data(),
data()+size()) is a valid subrange of [bp, bp+bn) where [bp, bp+bn)
identifies the range last assigned to the string_view (on construction,
through assignment, or through clear())?
Is that even necessary? I had thought it was the original intent and that
the necessary language is already there, but I'm not convinced everybody
else sees it that way, and that part of the reason is a belief in
equivalence of empty ranges.
Or maybe I'm mistaken in my impression that some people don't accept the
use of data() as an iterator outside the range of the string_view that
returned it, a key capability that I believe the reference semantics of
string_view must permit.
Peter
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_8_1283287.1390224632687
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Monday, January 20, 2014 6:15:16 AM UTC-6, Alex=
ander Bolz wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr"><div>Please let me summarize why I think string_view should be construc=
tible</div><div>from a nullptr (and a zero length) and and data() should re=
turn the</div><div>pointer passed to the constructor. Please, if I got anyt=
hing wrong, let me</div><div>know! I really don't understand the reason for=
data() !=3D null.</div><div><br></div><div>The only reason presented here =
that data() should always return non-null is</div><div>that "nullptrs are b=
ad". I'm not convinced. If there are other arguments,</div><div>I really wo=
uld like to hear them.</div><div><br></div><div>Since it's not null termina=
ted, string_view's data() is not a replacement</div><div>for string's data(=
) and since it might contain null characters, string's</div><div>data() is =
not a replacement for C-strings. When using data() I have to</div><div>be c=
areful anyway.</div><div><br></div><div>data() =3D=3D null (which implies s=
ize() =3D=3D 0) doesn't force the user</div><div>to write additional null c=
hecks. The standard _explicitly_ allows</div><div>nullptr + 0 and nullptr -=
nullptr. So if I use any standard algorithm</div><div>like find, I can wri=
te</div><div><br></div><div><font face=3D"courier new, monospace">find(sv.d=
ata(), sv.data() + sv.size(), 'x')</font></div><div><br></div><div>or</div>=
<div><br></div><div><font face=3D"courier new, monospace">find(sv.begin(), =
sv.end(), 'x').</font></div><div><br></div><div>If a function f takes an it=
erator and and a length I could also write</div><div><br></div><div><font f=
ace=3D"courier new, monospace">f(sv.begin(), sv.end() - sv.begin()).</font>=
</div><div><br></div><div>For all these algorithms using iterators, a null =
string_view is exactly</div><div>the same as an empty string_view.</div><di=
v><br></div><div>Actually, allowing data() =3D=3D null frees the user from =
performing null checks.</div><div><br></div><div>So I think allowing data()=
=3D=3D null makes working with C-strings more safe</div><div>and working w=
ith std::string's more efficient. And of course I can directly</div><div>us=
e any other contiguous range of characters as a (sub-)string.</div><div><br=
></div><div>And if there are situations where I need/want to know whether a=
string_view</div><div>was constructed from a nullptr, I can get this infor=
mation, too.</div><div><br></div><div>This would not (directly) be possible=
if string_view were constructible from</div><div>a nullptr, but the return=
value of data() is unspecified. It actually</div><div>would introduce UB i=
f I don't pay extra attention to this.</div><div><br></div><div><font face=
=3D"courier new, monospace">void f(char const* ptr, size_t len)</font></div=
><div><font face=3D"courier new, monospace">{</font></div><div><font face=
=3D"courier new, monospace"> auto s =3D string_view(ptr, len);=
</font></div><div><font face=3D"courier new, monospace"> // ..=
..</font></div><div><font face=3D"courier new, monospace"> g(pt=
r, s.data() - ptr);</font></div><div><font face=3D"courier new, monospace">=
}</font></div><div><br></div><div>Summary: I pay for what I don't use: a no=
n-null ptr.</div><div><br></div></div></blockquote><div><br>Thanks; that's =
a clear statement. In return, here's my reasoning for the other persp=
ective:<br><br>In addition to that it expresses something std::string canno=
t express, my main objection to allowing string_view(p) where p is a null p=
ointer value is the assumption that this should be implicitly treated as id=
entical to construction from an empty string. I believe emptiness com=
es from size()=3D=3D0, not from data()=3D=3Dnullptr in conjunction with an =
inference that therefore size() must also be zero because that's necessary =
to allow data() to be the basis of a valid range.<br><br>E.g., when getenv(=
3) returns a null pointer it means something very different from when it re=
turns a non-null pointer to an empty string. The argument that allowi=
ng null frees you from null checks only works when those two pointers signi=
fy the same thing and all uses of data() involve range operations. It=
's equally true that disallowing null frees you from null checks because if=
you have a string_view at all you know data() cannot be null, and this bec=
omes important when data() is being used as an iterator in its own right.<b=
r><br>My strongest objection is to any line of reasoning that leads to:<br>=
<br> const std::string base("ABCDE");<br> string_view sv(base);=
<br> ASSERT_EQ(base.data(), sv.data());<br> sv.remove_prefix(2)=
;<br> ASSERT_EQ(base.data()+2, sv.data());<br> sv.remove_suffix=
(3);<br> ASSERT_EQ(0, sv.size());<br> ASSERT_EQ(nullptr, sv.dat=
a());<br><br>passing in a conforming implementation due to an expectation t=
hat all empty ranges are equivalent.<br><br>Would it be acceptable to every=
body if language were added to the proposal to the effect that all mutating=
string_view operations ensure that [data(), data()+size()) is a valid subr=
ange of [bp, bp+bn) where [bp, bp+bn) identifies the range last assigned to=
the string_view (on construction, through assignment, or through clear())?=
<br><br>Is that even necessary? I had thought it was the original int=
ent and that the necessary language is already there, but I'm not convinced=
everybody else sees it that way, and that part of the reason is a belief i=
n equivalence of empty ranges.<br><br>Or maybe I'm mistaken in my impressio=
n that some people don't accept the use of data() as an iterator outside th=
e range of the string_view that returned it, a key capability that I believ=
e the reference semantics of string_view must permit.<br><br>Peter<br></div=
></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_8_1283287.1390224632687--
.
Author: Paul Tessier <phernost@gmail.com>
Date: Mon, 20 Jan 2014 09:18:00 -0800 (PST)
Raw View
------=_Part_375_31824433.1390238281051
Content-Type: text/plain; charset=UTF-8
On Monday, January 20, 2014 1:25:58 AM UTC-5, Nevin ":-)" Liber wrote:
>
> On 20 January 2014 00:12, Jeffrey Yasskin <jyas...@google.com<javascript:>
> > wrote:
>
>> > My personal preference for all this is that string_view(nullptr, 0) be
>> > allowed, and it is a Quality of Implementation issue whether or not
>> > sv.data() can ever return a nullptr; i.e., it would be allowed to
>> return any
>> > legal pointer it wants for an empty string_view.
>>
>> That's interesting. It's easier to both specify and implement to just
>> say that string_view(x, y).data()==x and string_view(x, y).size()==y,
>> assuming [x, x+y) is a valid range. Why would you special-case data()
>> to return arbitrary things when y==0?
>>
>
> A debugging implementation may want to ensure that developers aren't
> dependent on "knowing" that a nullptr was passed in.
> --
> Nevin ":-)" Liber <mailto:ne...@eviloverlord.com <javascript:>> (847)
> 691-1404
>
A simple implementation would be much better. Allowing the pointer and
size to pass through directly would allow one to track down their origins,
if it is a cause for concern. Preventing null solves nothing, a mishandled
view will still be mishandled. Mutating a null input is equally pointless
in debugging aspect, as you have allowed a logical input to be changed into
a different input which will be harder to trace back to the origin.
None of these arguments against have been of the fashion of preventing
common programming pitfalls. Just because std::string will never produce
or accept a range beginning a null, does not mean it is logical or
reasonable in all cases. [ P, P+N ) is a valid range for any non-negative
N, therefore [ P, P ) is a valid range, for any P, even when P is in a
protected segment. Validity of a range only describes if it is rational.
It does not describe if it is rational to use it in all contexts. Any P in
a protected segment will trap when dereferenced. There is no way to
protected against this. Dereferencing an empty range is almost always a
mistake, no matter where it is located.
I would also argue against string_view( char* ) doing runtime null checks
and creating an empty view, as this only defends against ( P == null ) and
not P being in protected memory, of which null falls into. Asserts on
null, would be more reasonable. Although in this case it can be argued the
other way as it is a common practice to signal an empty C string with a
null. Empty C strings should be "" and not null but, there is no changing
the past. string_view( null ) being [ null, null ) is not my preference
but, something that I cannot argue against as being unreasonable. (
string_view( null ) : string_view( rand(), 0 ) {} ) on the other hand is
not reasonable.
If string_view cannot accept C string valid ranges, but only the ranges
allow by std:string, it's C string constructors and support should be
deleted. It should work as any novice would expect. A range passed in
will be the same range returned. Nothing more complicated than a thin
wrapper around a valid range with string helper methods.
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_375_31824433.1390238281051
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Monday, January 20, 2014 1:25:58 AM UTC-5, Nevi=
n ":-)" Liber wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr">On 20 January 2014 00:12, Jeffrey Yasskin <span dir=3D"ltr"><<a=
href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"8kdwhrIS3i=
4J" onmousedown=3D"this.href=3D'javascript:';return true;" onclick=3D"this.=
href=3D'javascript:';return true;">jyas...@google.com</a>></span> wrote:=
<br><div><div class=3D"gmail_quote">
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div>> My personal preference for all thi=
s is that string_view(nullptr, 0) be<br>
> allowed, and it is a Quality of Implementation issue whether or not<br=
>
> sv.data() can ever return a nullptr; i.e., it would be allowed to retu=
rn any<br>
> legal pointer it wants for an empty string_view.<br>
<br>
</div>That's interesting. It's easier to both specify and implement to just=
<br>
say that string_view(x, y).data()=3D=3Dx and string_view(x, y).size()=3D=3D=
y,<br>
assuming [x, x+y) is a valid range. Why would you special-case data()<br>
to return arbitrary things when y=3D=3D0?<br></blockquote><div><br></div><d=
iv>A debugging implementation may want to ensure that developers aren't dep=
endent on "knowing" that a nullptr was passed in.</div></div>
-- <br> Nevin ":-)" Liber <mailto:<a href=3D"javascript:" tar=
get=3D"_blank" gdf-obfuscated-mailto=3D"8kdwhrIS3i4J" onmousedown=3D"this.h=
ref=3D'javascript:';return true;" onclick=3D"this.href=3D'javascript:';retu=
rn true;">ne...@eviloverlord.com</a><wbr>> (847) 691-1404
</div></div></blockquote><div><br>A simple implementation would be much bet=
ter. Allowing the pointer and size to pass through directly would all=
ow one to track down their origins, if it is a cause for concern. Pre=
venting null solves nothing, a mishandled view will still be mishandled.&nb=
sp; Mutating a null input is equally pointless in debugging aspect, as you =
have allowed a logical input to be changed into a different input which wil=
l be harder to trace back to the origin.<br><br>None of these arguments aga=
inst have been of the fashion of preventing=20
common programming pitfalls. Just because std::string will never=20
produce or accept a range beginning a null, does not mean it is logical=20
or reasonable in all cases. [ P, P+N ) is a valid range for any non-negativ=
e N, therefore [ P, P ) is a valid range, for any P, even=20
when P is in a protected segment. Validity of a range only describes =
if it is rational. It does not describe if it is rational to use it i=
n all contexts. Any P in a protected segment will trap when dereferen=
ced. There is no way to protected against this. Dereferencing a=
n empty range is almost always a mistake, no matter where it is located.<br=
><br>I would also argue against string_view( char* ) doing runtime null che=
cks and creating an empty view, as this only defends against ( P =3D=3D nul=
l ) and not P being in protected memory, of which null falls into. As=
serts on null, would be more reasonable. Although in this case it can=
be argued the other way as it is a common practice to signal an empty C st=
ring with a null. Empty C strings should be "" and not null but, ther=
e is no changing the past. string_view( null ) being [ null, null ) is not =
my preference but, something that I cannot argue against as being unreasona=
ble. ( string_view( null ) : string_view( rand(), 0 ) {} ) on the oth=
er hand is not reasonable.<br><br>If string_view cannot accept C string val=
id ranges, but only the ranges allow by std:string, it's C string construct=
ors and support should be deleted. It should work as any novice would=
expect. A range passed in will be the same range returned. Not=
hing more complicated than a thin wrapper around a valid range with string =
helper methods.<br><br><br><br><br></div></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_375_31824433.1390238281051--
.
Author: Marshall Clow <mclow.lists@gmail.com>
Date: Mon, 20 Jan 2014 12:14:03 -0800
Raw View
--Apple-Mail=_A5434CFD-9E09-45B8-83F8-E7E2FBA5BA34
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=windows-1252
On Jan 20, 2014, at 9:18 AM, Paul Tessier <phernost@gmail.com> wrote:
> I would also argue against string_view( char* ) doing runtime null checks=
and creating an empty view, as this only defends against ( P =3D=3D null )=
and not P being in protected memory, of which null falls into.=20
I agree.=20
string_view(char *) should require that the char * point to a null terminat=
ed string.
=97 Marshall
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--Apple-Mail=_A5434CFD-9E09-45B8-83F8-E7E2FBA5BA34
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=windows-1252
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;">On Jan 20, 2014, at 9:=
18 AM, Paul Tessier <<a href=3D"mailto:phernost@gmail.com">phernost@gmai=
l.com</a>> wrote:<br><div><br class=3D"Apple-interchange-newline"><block=
quote type=3D"cite"><span style=3D"font-family: LucidaGrande; font-size: 11=
px; font-style: normal; font-variant: normal; font-weight: normal; letter-s=
pacing: normal; line-height: normal; orphans: auto; text-align: start; text=
-indent: 0px; text-transform: none; white-space: normal; widows: auto; word=
-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline=
!important;">I would also argue against string_view( char* ) doing runtime=
null checks and creating an empty view, as this only defends against ( P =
=3D=3D null ) and not P being in protected memory, of which null falls into=
.. </span></blockquote><div><br></div>I agree. </div><div>string_=
view(char *) should require that the char * point to a null terminated stri=
ng.</div><div><br></div><div>=97 Marshall</div><div><br></div><br></body></=
html>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--Apple-Mail=_A5434CFD-9E09-45B8-83F8-E7E2FBA5BA34--
.