Topic: extend stringstreams


Author: "Diego R." <dieram3@gmail.com>
Date: Tue, 24 Sep 2013 09:26:26 -0700 (PDT)
Raw View
------=_Part_233_19915520.1380039986402
Content-Type: text/plain; charset=ISO-8859-1

Sometimes we have functions like

std::string parse_something(...)
{
  std::istringstream iss;
  //parse something
  return iss.str();
}

and we have to do unnecessary copies and allocations. I propose a member
function *.release()* that move the internal string so no copy nor
allocation is made. I found only one problem, wording should say that
basic_stingbuf always holds a std::basic_string an not another string-like
class. We additionaly could add a move constructor from basic_string:

*basic_stringbuf(std::basic_string<CharT, Traits,Allocator>&& str,
ios_base::openmode = /*default*/);*
*
*
*basic_stringstream(std::basic_string<CharT, Traits,Allocator>&& str,
ios_base::openmode = /*default*/);**
*
*
*
basic_istringstream(...), basic_ostringstream(...)

So we could prepare our string before move it with reserve for example to
avoid reallocations.

Finally I would add a *reset *member function which acts as reset from
unique_ptr.

*In summary:*

let *sstream_key* be basic_stringbuf or basic_stringstream or
basic_ostringstream or basic_istringstream, the following member functions
would be added:

template < class C, class T, class A>
 class *sstream_key*
 {
   /*others member functions
      ....
   more member functions
   */
  *sstream_key*(basic_string<C,T,A>&&, ios_base::open_mode = /*default*/)
noexcept;
*  *
*  basic_string<C,T,A> release() noexcept; *
*  *
*  basic_string<C,T,A> reset(const basic_string<C,T,A>&,
ios_base::open_mode = /*default*/);   *
*  *
*  basic_string<C,T,A> reset(basic_string<C,T,A>&& = "",
ios_base::open_mode = /*default*/) noexcept;*
};

--

---
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_233_19915520.1380039986402
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Sometimes we have functions like<div><br></div><div>std::s=
tring parse_something(...)</div><div>{</div><div>&nbsp; std::istringstream =
iss;</div><div>&nbsp; //parse something</div><div>&nbsp; return iss.str();<=
/div><div>}</div><div><br></div><div>and we have to do unnecessary copies a=
nd allocations. I propose a member function <b>.release()</b> that move the=
 internal string so no copy nor allocation is made. I found only one proble=
m, wording should say that basic_stingbuf always holds a std::basic_string =
an not another string-like class. We additionaly could add a move construct=
or from basic_string:</div><div><br></div><div><b>basic_stringbuf(std::basi=
c_string&lt;CharT, Traits,Allocator&gt;&amp;&amp; str, ios_base::openmode =
=3D /*default*/);</b></div><div><b><br></b></div><div><b>basic_stringstream=
(std::basic_string&lt;CharT, Traits,Allocator&gt;&amp;&amp; str, ios_base::=
openmode =3D /*default*/);</b><b><br></b></div><div><b><br></b></div><div>b=
asic_istringstream(...), basic_ostringstream(...)</div><div><br></div><div>=
<span style=3D"font-size: 13px;">So we could prepare our string before move=
 it with reserve for example to avoid reallocations.</span><br></div><div><=
span style=3D"font-size: 13px;"><br></span></div><div><span style=3D"font-s=
ize: 13px;">Finally I would add a <b>reset </b>member function which acts a=
s reset from unique_ptr.</span></div><div><span style=3D"font-size: 13px;">=
<br></span></div><div><span style=3D"font-size: 13px;"><b>In summary:</b></=
span></div><div><span style=3D"font-size: 13px;"><br></span></div><div><spa=
n style=3D"font-size: 13px;">let <i><b>sstream_key</b></i> be basic_stringb=
uf or basic_stringstream or basic_ostringstream or basic_istringstream, the=
 following member functions would be added:</span></div><div><span style=3D=
