Rvalue Reference Recommendations for Chapter 20
Rvalue Reference Recommendations for Chapter 21
Rvalue Reference Recommendations for Chapter 23
Rvalue Reference Recommendations for Chapter 24
Rvalue Reference Recommendations for Chapter 25
Rvalue Reference Recommendations for Chapter 26
This paper recommends proposed wording with respect to the rvalue reference for the C++0X working draft. This paper restricts its scope to Chapter 27 "Input/output library" for the purpose of breaking the library work associated with the rvalue reference up into manageable chunks. This paper largely follows the lead of N1771: Impact of the rvalue reference on the Standard Library, but adds more detail as appropriate.
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:
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:
#include <fstream> #include <locale> #include <vector> #include <string> std::vector<std::ofstream> create_files(const std::vector<std::string>& names) { std::vector<std::ofstream> files; for (unsigned i = 0; i < names.size(); ++i) { files.push_back(std::ofstream(names[i].c_str())); files.back().imbue(std::locale(names[i].c_str())); } return files; } void output(std::vector<std::ofstream>& files, double amount) { for (unsigned i = 0; i < files.size(); ++i) files[i] << amount; } int main() { std::vector<std::string> names; names.push_back("english"); names.push_back("french"); // ... std::vector<std::ofstream> files = create_files(names); output(files, 12346.78); }
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):
files.erase( remove_if(files.begin(), files.end(), bind(&ofstream::bad, _1) ), files.end() );
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.
void erase_bad_files(file_container files) {...} ... erase_bad_files(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:
ofstream("log", ios::app) << "message"; // open file, write message, close file
The proposed wording in this section adds three new protected member functions to basic_ios:
void move(basic_ios&& rhs); void swap(basic_ios&& rhs); void set_rdbuf(basic_streambuf<charT, traits>* sb);These aid derived classes in implementing a move constructor, move assignment and member swap.
namespace std { template <class charT, class traits = char_traits<charT> > class basic_ios : public ios_base { public: // Types: typedef charT char_type; typedef typename traits::int_type int_type; typedef typename traits::pos_type pos_type; typedef typename traits::off_type off_type; typedef traits traits_type; operator void*() const bool operator!() const iostate rdstate() const; void clear(iostate state = goodbit); void setstate(iostate state); bool good() const; bool eof() const; bool fail() const; bool bad() const; iostate exceptions() const; void exceptions(iostate except); // lib.basic.ios.cons Constructor/destructor: explicit basic_ios(basic_streambuf<charT,traits>* sb); virtual ~basic_ios(); // lib.basic.ios.members Members: basic_ostream<charT,traits>* tie() const; basic_ostream<charT,traits>* tie(basic_ostream<charT,traits>* tiestr); basic_streambuf<charT,traits>* rdbuf() const; basic_streambuf<charT,traits>* rdbuf(basic_streambuf<charT,traits>* sb); basic_ios& copyfmt(const basic_ios& rhs); char_type fill() const; char_type fill(char_type ch); // lib.ios.base.locales locales: locale imbue(const locale& loc); char narrow(char_type c, char dfault) const; char_type widen(char c) const; protected: basic_ios(); void init(basic_streambuf<charT,traits>* sb); void move(basic_ios&& rhs); void swap(basic_ios&& rhs); void set_rdbuf(basic_streambuf<charT, traits>* sb); private: basic_ios(const basic_ios& ); // not defined basic_ios& operator=(const basic_ios&); // not defined }; }
void move(basic_ios&& rhs);
-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.
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.
namespace std { template <class charT, class traits = char_traits<charT> > class basic_streambuf { public: // Types: typedef charT char_type; typedef typename traits::int_type int_type; typedef typename traits::pos_type pos_type; typedef typename traits::off_type off_type; typedef traits traits_type; virtual ~basic_streambuf(); // lib.streambuf.locales locales: locale pubimbue(const locale &loc); locale getloc() const; // lib.streambuf.buffer buffer and positioning: basic_streambuf<char_type,traits>* pubsetbuf(char_type* s, streamsize n); pos_type pubseekoff(off_type off, ios_base::seekdir way, ios_base::openmode which = ios_base::in | ios_base::out); pos_type pubseekpos(pos_type sp, ios_base::openmode which = ios_base::in | ios_base::out); int pubsync(); // Get and put areas: // lib.streambuf.pub.get Get area: streamsize in_avail(); int_type snextc(); int_type sbumpc(); int_type sgetc(); streamsize sgetn(char_type* s, streamsize n); // lib.streambuf.pub.pback Putback: int_type sputbackc(char_type c); int_type sungetc(); // lib.streambuf.pub.put Put area: int_type sputc(char_type c); streamsize sputn(const char_type* s, streamsize n); protected: basic_streambuf(); basic_streambuf(const basic_streambuf& rhs); basic_streambuf& operator=(const basic_streambuf& rhs); void swap(basic_streambuf&& rhs); // lib.streambuf.get.area Get area: char_type* eback() const; char_type* gptr() const; char_type* egptr() const; void gbump(int n); void setg(char_type* gbeg, char_type* gnext, char_type* gend); // lib.streambuf.put.area Put area: char_type* pbase() const; char_type* pptr() const; char_type* epptr() const; void pbump(int n); void setp(char_type* pbeg, char_type* pend); // lib.streambuf.virtuals virtual functions: // lib.streambuf.virt.locales Locales: virtual void imbue(const locale &loc); // lib.streambuf.virt.buffer Buffer management and positioning: virtual basic_streambuf<char_type,traits>* setbuf(char_type* s, streamsize n); virtual pos_type seekoff(off_type off, ios_base::seekdir way, ios_base::openmode which = ios_base::in | ios_base::out); virtual pos_type seekpos(pos_type sp, ios_base::openmode which = ios_base::in | ios_base::out); virtual int sync(); // lib.streambuf.virt.get Get area: virtual streamsize showmanyc(); virtual streamsize xsgetn(char_type* s, streamsize n); virtual int_type underflow(); virtual int_type uflow(); // lib.streambuf.virt.pback Putback: virtual int_type pbackfail(int_type c = traits::eof()); // lib.streambuf.virt.put Put area: virtual streamsize xsputn(const char_type* s, streamsize n); virtual int_type overflow (int_type c = traits::eof()); }; }
basic_streambuf(const basic_streambuf& rhs);
-3- Effects: Constructs a copy of rhs.
-4- Postconditions:
basic_streambuf& operator=(const basic_streambuf& rhs);
-1- Effects: Assigns the data members of rhs to *this.
-2- Postconditions:
-3- Returns: *this.
void swap(basic_streambuf&& rhs);
-4- Effects: Swaps the data members of rhs and *this.
Header <istream> synopsis
namespace std { template <class charT, class traits = char_traits<charT> > class basic_istream; typedef basic_istream<char> istream; typedef basic_istream<wchar_t> wistream; template <class charT, class traits = char_traits<charT> > class basic_iostream; typedef basic_iostream<char> iostream; typedef basic_iostream<wchar_t> wiostream; template <class charT, class traits> basic_istream<charT,traits>& ws(basic_istream<charT,traits>& is); template <class charT, class traits> void swap(basic_istream<charT, traits>& x, basic_istream<charT, traits>& y); template <class charT, class traits> void swap(basic_istream<charT, traits>&& x, basic_istream<charT, traits>& y); template <class charT, class traits> void swap(basic_istream<charT, traits>& x, basic_istream<charT, traits>&& y); template <class charT, class traits> void swap(basic_iostream<charT, traits>& x, basic_iostream<charT, traits>& y); template <class charT, class traits> void swap(basic_iostream<charT, traits>&& x, basic_iostream<charT, traits>& y); template <class charT, class traits> void swap(basic_iostream<charT, traits>& x, basic_iostream<charT, traits>&& y); }
Header <ostream> synopsis
namespace std { template <class charT, class traits = char_traits<charT> > class basic_ostream; typedef basic_ostream<char> ostream; typedef basic_ostream<wchar_t> wostream; template <class charT, class traits> basic_ostream<charT,traits>& endl(basic_ostream<charT,traits>& os); template <class charT, class traits> basic_ostream<charT,traits>& ends(basic_ostream<charT,traits>& os); template <class charT, class traits> basic_ostream<charT,traits>& flush(basic_ostream<charT,traits>& os); template <class charT, class traits> void swap(basic_ostream<charT, traits>& x, basic_ostream<charT, traits>& y); template <class charT, class traits> void swap(basic_ostream<charT, traits>&& x, basic_ostream<charT, traits>& y); template <class charT, class traits> void swap(basic_ostream<charT, traits>& x, basic_ostream<charT, traits>&& y); }
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.
namespace std { template <class charT, class traits = char_traits<charT> > class basic_istream : virtual public basic_ios<charT,traits> { public: // Types (inherited from basic_ios (lib.ios)): typedef charT char_type; typedef typename traits::int_type int_type; typedef typename traits::pos_type pos_type; typedef typename traits::off_type off_type; typedef traits traits_type; // lib.istream.cons Constructor/destructor: explicit basic_istream(basic_streambuf<charT,traits>* sb); basic_istream(basic_istream&& rhs); virtual ~basic_istream(); basic_istream& operator=(basic_istream&& rhs); void swap(basic_istream&& rhs); // lib.istream::sentry Prefix/suffix: class sentry; // lib.istream.formatted Formatted input: basic_istream<charT,traits>& operator>> (basic_istream<charT,traits>& (*pf)(basic_istream<charT,traits>&)) basic_istream<charT,traits>& operator>> (basic_ios<charT,traits>& (*pf)(basic_ios<charT,traits>&)) basic_istream<charT,traits>& operator>> (ios_base& (*pf)(ios_base&)) basic_istream<charT,traits>& operator>>(bool& n); basic_istream<charT,traits>& operator>>(short& n); basic_istream<charT,traits>& operator>>(unsigned short& n); basic_istream<charT,traits>& operator>>(int& n); basic_istream<charT,traits>& operator>>(unsigned int& n); basic_istream<charT,traits>& operator>>(long& n); basic_istream<charT,traits>& operator>>(unsigned long& n); basic_istream<charT,traits>& operator>>(float& f); basic_istream<charT,traits>& operator>>(double& f); basic_istream<charT,traits>& operator>>(long double& f); basic_istream<charT,traits>& operator>>(void*& p); basic_istream<charT,traits>& operator>> (basic_streambuf<char_type,traits>* sb); // lib.istream.unformatted Unformatted input: streamsize gcount() const; int_type get(); basic_istream<charT,traits>& get(char_type& c); basic_istream<charT,traits>& get(char_type* s, streamsize n); basic_istream<charT,traits>& get(char_type* s, streamsize n, char_type delim); basic_istream<charT,traits>& get(basic_streambuf<char_type,traits>& sb); basic_istream<charT,traits>& get(basic_streambuf<char_type,traits>& sb, char_type delim); basic_istream<charT,traits>& getline(char_type* s, streamsize n); basic_istream<charT,traits>& getline(char_type* s, streamsize n, char_type delim); basic_istream<charT,traits>& ignore (streamsize n = 1, int_type delim = traits::eof()); int_type peek(); basic_istream<charT,traits>& read (char_type* s, streamsize n); streamsize readsome(char_type* s, streamsize n); basic_istream<charT,traits>& putback(char_type c); basic_istream<charT,traits>& unget(); int sync(); pos_type tellg(); basic_istream<charT,traits>& seekg(pos_type); basic_istream<charT,traits>& seekg(off_type, ios_base::seekdir); }; // lib.istream::extractors character extraction templates: template<class charT, class traits> basic_istream<charT,traits>& operator>>(basic_istream<charT,traits>&&, charT&); template<class traits> basic_istream<char,traits>& operator>>(basic_istream<char,traits>&&, unsigned char&); template<class traits> basic_istream<char,traits>& operator>>(basic_istream<char,traits>&&, signed char&); template<class charT, class traits> basic_istream<charT,traits>& operator>>(basic_istream<charT,traits>&&, charT*); template<class traits> basic_istream<char,traits>& operator>>(basic_istream<char,traits>&&, unsigned char*); template<class traits> basic_istream<char,traits>& operator>>(basic_istream<char,traits>&&, signed char*); template <class charT, class traits> void swap(basic_istream<charT, traits>& x, basic_istream<charT, traits>& y); template <class charT, class traits> void swap(basic_istream<charT, traits>&& x, basic_istream<charT, traits>& y); template <class charT, class traits> void swap(basic_istream<charT, traits>& x, basic_istream<charT, traits>&& y); }
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.
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().
template <class charT, class traits> void swap(basic_istream<charT, traits>& x, basic_istream<charT, traits>& y); template <class charT, class traits> void swap(basic_istream<charT, traits>&& x, basic_istream<charT, traits>& y); template <class charT, class traits> void swap(basic_istream<charT, traits>& x, basic_istream<charT, traits>&& y);
-4- Effects: x.swap(y).
template<class charT, class traits> basic_istream<charT,traits>& operator>>(basic_istream<charT,traits>&&, charT&); template<class traits> basic_istream<char,traits>& operator>>(basic_istream<char,traits>&&, unsigned char&); template<class traits> basic_istream<char,traits>& operator>>(basic_istream<char,traits>&&, signed char&); template<class charT, class traits> basic_istream<charT,traits>& operator>>(basic_istream<charT,traits>&&, charT*); template<class traits> basic_istream<char,traits>& operator>>(basic_istream<char,traits>&&, unsigned char*); template<class traits> basic_istream<char,traits>& operator>>(basic_istream<char,traits>&&, signed char*);
The proposed wording in this section gives basic_iostream a move constructor, move assignment operator, member swap, and namespace scope swap functions.
namespace std { template <class charT, class traits = char_traits<charT> > class basic_iostream : public basic_istream<charT,traits>, public basic_ostream<charT,traits> { public: // constructor/destructor explicit basic_iostream(basic_streambuf<charT,traits>* sb); basic_iostream(basic_iostream&& rhs); virtual ~basic_iostream(); basic_iostream& operator=(basic_iostream&& rhs); void swap(basic_iostream&& rhs); }; template <class charT, class traits> void swap(basic_iostream<charT, traits>& x, basic_iostream<charT, traits>& y); template <class charT, class traits> void swap(basic_iostream<charT, traits>&& x, basic_iostream<charT, traits>& y); template <class charT, class traits> void swap(basic_iostream<charT, traits>& x, basic_iostream<charT, traits>&& y); }
basic_iostream(basic_iostream&& rhs);
-3- Effects: Move constructs from the rvalue rhs by constructing the basic_istream base class with move(rhs).
basic_iostream& operator=(basic_iostream&& rhs);
-1- Effects: swap(rhs).
-2- Returns: *this.
void swap(basic_iostream&& rhs);
-3- Effects: Calls basic_istream<charT, traits>::swap(rhs).
template <class charT, class traits> void swap(basic_iostream<charT, traits>& x, basic_iostream<charT, traits>& y); template <class charT, class traits> void swap(basic_iostream<charT, traits>&& x, basic_iostream<charT, traits>& y); template <class charT, class traits> void swap(basic_iostream<charT, traits>& x, basic_iostream<charT, traits>&& y);
-4- Effects: x.swap(y).
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.
namespace std { template <class charT, class traits = char_traits<charT> > class basic_ostream : virtual public basic_ios<charT,traits> { public: // Types (inherited from basic_ios (lib.ios)): typedef charT char_type; typedef typename traits::int_type int_type; typedef typename traits::pos_type pos_type; typedef typename traits::off_type off_type; typedef traits traits_type; // lib.ostream.cons Constructor/destructor: explicit basic_ostream(basic_streambuf<char_type,traits>* sb); basic_ostream(basic_ostream&& rhs); virtual ~basic_ostream(); basic_ostream& operator=(basic_ostream&& rhs); void swap(basic_ostream&& rhs); // lib.ostream::sentry Prefix/suffix: class sentry; // lib.ostream.formatted Formatted output: basic_ostream<charT,traits>& operator<< (basic_ostream<charT,traits>& (*pf)(basic_ostream<charT,traits>&)); basic_ostream<charT,traits>& operator<< (basic_ios<charT,traits>& (*pf)(basic_ios<charT,traits>&)); basic_ostream<charT,traits>& operator<< (ios_base& (*pf)(ios_base&)); basic_ostream<charT,traits>& operator<<(bool n); basic_ostream<charT,traits>& operator<<(short n); basic_ostream<charT,traits>& operator<<(unsigned short n); basic_ostream<charT,traits>& operator<<(int n); basic_ostream<charT,traits>& operator<<(unsigned int n); basic_ostream<charT,traits>& operator<<(long n); basic_ostream<charT,traits>& operator<<(unsigned long n); basic_ostream<charT,traits>& operator<<(float f); basic_ostream<charT,traits>& operator<<(double f); basic_ostream<charT,traits>& operator<<(long double f); basic_ostream<charT,traits>& operator<<(const void* p); basic_ostream<charT,traits>& operator<< (basic_streambuf<char_type,traits>* sb); // lib.ostream.unformatted Unformatted output: basic_ostream<charT,traits>& put(char_type c); basic_ostream<charT,traits>& write(const char_type* s, streamsize n); basic_ostream<charT,traits>& flush(); // lib.ostream.seeks seeks: pos_type tellp(); basic_ostream<charT,traits>& seekp(pos_type); basic_ostream<charT,traits>& seekp(off_type, ios_base::seekdir); }; // lib.ostream.inserters.character character inserters template<class charT, class traits> basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&, charT); template<class charT, class traits> basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&&, charT); template<class charT, class traits> basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&, char); template<class charT, class traits> basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&&, char); // specialization template<class traits> basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&, char); template<class traits> basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&&, char); // signed and unsigned template<class traits> basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&, signed char); template<class traits> basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&&, signed char); template<class traits> basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&, unsigned char); template<class traits> basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&&, unsigned char); template<class charT, class traits> basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&, const charT*); template<class charT, class traits> basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&&, const charT*); template<class charT, class traits> basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&, const char*); template<class charT, class traits> basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&&, const char*); // partial specializationss template<class traits> basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&&, const char*); template<class traits> basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&&, const char*); // signed and unsigned template<class traits> basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&, const signed char*); template<class traits> basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&&, const signed char*); template<class traits> basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&, const unsigned char*); template<class traits> basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&&, const unsigned char*); template <class charT, class traits> void swap(basic_ostream<charT, traits>& x, basic_ostream<charT, traits>& y); template <class charT, class traits> void swap(basic_ostream<charT, traits>&& x, basic_ostream<charT, traits>& y); template <class charT, class traits> void swap(basic_ostream<charT, traits>& x, basic_ostream<charT, traits>&& y); }
basic_ostream(basic_ostream&& rhs);
-3- Effects: Move constructs from the rvalue rhs. This is accomplished by default constructing the base class and calling basic_ios<charT, traits>::move(rhs) to initialize the base class.
basic_ostream& operator=(basic_ostream&& rhs);
-1- Effects: swap(rhs).
-2- Returns: *this.
void swap(basic_ostream&& rhs);
-3- Effects: Calls basic_ios<charT, traits>::swap(rhs).
template <class charT, class traits> void swap(basic_ostream<charT, traits>& x, basic_ostream<charT, traits>& y); template <class charT, class traits> void swap(basic_ostream<charT, traits>&& x, basic_ostream<charT, traits>& y); template <class charT, class traits> void swap(basic_ostream<charT, traits>& x, basic_ostream<charT, traits>&& y);
-4- Effects: x.swap(y).
template<class charT, class traits> basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&, charT); template<class charT, class traits> basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&&, charT); template<class charT, class traits> basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&, char); template<class charT, class traits> basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&&, char); template<class traits> basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&, char); template<class traits> basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&&, char); template<class traits> basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&, signed char); template<class traits> basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&&, signed char); template<class traits> basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&, unsigned char); template<class traits> basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&&, unsigned char); template<class charT, class traits> basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&, const charT*); template<class charT, class traits> basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&&, const charT*); template<class charT, class traits> basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&, const char*); template<class charT, class traits> basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&&, const char*); template<class traits> basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&&, const char*); template<class traits> basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&&, const char*); template<class traits> basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&, const signed char*); template<class traits> basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&&, const signed char*); template<class traits> basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&, const unsigned char*); template<class traits> basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&&, const unsigned char*);
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.
Header <sstream> synopsis
namespace std { template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> > class basic_stringbuf; template <class charT, class traits, class Allocator> void swap(basic_stringbuf<charT, traits, Allocator>& x, basic_stringbuf<charT, traits, Allocator>& y); template <class charT, class traits, class Allocator> void swap(basic_stringbuf<charT, traits, Allocator>&& x, basic_stringbuf<charT, traits, Allocator>& y); template <class charT, class traits, class Allocator> void swap(basic_stringbuf<charT, traits, Allocator>& x, basic_stringbuf<charT, traits, Allocator>&& y); typedef basic_stringbuf<char> stringbuf; typedef basic_stringbuf<wchar_t> wstringbuf; template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> > class basic_istringstream; template <class charT, class traits, class Allocator> void swap(basic_istringstream<charT, traits, Allocator>& x, basic_istringstream<charT, traits, Allocator>& y); template <class charT, class traits, class Allocator> void swap(basic_istringstream<charT, traits, Allocator>&& x, basic_istringstream<charT, traits, Allocator>& y); template <class charT, class traits, class Allocator> void swap(basic_istringstream<charT, traits, Allocator>& x, basic_istringstream<charT, traits, Allocator>&& y); typedef basic_istringstream<char> istringstream; typedef basic_istringstream<wchar_t> wistringstream; template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> > class basic_ostringstream; template <class charT, class traits, class Allocator> void swap(basic_ostringstream<charT, traits, Allocator>& x, basic_ostringstream<charT, traits, Allocator>& y); template <class charT, class traits, class Allocator> void swap(basic_ostringstream<charT, traits, Allocator>&& x, basic_ostringstream<charT, traits, Allocator>& y); template <class charT, class traits, class Allocator> void swap(basic_ostringstream<charT, traits, Allocator>& x, basic_ostringstream<charT, traits, Allocator>&& y); typedef basic_ostringstream<char> ostringstream; typedef basic_ostringstream<wchar_t> wostringstream; template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> > class basic_stringstream; template <class charT, class traits, class Allocator> void swap(basic_stringstream<charT, traits, Allocator>& x, basic_stringstream<charT, traits, Allocator>& y); template <class charT, class traits, class Allocator> void swap(basic_stringstream<charT, traits, Allocator>&& x, basic_stringstream<charT, traits, Allocator>& y); template <class charT, class traits, class Allocator> void swap(basic_stringstream<charT, traits, Allocator>& x, basic_stringstream<charT, traits, Allocator>&& y); typedef basic_stringstream<char> stringstream; typedef basic_stringstream<wchar_t> wstringstream; }
namespace std { template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> > class basic_stringbuf : public basic_streambuf<charT,traits> { public: typedef charT char_type; typedef typename traits::int_type int_type; typedef typename traits::pos_type pos_type; typedef typename traits::off_type off_type; typedef traits traits_type; // lib.stringbuf.cons Constructors: explicit basic_stringbuf(ios_base::openmode which = ios_base::in | ios_base::out); explicit basic_stringbuf (const basic_string<charT,traits,Allocator>& str, ios_base::openmode which = ios_base::in | ios_base::out); basic_stringbuf(basic_stringbuf&& rhs); basic_stringbuf& operator=(basic_stringbuf&& rhs); void swap(basic_stringbuf&& rhs); // lib.stringbuf.members Get and set: basic_string<charT,traits,Allocator> str() const; void str(const basic_string<charT,traits,Allocator>& s); protected: // lib.stringbuf.virtuals Overridden virtual functions: virtual int_type underflow(); virtual int_type pbackfail(int_type c = traits::eof()); virtual int_type overflow (int_type c = traits::eof()); virtual basic_streambuf<charT,traits>* setbuf(charT*, streamsize); virtual pos_type seekoff(off_type off, ios_base::seekdir way, ios_base::openmode which = ios_base::in | ios_base::out); virtual pos_type seekpos(pos_type sp, ios_base::openmode which = ios_base::in | ios_base::out); private: // ios_base::openmode mode; exposition only }; template <class charT, class traits, class Allocator> void swap(basic_stringbuf<charT, traits, Allocator>& x, basic_stringbuf<charT, traits, Allocator>& y); template <class charT, class traits, class Allocator> void swap(basic_stringbuf<charT, traits, Allocator>&& x, basic_stringbuf<charT, traits, Allocator>& y); template <class charT, class traits, class Allocator> void swap(basic_stringbuf<charT, traits, Allocator>& x, basic_stringbuf<charT, traits, Allocator>&& y); }
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.
basic_stringbuf& operator=(basic_stringbuf&& rhs);
-3- Effects: swap(rhs).
-4- Returns: *this.
void swap(basic_stringbuf&& rhs);
-5- Effects: Exchanges the state of *this and rhs.
template <class charT, class traits, class Allocator> void swap(basic_stringbuf<charT, traits, Allocator>& x, basic_stringbuf<charT, traits, Allocator>& y); template <class charT, class traits, class Allocator> void swap(basic_stringbuf<charT, traits, Allocator>&& x, basic_stringbuf<charT, traits, Allocator>& y); template <class charT, class traits, class Allocator> void swap(basic_stringbuf<charT, traits, Allocator>& x, basic_stringbuf<charT, traits, Allocator>&& y);
-6- Effects: x.swap(y).
namespace std { template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> > class basic_istringstream : public basic_istream<charT,traits> { public: typedef charT char_type; typedef typename traits::int_type int_type; typedef typename traits::pos_type pos_type; typedef typename traits::off_type off_type; typedef traits traits_type; // lib.istringstream.cons Constructors: explicit basic_istringstream(ios_base::openmode which = ios_base::in); explicit basic_istringstream( const basic_string<charT,traits,Allocator>& str, ios_base::openmode which = ios_base::in); basic_istringstream(basic_istringstream&& rhs); basic_istringstream& operator=(basic_istringstream&& rhs); void swap(basic_istringstream&& rhs); // lib.istringstream.members Members: basic_stringbuf<charT,traits,Allocator>* rdbuf() const; basic_string<charT,traits,Allocator> str() const; void str(const basic_string<charT,traits,Allocator>& s); private: // basic_stringbuf<charT,traits,Allocator> sb; exposition only }; template <class charT, class traits, class Allocator> void swap(basic_istringstream<charT, traits, Allocator>& x, basic_istringstream<charT, traits, Allocator>& y); template <class charT, class traits, class Allocator> void swap(basic_istringstream<charT, traits, Allocator>&& x, basic_istringstream<charT, traits, Allocator>& y); template <class charT, class traits, class Allocator> void swap(basic_istringstream<charT, traits, Allocator>& x, basic_istringstream<charT, traits, Allocator>&& y); }
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.
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).
template <class charT, class traits, class Allocator> void swap(basic_istringstream<charT, traits, Allocator>& x, basic_istringstream<charT, traits, Allocator>& y); template <class charT, class traits, class Allocator> void swap(basic_istringstream<charT, traits, Allocator>&& x, basic_istringstream<charT, traits, Allocator>& y); template <class charT, class traits, class Allocator> void swap(basic_istringstream<charT, traits, Allocator>& x, basic_istringstream<charT, traits, Allocator>&& y);
-7- Effects: x.swap(y).
namespace std { template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> > class basic_ostringstream : public basic_istream<charT,traits> { public: typedef charT char_type; typedef typename traits::int_type int_type; typedef typename traits::pos_type pos_type; typedef typename traits::off_type off_type; typedef traits traits_type; // lib.ostringstream.cons Constructors: explicit basic_ostringstream(ios_base::openmode which = ios_base::out); explicit basic_ostringstream( const basic_string<charT,traits,Allocator>& str, ios_base::openmode which = ios_base::out); basic_ostringstream(basic_ostringstream&& rhs); basic_ostringstream& operator=(basic_ostringstream&& rhs); void swap(basic_ostringstream&& rhs); // lib.ostringstream.members Members: basic_stringbuf<charT,traits,Allocator>* rdbuf() const; basic_string<charT,traits,Allocator> str() const; void str(const basic_string<charT,traits,Allocator>& s); private: // basic_stringbuf<charT,traits,Allocator> sb; exposition only }; template <class charT, class traits, class Allocator> void swap(basic_ostringstream<charT, traits, Allocator>& x, basic_ostringstream<charT, traits, Allocator>& y); template <class charT, class traits, class Allocator> void swap(basic_ostringstream<charT, traits, Allocator>&& x, basic_ostringstream<charT, traits, Allocator>& y); template <class charT, class traits, class Allocator> void swap(basic_ostringstream<charT, traits, Allocator>& x, basic_ostringstream<charT, traits, Allocator>&& y); }
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.
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).
template <class charT, class traits, class Allocator> void swap(basic_ostringstream<charT, traits, Allocator>& x, basic_ostringstream<charT, traits, Allocator>& y); template <class charT, class traits, class Allocator> void swap(basic_ostringstream<charT, traits, Allocator>&& x, basic_ostringstream<charT, traits, Allocator>& y); template <class charT, class traits, class Allocator> void swap(basic_ostringstream<charT, traits, Allocator>& x, basic_ostringstream<charT, traits, Allocator>&& y);
-7- Effects: x.swap(y).
namespace std { template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> > class basic_stringstream : public basic_istream<charT,traits> { public: typedef charT char_type; typedef typename traits::int_type int_type; typedef typename traits::pos_type pos_type; typedef typename traits::off_type off_type; typedef traits traits_type; // lib.stringstream.cons Constructors: explicit basic_stringstream(ios_base::openmode which = ios_base::out | ios_base::in); explicit basic_stringstream( const basic_string<charT,traits,Allocator>& str, ios_base::openmode which = ios_base::out | ios_base::in); basic_stringstream(basic_stringstream&& rhs); basic_stringstream& operator=(basic_stringstream&& rhs); void swap(basic_stringstream&& rhs); // lib.stringstream.members Members: basic_stringbuf<charT,traits,Allocator>* rdbuf() const; basic_string<charT,traits,Allocator> str() const; void str(const basic_string<charT,traits,Allocator>& s); private: // basic_stringbuf<charT,traits,Allocator> sb; exposition only }; template <class charT, class traits, class Allocator> void swap(basic_stringstream<charT, traits, Allocator>& x, basic_stringstream<charT, traits, Allocator>& y); template <class charT, class traits, class Allocator> void swap(basic_stringstream<charT, traits, Allocator>&& x, basic_stringstream<charT, traits, Allocator>& y); template <class charT, class traits, class Allocator> void swap(basic_stringstream<charT, traits, Allocator>& x, basic_stringstream<charT, traits, Allocator>&& y); }
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.
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).
template <class charT, class traits, class Allocator> void swap(basic_stringstream<charT, traits, Allocator>& x, basic_stringstream<charT, traits, Allocator>& y); template <class charT, class traits, class Allocator> void swap(basic_stringstream<charT, traits, Allocator>&& x, basic_stringstream<charT, traits, Allocator>& y); template <class charT, class traits, class Allocator> void swap(basic_stringstream<charT, traits, Allocator>& x, basic_stringstream<charT, traits, Allocator>&& y);
-7- Effects: x.swap(y).
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.
Header <fstream> synopsis
namespace std { template <class charT, class traits = char_traits<charT> > class basic_filebuf; template <class charT, class traits> void swap(basic_filebuf<charT, traits>& x, basic_filebuf<charT, traits>& y); template <class charT, class traits> void swap(basic_filebuf<charT, traits>&& x, basic_filebuf<charT, traits>& y); template <class charT, class traits> void swap(basic_filebuf<charT, traits>& x, basic_filebuf<charT, traits>&& y); typedef basic_filebuf<char> filebuf; typedef basic_filebuf<wchar_t> wfilebuf; template <class charT, class traits = char_traits<charT> > class basic_ifstream; template <class charT, class traits> void swap(basic_ifstream<charT, traits>& x, basic_ifstream<charT, traits>& y); template <class charT, class traits> void swap(basic_ifstream<charT, traits>&& x, basic_ifstream<charT, traits>& y); template <class charT, class traits> void swap(basic_ifstream<charT, traits>& x, basic_ifstream<charT, traits>&& y); typedef basic_ifstream<char> ifstream; typedef basic_ifstream<wchar_t> wifstream; template <class charT, class traits = char_traits<charT> > class basic_ofstream; template <class charT, class traits> void swap(basic_ofstream<charT, traits>& x, basic_ofstream<charT, traits>& y); template <class charT, class traits> void swap(basic_ofstream<charT, traits>&& x, basic_ofstream<charT, traits>& y); template <class charT, class traits> void swap(basic_ofstream<charT, traits>& x, basic_ofstream<charT, traits>&& y); typedef basic_ofstream<char> ofstream; typedef basic_ofstream<wchar_t> wofstream; template <class charT, class traits = char_traits<charT> > class basic_fstream; template <class charT, class traits> void swap(basic_fstream<charT, traits>& x, basic_fstream<charT, traits>& y); template <class charT, class traits> void swap(basic_fstream<charT, traits>&& x, basic_fstream<charT, traits>& y); template <class charT, class traits> void swap(basic_fstream<charT, traits>& x, basic_fstream<charT, traits>&& y); typedef basic_fstream<char> fstream; typedef basic_fstream<wchar_t> wfstream; }
namespace std { template <class charT, class traits = char_traits<charT> > class basic_filebuf : public basic_streambuf<charT,traits> { public: typedef charT char_type; typedef typename traits::int_type int_type; typedef typename traits::pos_type pos_type; typedef typename traits::off_type off_type; typedef traits traits_type; // lib.filebuf.cons Constructors/destructor: basic_filebuf(); virtual ~basic_filebuf(); basic_filebuf(basic_filebuf&& rhs); basic_filebuf& operator=(basic_filebuf&& rhs); void swap(basic_filebuf&& rhs); // lib.filebuf.members Members: bool is_open() const; basic_filebuf<charT,traits>* open (const char* s, ios_base::openmode mode); basic_filebuf<charT,traits>* close(); protected: // lib.filebuf.virtuals Overridden virtual functions: virtual streamsize showmanyc(); virtual int_type underflow(); virtual int_type uflow(); virtual int_type pbackfail(int_type c = traits::eof()); virtual int_type overflow (int_type c = traits::eof()); virtual basic_streambuf<charT,traits>* setbuf(char_type* s, streamsize n); virtual pos_type seekoff(off_type off, ios_base::seekdir way, ios_base::openmode which = ios_base::in | ios_base::out); virtual pos_type seekpos(pos_type sp, ios_base::openmode which = ios_base::in | ios_base::out); virtual int sync(); virtual void imbue(const locale& loc); }; template <class charT, class traits> void swap(basic_filebuf<charT, traits>& x, basic_filebuf<charT, traits>& y); template <class charT, class traits> void swap(basic_filebuf<charT, traits>&& x, basic_filebuf<charT, traits>& y); template <class charT, class traits> void swap(basic_filebuf<charT, traits>& x, basic_filebuf<charT, traits>&& y); }
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.
basic_filebuf& operator=(basic_filebuf&& rhs);
-9- Effects: swap(rhs).
-10- Returns: *this.
void swap(basic_filebuf&& rhs);
-11- Effects: Exchanges the state of *this and rhs.
template <class charT, class traits> void swap(basic_filebuf<charT, traits>& x, basic_filebuf<charT, traits>& y); template <class charT, class traits> void swap(basic_filebuf<charT, traits>&& x, basic_filebuf<charT, traits>& y); template <class charT, class traits> void swap(basic_filebuf<charT, traits>& x, basic_filebuf<charT, traits>&& y);
-12- Effects: x.swap(y).
namespace std { template <class charT, class traits = char_traits<charT> > class basic_ifstream : public basic_istream<charT,traits> { public: typedef charT char_type; typedef typename traits::int_type int_type; typedef typename traits::pos_type pos_type; typedef typename traits::off_type off_type; typedef traits traits_type; // lib.ifstream.cons Constructors: basic_ifstream(); explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in); basic_ifstream(basic_ifstream&& rhs); basic_ifstream& operator=(basic_ifstream&& rhs); void swap(basic_ifstream&& rhs); // lib.ifstream.members Members: basic_filebuf<charT,traits>* rdbuf() const; bool is_open(); void open(const char* s, ios_base::openmode mode = ios_base::in); void close(); private: // basic_filebuf<charT,traits> sb; exposition only }; template <class charT, class traits> void swap(basic_ifstream<charT, traits>& x, basic_ifstream<charT, traits>& y); template <class charT, class traits> void swap(basic_ifstream<charT, traits>&& x, basic_ifstream<charT, traits>& y); template <class charT, class traits> void swap(basic_ifstream<charT, traits>& x, basic_ifstream<charT, traits>&& y); }
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.
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).
template <class charT, class traits> void swap(basic_ifstream<charT, traits>& x, basic_ifstream<charT, traits>& y); template <class charT, class traits> void swap(basic_ifstream<charT, traits>&& x, basic_ifstream<charT, traits>& y); template <class charT, class traits> void swap(basic_ifstream<charT, traits>& x, basic_ifstream<charT, traits>&& y);
-8- Effects: x.swap(y).
namespace std { template <class charT, class traits = char_traits<charT> > class basic_ofstream : public basic_istream<charT,traits> { public: typedef charT char_type; typedef typename traits::int_type int_type; typedef typename traits::pos_type pos_type; typedef typename traits::off_type off_type; typedef traits traits_type; // lib.ifstream.cons Constructors: basic_ofstream(); explicit basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out); basic_ofstream(basic_ofstream&& rhs); basic_ofstream& operator=(basic_ofstream&& rhs); void swap(basic_ofstream&& rhs); // lib.ofstream.members Members: basic_filebuf<charT,traits>* rdbuf() const; bool is_open(); void open(const char* s, ios_base::openmode mode = ios_base::out); void close(); private: // basic_filebuf<charT,traits> sb; exposition only }; template <class charT, class traits> void swap(basic_ofstream<charT, traits>& x, basic_ofstream<charT, traits>& y); template <class charT, class traits> void swap(basic_ofstream<charT, traits>&& x, basic_ofstream<charT, traits>& y); template <class charT, class traits> void swap(basic_ofstream<charT, traits>& x, basic_ofstream<charT, traits>&& y); }
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.
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).
template <class charT, class traits> void swap(basic_ofstream<charT, traits>& x, basic_ofstream<charT, traits>& y); template <class charT, class traits> void swap(basic_ofstream<charT, traits>&& x, basic_ofstream<charT, traits>& y); template <class charT, class traits> void swap(basic_ofstream<charT, traits>& x, basic_ofstream<charT, traits>&& y);
-8- Effects: x.swap(y).
namespace std { template <class charT, class traits = char_traits<charT> > class basic_fstream : public basic_istream<charT,traits> { public: typedef charT char_type; typedef typename traits::int_type int_type; typedef typename traits::pos_type pos_type; typedef typename traits::off_type off_type; typedef traits traits_type; // lib.ifstream.cons Constructors: basic_fstream(); explicit basic_fstream(const char* s, ios_base::openmode mode = ios_base::in | ios_base::out); basic_fstream(basic_fstream&& rhs); basic_fstream& operator=(basic_fstream&& rhs); void swap(basic_fstream&& rhs); // lib.ifstream.members Members: basic_filebuf<charT,traits>* rdbuf() const; bool is_open(); void open(const char* s, ios_base::openmode mode = ios_base::in | ios_base::out); void close(); private: // basic_filebuf<charT,traits> sb; exposition only }; template <class charT, class traits> void swap(basic_fstream<charT, traits>& x, basic_fstream<charT, traits>& y); template <class charT, class traits> void swap(basic_fstream<charT, traits>&& x, basic_fstream<charT, traits>& y); template <class charT, class traits> void swap(basic_fstream<charT, traits>& x, basic_fstream<charT, traits>&& y); }
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.
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).
template <class charT, class traits> void swap(basic_fstream<charT, traits>& x, basic_fstream<charT, traits>& y); template <class charT, class traits> void swap(basic_fstream<charT, traits>&& x, basic_fstream<charT, traits>& y); template <class charT, class traits> void swap(basic_fstream<charT, traits>& x, basic_fstream<charT, traits>&& y);
-8- Effects: x.swap(y).