streambuf_iterator.h

Go to the documentation of this file.
00001 // Streambuf iterators
00002 
00003 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
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 _CPP_BITS_STREAMBUF_ITERATOR_H
00037 #define _CPP_BITS_STREAMBUF_ITERATOR_H 1
00038 
00039 #pragma GCC system_header
00040 
00041 #include <streambuf>
00042 
00043 // NB: Should specialize copy, find algorithms for streambuf iterators.
00044 
00045 namespace std
00046 {
00047   // 24.5.3 Template class istreambuf_iterator
00048   template<typename _CharT, typename _Traits>
00049     class istreambuf_iterator
00050     : public iterator<input_iterator_tag, _CharT, typename _Traits::off_type,
00051                   _CharT*, _CharT&>
00052     {
00053     public:
00054       // Types:
00055       typedef _CharT                                char_type;
00056       typedef _Traits                               traits_type;
00057       typedef typename _Traits::int_type            int_type;
00058       typedef basic_streambuf<_CharT, _Traits>      streambuf_type;
00059       typedef basic_istream<_CharT, _Traits>            istream_type;
00060 
00061     private:
00062       // 24.5.3 istreambuf_iterator 
00063       // p 1 
00064       // If the end of stream is reached (streambuf_type::sgetc()
00065       // returns traits_type::eof()), the iterator becomes equal to
00066       // the "end of stream" iterator value.
00067       // NB: This implementation assumes the "end of stream" value
00068       // is EOF, or -1.
00069       mutable streambuf_type*   _M_sbuf;  
00070       int_type          _M_c;
00071 
00072     public:
00073       istreambuf_iterator() throw() 
00074       : _M_sbuf(0), _M_c(traits_type::eof()) { }
00075       
00076       istreambuf_iterator(istream_type& __s) throw()
00077       : _M_sbuf(__s.rdbuf()), _M_c(traits_type::eof()) { }
00078 
00079       istreambuf_iterator(streambuf_type* __s) throw()
00080       : _M_sbuf(__s), _M_c(traits_type::eof()) { }
00081        
00082       // NB: The result of operator*() on an end of stream is undefined.
00083       char_type 
00084       operator*() const
00085       { return traits_type::to_char_type(_M_get()); }
00086     
00087       istreambuf_iterator& 
00088       operator++()
00089       { 
00090     const int_type __eof = traits_type::eof();
00091     if (_M_sbuf && traits_type::eq_int_type(_M_sbuf->sbumpc(), __eof))
00092       _M_sbuf = 0;
00093     else
00094       _M_c = __eof;
00095     return *this; 
00096       }
00097 
00098       istreambuf_iterator
00099       operator++(int)
00100       {
00101     const int_type __eof = traits_type::eof();
00102     istreambuf_iterator __old = *this;
00103     if (_M_sbuf
00104         && traits_type::eq_int_type((__old._M_c = _M_sbuf->sbumpc()), 
00105                     __eof))
00106       _M_sbuf = 0;
00107     else
00108       _M_c = __eof;
00109     return __old; 
00110       }
00111 
00112 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
00113       // 110 istreambuf_iterator::equal not const
00114       // NB: there is also number 111 (NAD, Future) pending on this function.
00115       bool 
00116       equal(const istreambuf_iterator& __b) const
00117       {
00118     const int_type __eof = traits_type::eof();
00119     bool __thiseof = traits_type::eq_int_type(_M_get(), __eof);
00120     bool __beof = traits_type::eq_int_type(__b._M_get(), __eof);
00121     return (__thiseof && __beof || (!__thiseof && !__beof));
00122       }
00123 #endif
00124 
00125     private:
00126       int_type 
00127       _M_get() const
00128       { 
00129     const int_type __eof = traits_type::eof();
00130     int_type __ret = __eof;
00131     if (_M_sbuf)
00132       { 
00133         if (!traits_type::eq_int_type(_M_c, __eof))
00134           __ret = _M_c;
00135         else 
00136           if (traits_type::eq_int_type((__ret = _M_sbuf->sgetc()), __eof))
00137         _M_sbuf = 0;
00138       }
00139     return __ret;
00140       }
00141     };
00142 
00143   template<typename _CharT, typename _Traits>
00144     inline bool 
00145     operator==(const istreambuf_iterator<_CharT, _Traits>& __a,
00146            const istreambuf_iterator<_CharT, _Traits>& __b)
00147     { return __a.equal(__b); }
00148 
00149   template<typename _CharT, typename _Traits>
00150     inline bool 
00151     operator!=(const istreambuf_iterator<_CharT, _Traits>& __a,
00152            const istreambuf_iterator<_CharT, _Traits>& __b)
00153     { return !__a.equal(__b); }
00154 
00155   template<typename _CharT, typename _Traits>
00156     class ostreambuf_iterator
00157     : public iterator<output_iterator_tag, void, void, void, void>
00158     {
00159     public:
00160       // Types:
00161       typedef _CharT                           char_type;
00162       typedef _Traits                          traits_type;
00163       typedef basic_streambuf<_CharT, _Traits> streambuf_type;
00164       typedef basic_ostream<_CharT, _Traits>   ostream_type;
00165 
00166     private:
00167       streambuf_type*   _M_sbuf;
00168       bool      _M_failed;
00169 
00170     public:
00171       ostreambuf_iterator(ostream_type& __s) throw ()
00172       : _M_sbuf(__s.rdbuf()), _M_failed(!_M_sbuf) { }
00173       
00174       ostreambuf_iterator(streambuf_type* __s) throw ()
00175       : _M_sbuf(__s), _M_failed(!_M_sbuf) { }
00176 
00177       ostreambuf_iterator& 
00178       operator=(_CharT __c)
00179       {
00180     if (!_M_failed && 
00181         _Traits::eq_int_type(_M_sbuf->sputc(__c), _Traits::eof()))
00182       _M_failed = true;
00183     return *this;
00184       }
00185 
00186       ostreambuf_iterator& 
00187       operator*() throw()
00188       { return *this; }
00189 
00190       ostreambuf_iterator& 
00191       operator++(int) throw()
00192       { return *this; }
00193 
00194       ostreambuf_iterator& 
00195       operator++() throw()
00196       { return *this; }
00197 
00198       bool 
00199       failed() const throw()
00200       { return _M_failed; }
00201 
00202       ostreambuf_iterator& 
00203       _M_put(const _CharT* __ws, streamsize __len)
00204       {
00205     if (__builtin_expect(!_M_failed, true) && 
00206         __builtin_expect(this->_M_sbuf->sputn(__ws, __len) != __len, false))
00207       _M_failed = true;
00208     return *this;
00209       }
00210     };
00211 } // namespace std
00212 #endif

Generated on Thu Feb 10 23:23:00 2005 for libstdc++-v3 Source by  doxygen 1.4.0