"font-size: 13px;"><br></span></div><div><span style=3D"font-size: 13px;">t=
emplate &lt; class C, class T, class A&gt;</span></div><div><span style=3D"=
font-size: 13px;">&nbsp;class&nbsp;</span><i style=3D"font-size: 13px;">sst=
ream_key</i></div><div><span style=3D"font-size: 13px;">&nbsp;{</span></div=
><div><span style=3D"font-size: 13px;">&nbsp; &nbsp;/*others member functio=
ns</span></div><div><span style=3D"font-size: 13px;">&nbsp; &nbsp; &nbsp; .=
....</span></div><div><span style=3D"font-size: 13px;">&nbsp; &nbsp;more mem=
ber functions</span></div><div><span style=3D"font-size: 13px;">&nbsp; &nbs=
p;*/</span></div><div><span style=3D"font-size: 13px;">&nbsp;&nbsp;</span><=
i>sstream_key</i><span style=3D"font-size: 13px;">(basic_string&lt;C,T,A&gt=
;&amp;&amp;, ios_base::open_mode =3D /*default*/) noexcept;</span></div><di=
v><span style=3D"font-size: 13px;"><i>&nbsp;&nbsp;</i></span></div><div><sp=
an style=3D"font-size: 13px;"><i>&nbsp; basic_string&lt;C,T,A&gt; release()=
 noexcept;&nbsp;</i></span></div><div><span style=3D"font-size: 13px;"><i>&=
nbsp;&nbsp;</i></span></div><div><span style=3D"font-size: 13px;"><i>&nbsp;=
 basic_string&lt;C,T,A&gt; reset(const basic_string&lt;C,T,A&gt;&amp;, ios_=
base::open_mode =3D /*default*/); &nbsp;&nbsp;</i></span></div><div><span s=
tyle=3D"font-size: 13px;"><i>&nbsp;&nbsp;</i></span></div><div><span style=
=3D"font-size: 13px;"><i>&nbsp; basic_string&lt;C,T,A&gt; reset(basic_strin=
g&lt;C,T,A&gt;&amp;&amp; =3D "", ios_base::open_mode =3D /*default*/) noexc=
ept;</i></span></div><div>};</div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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_233_19915520.1380039986402--

.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Tue, 24 Sep 2013 11:30:15 -0500
Raw View
--001a11c2c8ea3aa15b04e723a998
Content-Type: text/plain; charset=ISO-8859-1

On 24 September 2013 11:26, Diego R. <dieram3@gmail.com> wrote:

> and we have to do unnecessary copies and allocations. I propose a member
> function *.release()* that move the internal string so no copy nor
> allocation is made.
>

I do not believe that implementations are required to use strings
internally.
--
 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/.

--001a11c2c8ea3aa15b04e723a998
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On 24 September 2013 11:26, Diego R. <span dir=3D"ltr">&lt=
;<a href=3D"mailto:dieram3@gmail.com" target=3D"_blank">dieram3@gmail.com</=
a>&gt;</span> wrote:<br><div class=3D"gmail_extra"><div class=3D"gmail_quot=
e"><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>and we have to do unnecessary copies and allocations.=
 I propose a member function <b>.release()</b> that move the internal strin=
g so no copy nor allocation is made. </div></div></blockquote><div><br></di=
v>

<div>I do not believe that implementations are required to use strings inte=
rnally.</div></div>-- <br>=A0Nevin &quot;:-)&quot; Liber=A0 &lt;mailto:<a h=
ref=3D"mailto:nevin@eviloverlord.com" target=3D"_blank">nevin@eviloverlord.=
com</a>&gt;=A0 (847) 691-1404
</div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />

--001a11c2c8ea3aa15b04e723a998--

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Tue, 24 Sep 2013 19:47:42 +0300
Raw View
--047d7bae47383787c904e723e5bf
Content-Type: text/plain; charset=ISO-8859-1

On 24 September 2013 19:30, Nevin Liber <nevin@eviloverlord.com> wrote:

> On 24 September 2013 11:26, Diego R. <dieram3@gmail.com> wrote:
>
>> and we have to do unnecessary copies and allocations. I propose a member
>> function *.release()* that move the internal string so no copy nor
>> allocation is made.
>>
>
> I do not believe that implementations are required to use strings
> internally.
>

