Topic: Move semantics for string based stringstream operations


Author: Curious <rmn100@gmail.com>
Date: Sun, 5 Mar 2017 17:27:27 -0800 (PST)
Raw View
------=_Part_3420_1079341650.1488763647447
Content-Type: multipart/alternative;
 boundary="----=_Part_3421_1817342096.1488763647447"

------=_Part_3421_1817342096.1488763647447
Content-Type: text/plain; charset=UTF-8

Stringstreams still don't seem to have any planned changes for enabling
moving to and from std::string objects.  Since it seems to be too difficult
and out of the way to change std::basic_stringbuf to work seamlessly (in
particular when it comes to movability) with std::string objects.  I was
thinking that there can be another class that has the same functionality as
a std::stringstream but is based on std::string for its internal storage.
 The type would be named std::sstream, which is in line with the name of
the header that contains the implementation of std::stringstream.  Then deprecate
std::stringstream in favor of that, like was previously done with
std::strstream.  Or leave std::stringstream in the library if relying on
the rdbuf() member function for processing data directly with a stringbuf
is common.

Stringstreams are a useful concept to have but most of the time but their
move and reference limitations makes it feel like users should use other
APIs that do not require expensive copying.  I have even seen people use
std::sscanf() and std::sprintf(), just to avoid memory allocations..

The member functions I was hoping to see were the following

/**
 * str() returns a copy of the string contained in the sstream and
 * remove_str() moves the string into a temporary string which then
 * is treated as a prvalue in the calling expression and will therefore
 * be moveable or elidable
 */
std::basic_string<CharT, Traits, Allocator> str() const;
std::basic_string<CharT, Traits, Allocator> remove_str() noexcept;

/**
 * Move and copy assigning a string into a stringstream
 */
void str(const std::basic_string<CharT, Traits, Allocator>& other);
void str(std::basic_string<CharT, Traits, Allocator>&& other);

If another class which allows moving to/from a stringstream
seems unnecessary, another option is to make std::stringstream accept one
or two more template parameters, one of which is the internal storage type
that will be used to store the characters and another which is a traits
class that encapsulates how the implementation will interact with the
storage object.  And then rdbuf() could just return a pointer to the
internally stored storage object (be it a std::basic_streambuf or a
std::basic_string),  this would be backwards compatible with other uses of
stringstreams since the other two template parameters would default to the
ones used right now.

--
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/9baf4a1e-a355-45e6-9f29-dfff0f17f805%40isocpp.org.

------=_Part_3421_1817342096.1488763647447
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div><font face=3D"arial, sans-serif">Stringstreams still =
don&#39;t seem to have any planned changes for enabling moving to and from =
</font><font face=3D"courier new, monospace">std::string</font><font face=
=3D"arial, sans-serif"> objects. =C2=A0Since it seems to be too difficult a=
nd out of the way to change </font><font face=3D"courier new, monospace">st=
d::basic_stringbuf</font><font face=3D"arial, sans-serif"> to work seamless=
ly (in particular when it comes to=C2=A0movability) with </font><font face=
=3D"courier new, monospace">std::string</font><font face=3D"arial, sans-ser=
if"> objects. =C2=A0I was thinking that there can be another class that has=
 the same functionality as a </font><font face=3D"courier new, monospace">s=
td::stringstream</font><font face=3D"arial, sans-serif"> but is based on </=
font><font face=3D"courier new, monospace">std::string</font><font face=3D"=
arial, sans-serif"> for its internal storage. =C2=A0The type would be named=
 </font><font face=3D"courier new, monospace">std::sstream</font><font face=
=3D"arial, sans-serif">, which is in line with the name of the header that =
contains the implementation of </font><font face=3D"courier new, monospace"=
>std::stringstream</font><font face=3D"arial, sans-serif">. =C2=A0Then</fon=
t><font face=3D"arial, sans-serif">=C2=A0deprecate </font><font face=3D"cou=
rier new, monospace">std::stringstream</font><font face=3D"arial, sans-seri=
f"> in favor of that, like was previously done with </font><font face=3D"co=
urier new, monospace">std::strstream</font><font face=3D"arial, sans-serif"=
>. =C2=A0Or leave </font><font face=3D"courier new, monospace">std::strings=
tream</font><font face=3D"arial, sans-serif"> in the library if relying on =
the </font><font face=3D"courier new, monospace">rdbuf()</font><font face=
=3D"arial, sans-serif"> member function for processing data directly with a=
 </font><font face=3D"courier new, monospace">stringbuf</font><font face=3D=
"arial, sans-serif"> is common.</font></div><div><font face=3D"arial, sans-=
serif"><br></font></div><div><font face=3D"arial, sans-serif">Stringstreams=
 are a useful concept to have but most of the time but their move and refer=
ence limitations makes it feel like users should use other APIs that do not=
 require expensive copying. =C2=A0I have even seen people use </font><font =
face=3D"courier new, monospace">std::sscanf()</font><font face=3D"arial, sa=
ns-serif"> and </font><font face=3D"courier new, monospace">std::sprintf()<=
/font><font face=3D"arial, sans-serif">, just to avoid memory allocations..=
</font><div><font face=3D"arial, sans-serif"><br></font></div><div><font fa=
ce=3D"arial, sans-serif">The member functions I was hoping to see were the =
following</font><br><div><br></div><div><font face=3D"courier new, monospac=
e">/**</font></div><div><font face=3D"courier new, monospace">=C2=A0* str()=
 returns a copy of the string contained in the sstream and=C2=A0</font></di=
