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

  1. // ostream classes -*- C++ -*-
  2.  
  3. // Copyright (C) 1997, 1998, 1999, 2000, 2001, 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.6.2  Output streams
  33. //
  34.  
  35. #ifndef _OSTREAM_TCC
  36. #define _OSTREAM_TCC 1
  37.  
  38. #pragma GCC system_header
  39.  
  40. #include <locale>
  41.  
  42. namespace std
  43. {
  44.   template<typename _CharT, typename _Traits>
  45.     basic_ostream<_CharT, _Traits>::sentry::
  46.     sentry(basic_ostream<_CharT, _Traits>& __os)
  47.     : _M_ok(false), _M_os(__os)
  48.     {
  49.       // XXX MT
  50.       if (__os.tie() && __os.good())
  51.     __os.tie()->flush();
  52.  
  53.       if (__os.good())
  54.     _M_ok = true;
  55.       else
  56.     __os.setstate(ios_base::failbit);
  57.     }
  58.  
  59.   template<typename _CharT, typename _Traits>
  60.     basic_ostream<_CharT, _Traits>&
  61.     basic_ostream<_CharT, _Traits>::
  62.     operator<<(__ostream_type& (*__pf)(__ostream_type&))
  63.     {
  64.       // _GLIBCXX_RESOLVE_LIB_DEFECTS
  65.       // DR 60. What is a formatted input function?
  66.       // The inserters for manipulators are *not* formatted output functions.
  67.       return __pf(*this);
  68.     }
  69.  
  70.   template<typename _CharT, typename _Traits>
  71.     basic_ostream<_CharT, _Traits>&
  72.     basic_ostream<_CharT, _Traits>::
  73.     operator<<(__ios_type& (*__pf)(__ios_type&))
  74.     {
  75.       // _GLIBCXX_RESOLVE_LIB_DEFECTS
  76.       // DR 60. What is a formatted input function?
  77.       // The inserters for manipulators are *not* formatted output functions.
  78.       __pf(*this);
  79.       return *this;
  80.     }
  81.  
  82.   template<typename _CharT, typename _Traits>
  83.     basic_ostream<_CharT, _Traits>&
  84.     basic_ostream<_CharT, _Traits>::
  85.     operator<<(ios_base& (*__pf)(ios_base&))
  86.     {
  87.       // _GLIBCXX_RESOLVE_LIB_DEFECTS
  88.       // DR 60. What is a formatted input function?
  89.       // The inserters for manipulators are *not* formatted output functions.
  90.       __pf(*this);
  91.       return *this;
  92.     }
  93.  
  94.   template<typename _CharT, typename _Traits>
  95.     basic_ostream<_CharT, _Traits>&
  96.     basic_ostream<_CharT, _Traits>::
  97.     operator<<(bool __n)
  98.     {
  99.       sentry __cerb(*this);
  100.       if (__cerb)
  101.     {
  102.       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  103.       try
  104.         {
  105.           const __num_put_type& __np = __check_facet(this->_M_num_put);
  106.           if (__np.put(*this, *this, this->fill(), __n).failed())
  107.         __err |= ios_base::badbit;
  108.         }
  109.       catch(...)
  110.         { this->_M_setstate(ios_base::badbit); }
  111.       if (__err)
  112.         this->setstate(__err);
  113.     }
  114.       return *this;
  115.     }
  116.  
  117.   template<typename _CharT, typename _Traits>
  118.     basic_ostream<_CharT, _Traits>&
  119.     basic_ostream<_CharT, _Traits>::
  120.     operator<<(long __n)
  121.     {
  122.       sentry __cerb(*this);
  123.       if (__cerb)
  124.     {
  125.       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  126.       try
  127.         {
  128.           bool __b = false;
  129.           const char_type __c = this->fill();
  130.           const ios_base::fmtflags __fmt = (this->flags()
  131.                         & ios_base::basefield);
  132.           const __num_put_type& __np = __check_facet(this->_M_num_put);
  133.           if ((__fmt & ios_base::oct) || (__fmt & ios_base::hex))
  134.         {
  135.           const unsigned long __l = static_cast<unsigned long>(__n);
  136.           __b = __np.put(*this, *this, __c, __l).failed();
  137.         }
  138.           else
  139.         __b = __np.put(*this, *this, __c, __n).failed();
  140.           if (__b)
  141.         __err |= ios_base::badbit;
  142.         }
  143.       catch(...)
  144.         { this->_M_setstate(ios_base::badbit); }
  145.       if (__err)
  146.         this->setstate(__err);
  147.     }
  148.       return *this;
  149.     }
  150.  
  151.   template<typename _CharT, typename _Traits>
  152.     basic_ostream<_CharT, _Traits>&
  153.     basic_ostream<_CharT, _Traits>::
  154.     operator<<(unsigned long __n)
  155.     {
  156.       sentry __cerb(*this);
  157.       if (__cerb)
  158.     {
  159.       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  160.       try
  161.         {
  162.           const __num_put_type& __np = __check_facet(this->_M_num_put);
  163.           if (__np.put(*this, *this, this->fill(), __n).failed())
  164.         __err |= ios_base::badbit;
  165.         }
  166.       catch(...)
  167.         { this->_M_setstate(ios_base::badbit); }
  168.       if (__err)
  169.         this->setstate(__err);
  170.     }
  171.       return *this;
  172.     }
  173.  
  174. #ifdef _GLIBCXX_USE_LONG_LONG
  175.   template<typename _CharT, typename _Traits>
  176.     basic_ostream<_CharT, _Traits>&
  177.     basic_ostream<_CharT, _Traits>::
  178.     operator<<(long long __n)
  179.     {
  180.       sentry __cerb(*this);
  181.       if (__cerb)
  182.     {
  183.       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  184.       try
  185.         {
  186.           bool __b = false;
  187.           const char_type __c = this->fill();
  188.           const ios_base::fmtflags __fmt = (this->flags()
  189.                         & ios_base::basefield);
  190.           const __num_put_type& __np = __check_facet(this->_M_num_put);
  191.           if ((__fmt & ios_base::oct) || (__fmt & ios_base::hex))
  192.         {
  193.           const unsigned long long __l = (static_cast<
  194.                           unsigned long long>(__n));
  195.           __b = __np.put(*this, *this, __c, __l).failed();
  196.         }
  197.           else
  198.         __b = __np.put(*this, *this, __c, __n).failed();
  199.           if (__b)
  200.         __err |= ios_base::badbit;
  201.         }
  202.       catch(...)
  203.         { this->_M_setstate(ios_base::badbit); }
  204.       if (__err)
  205.         this->setstate(__err);
  206.     }
  207.       return *this;
  208.     }
  209.  
  210.   template<typename _CharT, typename _Traits>
  211.     basic_ostream<_CharT, _Traits>&
  212.     basic_ostream<_CharT, _Traits>::
  213.     operator<<(unsigned long long __n)
  214.     {
  215.       sentry __cerb(*this);
  216.       if (__cerb)
  217.     {
  218.       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  219.       try
  220.         {
  221.           const __num_put_type& __np = __check_facet(this->_M_num_put);
  222.           if (__np.put(*this, *this, this->fill(), __n).failed())
  223.         __err |= ios_base::badbit;
  224.         }
  225.       catch(...)
  226.         { this->_M_setstate(ios_base::badbit); }
  227.       if (__err)
  228.         this->setstate(__err);
  229.     }
  230.       return *this;
  231.     }
  232. #endif
  233.  
  234.   template<typename _CharT, typename _Traits>
  235.     basic_ostream<_CharT, _Traits>&
  236.     basic_ostream<_CharT, _Traits>::
  237.     operator<<(double __n)
  238.     {
  239.       sentry __cerb(*this);
  240.       if (__cerb)
  241.     {
  242.       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  243.       try
  244.         {
  245.           const __num_put_type& __np = __check_facet(this->_M_num_put);
  246.           if (__np.put(*this, *this, this->fill(), __n).failed())
  247.         __err |= ios_base::badbit;
  248.         }
  249.       catch(...)
  250.         { this->_M_setstate(ios_base::badbit); }
  251.       if (__err)
  252.         this->setstate(__err);
  253.     }
  254.       return *this;
  255.     }
  256.  
  257.   template<typename _CharT, typename _Traits>
  258.     basic_ostream<_CharT, _Traits>&
  259.     basic_ostream<_CharT, _Traits>::
  260.     operator<<(long double __n)
  261.     {
  262.       sentry __cerb(*this);
  263.       if (__cerb)
  264.     {
  265.       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  266.       try
  267.         {
  268.           const __num_put_type& __np = __check_facet(this->_M_num_put);
  269.           if (__np.put(*this, *this, this->fill(), __n).failed())
  270.         __err |= ios_base::badbit;
  271.         }
  272.       catch(...)
  273.         { this->_M_setstate(ios_base::badbit); }
  274.       if (__err)
  275.         this->setstate(__err);
  276.     }
  277.       return *this;
  278.     }
  279.  
  280.   template<typename _CharT, typename _Traits>
  281.     basic_ostream<_CharT, _Traits>&
  282.     basic_ostream<_CharT, _Traits>::
  283.     operator<<(const void* __n)
  284.     {
  285.       sentry __cerb(*this);
  286.       if (__cerb)
  287.     {
  288.       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  289.       try
  290.         {
  291.           const __num_put_type& __np = __check_facet(this->_M_num_put);
  292.           if (__np.put(*this, *this, this->fill(), __n).failed())
  293.         __err |= ios_base::badbit;
  294.         }
  295.       catch(...)
  296.         { this->_M_setstate(ios_base::badbit); }
  297.       if (__err)
  298.         this->setstate(__err);
  299.     }
  300.       return *this;
  301.     }
  302.  
  303.   template<typename _CharT, typename _Traits>
  304.     basic_ostream<_CharT, _Traits>&
  305.     basic_ostream<_CharT, _Traits>::
  306.     operator<<(__streambuf_type* __sbin)
  307.     {
  308.       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  309.       sentry __cerb(*this);
  310.       if (__cerb && __sbin)
  311.     {
  312.       try
  313.         {
  314.           if (!__copy_streambufs(__sbin, this->rdbuf()))
  315.         __err |= ios_base::failbit;
  316.         }
  317.       catch(...)
  318.         { this->_M_setstate(ios_base::failbit); }
  319.     }
  320.       else if (!__sbin)
  321.     __err |= ios_base::badbit;
  322.       if (__err)
  323.     this->setstate(__err);
  324.       return *this;
  325.     }
  326.  
  327.   template<typename _CharT, typename _Traits>
  328.     basic_ostream<_CharT, _Traits>&
  329.     basic_ostream<_CharT, _Traits>::
  330.     put(char_type __c)
  331.     {
  332.       // _GLIBCXX_RESOLVE_LIB_DEFECTS
  333.       // DR 60. What is a formatted input function?
  334.       // basic_ostream::put(char_type) is an unformatted output function.
  335.       // DR 63. Exception-handling policy for unformatted output.
  336.       // Unformatted output functions should catch exceptions thrown
  337.       // from streambuf members.
  338.       sentry __cerb(*this);
  339.       if (__cerb)
  340.     {
  341.       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  342.       try
  343.         {
  344.           const int_type __put = this->rdbuf()->sputc(__c);
  345.           if (traits_type::eq_int_type(__put, traits_type::eof()))
  346.         __err |= ios_base::badbit;
  347.         }
  348.       catch (...)
  349.         { this->_M_setstate(ios_base::badbit); }
  350.       if (__err)
  351.         this->setstate(__err);
  352.     }
  353.       return *this;
  354.     }
  355.  
  356.   template<typename _CharT, typename _Traits>
  357.     basic_ostream<_CharT, _Traits>&
  358.     basic_ostream<_CharT, _Traits>::
  359.     write(const _CharT* __s, streamsize __n)
  360.     {
  361.       // _GLIBCXX_RESOLVE_LIB_DEFECTS
  362.       // DR 60. What is a formatted input function?
  363.       // basic_ostream::write(const char_type*, streamsize) is an
  364.       // unformatted output function.
  365.       // DR 63. Exception-handling policy for unformatted output.
  366.       // Unformatted output functions should catch exceptions thrown
  367.       // from streambuf members.
  368.       sentry __cerb(*this);
  369.       if (__cerb)
  370.     {
  371.       try
  372.         { _M_write(__s, __n); }
  373.       catch (...)
  374.         { this->_M_setstate(ios_base::badbit); }
  375.     }
  376.       return *this;
  377.     }
  378.  
  379.   template<typename _CharT, typename _Traits>
  380.     basic_ostream<_CharT, _Traits>&
  381.     basic_ostream<_CharT, _Traits>::
  382.     flush()
  383.     {
  384.       // _GLIBCXX_RESOLVE_LIB_DEFECTS
  385.       // DR 60. What is a formatted input function?
  386.       // basic_ostream::flush() is *not* an unformatted output function.
  387.       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  388.       try
  389.     {
  390.       if (this->rdbuf() && this->rdbuf()->pubsync() == -1)
  391.         __err |= ios_base::badbit;
  392.     }
  393.       catch(...)
  394.     { this->_M_setstate(ios_base::badbit); }
  395.       if (__err)
  396.     this->setstate(__err);
  397.       return *this;
  398.     }
  399.  
  400.   template<typename _CharT, typename _Traits>
  401.     typename basic_ostream<_CharT, _Traits>::pos_type
  402.     basic_ostream<_CharT, _Traits>::
  403.     tellp()
  404.     {
  405.       pos_type __ret = pos_type(-1);
  406.       try
  407.     {
  408.       if (!this->fail())
  409.         __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out);
  410.     }
  411.       catch(...)
  412.     { this->_M_setstate(ios_base::badbit); }
  413.       return __ret;
  414.     }
  415.  
  416.   template<typename _CharT, typename _Traits>
  417.     basic_ostream<_CharT, _Traits>&
  418.     basic_ostream<_CharT, _Traits>::
  419.     seekp(pos_type __pos)
  420.     {
  421.       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  422.       try
  423.     {
  424.       if (!this->fail())
  425.         {
  426.           // _GLIBCXX_RESOLVE_LIB_DEFECTS
  427.           // 136.  seekp, seekg setting wrong streams?
  428.           const pos_type __p = this->rdbuf()->pubseekpos(__pos,
  429.                                  ios_base::out);
  430.  
  431.           // 129. Need error indication from seekp() and seekg()
  432.           if (__p == pos_type(off_type(-1)))
  433.         __err |= ios_base::failbit;
  434.         }
  435.     }
  436.       catch(...)
  437.     { this->_M_setstate(ios_base::badbit); }
  438.       if (__err)
  439.     this->setstate(__err);
  440.       return *this;
  441.     }
  442.  
  443.   template<typename _CharT, typename _Traits>
  444.     basic_ostream<_CharT, _Traits>&
  445.     basic_ostream<_CharT, _Traits>::
  446.     seekp(off_type __off, ios_base::seekdir __dir)
  447.     {
  448.       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  449.       try
  450.     {
  451.       if (!this->fail())
  452.         {
  453.           // _GLIBCXX_RESOLVE_LIB_DEFECTS
  454.           // 136.  seekp, seekg setting wrong streams?
  455.           const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir,
  456.                                  ios_base::out);
  457.  
  458.           // 129. Need error indication from seekp() and seekg()
  459.           if (__p == pos_type(off_type(-1)))
  460.         __err |= ios_base::failbit;
  461.         }
  462.     }
  463.       catch(...)
  464.     { this->_M_setstate(ios_base::badbit); }
  465.       if (__err)
  466.     this->setstate(__err);
  467.       return *this;
  468.     }
  469.  
  470.   // 27.6.2.5.4 Character inserters.
  471.   template<typename _CharT, typename _Traits>
  472.     basic_ostream<_CharT, _Traits>&
  473.     operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c)
  474.     {
  475.       typedef basic_ostream<_CharT, _Traits> __ostream_type;
  476.       typename __ostream_type::sentry __cerb(__out);
  477.       if (__cerb)
  478.     {
  479.       try
  480.         {
  481.           const streamsize __w = __out.width();
  482.           streamsize __len = 1;
  483.           _CharT* __cs = &__c;
  484.           if (__w > __len)
  485.         {
  486.           __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
  487.                                    * __w));
  488.           __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __cs,
  489.                          &__c, __w, __len, false);
  490.           __len = __w;
  491.         }
  492.           __out._M_write(__cs, __len);
  493.           __out.width(0);
  494.         }
  495.       catch(...)
  496.         { __out._M_setstate(ios_base::badbit); }
  497.     }
  498.       return __out;
  499.     }
  500.  
  501.   // Specializations.
  502.   template <class _Traits>
  503.     basic_ostream<char, _Traits>&
  504.     operator<<(basic_ostream<char, _Traits>& __out, char __c)
  505.     {
  506.       typedef basic_ostream<char, _Traits> __ostream_type;
  507.       typename __ostream_type::sentry __cerb(__out);
  508.       if (__cerb)
  509.     {
  510.       try
  511.         {
  512.           const streamsize __w = __out.width();
  513.           streamsize __len = 1;
  514.           char* __cs = &__c;
  515.           if (__w > __len)
  516.         {
  517.           __cs = static_cast<char*>(__builtin_alloca(__w));
  518.           __pad<char, _Traits>::_S_pad(__out, __out.fill(), __cs,
  519.                            &__c, __w, __len, false);
  520.           __len = __w;
  521.         }
  522.           __out._M_write(__cs, __len);
  523.           __out.width(0);
  524.         }
  525.       catch(...)
  526.         { __out._M_setstate(ios_base::badbit); }
  527.     }
  528.       return __out;
  529.      }
  530.  
  531.   template<typename _CharT, typename _Traits>
  532.     basic_ostream<_CharT, _Traits>&
  533.     operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s)
  534.     {
  535.       typedef basic_ostream<_CharT, _Traits> __ostream_type;
  536.       typename __ostream_type::sentry __cerb(__out);
  537.       if (__cerb && __s)
  538.     {
  539.       try
  540.         {
  541.           const streamsize __w = __out.width();
  542.           streamsize __len = static_cast<streamsize>(_Traits::length(__s));
  543.           if (__w > __len)
  544.         {
  545.           _CharT* __cs = (static_cast<
  546.                   _CharT*>(__builtin_alloca(sizeof(_CharT)
  547.                                 * __w)));
  548.           __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __cs,
  549.                          __s, __w, __len, false);
  550.           __s = __cs;
  551.           __len = __w;
  552.         }
  553.           __out._M_write(__s, __len);
  554.           __out.width(0);
  555.         }
  556.       catch(...)
  557.         { __out._M_setstate(ios_base::badbit); }
  558.     }
  559.       else if (!__s)
  560.     __out.setstate(ios_base::badbit);
  561.       return __out;
  562.     }
  563.  
  564.   template<typename _CharT, typename _Traits>
  565.     basic_ostream<_CharT, _Traits>&
  566.     operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s)
  567.     {
  568.       typedef basic_ostream<_CharT, _Traits> __ostream_type;
  569.       // _GLIBCXX_RESOLVE_LIB_DEFECTS
  570.       // 167.  Improper use of traits_type::length()
  571.       // Note that this is only in 'Review' status.
  572.       typedef char_traits<char>             __traits_type;
  573.       typename __ostream_type::sentry __cerb(__out);
  574.       if (__cerb && __s)
  575.     {
  576.       size_t __clen = __traits_type::length(__s);
  577.       _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
  578.                                    * __clen));
  579.       for (size_t  __i = 0; __i < __clen; ++__i)
  580.         __ws[__i] = __out.widen(__s[__i]);
  581.       _CharT* __str = __ws;
  582.  
  583.       try
  584.         {
  585.           const streamsize __w = __out.width();
  586.           streamsize __len = static_cast<streamsize>(__clen);
  587.           if (__w > __len)
  588.         {
  589.           _CharT* __cs = (static_cast<
  590.                   _CharT*>(__builtin_alloca(sizeof(_CharT)
  591.                                 * __w)));
  592.           __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __cs,
  593.                          __ws, __w, __len, false);
  594.           __str = __cs;
  595.           __len = __w;
  596.         }
  597.           __out._M_write(__str, __len);
  598.           __out.width(0);
  599.         }
  600.       catch(...)
  601.         { __out._M_setstate(ios_base::badbit); }
  602.     }
  603.       else if (!__s)
  604.     __out.setstate(ios_base::badbit);
  605.       return __out;
  606.     }
  607.  
  608.   // Partial specializations.
  609.   template<class _Traits>
  610.     basic_ostream<char, _Traits>&
  611.     operator<<(basic_ostream<char, _Traits>& __out, const char* __s)
  612.     {
  613.       typedef basic_ostream<char, _Traits> __ostream_type;
  614.       typename __ostream_type::sentry __cerb(__out);
  615.       if (__cerb && __s)
  616.     {
  617.       try
  618.         {
  619.           const streamsize __w = __out.width();
  620.           streamsize __len = static_cast<streamsize>(_Traits::length(__s));
  621.           if (__w > __len)
  622.         {
  623.           char* __cs = static_cast<char*>(__builtin_alloca(__w));
  624.           __pad<char, _Traits>::_S_pad(__out, __out.fill(), __cs,
  625.                          __s, __w, __len, false);
  626.           __s = __cs;
  627.           __len = __w;
  628.         }
  629.           __out._M_write(__s, __len);
  630.           __out.width(0);
  631.         }
  632.       catch(...)
  633.         { __out._M_setstate(ios_base::badbit); }
  634.     }
  635.       else if (!__s)
  636.     __out.setstate(ios_base::badbit);
  637.       return __out;
  638.     }
  639.  
  640.   // 21.3.7.9 basic_string::operator<<
  641.   template<typename _CharT, typename _Traits, typename _Alloc>
  642.     basic_ostream<_CharT, _Traits>&
  643.     operator<<(basic_ostream<_CharT, _Traits>& __out,
  644.            const basic_string<_CharT, _Traits, _Alloc>& __str)
  645.     {
  646.       typedef basic_ostream<_CharT, _Traits> __ostream_type;
  647.       typename __ostream_type::sentry __cerb(__out);
  648.       if (__cerb)
  649.     {
  650.       const streamsize __w = __out.width();
  651.       streamsize __len = static_cast<streamsize>(__str.size());
  652.       const _CharT* __s = __str.data();
  653.  
  654.       // _GLIBCXX_RESOLVE_LIB_DEFECTS
  655.       // 25. String operator<< uses width() value wrong
  656.       if (__w > __len)
  657.         {
  658.           _CharT* __cs = (static_cast<
  659.                   _CharT*>(__builtin_alloca(sizeof(_CharT) * __w)));
  660.           __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __cs, __s,
  661.                          __w, __len, false);
  662.           __s = __cs;
  663.           __len = __w;
  664.         }
  665.       __out._M_write(__s, __len);
  666.       __out.width(0);
  667.     }
  668.       return __out;
  669.     }
  670.  
  671.   // Inhibit implicit instantiations for required instantiations,
  672.   // which are defined via explicit instantiations elsewhere.
  673.   // NB:  This syntax is a GNU extension.
  674. #if _GLIBCXX_EXTERN_TEMPLATE
  675.   extern template class basic_ostream<char>;
  676.   extern template ostream& endl(ostream&);
  677.   extern template ostream& ends(ostream&);
  678.   extern template ostream& flush(ostream&);
  679.   extern template ostream& operator<<(ostream&, char);
  680.   extern template ostream& operator<<(ostream&, unsigned char);
  681.   extern template ostream& operator<<(ostream&, signed char);
  682.   extern template ostream& operator<<(ostream&, const char*);
  683.   extern template ostream& operator<<(ostream&, const unsigned char*);
  684.   extern template ostream& operator<<(ostream&, const signed char*);
  685.  
  686. #ifdef _GLIBCXX_USE_WCHAR_T
  687.   extern template class basic_ostream<wchar_t>;
  688.   extern template wostream& endl(wostream&);
  689.   extern template wostream& ends(wostream&);
  690.   extern template wostream& flush(wostream&);
  691.   extern template wostream& operator<<(wostream&, wchar_t);
  692.   extern template wostream& operator<<(wostream&, char);
  693.   extern template wostream& operator<<(wostream&, const wchar_t*);
  694.   extern template wostream& operator<<(wostream&, const char*);
  695. #endif
  696. #endif
  697. } // namespace std
  698.  
  699. #endif
  700.