This discussion is a duplicate of
https://groups.google.com/a/isocpp.org/d/msg/std-proposals/0ghCtoZPbdw/o7Jkt-010QkJ

--

---
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/.

--047d7bae47383787c904e723e5bf
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><br><div class=3D"gmail=
_quote">On 24 September 2013 19:30, Nevin Liber <span dir=3D"ltr">&lt;<a hr=
ef=3D"mailto:nevin@eviloverlord.com" target=3D"_blank">nevin@eviloverlord.c=
om</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div cla=
ss=3D"im">On 24 September 2013 11:26, Diego R. <span dir=3D"ltr">&lt;<a hre=
f=3D"mailto:dieram3@gmail.com" target=3D"_blank">dieram3@gmail.com</a>&gt;<=
/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:0px 0px 0px 0.8ex;bord=
er-left:1px solid rgb(204,204,204);padding-left:1ex">

<div dir=3D"ltr"><div>and we have to do unnecessary copies and allocations.=
 I propose a member function <b>.release()</b> that move the internal strin=
g so no copy nor allocation is made. </div></div></blockquote><div><br></di=
v>


</div><div>I do not believe that implementations are required to use string=
s internally.</div></div></div></div></blockquote><div><br></div><div>This =
discussion is a duplicate of<br><a href=3D"https://groups.google.com/a/isoc=
pp.org/d/msg/std-proposals/0ghCtoZPbdw/o7Jkt-010QkJ">https://groups.google.=
com/a/isocpp.org/d/msg/std-proposals/0ghCtoZPbdw/o7Jkt-010QkJ</a><br>
<br></div></div><br></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />

--047d7bae47383787c904e723e5bf--

.


Author: David Krauss <potswa@gmail.com>
Date: Wed, 25 Sep 2013 09:54:59 +0800
Raw View
On 9/25/13 12:26 AM, Diego R. wrote:
> I propose a member
> function *.release()* that move the internal string so no copy nor
> allocation is made.
Wow, I'm surprised this isn't already available as std::move( stringbuf
).str(). It should be an idiomatic ref-qualified accessor.
>   I found only one problem, wording should say that
> basic_stingbuf always holds a std::basic_string an not another string-like
> class.
This would guarantee that the operation is really a move, i.e. O(1). An
implementation would need a crazy reason to do otherwise, but outlawing
crazy reasons isn't necessarily good.
>   We additionaly could add a move constructor from basic_string:
Again, surprised this is still lacking, even given the absence of the
accessor.

Would these overloads be compliant extensions if used to implement the
current standard?
> Finally I would add a *reset *member function which acts as reset from
> unique_ptr.
Huh? This doesn't seem to relate to unique_ptr per se.

Given the summary, it looks like you want to combine the two existing
str() overloads into a new function. And you're missing the existing
str() overload which sets the underlying string.

Probably you should propose a void str( std::string && ) overload to
complement the C++98 by-copy overload. reset sounds like another proposal.

--

---
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: Dietmar Kuehl <dietmar.kuehl@gmail.com>
Date: Wed, 25 Sep 2013 00:45:46 -0500
Raw View
> On 24 Sep 2013, at 20:54, David Krauss <potswa@gmail.com> wrote:
>=20
>> On 9/25/13 12:26 AM, Diego R. wrote:
>> I propose a member
>> function *.release()* that move the internal string so no copy nor
>> allocation is made.
> Wow, I'm surprised this isn't already available as std::move( stringbuf )=
..str(). It should be an idiomatic ref-qualified accessor.

It seems you are under the illusion that `std::basic_stringbuf` internally =
holds a `std::basic_string`: without a backdoor to `std::basic_string` stor=
ing an object of this type would be an odd idea as buffering is crucial for=
 stream buffers but without a backdoor it can't be implemented efficiently.