v><div><font face=3D"courier new, monospace">=C2=A0* remove_str() moves the=
 string into a temporary string which then=C2=A0</font></div><div><font fac=
e=3D"courier new, monospace">=C2=A0* is treated as a prvalue in the calling=
 expression and will therefore=C2=A0</font></div><div><font face=3D"courier=
 new, monospace">=C2=A0* be moveable or elidable</font></div><div><font fac=
e=3D"courier new, monospace">=C2=A0*/</font></div><div><font face=3D"courie=
r new, monospace">std::basic_string&lt;CharT, Traits, Allocator&gt; str() c=
onst;</font></div><div><font face=3D"courier new, monospace">std::basic_str=
ing&lt;CharT, Traits, Allocator&gt; remove_str() noexcept;</font></div><div=
><font face=3D"courier new, monospace"><br></font></div><div><font face=3D"=
courier new, monospace">/**</font></div><div><font face=3D"courier new, mon=
ospace">=C2=A0* Move and copy assigning a string into a stringstream</font>=
</div><div><font face=3D"courier new, monospace">=C2=A0*/</font></div><div>=
<font face=3D"courier new, monospace">void str(const std::basic_string&lt;C=
harT, Traits, Allocator&gt;&amp; other);</font></div><div><font face=3D"cou=
rier new, monospace">void str(std::basic_string&lt;CharT, Traits, Allocator=
&gt;&amp;&amp; other);</font></div><div><font face=3D"arial, sans-serif"><b=
r></font></div><div><font face=3D"arial, sans-serif">If another class which=
 allows moving to/from a stringstream seems=C2=A0unnecessary, another optio=
n is to make</font><font face=3D"arial, sans-serif">=C2=A0</font><font face=
=3D"courier new, monospace">std::stringstream</font><font face=3D"arial, sa=
ns-serif">=C2=A0accept one or two more template parameters, one of which is=
 the internal storage type that will be used to store the characters and an=
other which is a traits class that encapsulates how the implementation will=
 interact with the storage object. =C2=A0And then rdbuf() could just return=
 a pointer to the internally stored storage object (be it a </font><font fa=
ce=3D"courier new, monospace">std::basic_streambuf</font><font face=3D"aria=
l, sans-serif"> or a </font><font face=3D"courier new, monospace">std::basi=
c_string</font><font face=3D"arial, sans-serif">), =C2=A0this would be back=
wards compatible with other uses of stringstreams since the other two templ=
ate parameters would default to the ones used right now.=C2=A0</font></div>=
</div></div></div>

<p></p>

-- <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 <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/9baf4a1e-a355-45e6-9f29-dfff0f17f805%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/9baf4a1e-a355-45e6-9f29-dfff0f17f805=
%40isocpp.org</a>.<br />

------=_Part_3421_1817342096.1488763647447--

------=_Part_3420_1079341650.1488763647447--

.


Author: =?UTF-8?Q?Daniel_Kr=C3=BCgler?= <daniel.kruegler@gmail.com>
Date: Tue, 7 Mar 2017 21:40:22 +0100
Raw View
2017-03-06 2:27 GMT+01:00 Curious <rmn100@gmail.com>:
> Stringstreams still don't seem to have any planned changes for enabling
> moving to and from std::string objects.  Since it seems to be too difficult
> and out of the way to change std::basic_stringbuf to work seamlessly (in
> particular when it comes to movability) with std::string objects.  I was
> thinking that there can be another class that has the same functionality as
> a std::stringstream but is based on std::string for its internal storage.
> The type would be named std::sstream, which is in line with the name of the
> header that contains the implementation of std::stringstream.  Then
> deprecate std::stringstream in favor of that, like was previously done with
> std::strstream.  Or leave std::stringstream in the library if relying on the
> rdbuf() member function for processing data directly with a stringbuf is
> common.
>
> Stringstreams are a useful concept to have but most of the time but their
> move and reference limitations makes it feel like users should use other
> APIs that do not require expensive copying.  I have even seen people use
> std::sscanf() and std::sprintf(), just to avoid memory allocations..
>
> The member functions I was hoping to see were the following
>
> /**
>  * str() returns a copy of the string contained in the sstream and
>  * remove_str() moves the string into a temporary string which then
>  * is treated as a prvalue in the calling expression and will therefore
>  * be moveable or elidable
>  */
> std::basic_string<CharT, Traits, Allocator> str() const;
> std::basic_string<CharT, Traits, Allocator> remove_str() noexcept;
>
> /**
>  * Move and copy assigning a string into a stringstream
>  */
> void str(const std::basic_string<CharT, Traits, Allocator>& other);
> void str(std::basic_string<CharT, Traits, Allocator>&& other);
>
> If another class which allows moving to/from a stringstream seems
> unnecessary, another option is to make std::stringstream accept one or two
> more template parameters, one of which is the internal storage type that
> will be used to store the characters and another which is a traits class
> that encapsulates how the implementation will interact with the storage
> object.  And then rdbuf() could just return a pointer to the internally
> stored storage object (be it a std::basic_streambuf or a std::basic_string),
> this would be backwards compatible with other uses of stringstreams since
> the other two template parameters would default to the ones used right now.

There is already work in progress in that area. Please read

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0408r1.pdf

and I would expect that it suggests to provide the functionality you
are expecting above (and more).

- 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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAGNvRgAtk2YctA5iMJuAN0DwV4UiejCG5hO1ThWuOWG0P3UeUA%40mail.gmail.com.

.