Document number: N1862=05-0122

Howard E. Hinnant
2005-08-26

Rvalue Reference Recommendations for Chapter 27

Contents

Related papers

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

Introduction

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

27.4.4 - Class template basic_ios

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
  };
}

27.4.4.2 - Member functions


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:


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.

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());
  };
}

27.5.2.1 - basic_streambuf constructors


basic_streambuf(const basic_streambuf& rhs);

-3- Effects: Constructs a copy of rhs.

-4- Postconditions:

27.5.2.3 - basic_streambuf protected member functions


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.

27.6 - Formatting and manipulators

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);
}

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.

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);
}

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().


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

27.6.1.2.3 - basic_istream::operator>>

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*);

27.6.1.5 - Class template basic_iostream

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);
}

27.6.1.5.1 - basic_iostream constructors


basic_iostream(basic_iostream&& rhs);

-3- Effects: Move constructs from the rvalue rhs by constructing the basic_istream base class with move(rhs).

27.6.1.5.3 - basic_iostream member / non-member functions


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

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.

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);
}

27.6.2.2 - basic_ostream constructors


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.

27.6.2.3 - basic_ostream member / non-member functions


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

27.6.2.56.4 - Character inserter function templates

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*);

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.

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;
}

27.7.1 - Class template basic_stringbuf

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);
}

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.1.2 - Member / non-member functions


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

27.7.2 - Class template basic_istringstream

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);
}

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


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

27.7.3 - Class template basic_ostringstream

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);
}

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


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

27.7.4 - Class template basic_stringstream

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);
}

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


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

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.

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;
}

27.8.1.1 - Class template basic_filebuf

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);
}

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.3 - Member / non-member functions


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

27.8.1.5 - Class template basic_ifstream

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);
}

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


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

27.8.1.8 - Class template basic_ofstream

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);
}

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


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

27.8.1.11 - Class template basic_fstream

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);
}

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


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