# streambuf_iterator.h

Go to the documentation of this file.

    00001 // Streambuf iterators
    00002
    00003 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
    00004 // Free Software Foundation, Inc.
    00005 //
    00006 // This file is part of the GNU ISO C++ Library.  This library is free
    00007 // software; you can redistribute it and/or modify it under the
    00008 // terms of the GNU General Public License as published by the
    00009 // Free Software Foundation; either version 2, or (at your option)
    00010 // any later version.
    00011
    00012 // This library is distributed in the hope that it will be useful,
    00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
    00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00015 // GNU General Public License for more details.
    00016
    00017 // You should have received a copy of the GNU General Public License along
    00018 // with this library; see the file COPYING.  If not, write to the Free
    00019 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
    00020 // USA.
    00021
    00022 // As a special exception, you may use this file as part of a free software
    00023 // library without restriction.  Specifically, if other files instantiate
    00024 // templates or use macros or inline functions from this file, or you compile
    00025 // this file and link it with other files to produce an executable, this
    00026 // file does not by itself cause the resulting executable to be covered by
    00027 // the GNU General Public License.  This exception does not however
    00028 // invalidate any other reasons why the executable file might be covered by
    00029 // the GNU General Public License.
    00030
    00031 // XXX Should specialize copy, find algorithms for streambuf iterators.
    00032
    00038 #ifndef _CPP_BITS_STREAMBUF_ITERATOR_H
    00039 #define _CPP_BITS_STREAMBUF_ITERATOR_H 1
    00040
    00041 #pragma GCC system_header
    00042
    00043 namespace std
    00044 {
    00045   // 24.5.3 Template class istreambuf_iterator
    00046   template<typename _CharT, typename _Traits>
    00047     class istreambuf_iterator
    00048     : public iterator<input_iterator_tag, _CharT, typename _Traits::off_type,
    00049                   _CharT*, _CharT&>
    00050     {
    00051     public:
    00052       // Types:
    00053       typedef _CharT                                char_type;
    00054       typedef _Traits                               traits_type;
    00055       typedef typename _Traits::int_type            int_type;
    00056       typedef basic_streambuf<_CharT, _Traits>      streambuf_type;
    00057       typedef basic_istream<_CharT, _Traits>            istream_type;
    00058
    00059     private:
    00060       // 24.5.3 istreambuf_iterator
    00061       // p 1
    00062       // If the end of stream is reached (streambuf_type::sgetc()
    00063       // returns traits_type::eof()), the iterator becomes equal to
    00064       // the "end of stream" iterator value.
    00065       // NB: This implementation assumes the "end of stream" value
    00066       // is EOF, or -1.
    00067       mutable streambuf_type*   _M_sbuf;
    00068       int_type          _M_c;
    00069
    00070     public:
    00071       istreambuf_iterator() throw()
    00072       : _M_sbuf(0), _M_c(traits_type::eof()) { }
    00073
    00074       istreambuf_iterator(istream_type& __s) throw()
    00075       : _M_sbuf(__s.rdbuf()), _M_c(traits_type::eof()) { }
    00076
    00077       istreambuf_iterator(streambuf_type* __s) throw()
    00078       : _M_sbuf(__s), _M_c(traits_type::eof()) { }
    00079
    00080       // NB: The result of operator*() on an end of stream is undefined.
    00081       char_type
    00082       operator*() const
    00083       { return traits_type::to_char_type(_M_get()); }
    00084
    00085       istreambuf_iterator&
    00086       operator++()
    00087       {
    00088     const int_type __eof = traits_type::eof();
    00089     if (_M_sbuf && traits_type::eq_int_type(_M_sbuf->sbumpc(), __eof))
    00090       _M_sbuf = 0;
    00091     else
    00092       _M_c = __eof;
    00093     return *this;
    00094       }
    00095
    00096       istreambuf_iterator
    00097       operator++(int)
    00098       {
    00099     const int_type __eof = traits_type::eof();
    00100     istreambuf_iterator __old = *this;
    00101     if (_M_sbuf
    00102         && traits_type::eq_int_type((__old._M_c = _M_sbuf->sbumpc()),
    00103                     __eof))
    00104       _M_sbuf = 0;
    00105     else
    00106       _M_c = __eof;
    00107     return __old;
    00108       }
    00109
    00110 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
    00111       // 110 istreambuf_iterator::equal not const
    00112       // NB: there is also number 111 (NAD, Future) pending on this function.
    00113       bool
    00114       equal(const istreambuf_iterator& __b) const
    00115       {
    00116     const int_type __eof = traits_type::eof();
    00117     bool __thiseof = traits_type::eq_int_type(_M_get(), __eof);
    00118     bool __beof = traits_type::eq_int_type(__b._M_get(), __eof);
    00119     return (__thiseof && __beof || (!__thiseof && !__beof));
    00120       }
    00121 #endif
    00122
    00123     private:
    00124       int_type
    00125       _M_get() const
    00126       {
    00127     const int_type __eof = traits_type::eof();
    00128     int_type __ret = __eof;
    00129     if (_M_sbuf)
    00130       {
    00131         if (!traits_type::eq_int_type(_M_c, __eof))
    00132           __ret = _M_c;
    00133         else
    00134           if (traits_type::eq_int_type((__ret = _M_sbuf->sgetc()), __eof))
    00135         _M_sbuf = 0;
    00136       }
    00137     return __ret;
    00138       }
    00139     };
    00140
    00141   template<typename _CharT, typename _Traits>
    00142     inline bool
    00143     operator==(const istreambuf_iterator<_CharT, _Traits>& __a,
    00144            const istreambuf_iterator<_CharT, _Traits>& __b)
    00145     { return __a.equal(__b); }
    00146
    00147   template<typename _CharT, typename _Traits>
    00148     inline bool
    00149     operator!=(const istreambuf_iterator<_CharT, _Traits>& __a,
    00150            const istreambuf_iterator<_CharT, _Traits>& __b)
    00151     { return !__a.equal(__b); }
    00152
    00153   template<typename _CharT, typename _Traits>
    00154     class ostreambuf_iterator
    00155     : public iterator<output_iterator_tag, void, void, void, void>
    00156     {
    00157     public:
    00158       // Types:
    00159       typedef _CharT                           char_type;
    00160       typedef _Traits                          traits_type;
    00161       typedef basic_streambuf<_CharT, _Traits> streambuf_type;
    00162       typedef basic_ostream<_CharT, _Traits>   ostream_type;
    00163
    00164     private:
    00165       streambuf_type*   _M_sbuf;
    00166       bool      _M_failed;
    00167
    00168     public:
    00169       inline
    00170       ostreambuf_iterator(ostream_type& __s) throw ()
    00171       : _M_sbuf(__s.rdbuf()), _M_failed(!_M_sbuf) { }
    00172
    00173       ostreambuf_iterator(streambuf_type* __s) throw ()
    00174       : _M_sbuf(__s), _M_failed(!_M_sbuf) { }
    00175
    00176       ostreambuf_iterator&
    00177       operator=(_CharT __c);
    00178
    00179       ostreambuf_iterator&
    00180       operator*() throw()
    00181       { return *this; }
    00182
    00183       ostreambuf_iterator&
    00184       operator++(int) throw()
    00185       { return *this; }
    00186
    00187       ostreambuf_iterator&
    00188       operator++() throw()
    00189       { return *this; }
    00190
    00191       bool
    00192       failed() const throw()
    00193       { return _M_failed; }
    00194     };
    00195
    00196   template<typename _CharT, typename _Traits>
    00197     inline ostreambuf_iterator<_CharT, _Traits>&
    00198     ostreambuf_iterator<_CharT, _Traits>::operator=(_CharT __c)
    00199     {
    00200       if (!_M_failed &&
    00201           _Traits::eq_int_type(_M_sbuf->sputc(__c), _Traits::eof()))
    00202     _M_failed = true;
    00203       return *this;
    00204     }
    00205 } // namespace std
    00206 #endif