home *** CD-ROM | disk | FTP | other *** search
/ Beginning C++ Through Gam…rogramming (2nd Edition) / BCGP2E.ISO / bloodshed / devcpp-4.9.9.2_setup.exe / sstream < prev    next >
Text File  |  2005-01-29  |  21KB  |  646 lines

  1. // String based streams -*- C++ -*-
  2.  
  3. // Copyright (C) 1997, 1998, 1999, 2002, 2003, 2004
  4. // Free Software Foundation, Inc.
  5. //
  6. // This file is part of the GNU ISO C++ Library.  This library is free
  7. // software; you can redistribute it and/or modify it under the
  8. // terms of the GNU General Public License as published by the
  9. // Free Software Foundation; either version 2, or (at your option)
  10. // any later version.
  11.  
  12. // This library is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. // GNU General Public License for more details.
  16.  
  17. // You should have received a copy of the GNU General Public License along
  18. // with this library; see the file COPYING.  If not, write to the Free
  19. // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  20. // USA.
  21.  
  22. // As a special exception, you may use this file as part of a free software
  23. // library without restriction.  Specifically, if other files instantiate
  24. // templates or use macros or inline functions from this file, or you compile
  25. // this file and link it with other files to produce an executable, this
  26. // file does not by itself cause the resulting executable to be covered by
  27. // the GNU General Public License.  This exception does not however
  28. // invalidate any other reasons why the executable file might be covered by
  29. // the GNU General Public License.
  30.  
  31. //
  32. // ISO C++ 14882: 27.7  String-based streams
  33. //
  34.  
  35. /** @file sstream
  36.  *  This is a Standard C++ Library header.  You should @c #include this header
  37.  *  in your programs, rather than any of the "st[dl]_*.h" implementation files.
  38.  */
  39.  
  40. #ifndef _GLIBCXX_SSTREAM
  41. #define _GLIBCXX_SSTREAM 1
  42.  
  43. #pragma GCC system_header
  44.  
  45. #include <istream>
  46. #include <ostream>
  47.  
  48. namespace std
  49. {
  50.   // [27.7.1] template class basic_stringbuf
  51.   /**
  52.    *  @brief  The actual work of input and output (for std::string).
  53.    *
  54.    *  This class associates either or both of its input and output sequences
  55.    *  with a sequence of characters, which can be initialized from, or made
  56.    *  available as, a @c std::basic_string.  (Paraphrased from [27.7.1]/1.)
  57.    *
  58.    *  For this class, open modes (of type @c ios_base::openmode) have
  59.    *  @c in set if the input sequence can be read, and @c out set if the
  60.    *  output sequence can be written.
  61.   */
  62.   template<typename _CharT, typename _Traits, typename _Alloc>
  63.     class basic_stringbuf : public basic_streambuf<_CharT, _Traits>
  64.     {
  65.     public:
  66.       // Types:
  67.       typedef _CharT                     char_type;
  68.       typedef _Traits                     traits_type;
  69.       // _GLIBCXX_RESOLVE_LIB_DEFECTS
  70.       // 251. basic_stringbuf missing allocator_type
  71.       typedef _Alloc                           allocator_type;
  72.       typedef typename traits_type::int_type         int_type;
  73.       typedef typename traits_type::pos_type         pos_type;
  74.       typedef typename traits_type::off_type         off_type;
  75.  
  76.       //@{
  77.       /**
  78.        *  @if maint
  79.        *  @doctodo
  80.        *  @endif
  81.       */
  82.       typedef basic_streambuf<char_type, traits_type>      __streambuf_type;
  83.       typedef basic_string<char_type, _Traits, _Alloc>     __string_type;
  84.       typedef typename __string_type::size_type        __size_type;
  85.       //@}
  86.  
  87.     protected:
  88.       /**
  89.        *  @if maint
  90.        *  Place to stash in || out || in | out settings for current stringbuf.
  91.        *  @endif
  92.       */
  93.       ios_base::openmode     _M_mode;
  94.  
  95.       // Data Members:
  96.       /**
  97.        *  @if maint
  98.        *  @doctodo
  99.        *  @endif
  100.       */
  101.       __string_type         _M_string;
  102.  
  103.     public:
  104.       // Constructors:
  105.       /**
  106.        *  @brief  Starts with an empty string buffer.
  107.        *  @param  mode  Whether the buffer can read, or write, or both.
  108.        *
  109.        *  The default constructor initializes the parent class using its
  110.        *  own default ctor.
  111.       */
  112.       explicit
  113.       basic_stringbuf(ios_base::openmode __mode = ios_base::in | ios_base::out)
  114.       : __streambuf_type(), _M_mode(), _M_string()
  115.       { _M_stringbuf_init(__mode); }
  116.  
  117.       /**
  118.        *  @brief  Starts with an existing string buffer.
  119.        *  @param  str  A string to copy as a starting buffer.
  120.        *  @param  mode  Whether the buffer can read, or write, or both.
  121.        *
  122.        *  This constructor initializes the parent class using its
  123.        *  own default ctor.
  124.       */
  125.       explicit
  126.       basic_stringbuf(const __string_type& __str,
  127.               ios_base::openmode __mode = ios_base::in | ios_base::out)
  128.       : __streambuf_type(), _M_mode(), _M_string(__str.data(), __str.size())
  129.       { _M_stringbuf_init(__mode); }
  130.  
  131.       // Get and set:
  132.       /**
  133.        *  @brief  Copying out the string buffer.
  134.        *  @return  A copy of one of the underlying sequences.
  135.        *
  136.        *  "If the buffer is only created in input mode, the underlying
  137.        *  character sequence is equal to the input sequence; otherwise, it
  138.        *  is equal to the output sequence." [27.7.1.2]/1
  139.       */
  140.       __string_type
  141.       str() const
  142.       {
  143.     const bool __testout = this->_M_mode & ios_base::out;
  144.     if (__testout)
  145.       {
  146.         // The current egptr() may not be the actual string end.
  147.         if (this->pptr() > this->egptr())
  148.           return __string_type(this->pbase(), this->pptr());
  149.         else
  150.            return __string_type(this->pbase(), this->egptr());
  151.       }
  152.     else
  153.       return _M_string;
  154.       }
  155.  
  156.       /**
  157.        *  @brief  Setting a new buffer.
  158.        *  @param  s  The string to use as a new sequence.
  159.        *
  160.        *  Deallocates any previous stored sequence, then copies @a s to
  161.        *  use as a new one.
  162.       */
  163.       void
  164.       str(const __string_type& __s)
  165.       {
  166.     // Cannot use _M_string = __s, since v3 strings are COW.
  167.     _M_string.assign(__s.data(), __s.size());
  168.     _M_stringbuf_init(this->_M_mode);
  169.       }
  170.  
  171.     protected:
  172.       // Common initialization code for both ctors goes here.
  173.       /**
  174.        *  @if maint
  175.        *  @doctodo
  176.        *  @endif
  177.       */
  178.       void
  179.       _M_stringbuf_init(ios_base::openmode __mode)
  180.       {
  181.     this->_M_mode = __mode;
  182.  
  183.     __size_type __len = 0;
  184.     if (this->_M_mode & (ios_base::ate | ios_base::app))
  185.       __len = _M_string.size();
  186.     _M_sync(const_cast<char_type*>(_M_string.data()), 0, __len);
  187.       }
  188.  
  189.       // [documentation is inherited]
  190.       virtual int_type
  191.       underflow();
  192.  
  193.       // [documentation is inherited]
  194.       virtual int_type
  195.       pbackfail(int_type __c = traits_type::eof());
  196.  
  197.       // [documentation is inherited]
  198.       virtual int_type
  199.       overflow(int_type __c = traits_type::eof());
  200.  
  201.       /**
  202.        *  @brief  Manipulates the buffer.
  203.        *  @param  s  Pointer to a buffer area.
  204.        *  @param  n  Size of @a s.
  205.        *  @return  @c this
  206.        *
  207.        *  If no buffer has already been created, and both @a s and @a n are
  208.        *  non-zero, then @c s is used as a buffer; see
  209.        *  http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#2
  210.        *  for more.
  211.       */
  212.       virtual __streambuf_type*
  213.       setbuf(char_type* __s, streamsize __n)
  214.       {
  215.     if (__s && __n >= 0)
  216.       {
  217.         // This is implementation-defined behavior, and assumes
  218.         // that an external char_type array of length __n exists
  219.         // and has been pre-allocated. If this is not the case,
  220.         // things will quickly blow up.
  221.         
  222.         // Step 1: Destroy the current internal array.
  223.         _M_string = __string_type(__s, __n);
  224.         
  225.         // Step 2: Use the external array.
  226.         _M_sync(__s, 0, 0);
  227.       }
  228.     return this;
  229.       }
  230.  
  231.       // [documentation is inherited]
  232.       virtual pos_type
  233.       seekoff(off_type __off, ios_base::seekdir __way,
  234.           ios_base::openmode __mode = ios_base::in | ios_base::out);
  235.  
  236.       // [documentation is inherited]
  237.       virtual pos_type
  238.       seekpos(pos_type __sp,
  239.           ios_base::openmode __mode = ios_base::in | ios_base::out);
  240.  
  241.       // Internal function for correctly updating the internal buffer
  242.       // for a particular _M_string, due to initialization or
  243.       // re-sizing of an existing _M_string.
  244.       // Assumes: contents of _M_string and internal buffer match exactly.
  245.       // __i == _M_in_cur - _M_in_beg
  246.       // __o == _M_out_cur - _M_out_beg
  247.       /**
  248.        *  @if maint
  249.        *  @doctodo
  250.        *  @endif
  251.       */
  252.       void
  253.       _M_sync(char_type* __base, __size_type __i, __size_type __o)
  254.       {
  255.     const bool __testin = this->_M_mode & ios_base::in;
  256.     const bool __testout = this->_M_mode & ios_base::out;
  257.     const __size_type __len = _M_string.size();
  258.  
  259.     if (__testin)
  260.       this->setg(__base, __base + __i, __base + __len);
  261.     if (__testout)
  262.       {
  263.         this->setp(__base, __base + _M_string.capacity());
  264.         this->pbump(__o);
  265.         // We need a pointer to the string end anyway, even when
  266.         // !__testin: in that case, however, for the correct
  267.         // functioning of the streambuf inlines all the get area
  268.         // pointers must be identical.
  269.         if (!__testin)
  270.           this->setg(__base + __len, __base + __len, __base + __len);
  271.       }
  272.       }
  273.  
  274.       // Internal function for correctly updating egptr() to the actual
  275.       // string end.
  276.       void
  277.       _M_update_egptr()
  278.       {
  279.     const bool __testin = this->_M_mode & ios_base::in;
  280.     const bool __testout = this->_M_mode & ios_base::out;
  281.  
  282.     if (__testout && this->pptr() > this->egptr())
  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.  
  291.   // [27.7.2] Template class basic_istringstream
  292.   /**
  293.    *  @brief  Controlling input for std::string.
  294.    *
  295.    *  This class supports reading from objects of type std::basic_string,
  296.    *  using the inherited functions from std::basic_istream.  To control
  297.    *  the associated sequence, an instance of std::basic_stringbuf is used,
  298.    *  which this page refers to as @c sb.
  299.   */
  300.   template<typename _CharT, typename _Traits, typename _Alloc>
  301.     class basic_istringstream : public basic_istream<_CharT, _Traits>
  302.     {
  303.     public:
  304.       // Types:
  305.       typedef _CharT                     char_type;
  306.       typedef _Traits                     traits_type;
  307.       // _GLIBCXX_RESOLVE_LIB_DEFECTS
  308.       // 251. basic_stringbuf missing allocator_type
  309.       typedef _Alloc                           allocator_type;
  310.       typedef typename traits_type::int_type         int_type;
  311.       typedef typename traits_type::pos_type         pos_type;
  312.       typedef typename traits_type::off_type         off_type;
  313.  
  314.       // Non-standard types:
  315.       typedef basic_string<_CharT, _Traits, _Alloc>     __string_type;
  316.       typedef basic_stringbuf<_CharT, _Traits, _Alloc>     __stringbuf_type;
  317.       typedef basic_istream<char_type, traits_type>    __istream_type;
  318.  
  319.     private:
  320.       /**
  321.        *  @if maint
  322.        *  @doctodo
  323.        *  @endif
  324.       */
  325.       __stringbuf_type    _M_stringbuf;
  326.  
  327.     public:
  328.       // Constructors:
  329.       /**
  330.        *  @brief  Default constructor starts with an empty string buffer.
  331.        *  @param  mode  Whether the buffer can read, or write, or both.
  332.        *
  333.        *  @c ios_base::in is automatically included in @a mode.
  334.        *
  335.        *  Initializes @c sb using @c mode|in, and passes @c &sb to the base
  336.        *  class initializer.  Does not allocate any buffer.
  337.        *
  338.        *  @if maint
  339.        *  That's a lie.  We initialize the base class with NULL, because the
  340.        *  string class does its own memory management.
  341.        *  @endif
  342.       */
  343.       explicit
  344.       basic_istringstream(ios_base::openmode __mode = ios_base::in)
  345.       : __istream_type(), _M_stringbuf(__mode | ios_base::in)
  346.       { this->init(&_M_stringbuf); }
  347.  
  348.       /**
  349.        *  @brief  Starts with an existing string buffer.
  350.        *  @param  str  A string to copy as a starting buffer.
  351.        *  @param  mode  Whether the buffer can read, or write, or both.
  352.        *
  353.        *  @c ios_base::in is automatically included in @a mode.
  354.        *
  355.        *  Initializes @c sb using @a str and @c mode|in, and passes @c &sb
  356.        *  to the base class initializer.
  357.        *
  358.        *  @if maint
  359.        *  That's a lie.  We initialize the base class with NULL, because the
  360.        *  string class does its own memory management.
  361.        *  @endif
  362.       */
  363.       explicit
  364.       basic_istringstream(const __string_type& __str,
  365.               ios_base::openmode __mode = ios_base::in)
  366.       : __istream_type(), _M_stringbuf(__str, __mode | ios_base::in)
  367.       { this->init(&_M_stringbuf); }
  368.  
  369.       /**
  370.        *  @brief  The destructor does nothing.
  371.        *
  372.        *  The buffer is deallocated by the stringbuf object, not the
  373.        *  formatting stream.
  374.       */
  375.       ~basic_istringstream()
  376.       { }
  377.  
  378.       // Members:
  379.       /**
  380.        *  @brief  Accessing the underlying buffer.
  381.        *  @return  The current basic_stringbuf buffer.
  382.        *
  383.        *  This hides both signatures of std::basic_ios::rdbuf().
  384.       */
  385.       __stringbuf_type*
  386.       rdbuf() const
  387.       { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
  388.  
  389.       /**
  390.        *  @brief  Copying out the string buffer.
  391.        *  @return  @c rdbuf()->str()
  392.       */
  393.       __string_type
  394.       str() const
  395.       { return _M_stringbuf.str(); }
  396.  
  397.       /**
  398.        *  @brief  Setting a new buffer.
  399.        *  @param  s  The string to use as a new sequence.
  400.        *
  401.        *  Calls @c rdbuf()->str(s).
  402.       */
  403.       void
  404.       str(const __string_type& __s)
  405.       { _M_stringbuf.str(__s); }
  406.     };
  407.  
  408.  
  409.   // [27.7.3] Template class basic_ostringstream
  410.   /**
  411.    *  @brief  Controlling output for std::string.
  412.    *
  413.    *  This class supports writing to objects of type std::basic_string,
  414.    *  using the inherited functions from std::basic_ostream.  To control
  415.    *  the associated sequence, an instance of std::basic_stringbuf is used,
  416.    *  which this page refers to as @c sb.
  417.   */
  418.   template <typename _CharT, typename _Traits, typename _Alloc>
  419.     class basic_ostringstream : public basic_ostream<_CharT, _Traits>
  420.     {
  421.     public:
  422.       // Types:
  423.       typedef _CharT                     char_type;
  424.       typedef _Traits                     traits_type;
  425.       // _GLIBCXX_RESOLVE_LIB_DEFECTS
  426.       // 251. basic_stringbuf missing allocator_type
  427.       typedef _Alloc                           allocator_type;
  428.       typedef typename traits_type::int_type         int_type;
  429.       typedef typename traits_type::pos_type         pos_type;
  430.       typedef typename traits_type::off_type         off_type;
  431.  
  432.       // Non-standard types:
  433.       typedef basic_string<_CharT, _Traits, _Alloc>     __string_type;
  434.       typedef basic_stringbuf<_CharT, _Traits, _Alloc>     __stringbuf_type;
  435.       typedef basic_ostream<char_type, traits_type>    __ostream_type;
  436.  
  437.     private:
  438.       /**
  439.        *  @if maint
  440.        *  @doctodo
  441.        *  @endif
  442.       */
  443.       __stringbuf_type    _M_stringbuf;
  444.  
  445.     public:
  446.       // Constructors/destructor:
  447.       /**
  448.        *  @brief  Default constructor starts with an empty string buffer.
  449.        *  @param  mode  Whether the buffer can read, or write, or both.
  450.        *
  451.        *  @c ios_base::out is automatically included in @a mode.
  452.        *
  453.        *  Initializes @c sb using @c mode|out, and passes @c &sb to the base
  454.        *  class initializer.  Does not allocate any buffer.
  455.        *
  456.        *  @if maint
  457.        *  That's a lie.  We initialize the base class with NULL, because the
  458.        *  string class does its own memory management.
  459.        *  @endif
  460.       */
  461.       explicit
  462.       basic_ostringstream(ios_base::openmode __mode = ios_base::out)
  463.       : __ostream_type(), _M_stringbuf(__mode | ios_base::out)
  464.       { this->init(&_M_stringbuf); }
  465.  
  466.       /**
  467.        *  @brief  Starts with an existing string buffer.
  468.        *  @param  str  A string to copy as a starting buffer.
  469.        *  @param  mode  Whether the buffer can read, or write, or both.
  470.        *
  471.        *  @c ios_base::out is automatically included in @a mode.
  472.        *
  473.        *  Initializes @c sb using @a str and @c mode|out, and passes @c &sb
  474.        *  to the base class initializer.
  475.        *
  476.        *  @if maint
  477.        *  That's a lie.  We initialize the base class with NULL, because the
  478.        *  string class does its own memory management.
  479.        *  @endif
  480.       */
  481.       explicit
  482.       basic_ostringstream(const __string_type& __str,
  483.               ios_base::openmode __mode = ios_base::out)
  484.       : __ostream_type(), _M_stringbuf(__str, __mode | ios_base::out)
  485.       { this->init(&_M_stringbuf); }
  486.  
  487.       /**
  488.        *  @brief  The destructor does nothing.
  489.        *
  490.        *  The buffer is deallocated by the stringbuf object, not the
  491.        *  formatting stream.
  492.       */
  493.       ~basic_ostringstream()
  494.       { }
  495.  
  496.       // Members:
  497.       /**
  498.        *  @brief  Accessing the underlying buffer.
  499.        *  @return  The current basic_stringbuf buffer.
  500.        *
  501.        *  This hides both signatures of std::basic_ios::rdbuf().
  502.       */
  503.       __stringbuf_type*
  504.       rdbuf() const
  505.       { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
  506.  
  507.       /**
  508.        *  @brief  Copying out the string buffer.
  509.        *  @return  @c rdbuf()->str()
  510.       */
  511.       __string_type
  512.       str() const
  513.       { return _M_stringbuf.str(); }
  514.  
  515.       /**
  516.        *  @brief  Setting a new buffer.
  517.        *  @param  s  The string to use as a new sequence.
  518.        *
  519.        *  Calls @c rdbuf()->str(s).
  520.       */
  521.       void
  522.       str(const __string_type& __s)
  523.       { _M_stringbuf.str(__s); }
  524.     };
  525.  
  526.  
  527.   // [27.7.4] Template class basic_stringstream
  528.   /**
  529.    *  @brief  Controlling input and output for std::string.
  530.    *
  531.    *  This class supports reading from and writing to objects of type
  532.    *  std::basic_string, using the inherited functions from
  533.    *  std::basic_iostream.  To control the associated sequence, an instance
  534.    *  of std::basic_stringbuf is used, which this page refers to as @c sb.
  535.   */
  536.   template <typename _CharT, typename _Traits, typename _Alloc>
  537.     class basic_stringstream : public basic_iostream<_CharT, _Traits>
  538.     {
  539.     public:
  540.       // Types:
  541.       typedef _CharT                     char_type;
  542.       typedef _Traits                     traits_type;
  543.       // _GLIBCXX_RESOLVE_LIB_DEFECTS
  544.       // 251. basic_stringbuf missing allocator_type
  545.       typedef _Alloc                           allocator_type;
  546.       typedef typename traits_type::int_type         int_type;
  547.       typedef typename traits_type::pos_type         pos_type;
  548.       typedef typename traits_type::off_type         off_type;
  549.  
  550.       // Non-standard Types:
  551.       typedef basic_string<_CharT, _Traits, _Alloc>     __string_type;
  552.       typedef basic_stringbuf<_CharT, _Traits, _Alloc>     __stringbuf_type;
  553.       typedef basic_iostream<char_type, traits_type>    __iostream_type;
  554.  
  555.     private:
  556.       /**
  557.        *  @if maint
  558.        *  @doctodo
  559.        *  @endif
  560.       */
  561.       __stringbuf_type    _M_stringbuf;
  562.  
  563.     public:
  564.       // Constructors/destructors
  565.       /**
  566.        *  @brief  Default constructor starts with an empty string buffer.
  567.        *  @param  mode  Whether the buffer can read, or write, or both.
  568.        *
  569.        *  Initializes @c sb using @c mode, and passes @c &sb to the base
  570.        *  class initializer.  Does not allocate any buffer.
  571.        *
  572.        *  @if maint
  573.        *  That's a lie.  We initialize the base class with NULL, because the
  574.        *  string class does its own memory management.
  575.        *  @endif
  576.       */
  577.       explicit
  578.       basic_stringstream(ios_base::openmode __m = ios_base::out | ios_base::in)
  579.       : __iostream_type(), _M_stringbuf(__m)
  580.       { this->init(&_M_stringbuf); }
  581.  
  582.       /**
  583.        *  @brief  Starts with an existing string buffer.
  584.        *  @param  str  A string to copy as a starting buffer.
  585.        *  @param  mode  Whether the buffer can read, or write, or both.
  586.        *
  587.        *  Initializes @c sb using @a str and @c mode, and passes @c &sb
  588.        *  to the base class initializer.
  589.        *
  590.        *  @if maint
  591.        *  That's a lie.  We initialize the base class with NULL, because the
  592.        *  string class does its own memory management.
  593.        *  @endif
  594.       */
  595.       explicit
  596.       basic_stringstream(const __string_type& __str,
  597.              ios_base::openmode __m = ios_base::out | ios_base::in)
  598.       : __iostream_type(), _M_stringbuf(__str, __m)
  599.       { this->init(&_M_stringbuf); }
  600.  
  601.       /**
  602.        *  @brief  The destructor does nothing.
  603.        *
  604.        *  The buffer is deallocated by the stringbuf object, not the
  605.        *  formatting stream.
  606.       */
  607.       ~basic_stringstream()
  608.       { }
  609.  
  610.       // Members:
  611.       /**
  612.        *  @brief  Accessing the underlying buffer.
  613.        *  @return  The current basic_stringbuf buffer.
  614.        *
  615.        *  This hides both signatures of std::basic_ios::rdbuf().
  616.       */
  617.       __stringbuf_type*
  618.       rdbuf() const
  619.       { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
  620.  
  621.       /**
  622.        *  @brief  Copying out the string buffer.
  623.        *  @return  @c rdbuf()->str()
  624.       */
  625.       __string_type
  626.       str() const
  627.       { return _M_stringbuf.str(); }
  628.  
  629.       /**
  630.        *  @brief  Setting a new buffer.
  631.        *  @param  s  The string to use as a new sequence.
  632.        *
  633.        *  Calls @c rdbuf()->str(s).
  634.       */
  635.       void
  636.       str(const __string_type& __s)
  637.       { _M_stringbuf.str(__s); }
  638.     };
  639. } // namespace std
  640.  
  641. #ifndef _GLIBCXX_EXPORT_TEMPLATE
  642. # include <bits/sstream.tcc>
  643. #endif
  644.  
  645. #endif /* _GLIBCXX_SSTREAM */
  646.