With the exception of this introduction, all non-proposed wording will have a
background color and formatting that

looks like this, so that motivation and description is more easily distinguished
from proposed wording.

In the proposed wording below, text to be inserted is formatted like
this, while wording to be deleted is formatted like this.

The proposed wording in this paper:

Makes streams move constructible, move assignable and swappable.

Makes use of rvalue streams practical.

To facilitate this functionality low level protected functionality is added to
basic_ios, and the basic_streambuf class is given protected
copy and swap semantics. The addition of these members makes it possible for clients to
create standard containers of streams while retaining stream integrity. For example:

The above example creates a vector<ofstream> where each element
refers to a file named by names[i] and imbued by a locale by the
same name (just to keep the example brief). The container of ofstream
can be efficiently returned by value from a factory function, but can't be truly
copied. That is, there is no way to accidently get into a situation where two
streams will refer to the same file. A utility to
output the same double to each file, but formatted for each locale is easily
written just to show a motivating use case for sequences of streams.

Additionally, with movable streams one can manipulate the stream sequence with
standard algorithms, perhaps checking for streams that are bad and getting rid
of them (just as an example):

This kind of functionality is achievable today with vector<shared_ptr<ofstream> >. However this rewrite is less readable, more expensive, and not as safe as it allows
the possibility that two containers might refer to the same set of files.

The above code is a silent run time error if file_container is a
vector<shared_ptr<ofstream> >, but a compile time error
if it is a vector<ofstream>. The error is a missing &.

void erase_bad_files(file_container& files) {...}

Otherwise a copy of the container is modified (and vector<ofstream>
can not be copied).

In addition to making the streams movable, this paper proposes wording that allows clients
to use the istream extractors and the ostream inserters for characters and
character arrays with rvalue streams:

27.4.4.2 - Member functions

-20- Effects: The state which rhs which had at the
beginning of the call is transferred to *this, except for
rdbuf().

-21- Postconditions:

*this now has the state rhs had, except

rdbuf() == 0.

rhs.rdbuf() is unchanged.

rhs.tie() == 0.

The state of rhs is otherwise undefined but valid.

void swap(basic_ios&& rhs);

-22- Effects: Except for rdbuf(), the states of *this
and rhs are exchanged.

-23- Throws: Nothing.

void set_rdbuf(basic_streambuf<charT, traits>* sb);

-24- Effects: Associates the streambuf sb with this
stream without calling clear().

-25- Postconditions:rdbuf() == sb.

-26- Throws: Nothing.

27.5.2 - Class template basic_streambuf<charT,traits>

The proposed wording in this section gives basic_streambuf protected
copy semantics, and a protected member swap. These new members aid derived
classes in implementing a move constructor, move assignment operator and member
swap. This impacts
lwg
issue 421
which concerns whether or not basic_streambuf has copy semantics. The
proposed wording herein compromises with protected copy semantics (as opposed to
public) which is just enough functionality to aid derived classes.

27.6.1.1 - Class template basic_istream

The proposed wording in this section gives basic_istream a move
constructor, move assignment operator, member swap, and namespace scope swap
functions. The namespace scope extractors taking characters and character
strings are modified to work with rvalue basic_istreams.

27.6.1.1.1 - basic_istream constructors

basic_istream(basic_istream&& rhs);

-3- Effects: Move constructs from the rvalue rhs. This
is accomplished by default constructing the base class, copying the
gcount() from rhs, calling basic_ios<charT,
traits>::move(rhs) to initialize the base class, and setting the
gcount() for rhs to 0.

27.6.1.1.3 - basic_istream member / non-member functions

basic_istream& operator=(basic_istream&& rhs);

-1- Effects:swap(rhs).

-2- Returns:*this.

void swap(basic_istream&& rhs);

-3- Effects: Calls basic_ios<charT,
traits>::swap(rhs). Exchanges the values returned by
gcount() and rhs.gcount().

27.6.2.1 - Class template basic_ostream

The proposed wording in this section gives basic_ostream a move
constructor, move assignment operator, member swap, and namespace scope swap
functions. The namespace scope inserters taking characters and character
strings are modified to work with rvalue basic_ostreams.

27.7 - String-based streams

The four class templates in this section: basic_stringbuf,
basic_istringstream, basic_ostringstream, and
basic_stringstream are given a move constructor, move assignment
operator, and member and non-member swap functions.

27.7.1.1 - basic_stringbuf constructors

basic_stringbuf(basic_stringbuf&& rhs);

-4- Effects: Move constructs from the rvalue rhs. It is
implementation defined whether the sequence pointers in *this
(eback(), gptr(), egptr(), pbase(),
pptr(), epptr()) obtain the values which rhs
had. Whether they do or not, *this and rhs reference
separate buffers (if any at all) after the construction. The openmode, locale
and any other state of rhs is also copied.

-5- Postconditions: Let rhs_p refer to the state of
rhs just prior to this construction and let
rhs_a refer to the state of rhs just after this
construction.

27.7.2.1 - basic_istringstream constructors

basic_istringstream(basic_istringstream&& rhs);

