Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. // String based streams -*- C++ -*-
  2.  
  3. // Copyright (C) 1997-2015 Free Software Foundation, Inc.
  4. //
  5. // This file is part of the GNU ISO C++ Library.  This library is free
  6. // software; you can redistribute it and/or modify it under the
  7. // terms of the GNU General Public License as published by the
  8. // Free Software Foundation; either version 3, or (at your option)
  9. // any later version.
  10.  
  11. // This library is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. // GNU General Public License for more details.
  15.  
  16. // Under Section 7 of GPL version 3, you are granted additional
  17. // permissions described in the GCC Runtime Library Exception, version
  18. // 3.1, as published by the Free Software Foundation.
  19.  
  20. // You should have received a copy of the GNU General Public License and
  21. // a copy of the GCC Runtime Library Exception along with this program;
  22. // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
  23. // <http://www.gnu.org/licenses/>.
  24.  
  25. /** @file include/sstream
  26.  *  This is a Standard C++ Library header.
  27.  */
  28.  
  29. //
  30. // ISO C++ 14882: 27.7  String-based streams
  31. //
  32.  
  33. #ifndef _GLIBCXX_SSTREAM
  34. #define _GLIBCXX_SSTREAM 1
  35.  
  36. #pragma GCC system_header
  37.  
  38. #include <istream>
  39. #include <ostream>
  40.  
  41. namespace std _GLIBCXX_VISIBILITY(default)
  42. {
  43. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  44. _GLIBCXX_BEGIN_NAMESPACE_CXX11
  45.  
  46.   // [27.7.1] template class basic_stringbuf
  47.   /**
  48.    *  @brief  The actual work of input and output (for std::string).
  49.    *  @ingroup io
  50.    *
  51.    *  @tparam _CharT  Type of character stream.
  52.    *  @tparam _Traits  Traits for character type, defaults to
  53.    *                   char_traits<_CharT>.
  54.    *  @tparam _Alloc  Allocator type, defaults to allocator<_CharT>.
  55.    *
  56.    *  This class associates either or both of its input and output sequences
  57.    *  with a sequence of characters, which can be initialized from, or made
  58.    *  available as, a @c std::basic_string.  (Paraphrased from [27.7.1]/1.)
  59.    *
  60.    *  For this class, open modes (of type @c ios_base::openmode) have
  61.    *  @c in set if the input sequence can be read, and @c out set if the
  62.    *  output sequence can be written.
  63.   */
  64.   template<typename _CharT, typename _Traits, typename _Alloc>
  65.     class basic_stringbuf : public basic_streambuf<_CharT, _Traits>
  66.     {
  67.       struct __xfer_bufptrs;
  68.     public:
  69.       // Types:
  70.       typedef _CharT                                    char_type;
  71.       typedef _Traits                                   traits_type;
  72.       // _GLIBCXX_RESOLVE_LIB_DEFECTS
  73.       // 251. basic_stringbuf missing allocator_type
  74.       typedef _Alloc                                    allocator_type;
  75.       typedef typename traits_type::int_type            int_type;
  76.       typedef typename traits_type::pos_type            pos_type;
  77.       typedef typename traits_type::off_type            off_type;
  78.  
  79.       typedef basic_streambuf<char_type, traits_type>   __streambuf_type;
  80.       typedef basic_string<char_type, _Traits, _Alloc>  __string_type;
  81.       typedef typename __string_type::size_type         __size_type;
  82.  
  83.     protected:
  84.       /// Place to stash in || out || in | out settings for current stringbuf.
  85.       ios_base::openmode        _M_mode;
  86.  
  87.       // Data Members:
  88.       __string_type             _M_string;
  89.  
  90.     public:
  91.       // Constructors:
  92.       /**
  93.        *  @brief  Starts with an empty string buffer.
  94.        *  @param  __mode  Whether the buffer can read, or write, or both.
  95.        *
  96.        *  The default constructor initializes the parent class using its
  97.        *  own default ctor.
  98.       */
  99.       explicit
  100.       basic_stringbuf(ios_base::openmode __mode = ios_base::in | ios_base::out)
  101.       : __streambuf_type(), _M_mode(__mode), _M_string()
  102.       { }
  103.  
  104.       /**
  105.        *  @brief  Starts with an existing string buffer.
  106.        *  @param  __str  A string to copy as a starting buffer.
  107.        *  @param  __mode  Whether the buffer can read, or write, or both.
  108.        *
  109.        *  This constructor initializes the parent class using its
  110.        *  own default ctor.
  111.       */
  112.       explicit
  113.       basic_stringbuf(const __string_type& __str,
  114.                       ios_base::openmode __mode = ios_base::in | ios_base::out)
  115.       : __streambuf_type(), _M_mode(), _M_string(__str.data(), __str.size())
  116.       { _M_stringbuf_init(__mode); }
  117.  
  118. #if __cplusplus >= 201103L
  119.       basic_stringbuf(const basic_stringbuf&) = delete;
  120.  
  121.       basic_stringbuf(basic_stringbuf&& __rhs)
  122.       : basic_stringbuf(std::move(__rhs), __xfer_bufptrs(__rhs, this))
  123.       { __rhs._M_sync(const_cast<char_type*>(__rhs._M_string.data()), 0, 0); }
  124.  
  125.       // 27.8.2.2 Assign and swap:
  126.  
  127.       basic_stringbuf&
  128.       operator=(const basic_stringbuf&) = delete;
  129.  
  130.       basic_stringbuf&
  131.       operator=(basic_stringbuf&& __rhs)
  132.       {
  133.         __xfer_bufptrs __st{__rhs, this};
  134.         const __streambuf_type& __base = __rhs;
  135.         __streambuf_type::operator=(__base);
  136.         this->pubimbue(__rhs.getloc());
  137.         _M_mode = __rhs._M_mode;
  138.         _M_string = std::move(__rhs._M_string);
  139.         __rhs._M_sync(const_cast<char_type*>(__rhs._M_string.data()), 0, 0);
  140.         return *this;
  141.       }
  142.  
  143.       void
  144.       swap(basic_stringbuf& __rhs)
  145.       {
  146.         __xfer_bufptrs __l_st{*this, std::__addressof(__rhs)};
  147.         __xfer_bufptrs __r_st{__rhs, this};
  148.         __streambuf_type& __base = __rhs;
  149.         __streambuf_type::swap(__base);
  150.         __rhs.pubimbue(this->pubimbue(__rhs.getloc()));
  151.         std::swap(_M_mode, __rhs._M_mode);
  152.         std::swap(_M_string, __rhs._M_string);
  153.       }
  154. #endif
  155.  
  156.       // Get and set:
  157.       /**
  158.        *  @brief  Copying out the string buffer.
  159.        *  @return  A copy of one of the underlying sequences.
  160.        *
  161.        *  <em>If the buffer is only created in input mode, the underlying
  162.        *  character sequence is equal to the input sequence; otherwise, it
  163.        *  is equal to the output sequence.</em> [27.7.1.2]/1
  164.       */
  165.       __string_type
  166.       str() const
  167.       {
  168.         __string_type __ret;
  169.         if (this->pptr())
  170.           {
  171.             // The current egptr() may not be the actual string end.
  172.             if (this->pptr() > this->egptr())
  173.               __ret = __string_type(this->pbase(), this->pptr());
  174.             else
  175.               __ret = __string_type(this->pbase(), this->egptr());
  176.           }
  177.         else
  178.           __ret = _M_string;
  179.         return __ret;
  180.       }
  181.  
  182.       /**
  183.        *  @brief  Setting a new buffer.
  184.        *  @param  __s  The string to use as a new sequence.
  185.        *
  186.        *  Deallocates any previous stored sequence, then copies @a s to
  187.        *  use as a new one.
  188.       */
  189.       void
  190.       str(const __string_type& __s)
  191.       {
  192.         // Cannot use _M_string = __s, since v3 strings are COW
  193.         // (not always true now but assign() always works).
  194.         _M_string.assign(__s.data(), __s.size());
  195.         _M_stringbuf_init(_M_mode);
  196.       }
  197.  
  198.     protected:
  199.       // Common initialization code goes here.
  200.       void
  201.       _M_stringbuf_init(ios_base::openmode __mode)
  202.       {
  203.         _M_mode = __mode;
  204.         __size_type __len = 0;
  205.         if (_M_mode & (ios_base::ate | ios_base::app))
  206.           __len = _M_string.size();
  207.         _M_sync(const_cast<char_type*>(_M_string.data()), 0, __len);
  208.       }
  209.  
  210.       virtual streamsize
  211.       showmanyc()
  212.       {
  213.         streamsize __ret = -1;
  214.         if (_M_mode & ios_base::in)
  215.           {
  216.             _M_update_egptr();
  217.             __ret = this->egptr() - this->gptr();
  218.           }
  219.         return __ret;
  220.       }
  221.  
  222.       virtual int_type
  223.       underflow();
  224.  
  225.       virtual int_type
  226.       pbackfail(int_type __c = traits_type::eof());
  227.  
  228.       virtual int_type
  229.       overflow(int_type __c = traits_type::eof());
  230.  
  231.       /**
  232.        *  @brief  Manipulates the buffer.
  233.        *  @param  __s  Pointer to a buffer area.
  234.        *  @param  __n  Size of @a __s.
  235.        *  @return  @c this
  236.        *
  237.        *  If no buffer has already been created, and both @a __s and @a __n are
  238.        *  non-zero, then @c __s is used as a buffer; see
  239.        *  https://gcc.gnu.org/onlinedocs/libstdc++/manual/streambufs.html#io.streambuf.buffering
  240.        *  for more.
  241.       */
  242.       virtual __streambuf_type*
  243.       setbuf(char_type* __s, streamsize __n)
  244.       {
  245.         if (__s && __n >= 0)
  246.           {
  247.             // This is implementation-defined behavior, and assumes
  248.             // that an external char_type array of length __n exists
  249.             // and has been pre-allocated. If this is not the case,
  250.             // things will quickly blow up.
  251.            
  252.             // Step 1: Destroy the current internal array.
  253.             _M_string.clear();
  254.            
  255.             // Step 2: Use the external array.
  256.             _M_sync(__s, __n, 0);
  257.           }
  258.         return this;
  259.       }
  260.  
  261.       virtual pos_type
  262.       seekoff(off_type __off, ios_base::seekdir __way,
  263.               ios_base::openmode __mode = ios_base::in | ios_base::out);
  264.  
  265.       virtual pos_type
  266.       seekpos(pos_type __sp,
  267.               ios_base::openmode __mode = ios_base::in | ios_base::out);
  268.  
  269.       // Internal function for correctly updating the internal buffer
  270.       // for a particular _M_string, due to initialization or re-sizing
  271.       // of an existing _M_string.
  272.       void
  273.       _M_sync(char_type* __base, __size_type __i, __size_type __o);
  274.  
  275.       // Internal function for correctly updating egptr() to the actual
  276.       // string end.
  277.       void
  278.       _M_update_egptr()
  279.       {
  280.         const bool __testin = _M_mode & ios_base::in;
  281.         if (this->pptr() && this->pptr() > this->egptr())
  282.           {
  283.             if (__testin)
  284.               this->setg(this->eback(), this->gptr(), this->pptr());
  285.             else
  286.               this->setg(this->pptr(), this->pptr(), this->pptr());
  287.           }
  288.       }
  289.  
  290.       // Works around the issue with pbump, part of the protected
  291.       // interface of basic_streambuf, taking just an int.
  292.       void
  293.       _M_pbump(char_type* __pbeg, char_type* __pend, off_type __off);
  294.  
  295.     private:
  296. #if __cplusplus >= 201103L
  297. #if _GLIBCXX_USE_CXX11_ABI
  298.       // This type captures the state of the gptr / pptr pointers as offsets
  299.       // so they can be restored in another object after moving the string.
  300.       struct __xfer_bufptrs
  301.       {
  302.         __xfer_bufptrs(const basic_stringbuf& __from, basic_stringbuf* __to)
  303.         : _M_to{__to}, _M_goff{-1, -1, -1}, _M_poff{-1, -1, -1}
  304.         {
  305.           const _CharT* __str = __from._M_string.data();
  306.           if (__from.eback())
  307.             {
  308.             _M_goff[0] = __from.eback() - __str;
  309.             _M_goff[1] = __from.gptr() - __str;
  310.             _M_goff[2] = __from.egptr() - __str;
  311.             }
  312.           if (__from.pbase())
  313.             {
  314.               _M_poff[0] = __from.pbase() - __str;
  315.               _M_poff[1] = __from.pptr() - __from.pbase();
  316.               _M_poff[2] = __from.epptr() - __str;
  317.             }
  318.         }
  319.  
  320.         ~__xfer_bufptrs()
  321.         {
  322.           char_type* __str = const_cast<char_type*>(_M_to->_M_string.data());
  323.           if (_M_goff[0] != -1)
  324.             _M_to->setg(__str+_M_goff[0], __str+_M_goff[1], __str+_M_goff[2]);
  325.           if (_M_poff[0] != -1)
  326.             _M_to->_M_pbump(__str+_M_poff[0], __str+_M_poff[2], _M_poff[1]);
  327.         }
  328.  
  329.         basic_stringbuf* _M_to;
  330.         off_type _M_goff[3];
  331.         off_type _M_poff[3];
  332.       };
  333. #else
  334.       // This type does nothing when using Copy-On-Write strings.
  335.       struct __xfer_bufptrs
  336.       {
  337.         __xfer_bufptrs(const basic_stringbuf&, basic_stringbuf*) { }
  338.       };
  339. #endif
  340.  
  341.       // The move constructor initializes an __xfer_bufptrs temporary then
  342.       // delegates to this constructor to performs moves during its lifetime.
  343.       basic_stringbuf(basic_stringbuf&& __rhs, __xfer_bufptrs&&)
  344.       : __streambuf_type(static_cast<const __streambuf_type&>(__rhs)),
  345.       _M_mode(__rhs._M_mode), _M_string(std::move(__rhs._M_string))
  346.       { }
  347. #endif
  348.     };
  349.  
  350.  
  351.   // [27.7.2] Template class basic_istringstream
  352.   /**
  353.    *  @brief  Controlling input for std::string.
  354.    *  @ingroup io
  355.    *
  356.    *  @tparam _CharT  Type of character stream.
  357.    *  @tparam _Traits  Traits for character type, defaults to
  358.    *                   char_traits<_CharT>.
  359.    *  @tparam _Alloc  Allocator type, defaults to allocator<_CharT>.
  360.    *
  361.    *  This class supports reading from objects of type std::basic_string,
  362.    *  using the inherited functions from std::basic_istream.  To control
  363.    *  the associated sequence, an instance of std::basic_stringbuf is used,
  364.    *  which this page refers to as @c sb.
  365.   */
  366.   template<typename _CharT, typename _Traits, typename _Alloc>
  367.     class basic_istringstream : public basic_istream<_CharT, _Traits>
  368.     {
  369.     public:
  370.       // Types:
  371.       typedef _CharT                                    char_type;
  372.       typedef _Traits                                   traits_type;
  373.       // _GLIBCXX_RESOLVE_LIB_DEFECTS
  374.       // 251. basic_stringbuf missing allocator_type
  375.       typedef _Alloc                                    allocator_type;
  376.       typedef typename traits_type::int_type            int_type;
  377.       typedef typename traits_type::pos_type            pos_type;
  378.       typedef typename traits_type::off_type            off_type;
  379.  
  380.       // Non-standard types:
  381.       typedef basic_string<_CharT, _Traits, _Alloc>     __string_type;
  382.       typedef basic_stringbuf<_CharT, _Traits, _Alloc>  __stringbuf_type;
  383.       typedef basic_istream<char_type, traits_type>     __istream_type;
  384.  
  385.     private:
  386.       __stringbuf_type  _M_stringbuf;
  387.  
  388.     public:
  389.       // Constructors:
  390.       /**
  391.        *  @brief  Default constructor starts with an empty string buffer.
  392.        *  @param  __mode  Whether the buffer can read, or write, or both.
  393.        *
  394.        *  @c ios_base::in is automatically included in @a __mode.
  395.        *
  396.        *  Initializes @c sb using @c __mode|in, and passes @c &sb to the base
  397.        *  class initializer.  Does not allocate any buffer.
  398.        *
  399.        *  That's a lie.  We initialize the base class with NULL, because the
  400.        *  string class does its own memory management.
  401.       */
  402.       explicit
  403.       basic_istringstream(ios_base::openmode __mode = ios_base::in)
  404.       : __istream_type(), _M_stringbuf(__mode | ios_base::in)
  405.       { this->init(&_M_stringbuf); }
  406.  
  407.       /**
  408.        *  @brief  Starts with an existing string buffer.
  409.        *  @param  __str  A string to copy as a starting buffer.
  410.        *  @param  __mode  Whether the buffer can read, or write, or both.
  411.        *
  412.        *  @c ios_base::in is automatically included in @a mode.
  413.        *
  414.        *  Initializes @c sb using @a str and @c mode|in, and passes @c &sb
  415.        *  to the base class initializer.
  416.        *
  417.        *  That's a lie.  We initialize the base class with NULL, because the
  418.        *  string class does its own memory management.
  419.       */
  420.       explicit
  421.       basic_istringstream(const __string_type& __str,
  422.                           ios_base::openmode __mode = ios_base::in)
  423.       : __istream_type(), _M_stringbuf(__str, __mode | ios_base::in)
  424.       { this->init(&_M_stringbuf); }
  425.  
  426.       /**
  427.        *  @brief  The destructor does nothing.
  428.        *
  429.        *  The buffer is deallocated by the stringbuf object, not the
  430.        *  formatting stream.
  431.       */
  432.       ~basic_istringstream()
  433.       { }
  434.  
  435. #if __cplusplus >= 201103L
  436.       basic_istringstream(const basic_istringstream&) = delete;
  437.  
  438.       basic_istringstream(basic_istringstream&& __rhs)
  439.       : __istream_type(std::move(__rhs)),
  440.       _M_stringbuf(std::move(__rhs._M_stringbuf))
  441.       { __istream_type::set_rdbuf(&_M_stringbuf); }
  442.  
  443.       // 27.8.3.2 Assign and swap:
  444.  
  445.       basic_istringstream&
  446.       operator=(const basic_istringstream&) = delete;
  447.  
  448.       basic_istringstream&
  449.       operator=(basic_istringstream&& __rhs)
  450.       {
  451.         __istream_type::operator=(std::move(__rhs));
  452.         _M_stringbuf = std::move(__rhs._M_stringbuf);
  453.         return *this;
  454.       }
  455.  
  456.       void
  457.       swap(basic_istringstream& __rhs)
  458.       {
  459.         __istream_type::swap(__rhs);
  460.         _M_stringbuf.swap(__rhs._M_stringbuf);
  461.       }
  462. #endif
  463.  
  464.       // Members:
  465.       /**
  466.        *  @brief  Accessing the underlying buffer.
  467.        *  @return  The current basic_stringbuf buffer.
  468.        *
  469.        *  This hides both signatures of std::basic_ios::rdbuf().
  470.       */
  471.       __stringbuf_type*
  472.       rdbuf() const
  473.       { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
  474.  
  475.       /**
  476.        *  @brief  Copying out the string buffer.
  477.        *  @return  @c rdbuf()->str()
  478.       */
  479.       __string_type
  480.       str() const
  481.       { return _M_stringbuf.str(); }
  482.  
  483.       /**
  484.        *  @brief  Setting a new buffer.
  485.        *  @param  __s  The string to use as a new sequence.
  486.        *
  487.        *  Calls @c rdbuf()->str(s).
  488.       */
  489.       void
  490.       str(const __string_type& __s)
  491.       { _M_stringbuf.str(__s); }
  492.     };
  493.  
  494.  
  495.   // [27.7.3] Template class basic_ostringstream
  496.   /**
  497.    *  @brief  Controlling output for std::string.
  498.    *  @ingroup io
  499.    *
  500.    *  @tparam _CharT  Type of character stream.
  501.    *  @tparam _Traits  Traits for character type, defaults to
  502.    *                   char_traits<_CharT>.
  503.    *  @tparam _Alloc  Allocator type, defaults to allocator<_CharT>.
  504.    *
  505.    *  This class supports writing to objects of type std::basic_string,
  506.    *  using the inherited functions from std::basic_ostream.  To control
  507.    *  the associated sequence, an instance of std::basic_stringbuf is used,
  508.    *  which this page refers to as @c sb.
  509.   */
  510.   template <typename _CharT, typename _Traits, typename _Alloc>
  511.     class basic_ostringstream : public basic_ostream<_CharT, _Traits>
  512.     {
  513.     public:
  514.       // Types:
  515.       typedef _CharT                                    char_type;
  516.       typedef _Traits                                   traits_type;
  517.       // _GLIBCXX_RESOLVE_LIB_DEFECTS
  518.       // 251. basic_stringbuf missing allocator_type
  519.       typedef _Alloc                                    allocator_type;
  520.       typedef typename traits_type::int_type            int_type;
  521.       typedef typename traits_type::pos_type            pos_type;
  522.       typedef typename traits_type::off_type            off_type;
  523.  
  524.       // Non-standard types:
  525.       typedef basic_string<_CharT, _Traits, _Alloc>     __string_type;
  526.       typedef basic_stringbuf<_CharT, _Traits, _Alloc>  __stringbuf_type;
  527.       typedef basic_ostream<char_type, traits_type>     __ostream_type;
  528.  
  529.     private:
  530.       __stringbuf_type  _M_stringbuf;
  531.  
  532.     public:
  533.       // Constructors/destructor:
  534.       /**
  535.        *  @brief  Default constructor starts with an empty string buffer.
  536.        *  @param  __mode  Whether the buffer can read, or write, or both.
  537.        *
  538.        *  @c ios_base::out is automatically included in @a mode.
  539.        *
  540.        *  Initializes @c sb using @c mode|out, and passes @c &sb to the base
  541.        *  class initializer.  Does not allocate any buffer.
  542.        *
  543.        *  That's a lie.  We initialize the base class with NULL, because the
  544.        *  string class does its own memory management.
  545.       */
  546.       explicit
  547.       basic_ostringstream(ios_base::openmode __mode = ios_base::out)
  548.       : __ostream_type(), _M_stringbuf(__mode | ios_base::out)
  549.       { this->init(&_M_stringbuf); }
  550.  
  551.       /**
  552.        *  @brief  Starts with an existing string buffer.
  553.        *  @param  __str  A string to copy as a starting buffer.
  554.        *  @param  __mode  Whether the buffer can read, or write, or both.
  555.        *
  556.        *  @c ios_base::out is automatically included in @a mode.
  557.        *
  558.        *  Initializes @c sb using @a str and @c mode|out, and passes @c &sb
  559.        *  to the base class initializer.
  560.        *
  561.        *  That's a lie.  We initialize the base class with NULL, because the
  562.        *  string class does its own memory management.
  563.       */
  564.       explicit
  565.       basic_ostringstream(const __string_type& __str,
  566.                           ios_base::openmode __mode = ios_base::out)
  567.       : __ostream_type(), _M_stringbuf(__str, __mode | ios_base::out)
  568.       { this->init(&_M_stringbuf); }
  569.  
  570.       /**
  571.        *  @brief  The destructor does nothing.
  572.        *
  573.        *  The buffer is deallocated by the stringbuf object, not the
  574.        *  formatting stream.
  575.       */
  576.       ~basic_ostringstream()
  577.       { }
  578.  
  579. #if __cplusplus >= 201103L
  580.       basic_ostringstream(const basic_ostringstream&) = delete;
  581.  
  582.       basic_ostringstream(basic_ostringstream&& __rhs)
  583.       : __ostream_type(std::move(__rhs)),
  584.       _M_stringbuf(std::move(__rhs._M_stringbuf))
  585.       { __ostream_type::set_rdbuf(&_M_stringbuf); }
  586.  
  587.       // 27.8.3.2 Assign and swap:
  588.  
  589.       basic_ostringstream&
  590.       operator=(const basic_ostringstream&) = delete;
  591.  
  592.       basic_ostringstream&
  593.       operator=(basic_ostringstream&& __rhs)
  594.       {
  595.         __ostream_type::operator=(std::move(__rhs));
  596.         _M_stringbuf = std::move(__rhs._M_stringbuf);
  597.         return *this;
  598.       }
  599.  
  600.       void
  601.       swap(basic_ostringstream& __rhs)
  602.       {
  603.         __ostream_type::swap(__rhs);
  604.         _M_stringbuf.swap(__rhs._M_stringbuf);
  605.       }
  606. #endif
  607.  
  608.       // Members:
  609.       /**
  610.        *  @brief  Accessing the underlying buffer.
  611.        *  @return  The current basic_stringbuf buffer.
  612.        *
  613.        *  This hides both signatures of std::basic_ios::rdbuf().
  614.       */
  615.       __stringbuf_type*
  616.       rdbuf() const
  617.       { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
  618.  
  619.       /**
  620.        *  @brief  Copying out the string buffer.
  621.        *  @return  @c rdbuf()->str()
  622.       */
  623.       __string_type
  624.       str() const
  625.       { return _M_stringbuf.str(); }
  626.  
  627.       /**
  628.        *  @brief  Setting a new buffer.
  629.        *  @param  __s  The string to use as a new sequence.
  630.        *
  631.        *  Calls @c rdbuf()->str(s).
  632.       */
  633.       void
  634.       str(const __string_type& __s)
  635.       { _M_stringbuf.str(__s); }
  636.     };
  637.  
  638.  
  639.   // [27.7.4] Template class basic_stringstream
  640.   /**
  641.    *  @brief  Controlling input and output for std::string.
  642.    *  @ingroup io
  643.    *
  644.    *  @tparam _CharT  Type of character stream.
  645.    *  @tparam _Traits  Traits for character type, defaults to
  646.    *                   char_traits<_CharT>.
  647.    *  @tparam _Alloc  Allocator type, defaults to allocator<_CharT>.
  648.    *
  649.    *  This class supports reading from and writing to objects of type
  650.    *  std::basic_string, using the inherited functions from
  651.    *  std::basic_iostream.  To control the associated sequence, an instance
  652.    *  of std::basic_stringbuf is used, which this page refers to as @c sb.
  653.   */
  654.   template <typename _CharT, typename _Traits, typename _Alloc>
  655.     class basic_stringstream : public basic_iostream<_CharT, _Traits>
  656.     {
  657.     public:
  658.       // Types:
  659.       typedef _CharT                                    char_type;
  660.       typedef _Traits                                   traits_type;
  661.       // _GLIBCXX_RESOLVE_LIB_DEFECTS
  662.       // 251. basic_stringbuf missing allocator_type
  663.       typedef _Alloc                                    allocator_type;
  664.       typedef typename traits_type::int_type            int_type;
  665.       typedef typename traits_type::pos_type            pos_type;
  666.       typedef typename traits_type::off_type            off_type;
  667.  
  668.       // Non-standard Types:
  669.       typedef basic_string<_CharT, _Traits, _Alloc>     __string_type;
  670.       typedef basic_stringbuf<_CharT, _Traits, _Alloc>  __stringbuf_type;
  671.       typedef basic_iostream<char_type, traits_type>    __iostream_type;
  672.  
  673.     private:
  674.       __stringbuf_type  _M_stringbuf;
  675.  
  676.     public:
  677.       // Constructors/destructors
  678.       /**
  679.        *  @brief  Default constructor starts with an empty string buffer.
  680.        *  @param  __m  Whether the buffer can read, or write, or both.
  681.        *
  682.        *  Initializes @c sb using the mode from @c __m, and passes @c
  683.        *  &sb to the base class initializer.  Does not allocate any
  684.        *  buffer.
  685.        *
  686.        *  That's a lie.  We initialize the base class with NULL, because the
  687.        *  string class does its own memory management.
  688.       */
  689.       explicit
  690.       basic_stringstream(ios_base::openmode __m = ios_base::out | ios_base::in)
  691.       : __iostream_type(), _M_stringbuf(__m)
  692.       { this->init(&_M_stringbuf); }
  693.  
  694.       /**
  695.        *  @brief  Starts with an existing string buffer.
  696.        *  @param  __str  A string to copy as a starting buffer.
  697.        *  @param  __m  Whether the buffer can read, or write, or both.
  698.        *
  699.        *  Initializes @c sb using @a __str and @c __m, and passes @c &sb
  700.        *  to the base class initializer.
  701.        *
  702.        *  That's a lie.  We initialize the base class with NULL, because the
  703.        *  string class does its own memory management.
  704.       */
  705.       explicit
  706.       basic_stringstream(const __string_type& __str,
  707.                          ios_base::openmode __m = ios_base::out | ios_base::in)
  708.       : __iostream_type(), _M_stringbuf(__str, __m)
  709.       { this->init(&_M_stringbuf); }
  710.  
  711.       /**
  712.        *  @brief  The destructor does nothing.
  713.        *
  714.        *  The buffer is deallocated by the stringbuf object, not the
  715.        *  formatting stream.
  716.       */
  717.       ~basic_stringstream()
  718.       { }
  719.  
  720. #if __cplusplus >= 201103L
  721.       basic_stringstream(const basic_stringstream&) = delete;
  722.  
  723.       basic_stringstream(basic_stringstream&& __rhs)
  724.       : __iostream_type(std::move(__rhs)),
  725.       _M_stringbuf(std::move(__rhs._M_stringbuf))
  726.       { __iostream_type::set_rdbuf(&_M_stringbuf); }
  727.  
  728.       // 27.8.3.2 Assign and swap:
  729.  
  730.       basic_stringstream&
  731.       operator=(const basic_stringstream&) = delete;
  732.  
  733.       basic_stringstream&
  734.       operator=(basic_stringstream&& __rhs)
  735.       {
  736.         __iostream_type::operator=(std::move(__rhs));
  737.         _M_stringbuf = std::move(__rhs._M_stringbuf);
  738.         return *this;
  739.       }
  740.  
  741.       void
  742.       swap(basic_stringstream& __rhs)
  743.       {
  744.         __iostream_type::swap(__rhs);
  745.         _M_stringbuf.swap(__rhs._M_stringbuf);
  746.       }
  747. #endif
  748.  
  749.       // Members:
  750.       /**
  751.        *  @brief  Accessing the underlying buffer.
  752.        *  @return  The current basic_stringbuf buffer.
  753.        *
  754.        *  This hides both signatures of std::basic_ios::rdbuf().
  755.       */
  756.       __stringbuf_type*
  757.       rdbuf() const
  758.       { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
  759.  
  760.       /**
  761.        *  @brief  Copying out the string buffer.
  762.        *  @return  @c rdbuf()->str()
  763.       */
  764.       __string_type
  765.       str() const
  766.       { return _M_stringbuf.str(); }
  767.  
  768.       /**
  769.        *  @brief  Setting a new buffer.
  770.        *  @param  __s  The string to use as a new sequence.
  771.        *
  772.        *  Calls @c rdbuf()->str(s).
  773.       */
  774.       void
  775.       str(const __string_type& __s)
  776.       { _M_stringbuf.str(__s); }
  777.     };
  778.  
  779. #if __cplusplus >= 201103L
  780.   /// Swap specialization for stringbufs.
  781.   template <class _CharT, class _Traits, class _Allocator>
  782.     inline void
  783.     swap(basic_stringbuf<_CharT, _Traits, _Allocator>& __x,
  784.          basic_stringbuf<_CharT, _Traits, _Allocator>& __y)
  785.     { __x.swap(__y); }
  786.  
  787.   /// Swap specialization for istringstreams.
  788.   template <class _CharT, class _Traits, class _Allocator>
  789.     inline void
  790.     swap(basic_istringstream<_CharT, _Traits, _Allocator>& __x,
  791.          basic_istringstream<_CharT, _Traits, _Allocator>& __y)
  792.     { __x.swap(__y); }
  793.  
  794.   /// Swap specialization for ostringstreams.
  795.   template <class _CharT, class _Traits, class _Allocator>
  796.     inline void
  797.     swap(basic_ostringstream<_CharT, _Traits, _Allocator>& __x,
  798.          basic_ostringstream<_CharT, _Traits, _Allocator>& __y)
  799.     { __x.swap(__y); }
  800.  
  801.   /// Swap specialization for stringstreams.
  802.   template <class _CharT, class _Traits, class _Allocator>
  803.     inline void
  804.     swap(basic_stringstream<_CharT, _Traits, _Allocator>& __x,
  805.          basic_stringstream<_CharT, _Traits, _Allocator>& __y)
  806.     { __x.swap(__y); }
  807. #endif
  808.  
  809. _GLIBCXX_END_NAMESPACE_CXX11
  810. _GLIBCXX_END_NAMESPACE_VERSION
  811. } // namespace
  812.  
  813. #include <bits/sstream.tcc>
  814.  
  815. #endif /* _GLIBCXX_SSTREAM */
  816.