Topic: std::c_str_iterator
Author: "'Vlad from Moscow' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Tue, 29 May 2018 08:31:19 -0700 (PDT)
Raw View
------=_Part_26880_103687995.1527607879708
Content-Type: multipart/alternative;
boundary="----=_Part_26881_970951566.1527607879708"
------=_Part_26881_970951566.1527607879708
Content-Type: text/plain; charset="UTF-8"
It is required very ofthen to apply standard algorithms based on forward
iterators to C-strings. To provide the last iterator of a range you have to
use standard C function *strlen*. Something like
auto cnt = std::count( s, s + strlen( s ), 'A' );
However it is inefficient and C-strings already have a sentinel value.
Why not provide a forward interator for example named like
*c_string_iterator* that wraps a string and uses the sentinel value *'\0*'
to determine the end of a range?
For example
auto cnt = std::count( std::c_string_iterator( s ), {}, 'A' );
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/5375a1a3-e40c-4197-a6d6-15f94c2fe5ca%40isocpp.org.
------=_Part_26881_970951566.1527607879708
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">It is required very ofthen to apply standard algorithms ba=
sed on forward iterators to C-strings. To provide the last iterator of a ra=
nge you have to use standard C function <b>strlen</b>. Something like<div><=
br></div><div><div class=3D"prettyprint" style=3D"background-color: rgb(250=
, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; border-=
width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> cn=
t </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">count</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> s</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> s </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">+</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
strlen</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> s </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">),</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #080;" class=3D"styled-by-prettify">'A'</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">);</span></div></code></div><br></div><div>H=
owever it is inefficient and C-strings already have a sentinel value.</div>=
<div><br></div><div>Why not provide a forward=C2=A0 interator for example n=
amed like <b>c_string_iterator</b> that wraps a string and uses the sentine=
l value <b>'\0</b>' to determine the end of a range?=C2=A0</div><di=
v><br></div><div>For example</div><div><br></div><div><div class=3D"prettyp=
rint" style=3D"border-width: 1px; border-style: solid; border-color: rgb(18=
7, 187, 187); background-color: rgb(250, 250, 250); word-wrap: break-word;"=
><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> cnt </span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">count</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> std=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify">c_string_iterator<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> s </span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">),</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">{},</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #080;" class=3D"style=
d-by-prettify">'A'</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">);</span></div><div><span class=3D"styled-by-prettify" style=3D"colo=
r: rgb(102, 102, 0);"><br></span></div></code></div></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/5375a1a3-e40c-4197-a6d6-15f94c2fe5ca%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/5375a1a3-e40c-4197-a6d6-15f94c2fe5ca=
%40isocpp.org</a>.<br />
------=_Part_26881_970951566.1527607879708--
------=_Part_26880_103687995.1527607879708--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 29 May 2018 08:45:00 -0700 (PDT)
Raw View
------=_Part_39128_322931777.1527608700956
Content-Type: multipart/alternative;
boundary="----=_Part_39129_1955159518.1527608700957"
------=_Part_39129_1955159518.1527608700957
Content-Type: text/plain; charset="UTF-8"
Or you could just wait for the Ranges TS and write a simple range that does
this job adequately. There's really no need to propagate the old-style of
sentinels (default-constructed objects of an iterator) when we're about to
replace it with a better paradigm.
Also, it's not clear how you would implement
`c_string_iterator::operator==` without having to do this:
bool c_string_iterator::operator==(const c_string_iterator &rhs) const
{
if(rhs->ptr_ == nullptr) then
return *this->ptr_ == '\0';
return this->ptr_ == rhs->ptr_;
}
See, the problem is that a c_string_iterator could point to an actual
string, in which case you need to test the pointers. If it doesn't point to
a string, then you need to test the current iterator with '\0'. That's
doing two runtime tests for each path.
A proper sentinel *type* doesn't have that problem. You have two functions:
one that tests against a proper iterator, and one that tests against a
sentinel. The compiler at compile-time knows which is being done, and will
call the right test appropriately.
Not only that, such a sentinel type could be used against a naked `char*`
just as easily as a specialized `c_string_iterator` type:
struct c_string_sentinel {};
strong_equality operator<=>(const char *lhs, c_string_sentinel) {return *lhs
<=> '\0';}
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/d05c4f45-8d86-443d-8ef3-9d2fd64a74f0%40isocpp.org.
------=_Part_39129_1955159518.1527608700957
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Or you could just wait for the Ranges TS and write a =
simple range that does this job adequately. There's really no need to p=
ropagate the old-style of sentinels (default-constructed objects of an iter=
ator) when we're about to replace it with a better paradigm.</div><div>=
</div><div><br></div><div>Also, it's not clear how you would implement =
`c_string_iterator::operator=3D=3D` without having to do this:</div><div><b=
r></div><div style=3D"background-color: rgb(250, 250, 250); border-color: r=
gb(187, 187, 187); border-style: solid; border-width: 1px; overflow-wrap: b=
reak-word;" class=3D"prettyprint"><code class=3D"prettyprint"><div class=3D=
"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">=
bool</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> c_str=
ing_iterator</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">::</span><span style=3D"color: #008;" class=3D"styled-by-prettify">operat=
or</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D(<=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">const</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> c_string_iterat=
or </span><span style=3D"color: #660;" class=3D"styled-by-prettify">&</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify">rhs</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">const</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br>=C2=A0 </span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">if</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
">rhs</span><span style=3D"color: #660;" class=3D"styled-by-prettify">->=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">ptr_ </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">nullptr</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">then</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">return</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">*</span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">this</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
-></span><span style=3D"color: #000;" class=3D"styled-by-prettify">ptr_ =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #080;" class=3D"styled-by-prettify">'\0'</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">return</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">this</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">-></span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">ptr_ </span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">=3D=3D</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> rhs</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">-></span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">ptr_</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">}</span></div></c=
ode></div><div><br></div><div></div><div>See, the problem is that a c_strin=
g_iterator could point to an actual string, in which case you need to test =
the pointers. If it doesn't point to a string, then you need to test th=
e current iterator with '\0'. That's doing two runtime tests fo=
r each path.<br></div><div><br></div><div>A proper sentinel <i>type</i> doe=
sn't have that problem. You have two functions: one that tests against =
a proper iterator, and one that tests against a sentinel. The compiler at c=
ompile-time knows which is being done, and will call the right test appropr=
iately.</div><div><br></div><div>Not only that, such a sentinel type could =
be used against a naked `char*` just as easily as a specialized `c_string_i=
terator` type:<br></div><div><br></div><div style=3D"background-color: rgb(=
250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; bord=
er-width: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><code clas=
s=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;=
" class=3D"styled-by-prettify">struct</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> c_string_sentinel </span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">{};</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br>strong_equality </span><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">operator</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify"><=3D>(</span><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">const</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">char</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">*</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>lhs</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> c_string_senti=
nel</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">return</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">*</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">lhs </span><span style=3D"color: #660;" class=3D"styled-=
by-prettify"><=3D></span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> </span><span style=3D"color: #080;" class=3D"styled-by-prett=
ify">'\0'</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">;}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br></span></div></code></div><div><br></div><br></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/d05c4f45-8d86-443d-8ef3-9d2fd64a74f0%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/d05c4f45-8d86-443d-8ef3-9d2fd64a74f0=
%40isocpp.org</a>.<br />
------=_Part_39129_1955159518.1527608700957--
------=_Part_39128_322931777.1527608700956--
.
Author: "'Vlad from Moscow' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Tue, 29 May 2018 08:50:08 -0700 (PDT)
Raw View
------=_Part_20506_1470449671.1527609008885
Content-Type: multipart/alternative;
boundary="----=_Part_20507_1913625850.1527609008886"
------=_Part_20507_1913625850.1527609008886
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
The operators can be defined like
friend bool operator =3D=3D( const c_string_iterator &lhs, const=20
c_string_iterator &rhs )
{
return ( lhs.s =3D=3D rhs.s ) || ( not lhs.s && not *rhs.s ) || ( not *=
lhs.s=20
&& not rhs.s );
}
friend bool operator =3D=3D( const c_string_iterator &lhs, const=20
c_string_iterator &rhs )
{
return not ( lhs =3D=3D rhs );
}
=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 29 =D0=BC=D0=B0=D1=8F 2018 =D0=
=B3., 18:45:01 UTC+3 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=
=D0=B5=D0=BB=D1=8C Nicol Bolas =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
>
> Or you could just wait for the Ranges TS and write a simple range that=20
> does this job adequately. There's really no need to propagate the old-sty=
le=20
> of sentinels (default-constructed objects of an iterator) when we're abou=
t=20
> to replace it with a better paradigm.
>
> Also, it's not clear how you would implement=20
> `c_string_iterator::operator=3D=3D` without having to do this:
>
> bool c_string_iterator::operator=3D=3D(const c_string_iterator &rhs) cons=
t
> {
> if(rhs->ptr_ =3D=3D nullptr) then
> return *this->ptr_ =3D=3D '\0';
> return this->ptr_ =3D=3D rhs->ptr_;
> }
>
> See, the problem is that a c_string_iterator could point to an actual=20
> string, in which case you need to test the pointers. If it doesn't point =
to=20
> a string, then you need to test the current iterator with '\0'. That's=20
> doing two runtime tests for each path.
>
> A proper sentinel *type* doesn't have that problem. You have two=20
> functions: one that tests against a proper iterator, and one that tests=
=20
> against a sentinel. The compiler at compile-time knows which is being don=
e,=20
> and will call the right test appropriately.
>
> Not only that, such a sentinel type could be used against a naked `char*`=
=20
> just as easily as a specialized `c_string_iterator` type:
>
> struct c_string_sentinel {};
> strong_equality operator<=3D>(const char *lhs, c_string_sentinel) {return=
*lhs=20
> <=3D> '\0';}
>
>
>
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/315b0317-4f24-491c-9bad-56a2b32b6f54%40isocpp.or=
g.
------=_Part_20507_1913625850.1527609008886
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">The operators can be defined like<div><br></div><div class=
=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-colo=
r: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: b=
reak-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span=
style=3D"color: #008;" class=3D"styled-by-prettify">friend</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">bool</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">operator</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">=3D=3D(</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">const</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> c=
_string_iterator </span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">&</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
">lhs</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #008;" class=3D"styled-by-prettify">const</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> c_string_iterator </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">&</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">rhs </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">return</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> lhs</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">.</span><span style=3D"color: #000;" class=3D"styled-by-prettify">s </s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> rhs</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify">s </span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">||</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
(</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">not</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> lhs</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">.</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify">s </span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">&&</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">not</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">*</span><span style=3D"color: #000;" class=3D"styled-by-prettify">rhs</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify">s </span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">||</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">not</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">*</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">lhs</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">.</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">s </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">&&</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">not</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> rhs</span><span style=3D"color: #660;" class=3D"styled-by-prettify">.</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">s </span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br><br><br></span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">friend</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D=
"styled-by-prettify">bool</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">operator</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=
=3D(</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">const</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> c_string_iterator <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">&</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">lhs</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">const</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> c_string_iterator </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">&</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">rhs </span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">return</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">no=
t</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> lhs </span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> rhs </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br><br></span></div></code></div><div><div><br><br></div>=D0=B2=
=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 29 =D0=BC=D0=B0=D1=8F 2018 =D0=B3., 1=
8:45:01 UTC+3 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=
=D0=BB=D1=8C Nicol Bolas =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:<blockq=
uote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-lef=
t: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>Or you could ju=
st wait for the Ranges TS and write a simple range that does this job adequ=
ately. There's really no need to propagate the old-style of sentinels (=
default-constructed objects of an iterator) when we're about to replace=
it with a better paradigm.</div><div></div><div><br></div><div>Also, it=
9;s not clear how you would implement `c_string_iterator::operator=3D=3D<wb=
r>` without having to do this:</div><div><br></div><div style=3D"background=
-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;bo=
rder-width:1px"><code><div><span style=3D"color:#008">bool</span><span styl=
e=3D"color:#000"> c_string_iterator</span><span style=3D"color:#660">::</sp=
an><span style=3D"color:#008">operator</span><span style=3D"color:#660">=3D=
=3D(</span><span style=3D"color:#008"><wbr>const</span><span style=3D"color=
:#000"> c_string_iterator </span><span style=3D"color:#660">&</span><sp=
an style=3D"color:#000">rhs</span><span style=3D"color:#660">)</span><span =
style=3D"color:#000"> </span><span style=3D"color:#008">const</span><span s=
tyle=3D"color:#000"><br></span><span style=3D"color:#660">{</span><span sty=
le=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:#008">if</span><sp=
an style=3D"color:#660">(</span><span style=3D"color:#000">rhs</span><span =
style=3D"color:#660">-></span><span style=3D"color:#000">ptr_ </span><sp=
an style=3D"color:#660">=3D=3D</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#008">nullptr</span><span style=3D"color:#660">)</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#008">then</span><spa=
n style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">=
return</span><span style=3D"color:#000"> </span><span style=3D"color:#660">=
*</span><span style=3D"color:#008">this</span><span style=3D"color:#660">-&=
gt;</span><span style=3D"color:#000">ptr_ </span><span style=3D"color:#660"=
>=3D=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#080"=
>'\0'</span><span style=3D"color:#660">;</span><span style=3D"color=
:#000"><br>=C2=A0 </span><span style=3D"color:#008">return</span><span styl=
e=3D"color:#000"> </span><span style=3D"color:#008">this</span><span style=
=3D"color:#660">-></span><span style=3D"color:#000">ptr_ </span><span st=
yle=3D"color:#660">=3D=3D</span><span style=3D"color:#000"> rhs</span><span=
style=3D"color:#660">-></span><span style=3D"color:#000">ptr_</span><sp=
an style=3D"color:#660">;</span><span style=3D"color:#000"><br></span><span=
style=3D"color:#660">}</span></div></code></div><div><br></div><div></div>=
<div>See, the problem is that a c_string_iterator could point to an actual =
string, in which case you need to test the pointers. If it doesn't poin=
t to a string, then you need to test the current iterator with '\0'=
.. That's doing two runtime tests for each path.<br></div><div><br></div=
><div>A proper sentinel <i>type</i> doesn't have that problem. You have=
two functions: one that tests against a proper iterator, and one that test=
s against a sentinel. The compiler at compile-time knows which is being don=
e, and will call the right test appropriately.</div><div><br></div><div>Not=
only that, such a sentinel type could be used against a naked `char*` just=
as easily as a specialized `c_string_iterator` type:<br></div><div><br></d=
iv><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187=
,187);border-style:solid;border-width:1px"><code><div><span style=3D"color:=
#008">struct</span><span style=3D"color:#000"> c_string_sentinel </span><sp=
an style=3D"color:#660">{};</span><span style=3D"color:#000"><br>strong_equ=
ality </span><span style=3D"color:#008">operator</span><span style=3D"color=
:#660"><=3D>(</span><span style=3D"color:#008">const</span><span styl=
e=3D"color:#000"> </span><span style=3D"color:#008">char</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">*</span><span style=3D"c=
olor:#000">lhs</span><span style=3D"color:#660">,</span><span style=3D"colo=
r:#000"> c_string_sentinel</span><span style=3D"color:#660">)</span><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=
=3D"color:#008">return</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">*</span><span style=3D"color:#000">lhs </span><span style=
=3D"color:#660"><=3D></span><span style=3D"color:#000"> </span><span =
style=3D"color:#080">'\0'</span><span style=3D"color:#660">;}</span=
><span style=3D"color:#000"><br></span></div></code></div><div><br></div><b=
r></div></blockquote></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/315b0317-4f24-491c-9bad-56a2b32b6f54%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/315b0317-4f24-491c-9bad-56a2b32b6f54=
%40isocpp.org</a>.<br />
------=_Part_20507_1913625850.1527609008886--
------=_Part_20506_1470449671.1527609008885--
.
Author: Andrey Semashev <andrey.semashev@gmail.com>
Date: Tue, 29 May 2018 18:58:38 +0300
Raw View
On 05/29/18 18:50, 'Vlad from Moscow' via ISO C++ Standard - Future
Proposals wrote:
> The operators can be defined like
>
> |
> friendbooloperator==(constc_string_iterator &lhs,constc_string_iterator
> &rhs )
> {
> return(lhs.s ==rhs.s )||(notlhs.s &¬*rhs.s )||(not*lhs.s &¬rhs.s );
> }
>
>
> friendbooloperator==(constc_string_iterator &lhs,constc_string_iterator
> &rhs )
> {
> returnnot(lhs ==rhs );
> }
>
> |
I think it's much more efficient to use string_view or regular pointers
or iterators.
Sentinel iterators are useful where the end iterator cannot be
reasonably obtained. This is not the 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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/17f80a15-5dad-f123-8f8c-230e2ce23b4a%40gmail.com.
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 29 May 2018 10:02:41 -0700 (PDT)
Raw View
------=_Part_39546_1367696994.1527613361738
Content-Type: multipart/alternative;
boundary="----=_Part_39547_1224105650.1527613361738"
------=_Part_39547_1224105650.1527613361738
Content-Type: text/plain; charset="UTF-8"
On Tuesday, May 29, 2018 at 11:58:42 AM UTC-4, Andrey Semashev wrote:
>
> On 05/29/18 18:50, 'Vlad from Moscow' via ISO C++ Standard - Future
> Proposals wrote:
> > The operators can be defined like
> >
> > |
> > friendbooloperator==(constc_string_iterator &lhs,constc_string_iterator
> > &rhs )
> > {
> > return(lhs.s ==rhs.s )||(notlhs.s &¬*rhs.s )||(not*lhs.s &¬rhs.s
> );
> > }
> >
> >
> > friendbooloperator==(constc_string_iterator &lhs,constc_string_iterator
> > &rhs )
> > {
> > returnnot(lhs ==rhs );
> > }
> >
> > |
>
> I think it's much more efficient to use string_view or regular pointers
> or iterators.
>
> Sentinel iterators are useful where the end iterator cannot be
> reasonably obtained. This is not the case.
>
I don't see how looping to find the `\0` character, for the sole purpose of
redoing that loop, can be considered "reasonable". Sure, if you already
have a `string_view` or pointer-pair or iterators or some other range,
that's fine. But if all you have is a `char*` and an expectation that
there's a null-character at the end? The idea of a null-termination
sentinel is not unreasonable.
It just has to be done the right way.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/a5abcb6c-6c36-416c-90d6-01a827e807f1%40isocpp.org.
------=_Part_39547_1224105650.1527613361738
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, May 29, 2018 at 11:58:42 AM UTC-4, Andrey Sema=
shev wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 05/29/18 18:50, =
'Vlad from Moscow' via ISO C++ Standard - Future=20
<br>Proposals wrote:
<br>> The operators can be defined like
<br>>=20
<br>> |
<br>> friendbooloperator=3D=3D(constc_<wbr>string_iterator &lhs,cons=
tc_string_iterator=20
<br>> &rhs )
<br>> {
<br>> return(lhs.s =3D=3Drhs.s )||(notlhs.s &&not*rhs.s )||(not*=
lhs.s &&notrhs.s );
<br>> }
<br>>=20
<br>>=20
<br>> friendbooloperator=3D=3D(constc_<wbr>string_iterator &lhs,cons=
tc_string_iterator=20
<br>> &rhs )
<br>> {
<br>> returnnot(lhs =3D=3Drhs );
<br>> }
<br>>=20
<br>> |
<br>
<br>I think it's much more efficient to use string_view or regular poin=
ters=20
<br>or iterators.
<br>
<br>Sentinel iterators are useful where the end iterator cannot be=20
<br>reasonably obtained. This is not the case.
<br></blockquote><div><br></div><div>I don't see how looping to find th=
e `\0` character, for the sole purpose of redoing that loop, can be conside=
red "reasonable". Sure, if you already have a `string_view` or po=
inter-pair or iterators or some other range, that's fine. But if all yo=
u have is a `char*` and an expectation that there's a null-character at=
the end? The idea of a null-termination sentinel is not unreasonable.</div=
><div><br></div><div>It just has to be done the right way.<br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/a5abcb6c-6c36-416c-90d6-01a827e807f1%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/a5abcb6c-6c36-416c-90d6-01a827e807f1=
%40isocpp.org</a>.<br />
------=_Part_39547_1224105650.1527613361738--
------=_Part_39546_1367696994.1527613361738--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 29 May 2018 10:11:17 -0700 (PDT)
Raw View
------=_Part_39226_1626715879.1527613877588
Content-Type: multipart/alternative;
boundary="----=_Part_39227_688873008.1527613877589"
------=_Part_39227_688873008.1527613877589
Content-Type: text/plain; charset="UTF-8"
On Tuesday, May 29, 2018 at 11:50:09 AM UTC-4, Vlad from Moscow wrote:
>
> The operators can be defined like
>
> friend bool operator ==( const c_string_iterator &lhs, const
> c_string_iterator &rhs )
> {
> return ( lhs.s == rhs.s ) || ( not lhs.s && not *rhs.s ) || ( not *lhs
> .s && not rhs.s );
> }
>
>
> friend bool operator ==( const c_string_iterator &lhs, const
> c_string_iterator &rhs )
> {
> return not ( lhs == rhs );
> }
>
>
>
That doesn't change the fact that you're doing multiple comparisons when
you only need to do *one*. This is *why* Ranges TS invented the concept of
a Sentinel type to begin with. This is why range-based `for` was extended
to allow the begin and end iterator types to be different.
Why are you so against the direction C++ is moving in?
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/4afcc376-213c-4779-b3ed-70e9f68ee2be%40isocpp.org.
------=_Part_39227_688873008.1527613877589
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, May 29, 2018 at 11:50:09 AM UTC-4, Vla=
d from Moscow 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">The operators can be defined like<div><br></div><div style=3D"back=
ground-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:so=
lid;border-width:1px;word-wrap:break-word"><code><div><span style=3D"color:=
#008">friend</span><span style=3D"color:#000"> </span><span style=3D"color:=
#008">bool</span><span style=3D"color:#000"> </span><span style=3D"color:#0=
08">operator</span><span style=3D"color:#000"> </span><span style=3D"color:=
#660">=3D=3D(</span><span style=3D"color:#000"> </span><span style=3D"color=
:#008">const</span><span style=3D"color:#000"> c_string_iterator </span><sp=
an style=3D"color:#660">&</span><span style=3D"color:#000">lhs</span><s=
pan style=3D"color:#660">,</span><span style=3D"color:#000"> </span><span s=
tyle=3D"color:#008">const</span><span style=3D"color:#000"> c_string_iterat=
or </span><span style=3D"color:#660">&</span><span style=3D"color:#000"=
>rhs </span><span style=3D"color:#660">)</span><span style=3D"color:#000"><=
br></span><span style=3D"color:#660">{</span><span style=3D"color:#000"><br=
>=C2=A0 =C2=A0 </span><span style=3D"color:#008">return</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">(</span><span style=3D"c=
olor:#000"> lhs</span><span style=3D"color:#660">.</span><span style=3D"col=
or:#000">s </span><span style=3D"color:#660">=3D=3D</span><span style=3D"co=
lor:#000"> rhs</span><span style=3D"color:#660">.</span><span style=3D"colo=
r:#000">s </span><span style=3D"color:#660">)</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#660">||</span><span style=3D"color:#000">=
</span><span style=3D"color:#660">(</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#008">not</span><span style=3D"color:#000"> lhs</sp=
an><span style=3D"color:#660">.</span><span style=3D"color:#000">s </span><=
span style=3D"color:#660">&&</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#008">not</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#660">*</span><span style=3D"color:#000">rhs</span><sp=
an style=3D"color:#660">.</span><span style=3D"color:#000">s </span><span s=
tyle=3D"color:#660">)</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">||</span><span style=3D"color:#000"> </span><span style=3D"=
color:#660">(</span><span style=3D"color:#000"> </span><span style=3D"color=
:#008">not</span><span style=3D"color:#000"> </span><span style=3D"color:#6=
60">*</span><span style=3D"color:#000">lhs</span><span style=3D"color:#660"=
>.</span><span style=3D"color:#000">s </span><span style=3D"color:#660">&am=
p;&</span><span style=3D"color:#000"> </span><span style=3D"color:#008"=
>not</span><span style=3D"color:#000"> rhs</span><span style=3D"color:#660"=
>.</span><span style=3D"color:#000">s </span><span style=3D"color:#660">);<=
/span><span style=3D"color:#000"><br></span><span style=3D"color:#660">}</s=
pan><span style=3D"color:#000"><br><br><br></span><span style=3D"color:#008=
">friend</span><span style=3D"color:#000"> </span><span style=3D"color:#008=
">bool</span><span style=3D"color:#000"> </span><span style=3D"color:#008">=
operator</span><span style=3D"color:#000"> </span><span style=3D"color:#660=
">=3D=3D(</span><span style=3D"color:#000"> </span><span style=3D"color:#00=
8">const</span><span style=3D"color:#000"> c_string_iterator </span><span s=
tyle=3D"color:#660">&</span><span style=3D"color:#000">lhs</span><span =
style=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=
=3D"color:#008">const</span><span style=3D"color:#000"> c_string_iterator <=
/span><span style=3D"color:#660">&</span><span style=3D"color:#000">rhs=
</span><span style=3D"color:#660">)</span><span style=3D"color:#000"><br><=
/span><span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=
=A0 =C2=A0 </span><span style=3D"color:#008">return</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#008">not</span><span style=3D"color=
:#000"> </span><span style=3D"color:#660">(</span><span style=3D"color:#000=
"> lhs </span><span style=3D"color:#660">=3D=3D</span><span style=3D"color:=
#000"> rhs </span><span style=3D"color:#660">);</span><span style=3D"color:=
#000"><br></span><span style=3D"color:#660">}</span><span style=3D"color:#0=
00"><br><br></span></div></code></div><div><br></div></div></blockquote><di=
v><br></div><div>That doesn't change the fact that you're doing mul=
tiple comparisons when you only need to do <i>one</i>. This is <i>why</i> R=
anges TS invented the concept of a Sentinel type to begin with. This is why=
range-based `for` was extended to allow the begin and end iterator types t=
o be different.</div><div><br></div><div>Why are you so against the directi=
on C++ is moving in?<br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/4afcc376-213c-4779-b3ed-70e9f68ee2be%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/4afcc376-213c-4779-b3ed-70e9f68ee2be=
%40isocpp.org</a>.<br />
------=_Part_39227_688873008.1527613877589--
------=_Part_39226_1626715879.1527613877588--
.
Author: Andrey Semashev <andrey.semashev@gmail.com>
Date: Tue, 29 May 2018 20:59:26 +0300
Raw View
On 05/29/18 20:02, Nicol Bolas wrote:
> On Tuesday, May 29, 2018 at 11:58:42 AM UTC-4, Andrey Semashev wrote:
>
> On 05/29/18 18:50, 'Vlad from Moscow' via ISO C++ Standard - Future
> Proposals wrote:
> > The operators can be defined like
> >
> > |
> > friendbooloperator==(constc_string_iterator
> &lhs,constc_string_iterator
> > &rhs )
> > {
> > return(lhs.s ==rhs.s )||(notlhs.s &¬*rhs.s )||(not*lhs.s
> &¬rhs.s );
> > }
> >
> >
> > friendbooloperator==(constc_string_iterator
> &lhs,constc_string_iterator
> > &rhs )
> > {
> > returnnot(lhs ==rhs );
> > }
> >
> > |
>
> I think it's much more efficient to use string_view or regular pointers
> or iterators.
>
> Sentinel iterators are useful where the end iterator cannot be
> reasonably obtained. This is not the case.
>
> I don't see how looping to find the `\0` character, for the sole purpose
> of redoing that loop, can be considered "reasonable". Sure, if you
> already have a `string_view` or pointer-pair or iterators or some other
> range, that's fine. But if all you have is a `char*` and an expectation
> that there's a null-character at the end? The idea of a null-termination
> sentinel is not unreasonable.
Adding a sentinel iterator for C strings means encouraging its use for
processing C strings, and I don't think this is a good idea. If you have
to process C strings then you might as well use C routines for doing
this or loop over the characters manually. If you want to consume this
string in C++ then chances are high that you'll need the size anyway, so
why not just obtain it by constructing a string_view.
As to whether that would be slower than trying to find the end of the
string during processing, it depends on how much processing you want to
do. It might be faster to do a simple strlen first, effectively fetching
the string to the CPU cache and then do the processing without having to
do extensive comparisons in the processing loop, like in the operators
above. The compiler might even be able to vectorize the code, which it
usually doesn't on complex loop exit conditions.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/fc8142de-e69a-bcc6-7b40-0afee4a4e447%40gmail.com.
.
Author: =?utf-8?Q?Dietmar_K=C3=BChl?= <dietmar.kuehl@gmail.com>
Date: Tue, 29 May 2018 18:59:55 +0100
Raw View
--Apple-Mail-8E842F2B-495C-4354-BC54-44F55F4851E5
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
The key observation when using ranges with an end whose whereabouts are unk=
nown is that the end can=E2=80=99t be used as an iterator. Instead it shoul=
d be a sentinel and have a different type. Conveniently, the C++ standard i=
s moving into that direction: range-based for was fixed for C++ 17 to allow=
different types for begin(r) and end(r). The expectation is that with or f=
ollowing the Ranges work algorithms will receive a similar treatment.
You don=E2=80=99t need special iterators in that case, you just use a speci=
al end: comparing an iterator to an end which says true when the iterators =
value is 0 and false otherwise sorts the C string issue out.
For more details see Eric Niebler=E2=80=99s sequence of posts on this topic=
: http://ericniebler.com/2014/02/16/delimited-ranges/
> On 29 May 2018, at 16:31, 'Vlad from Moscow' via ISO C++ Standard - Futur=
e Proposals <std-proposals@isocpp.org> wrote:
>=20
> use
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/4EAEC0C2-4D00-4A14-8DEF-0D0C0EF647E5%40gmail.com=
..
--Apple-Mail-8E842F2B-495C-4354-BC54-44F55F4851E5
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<html><head><meta http-equiv=3D"content-type" content=3D"text/html; charset=
=3Dutf-8"></head><body dir=3D"auto"><div></div><div><span style=3D"backgrou=
nd-color: rgba(255, 255, 255, 0);">The key observation when using ranges wi=
th an end whose whereabouts are unknown is that the end can=E2=80=99t be us=
ed as an iterator. Instead it should be a sentinel and have a different typ=
e. Conveniently, the C++ standard is moving into that direction: range-base=
d for was fixed for C++ 17 to allow different types for begin(r) and end(r)=
.. The expectation is that with or following the Ranges work algorithms will=
receive a similar treatment.</span></div><div><span style=3D"background-co=
lor: rgba(255, 255, 255, 0);"><br></span></div><div><span style=3D"backgrou=
nd-color: rgba(255, 255, 255, 0);">You don=E2=80=99t need special iterators=
in that case, you just use a special end: comparing an iterator to an end =
which says true when the iterators value is 0 and false otherwise sorts the=
C string issue out.</span></div><div><span style=3D"background-color: rgba=
(255, 255, 255, 0);"><br></span></div><div><span style=3D"background-color:=
rgba(255, 255, 255, 0);">For more details see Eric Niebler=E2=80=99s seque=
nce of posts on this topic: </span><a href=3D"http://ericniebler.com/2=
014/02/16/delimited-ranges/">http://ericniebler.com/2014/02/16/delimited-ra=
nges/</a></div><div><br></div><div><br></div><div><br>On 29 May 2018, at 16=
:31, 'Vlad from Moscow' via ISO C++ Standard - Future Proposals <<a href=
=3D"mailto:std-proposals@isocpp.org">std-proposals@isocpp.org</a>> wrote=
:<br><br></div><blockquote type=3D"cite"><div>use</div></blockquote></body>=
</html>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/4EAEC0C2-4D00-4A14-8DEF-0D0C0EF647E5%=
40gmail.com?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/4EAEC0C2-4D00-4A14-8DEF-0D0C0EF647E5%=
40gmail.com</a>.<br />
--Apple-Mail-8E842F2B-495C-4354-BC54-44F55F4851E5--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 29 May 2018 12:36:25 -0700 (PDT)
Raw View
------=_Part_39768_62748459.1527622585390
Content-Type: multipart/alternative;
boundary="----=_Part_39769_1843782182.1527622585390"
------=_Part_39769_1843782182.1527622585390
Content-Type: text/plain; charset="UTF-8"
On Tuesday, May 29, 2018 at 1:59:30 PM UTC-4, Andrey Semashev wrote:
>
> On 05/29/18 20:02, Nicol Bolas wrote:
> > On Tuesday, May 29, 2018 at 11:58:42 AM UTC-4, Andrey Semashev wrote:
> >
> > On 05/29/18 18:50, 'Vlad from Moscow' via ISO C++ Standard - Future
> > Proposals wrote:
> > > The operators can be defined like
> > >
> > > |
> > > friendbooloperator==(constc_string_iterator
> > &lhs,constc_string_iterator
> > > &rhs )
> > > {
> > > return(lhs.s ==rhs.s )||(notlhs.s &¬*rhs.s )||(not*lhs.s
> > &¬rhs.s );
> > > }
> > >
> > >
> > > friendbooloperator==(constc_string_iterator
> > &lhs,constc_string_iterator
> > > &rhs )
> > > {
> > > returnnot(lhs ==rhs );
> > > }
> > >
> > > |
> >
> > I think it's much more efficient to use string_view or regular
> pointers
> > or iterators.
> >
> > Sentinel iterators are useful where the end iterator cannot be
> > reasonably obtained. This is not the case.
> >
> > I don't see how looping to find the `\0` character, for the sole purpose
> > of redoing that loop, can be considered "reasonable". Sure, if you
> > already have a `string_view` or pointer-pair or iterators or some other
> > range, that's fine. But if all you have is a `char*` and an expectation
> > that there's a null-character at the end? The idea of a null-termination
> > sentinel is not unreasonable.
>
> Adding a sentinel iterator for C strings means encouraging its use for
> processing C strings, and I don't think this is a good idea.
Whether you think it is a good idea or not, people still have to do it. And
to pretend that they don't or deciding that such people don't matter isn't
helping anyone.
If you have
> to process C strings then you might as well use C routines for doing
> this or loop over the characters manually.
No, it isn't. If you got some C string from a C API in a C++ program, the
best thing we can do is encourage you to process that data in a C++ way. To
touch C and then leave it for the safety of C++ ASAP, but in the most
efficient way possible.
To do otherwise is basically telling people that C is a foreign language
and we will not support interacting with it. This would create a rift
between people who can work in "pure" C++ and people who have to talk to C
on occassion. Or frequently. We shouldn't separate our developers in such a
way needlessly; that's why the iterator model works just fine with
pointers, a common C-ism.
> If you want to consume this
> string in C++ then chances are high that you'll need the size anyway, so
> why not just obtain it by constructing a string_view.
>
> As to whether that would be slower than trying to find the end of the
> string during processing, it depends on how much processing you want to
> do. It might be faster to do a simple strlen first, effectively fetching
> the string to the CPU cache and then do the processing without having to
> do extensive comparisons in the processing loop, like in the operators
> above. The compiler might even be able to vectorize the code, which it
> usually doesn't on complex loop exit conditions.
>
`*p == '\0'` is not a "complex loop exit condition". There are millions of
programs out there that perform such exit conditions on a regular basis.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/1da84368-7c1a-438c-ae44-ee964b3ce15d%40isocpp.org.
------=_Part_39769_1843782182.1527622585390
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, May 29, 2018 at 1:59:30 PM UTC-4, Andr=
ey Semashev wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 05/29/18 =
20:02, Nicol Bolas wrote:
<br>> On Tuesday, May 29, 2018 at 11:58:42 AM UTC-4, Andrey Semashev wro=
te:
<br>>=20
<br>> =C2=A0 =C2=A0 On 05/29/18 18:50, 'Vlad from Moscow' via IS=
O C++ Standard - Future
<br>> =C2=A0 =C2=A0 Proposals wrote:
<br>> =C2=A0 =C2=A0 =C2=A0> The operators can be defined like
<br>> =C2=A0 =C2=A0 =C2=A0>
<br>> =C2=A0 =C2=A0 =C2=A0> |
<br>> =C2=A0 =C2=A0 =C2=A0> friendbooloperator=3D=3D(constc_<wbr>stri=
ng_iterator
<br>> =C2=A0 =C2=A0 &lhs,constc_string_iterator
<br>> =C2=A0 =C2=A0 =C2=A0> &rhs )
<br>> =C2=A0 =C2=A0 =C2=A0> {
<br>> =C2=A0 =C2=A0 =C2=A0> return(lhs.s =3D=3Drhs.s )||(notlhs.s &am=
p;&not*rhs.s )||(not*lhs.s
<br>> =C2=A0 =C2=A0 &&notrhs.s );
<br>> =C2=A0 =C2=A0 =C2=A0> }
<br>> =C2=A0 =C2=A0 =C2=A0>
<br>> =C2=A0 =C2=A0 =C2=A0>
<br>> =C2=A0 =C2=A0 =C2=A0> friendbooloperator=3D=3D(constc_<wbr>stri=
ng_iterator
<br>> =C2=A0 =C2=A0 &lhs,constc_string_iterator
<br>> =C2=A0 =C2=A0 =C2=A0> &rhs )
<br>> =C2=A0 =C2=A0 =C2=A0> {
<br>> =C2=A0 =C2=A0 =C2=A0> returnnot(lhs =3D=3Drhs );
<br>> =C2=A0 =C2=A0 =C2=A0> }
<br>> =C2=A0 =C2=A0 =C2=A0>
<br>> =C2=A0 =C2=A0 =C2=A0> |
<br>>=20
<br>> =C2=A0 =C2=A0 I think it's much more efficient to use string_v=
iew or regular pointers
<br>> =C2=A0 =C2=A0 or iterators.
<br>>=20
<br>> =C2=A0 =C2=A0 Sentinel iterators are useful where the end iterator=
cannot be
<br>> =C2=A0 =C2=A0 reasonably obtained. This is not the case.
<br>>=20
<br>> I don't see how looping to find the `\0` character, for the so=
le purpose=20
<br>> of redoing that loop, can be considered "reasonable". Su=
re, if you=20
<br>> already have a `string_view` or pointer-pair or iterators or some =
other=20
<br>> range, that's fine. But if all you have is a `char*` and an ex=
pectation=20
<br>> that there's a null-character at the end? The idea of a null-t=
ermination=20
<br>> sentinel is not unreasonable.
<br>
<br>Adding a sentinel iterator for C strings means encouraging its use for=
=20
<br>processing C strings, and I don't think this is a good idea.</block=
quote><div><br></div><div>Whether you think it is a good idea or not, peopl=
e still have to do it. And to pretend that they don't or deciding that =
such people don't matter isn't helping anyone.</div><div><br></div>=
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;">If you have=20
<br>to process C strings then you might as well use C routines for doing=20
<br>this or loop over the characters manually.</blockquote><div><br></div><=
div>No, it isn't. If you got some C string from a C API in a C++ progra=
m, the best thing we can do is encourage you to process that data in a C++ =
way. To touch C and then leave it for the safety of C++ ASAP, but in the mo=
st efficient way possible.<br></div><div><br></div><div>To do otherwise is =
basically telling people that C is a foreign language and we will not suppo=
rt interacting with it. This would create a rift between people who can wor=
k in "pure" C++ and people who have to talk to C on occassion. Or=
frequently. We shouldn't separate our developers in such a way needles=
sly; that's why the iterator model works just fine with pointers, a com=
mon C-ism.<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" styl=
e=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left:=
1ex;">If you want to consume this=20
<br>string in C++ then chances are high that you'll need the size anywa=
y, so=20
<br>why not just obtain it by constructing a string_view.
<br>
<br>As to whether that would be slower than trying to find the end of the=
=20
<br>string during processing, it depends on how much processing you want to=
=20
<br>do. It might be faster to do a simple strlen first, effectively fetchin=
g=20
<br>the string to the CPU cache and then do the processing without having t=
o=20
<br>do extensive comparisons in the processing loop, like in the operators=
=20
<br>above. The compiler might even be able to vectorize the code, which it=
=20
<br>usually doesn't on complex loop exit conditions.
<br></blockquote><div><br></div><div>`*p =3D=3D '\0'` is not a &quo=
t;complex loop exit condition". There are millions of programs out the=
re that perform such exit conditions on a regular basis.</div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/1da84368-7c1a-438c-ae44-ee964b3ce15d%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/1da84368-7c1a-438c-ae44-ee964b3ce15d=
%40isocpp.org</a>.<br />
------=_Part_39769_1843782182.1527622585390--
------=_Part_39768_62748459.1527622585390--
.