-3- Effects: Move constructs from the rvalue rhs. This
is accomplished by move constructing the base class, and the contained
basic_stringbuf. Next
basic_istream<charT,traits>::set_rdbuf(&sb) is called to
install the contained basic_stringbuf.

27.7.2.2 - Member / non-member functions

basic_istringstream& operator=(basic_istringstream&& rhs);

-4- Effects:swap(rhs).

-5- Returns:*this.

void swap(basic_istringstream&& rhs);

-6- Effects: Exchanges the state of *this and
rhs by calling
basic_istream<charT,traits>::swap(rhs) and
sb.swap(rhs.sb).

27.7.3.1 - basic_ostringstream constructors

basic_ostringstream(basic_ostringstream&& rhs);

-3- Effects: Move constructs from the rvalue rhs. This
is accomplished by move constructing the base class, and the contained
basic_stringbuf. Next
basic_ostream<charT,traits>::set_rdbuf(&sb) is called to
install the contained basic_stringbuf.

27.7.3.2 - Member / non-member functions

basic_ostringstream& operator=(basic_ostringstream&& rhs);

-4- Effects:swap(rhs).

-5- Returns:*this.

void swap(basic_ostringstream&& rhs);

-6- Effects: Exchanges the state of *this and
rhs by calling
basic_ostream<charT,traits>::swap(rhs) and
sb.swap(rhs.sb).

27.7.5 - basic_stringstream constructors

basic_stringstream(basic_stringstream&& rhs);

-3- Effects: Move constructs from the rvalue rhs. This
is accomplished by move constructing the base class, and the contained
basic_stringbuf. Next
basic_istream<charT,traits>::set_rdbuf(&sb) is called to
install the contained basic_stringbuf.

27.7.6 - Member / non-member functions

basic_stringstream& operator=(basic_stringstream&& rhs);

-4- Effects:swap(rhs).

-5- Returns:*this.

void swap(basic_stringstream&& rhs);

-6- Effects: Exchanges the state of *this and
rhs by calling
basic_iostream<charT,traits>::swap(rhs) and
sb.swap(rhs.sb).

27.8.1 - File streams

The four class templates in this section: basic_filebuf,
basic_ifstream, basic_ofstream, and basic_fstream are
given a move constructor, move assignment operator, and member and non-member
swap functions.

27.8.1.2 - basic_filebuf constructors

basic_filebuf(basic_filebuf&& rhs);

-4- Effects: Move constructs from the rvalue rhs. It is
implementation defined whether the sequence pointers in *this
(eback(), gptr(), egptr(), pbase(),
pptr(), epptr()) obtain the values which rhs
had. Whether they do or not, *this and rhs reference
separate buffers (if any at all) after the construction. Additionally
*this references the file which rhs did before the
construction, and rhs references no file after the construction.
The openmode, locale and any other state of rhs is also copied.

-5- Postconditions: Let rhs_p refer to the state of
rhs just prior to this construction and let
rhs_a refer to the state of rhs just after this
construction.

27.8.1.6 - basic_ifstream constructors

basic_ifstream(basic_ifstream&& rhs);

-3- Effects: Move constructs from the rvalue rhs. This
is accomplished by move constructing the base class, and the contained
basic_filebuf. Next
basic_istream<charT,traits>::set_rdbuf(&sb) is called to
install the contained basic_filebuf.

27.8.1.7 - Member / non-member functions

basic_ifstream& operator=(basic_ifstream&& rhs);

-5- Effects:swap(rhs).

-6- Returns:*this.

void swap(basic_ifstream&& rhs);

-7- Effects: Exchanges the state of *this and
rhs by calling
basic_istream<charT,traits>::swap(rhs) and
sb.swap(rhs.sb).

27.8.1.9 - basic_ofstream constructors

basic_ofstream(basic_ofstream&& rhs);

-3- Effects: Move constructs from the rvalue rhs. This
is accomplished by move constructing the base class, and the contained
basic_filebuf. Next
basic_ostream<charT,traits>::set_rdbuf(&sb) is called to
install the contained basic_filebuf.

27.8.1.10 - Member / non-member functions

basic_ofstream& operator=(basic_ofstream&& rhs);

-5- Effects:swap(rhs).

-6- Returns:*this.

void swap(basic_ofstream&& rhs);

-7- Effects: Exchanges the state of *this and
rhs by calling
basic_ostream<charT,traits>::swap(rhs) and
sb.swap(rhs.sb).

27.8.1.12 - basic_fstream constructors

basic_fstream(basic_fstream&& rhs);

-3- Effects: Move constructs from the rvalue rhs. This
is accomplished by move constructing the base class, and the contained
basic_filebuf. Next
basic_istream<charT,traits>::set_rdbuf(&sb) is called to
install the contained basic_filebuf.

27.8.1.13 - Member / non-member functions

basic_fstream& operator=(basic_fstream&& rhs);

-5- Effects:swap(rhs).

-6- Returns:*this.

void swap(basic_fstream&& rhs);

-7- Effects: Exchanges the state of *this and
rhs by calling
basic_iostream<charT,traits>::swap(rhs) and
sb.swap(rhs.sb).