I wouldn't object to a `release()` method which is specified as as returnin=
g a `std::basic_string` and resetting the buffer to be empty. Likewise, it =
sounds reasonable to allow moving a `std::basic_string` into the stream (I'=
d think an implementation is already allowed to have an overload of `str()`=
 doing so.

>>  I found only one problem, wording should say that
>> basic_stingbuf always holds a std::basic_string an not another string-li=
ke
>> class.
> This would guarantee that the operation is really a move, i.e. O(1). An i=
mplementation would need a crazy reason to do otherwise, but outlawing craz=
y reasons isn't necessarily good.

However, I would object to mandating that `std::basic_stringbuf` does store=
 a `std::basic_string`. It is a possible choice to store the characters but=
 I don't think it is necessarily the best choice. When stateful allocators =
enter the picture nailing the internal representation isn't helping anythin=
g either.

--=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: David Krauss <potswa@gmail.com>
Date: Wed, 25 Sep 2013 13:54:07 +0800
Raw View
On 9/25/13 1:45 PM, Dietmar Kuehl wrote:
>> On 24 Sep 2013, at 20:54, David Krauss <potswa@gmail.com> wrote:
>>
>> Wow, I'm surprised this isn't already available as std::move(=20
>> stringbuf ).str(). It should be an idiomatic ref-qualified accessor.=20
> It seems you are under the illusion that `std::basic_stringbuf` internall=
y holds a `std::basic_string`: without a backdoor to `std::basic_string` st=
oring an object of this type would be an odd idea as buffering is crucial f=
or stream buffers but without a backdoor it can't be implemented efficientl=
y.
The efficiency would be equal to the existing way of doing it. Is that=20
so bad?

Maybe I'm deluding myself to believe that an rvalue-ref overload doesn't=20
need to be O(1). I think libraries should be able to make this choice.=20
Most AFAIK already choose a std::string backing buffer for obvious reasons.

It's not like non-O(1) rvalue accessors would give libraries a free pass=20
to strip performance for no good reason. But failing to provide move=20
semantics, or hiding them under a different name (which would be=20
inaccessible to generic programming), also costs performance.

--=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: Dietmar Kuehl <dietmar.kuehl@gmail.com>
Date: Wed, 25 Sep 2013 01:13:56 -0500
Raw View
> On 25 Sep 2013, at 00:54, David Krauss <potswa@gmail.com> wrote:
>=20
> On 9/25/13 1:45 PM, Dietmar Kuehl wrote:
>>> On 24 Sep 2013, at 20:54, David Krauss <potswa@gmail.com> wrote:
>>>=20
>>> Wow, I'm surprised this isn't already available as std::move( stringbuf=
 ).str(). It should be an idiomatic ref-qualified accessor.=20
>> It seems you are under the illusion that `std::basic_stringbuf` internal=
ly holds a `std::basic_string`: without a backdoor to `std::basic_string` s=
toring an object of this type would be an odd idea as buffering is crucial =
for stream buffers but without a backdoor it can't be implemented efficient=
ly.
> The efficiency would be equal to the existing way of doing it. Is that so=
 bad?

The problem with backing the string buffer with a string is that it require=
s `resize()`ing the string to the buffer size which needs to initialize the=
 excess characters. These may be overwritten or maybe not.

> Maybe I'm deluding myself to believe that an rvalue-ref overload doesn't =
need to be O(1). I think libraries should be able to make this choice.

As I said: allowing the chouce is OK and improving the support for that cho=
ice with a `release()` function is a reasonable idea.

> Most AFAIK already choose a std::string backing buffer for obvious reason=
s.

I don't know about most but libstdc++ and libc++ do make this choice. I don=
't consider that choice to be obvious at all and although I had considered =
it I made a different, in my opinion more reasonable, choice.

> It's not like non-O(1) rvalue accessors would give libraries a free pass =
to strip performance for no good reason. But failing to provide move semant=
ics, or hiding them under a different name (which would be inaccessible to =
generic programming), also costs performance.

I don't see how you would use string streams diffeently if a `str(std::basi=
c_string<...>&&)` were mandated (as I said, it is already allowed to add it=
). I haven't done performance measurements on this since a couple of years,=
 which clearly also do depend on use cases, but I'm not convinced that mand=
ating a string under hood is guaranteed to give the best performance.

--=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/.

.