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(-2) { }
00073       
00074       istreambuf_iterator(istream_type& __s) throw()
00075       : _M_sbuf(__s.rdbuf()), _M_c(-2) { }
00076 
00077       istreambuf_iterator(streambuf_type* __s) throw()
00078       : _M_sbuf(__s), _M_c(-2) { }
00079        
00080       // NB: This should really have an int_type return
00081       // value, so "end of stream" postion can be checked without
00082       // hacking.
00083       char_type 
00084       operator*() const
00085       { 
00086     // The result of operator*() on an end of stream is undefined.
00087     int_type __ret = traits_type::eof();
00088     if (_M_sbuf)
00089       { 
00090         if (_M_c != static_cast<int_type>(-2))
00091           __ret = _M_c;
00092         else 
00093           if ((__ret = _M_sbuf->sgetc()) == traits_type::eof())
00094         _M_sbuf = 0;
00095       }
00096     return traits_type::to_char_type(__ret);
00097       }
00098     
00099       istreambuf_iterator& 
00100       operator++()
00101       { 
00102     if (_M_sbuf && _M_sbuf->sbumpc() == traits_type::eof())
00103       _M_sbuf = 0;
00104     else
00105       _M_c = -2;
00106     return *this; 
00107       }
00108 
00109       istreambuf_iterator
00110       operator++(int)
00111       {
00112     istreambuf_iterator __old = *this;
00113     if (_M_sbuf && (__old._M_c = _M_sbuf->sbumpc()) == traits_type::eof())
00114       _M_sbuf = 0;
00115     else
00116       _M_c = -2;
00117     return __old; 
00118       }
00119 
00120 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
00121       // 110 istreambuf_iterator::equal not const
00122       // NB: there is also number 111 (NAD, Future) pending on this function.
00123       bool 
00124       equal(const istreambuf_iterator& __b) const
00125       {
00126     const int_type __eof = traits_type::eof();
00127     bool __thiseof = traits_type::eq_int_type(this->operator*(), __eof);
00128     bool __beof = traits_type::eq_int_type(__b.operator*(), __eof);
00129     return (__thiseof && __beof || (!__thiseof && !__beof));
00130       }
00131 #endif
00132     };
00133 
00134   template<typename _CharT, typename _Traits>
00135     inline bool 
00136     operator==(const istreambuf_iterator<_CharT, _Traits>& __a,
00137            const istreambuf_iterator<_CharT, _Traits>& __b)
00138     { return __a.equal(__b); }
00139 
00140   template<typename _CharT, typename _Traits>
00141     inline bool 
00142     operator!=(const istreambuf_iterator<_CharT, _Traits>& __a,
00143            const istreambuf_iterator<_CharT, _Traits>& __b)
00144     { return !__a.equal(__b); }
00145 
00146   template<typename _CharT, typename _Traits>
00147     class ostreambuf_iterator
00148     : public iterator<output_iterator_tag, void, void, void, void>
00149     {
00150     public:
00151       // Types:
00152       typedef _CharT                           char_type;
00153       typedef _Traits                          traits_type;
00154       typedef basic_streambuf<_CharT, _Traits> streambuf_type;
00155       typedef basic_ostream<_CharT, _Traits>   ostream_type;
00156 
00157     private:
00158       streambuf_type*   _M_sbuf;
00159       bool      _M_failed;
00160 
00161     public:
00162       inline 
00163       ostreambuf_iterator(ostream_type& __s) throw ()
00164       : _M_sbuf(__s.rdbuf()), _M_failed(!_M_sbuf) { }
00165       
00166       ostreambuf_iterator(streambuf_type* __s) throw ()
00167       : _M_sbuf(__s), _M_failed(!_M_sbuf) { }
00168 
00169       ostreambuf_iterator& 
00170       operator=(_CharT __c);
00171 
00172       ostreambuf_iterator& 
00173       operator*() throw()
00174       { return *this; }
00175 
00176       ostreambuf_iterator& 
00177       operator++(int) throw()
00178       { return *this; }
00179 
00180       ostreambuf_iterator& 
00181       operator++() throw()
00182       { return *this; }
00183 
00184       bool 
00185       failed() const throw()
00186       { return _M_failed; }
00187     };
00188 
00189   template<typename _CharT, typename _Traits>
00190     inline ostreambuf_iterator<_CharT, _Traits>&
00191     ostreambuf_iterator<_CharT, _Traits>::operator=(_CharT __c)
00192     {
00193       if (!_M_failed && 
00194           _Traits::eq_int_type(_M_sbuf->sputc(__c), _Traits::eof()))
00195     _M_failed = true;
00196       return *this;
00197     }
00198 } // namespace std
00199 #endif

Generated on Wed May 1 19:19:38 2002 for libstdc++-v3 Source by doxygen1.2.15