# streambuf_iterator.h

Go to the documentation of this file.

    00001 // Streambuf iterators
    00002
    00003 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
    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 /** @file streambuf_iterator.h
    00032  *  This is an internal header file, included by other library headers.
    00033  *  You should not attempt to use it directly.
    00034  */
    00035
    00036 #ifndef _STREAMBUF_ITERATOR_H
    00037 #define _STREAMBUF_ITERATOR_H 1
    00038
    00039 #pragma GCC system_header
    00040
    00041 #include <streambuf>
    00042 #include <debug/debug.h>
    00043
    00044 // NB: Should specialize copy, find algorithms for streambuf iterators.
    00045
    00046 namespace std
    00047 {
    00048   // 24.5.3 Template class istreambuf_iterator
    00049   /// Provides input iterator semantics for streambufs.
    00050   template<typename _CharT, typename _Traits>
    00051     class istreambuf_iterator
    00052     : public iterator<input_iterator_tag, _CharT, typename _Traits::off_type,
    00053               _CharT*, _CharT&>
    00054     {
    00055     public:
    00056       // Types:
    00057       //@{
    00058       /// Public typedefs
    00059       typedef _CharT                    char_type;
    00060       typedef _Traits                   traits_type;
    00061       typedef typename _Traits::int_type        int_type;
    00062       typedef basic_streambuf<_CharT, _Traits>      streambuf_type;
    00063       typedef basic_istream<_CharT, _Traits>        istream_type;
    00064       //@}
    00065
    00066     private:
    00067       // 24.5.3 istreambuf_iterator
    00068       // p 1
    00069       // If the end of stream is reached (streambuf_type::sgetc()
    00070       // returns traits_type::eof()), the iterator becomes equal to
    00071       // the "end of stream" iterator value.
    00072       // NB: This implementation assumes the "end of stream" value
    00073       // is EOF, or -1.
    00074       mutable streambuf_type*   _M_sbuf;
    00075       int_type          _M_c;
    00076
    00077     public:
    00078       ///  Construct end of input stream iterator.
    00079       istreambuf_iterator() throw()
    00080       : _M_sbuf(0), _M_c(traits_type::eof()) { }
    00081
    00082       ///  Construct start of input stream iterator.
    00083       istreambuf_iterator(istream_type& __s) throw()
    00084       : _M_sbuf(__s.rdbuf()), _M_c(traits_type::eof()) { }
    00085
    00086       ///  Construct start of streambuf iterator.
    00087       istreambuf_iterator(streambuf_type* __s) throw()
    00088       : _M_sbuf(__s), _M_c(traits_type::eof()) { }
    00089
    00090       ///  Return the current character pointed to by iterator.  This returns
    00091       ///  streambuf.sgetc().  It cannot be assigned.  NB: The result of
    00092       ///  operator*() on an end of stream is undefined.
    00093       char_type
    00094       operator*() const
    00095       {
    00096 #ifdef _GLIBCXX_DEBUG_PEDANTIC
    00097     // Dereferencing a past-the-end istreambuf_iterator is a
    00098     // libstdc++ extension
    00099     __glibcxx_requires_cond(!_M_at_eof(),
    00100                 _M_message(__gnu_debug::__msg_deref_istreambuf)
    00101                 ._M_iterator(*this));
    00102 #endif
    00103     return traits_type::to_char_type(_M_get());
    00104       }
    00105
    00106       /// Advance the iterator.  Calls streambuf.sbumpc().
    00107       istreambuf_iterator&
    00108       operator++()
    00109       {
    00110     __glibcxx_requires_cond(!_M_at_eof(),
    00111                 _M_message(__gnu_debug::__msg_inc_istreambuf)
    00112                 ._M_iterator(*this));
    00113     const int_type __eof = traits_type::eof();
    00114     if (_M_sbuf && traits_type::eq_int_type(_M_sbuf->sbumpc(), __eof))
    00115       _M_sbuf = 0;
    00116     else
    00117       _M_c = __eof;
    00118     return *this;
    00119       }
    00120
    00121       /// Advance the iterator.  Calls streambuf.sbumpc().
    00122       istreambuf_iterator
    00123       operator++(int)
    00124       {
    00125     __glibcxx_requires_cond(!_M_at_eof(),
    00126                 _M_message(__gnu_debug::__msg_inc_istreambuf)
    00127                 ._M_iterator(*this));
    00128
    00129     const int_type __eof = traits_type::eof();
    00130     istreambuf_iterator __old = *this;
    00131     if (_M_sbuf
    00132         && traits_type::eq_int_type((__old._M_c = _M_sbuf->sbumpc()),
    00133                     __eof))
    00134       _M_sbuf = 0;
    00135     else
    00136       _M_c = __eof;
    00137     return __old;
    00138       }
    00139
    00140       // _GLIBCXX_RESOLVE_LIB_DEFECTS
    00141       // 110 istreambuf_iterator::equal not const
    00142       // NB: there is also number 111 (NAD, Future) pending on this function.
    00143       /// Return true both iterators are end or both are not end.
    00144       bool
    00145       equal(const istreambuf_iterator& __b) const
    00146       {
    00147     const bool __thiseof = _M_at_eof();
    00148     const bool __beof = __b._M_at_eof();
    00149     return (__thiseof && __beof || (!__thiseof && !__beof));
    00150       }
    00151
    00152     private:
    00153       int_type
    00154       _M_get() const
    00155       {
    00156     const int_type __eof = traits_type::eof();
    00157     int_type __ret = __eof;
    00158     if (_M_sbuf)
    00159       {
    00160         if (!traits_type::eq_int_type(_M_c, __eof))
    00161           __ret = _M_c;
    00162         else if (traits_type::eq_int_type((__ret = _M_sbuf->sgetc()),
    00163                           __eof))
    00164           _M_sbuf = 0;
    00165       }
    00166     return __ret;
    00167       }
    00168
    00169       bool
    00170       _M_at_eof() const
    00171       {
    00172     const int_type __eof = traits_type::eof();
    00173     return traits_type::eq_int_type(_M_get(), __eof);
    00174       }
    00175     };
    00176
    00177   template<typename _CharT, typename _Traits>
    00178     inline bool
    00179     operator==(const istreambuf_iterator<_CharT, _Traits>& __a,
    00180            const istreambuf_iterator<_CharT, _Traits>& __b)
    00181     { return __a.equal(__b); }
    00182
    00183   template<typename _CharT, typename _Traits>
    00184     inline bool
    00185     operator!=(const istreambuf_iterator<_CharT, _Traits>& __a,
    00186            const istreambuf_iterator<_CharT, _Traits>& __b)
    00187     { return !__a.equal(__b); }
    00188
    00189   /// Provides output iterator semantics for streambufs.
    00190   template<typename _CharT, typename _Traits>
    00191     class ostreambuf_iterator
    00192     : public iterator<output_iterator_tag, void, void, void, void>
    00193     {
    00194     public:
    00195       // Types:
    00196       //@{
    00197       /// Public typedefs
    00198       typedef _CharT                           char_type;
    00199       typedef _Traits                          traits_type;
    00200       typedef basic_streambuf<_CharT, _Traits> streambuf_type;
    00201       typedef basic_ostream<_CharT, _Traits>   ostream_type;
    00202       //@}
    00203
    00204     private:
    00205       streambuf_type*   _M_sbuf;
    00206       bool      _M_failed;
    00207
    00208     public:
    00209       ///  Construct output iterator from ostream.
    00210       ostreambuf_iterator(ostream_type& __s) throw ()
    00211       : _M_sbuf(__s.rdbuf()), _M_failed(!_M_sbuf) { }
    00212
    00213       ///  Construct output iterator from streambuf.
    00214       ostreambuf_iterator(streambuf_type* __s) throw ()
    00215       : _M_sbuf(__s), _M_failed(!_M_sbuf) { }
    00216
    00217       ///  Write character to streambuf.  Calls streambuf.sputc().
    00218       ostreambuf_iterator&
    00219       operator=(_CharT __c)
    00220       {
    00221     if (!_M_failed &&
    00222         _Traits::eq_int_type(_M_sbuf->sputc(__c), _Traits::eof()))
    00223       _M_failed = true;
    00224     return *this;
    00225       }
    00226
    00227       /// Return *this.
    00228       ostreambuf_iterator&
    00229       operator*()
    00230       { return *this; }
    00231
    00232       /// Return *this.
    00233       ostreambuf_iterator&
    00234       operator++(int)
    00235       { return *this; }
    00236
    00237       /// Return *this.
    00238       ostreambuf_iterator&
    00239       operator++()
    00240       { return *this; }
    00241
    00242       /// Return true if previous operator=() failed.
    00243       bool
    00244       failed() const throw()
    00245       { return _M_failed; }
    00246
    00247       ostreambuf_iterator&
    00248       _M_put(const _CharT* __ws, streamsize __len)
    00249       {
    00250     if (__builtin_expect(!_M_failed, true)
    00251         && __builtin_expect(this->_M_sbuf->sputn(__ws, __len) != __len,
    00252                 false))
    00253       _M_failed = true;
    00254     return *this;
    00255       }
    00256     };
    00257 } // namespace std
    00258 #endif