00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
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 _GLIBCXX_BEGIN_NAMESPACE(std)
00045
00046
00047
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
00055
00056
00057 typedef _CharT char_type;
00058 typedef _Traits traits_type;
00059 typedef typename _Traits::int_type int_type;
00060 typedef basic_streambuf<_CharT, _Traits> streambuf_type;
00061 typedef basic_istream<_CharT, _Traits> istream_type;
00062
00063
00064 template<typename _CharT2>
00065 friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value,
00066 ostreambuf_iterator<_CharT2> >::__type
00067 copy(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>,
00068 ostreambuf_iterator<_CharT2>);
00069
00070 template<typename _CharT2>
00071 friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value,
00072 _CharT2*>::__type
00073 __copy_aux(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>,
00074 _CharT2*);
00075
00076 template<typename _CharT2>
00077 friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value,
00078 istreambuf_iterator<_CharT2> >::__type
00079 find(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>,
00080 const _CharT2&);
00081
00082 private:
00083
00084
00085
00086
00087
00088
00089
00090 mutable streambuf_type* _M_sbuf;
00091 mutable int_type _M_c;
00092
00093 public:
00094
00095 istreambuf_iterator() throw()
00096 : _M_sbuf(0), _M_c(traits_type::eof()) { }
00097
00098
00099 istreambuf_iterator(istream_type& __s) throw()
00100 : _M_sbuf(__s.rdbuf()), _M_c(traits_type::eof()) { }
00101
00102
00103 istreambuf_iterator(streambuf_type* __s) throw()
00104 : _M_sbuf(__s), _M_c(traits_type::eof()) { }
00105
00106
00107
00108
00109 char_type
00110 operator*() const
00111 {
00112 #ifdef _GLIBCXX_DEBUG_PEDANTIC
00113
00114
00115 __glibcxx_requires_cond(!_M_at_eof(),
00116 _M_message(__gnu_debug::__msg_deref_istreambuf)
00117 ._M_iterator(*this));
00118 #endif
00119 return traits_type::to_char_type(_M_get());
00120 }
00121
00122
00123 istreambuf_iterator&
00124 operator++()
00125 {
00126 __glibcxx_requires_cond(!_M_at_eof(),
00127 _M_message(__gnu_debug::__msg_inc_istreambuf)
00128 ._M_iterator(*this));
00129 if (_M_sbuf)
00130 {
00131 _M_sbuf->sbumpc();
00132 _M_c = traits_type::eof();
00133 }
00134 return *this;
00135 }
00136
00137
00138 istreambuf_iterator
00139 operator++(int)
00140 {
00141 __glibcxx_requires_cond(!_M_at_eof(),
00142 _M_message(__gnu_debug::__msg_inc_istreambuf)
00143 ._M_iterator(*this));
00144
00145 istreambuf_iterator __old = *this;
00146 if (_M_sbuf)
00147 {
00148 __old._M_c = _M_sbuf->sbumpc();
00149 _M_c = traits_type::eof();
00150 }
00151 return __old;
00152 }
00153
00154
00155
00156
00157
00158 bool
00159 equal(const istreambuf_iterator& __b) const
00160 {
00161 const bool __thiseof = _M_at_eof();
00162 const bool __beof = __b._M_at_eof();
00163 return (__thiseof && __beof || (!__thiseof && !__beof));
00164 }
00165
00166 private:
00167 int_type
00168 _M_get() const
00169 {
00170 const int_type __eof = traits_type::eof();
00171 int_type __ret = __eof;
00172 if (_M_sbuf)
00173 {
00174 if (!traits_type::eq_int_type(_M_c, __eof))
00175 __ret = _M_c;
00176 else if (!traits_type::eq_int_type((__ret = _M_sbuf->sgetc()),
00177 __eof))
00178 _M_c = __ret;
00179 else
00180 _M_sbuf = 0;
00181 }
00182 return __ret;
00183 }
00184
00185 bool
00186 _M_at_eof() const
00187 {
00188 const int_type __eof = traits_type::eof();
00189 return traits_type::eq_int_type(_M_get(), __eof);
00190 }
00191 };
00192
00193 template<typename _CharT, typename _Traits>
00194 inline bool
00195 operator==(const istreambuf_iterator<_CharT, _Traits>& __a,
00196 const istreambuf_iterator<_CharT, _Traits>& __b)
00197 { return __a.equal(__b); }
00198
00199 template<typename _CharT, typename _Traits>
00200 inline bool
00201 operator!=(const istreambuf_iterator<_CharT, _Traits>& __a,
00202 const istreambuf_iterator<_CharT, _Traits>& __b)
00203 { return !__a.equal(__b); }
00204
00205
00206 template<typename _CharT, typename _Traits>
00207 class ostreambuf_iterator
00208 : public iterator<output_iterator_tag, void, void, void, void>
00209 {
00210 public:
00211
00212
00213
00214 typedef _CharT char_type;
00215 typedef _Traits traits_type;
00216 typedef basic_streambuf<_CharT, _Traits> streambuf_type;
00217 typedef basic_ostream<_CharT, _Traits> ostream_type;
00218
00219
00220 template<typename _CharT2>
00221 friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value,
00222 ostreambuf_iterator<_CharT2> >::__type
00223 copy(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>,
00224 ostreambuf_iterator<_CharT2>);
00225
00226 private:
00227 streambuf_type* _M_sbuf;
00228 bool _M_failed;
00229
00230 public:
00231
00232 ostreambuf_iterator(ostream_type& __s) throw ()
00233 : _M_sbuf(__s.rdbuf()), _M_failed(!_M_sbuf) { }
00234
00235
00236 ostreambuf_iterator(streambuf_type* __s) throw ()
00237 : _M_sbuf(__s), _M_failed(!_M_sbuf) { }
00238
00239
00240 ostreambuf_iterator&
00241 operator=(_CharT __c)
00242 {
00243 if (!_M_failed &&
00244 _Traits::eq_int_type(_M_sbuf->sputc(__c), _Traits::eof()))
00245 _M_failed = true;
00246 return *this;
00247 }
00248
00249
00250 ostreambuf_iterator&
00251 operator*()
00252 { return *this; }
00253
00254
00255 ostreambuf_iterator&
00256 operator++(int)
00257 { return *this; }
00258
00259
00260 ostreambuf_iterator&
00261 operator++()
00262 { return *this; }
00263
00264
00265 bool
00266 failed() const throw()
00267 { return _M_failed; }
00268
00269 ostreambuf_iterator&
00270 _M_put(const _CharT* __ws, streamsize __len)
00271 {
00272 if (__builtin_expect(!_M_failed, true)
00273 && __builtin_expect(this->_M_sbuf->sputn(__ws, __len) != __len,
00274 false))
00275 _M_failed = true;
00276 return *this;
00277 }
00278 };
00279
00280
00281 template<typename _CharT>
00282 typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
00283 ostreambuf_iterator<_CharT> >::__type
00284 copy(istreambuf_iterator<_CharT> __first,
00285 istreambuf_iterator<_CharT> __last,
00286 ostreambuf_iterator<_CharT> __result)
00287 {
00288 if (__first._M_sbuf && !__last._M_sbuf && !__result._M_failed)
00289 {
00290 bool __ineof;
00291 __copy_streambufs_eof(__first._M_sbuf, __result._M_sbuf, __ineof);
00292 if (!__ineof)
00293 __result._M_failed = true;
00294 }
00295 return __result;
00296 }
00297
00298 template<typename _CharT>
00299 typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
00300 ostreambuf_iterator<_CharT> >::__type
00301 __copy_aux(_CharT* __first, _CharT* __last,
00302 ostreambuf_iterator<_CharT> __result)
00303 {
00304 const streamsize __num = __last - __first;
00305 if (__num > 0)
00306 __result._M_put(__first, __num);
00307 return __result;
00308 }
00309
00310 template<typename _CharT>
00311 typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
00312 ostreambuf_iterator<_CharT> >::__type
00313 __copy_aux(const _CharT* __first, const _CharT* __last,
00314 ostreambuf_iterator<_CharT> __result)
00315 {
00316 const streamsize __num = __last - __first;
00317 if (__num > 0)
00318 __result._M_put(__first, __num);
00319 return __result;
00320 }
00321
00322 template<typename _CharT>
00323 typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
00324 _CharT*>::__type
00325 __copy_aux(istreambuf_iterator<_CharT> __first,
00326 istreambuf_iterator<_CharT> __last, _CharT* __result)
00327 {
00328 typedef istreambuf_iterator<_CharT> __is_iterator_type;
00329 typedef typename __is_iterator_type::traits_type traits_type;
00330 typedef typename __is_iterator_type::streambuf_type streambuf_type;
00331 typedef typename traits_type::int_type int_type;
00332
00333 if (__first._M_sbuf && !__last._M_sbuf)
00334 {
00335 streambuf_type* __sb = __first._M_sbuf;
00336 int_type __c = __sb->sgetc();
00337 while (!traits_type::eq_int_type(__c, traits_type::eof()))
00338 {
00339 const streamsize __n = __sb->egptr() - __sb->gptr();
00340 if (__n > 1)
00341 {
00342 traits_type::copy(__result, __sb->gptr(), __n);
00343 __sb->gbump(__n);
00344 __result += __n;
00345 __c = __sb->underflow();
00346 }
00347 else
00348 {
00349 *__result++ = traits_type::to_char_type(__c);
00350 __c = __sb->snextc();
00351 }
00352 }
00353 }
00354 return __result;
00355 }
00356
00357 template<typename _CharT>
00358 typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
00359 istreambuf_iterator<_CharT> >::__type
00360 find(istreambuf_iterator<_CharT> __first,
00361 istreambuf_iterator<_CharT> __last, const _CharT& __val)
00362 {
00363 typedef istreambuf_iterator<_CharT> __is_iterator_type;
00364 typedef typename __is_iterator_type::traits_type traits_type;
00365 typedef typename __is_iterator_type::streambuf_type streambuf_type;
00366 typedef typename traits_type::int_type int_type;
00367
00368 if (__first._M_sbuf && !__last._M_sbuf)
00369 {
00370 const int_type __ival = traits_type::to_int_type(__val);
00371 streambuf_type* __sb = __first._M_sbuf;
00372 int_type __c = __sb->sgetc();
00373 while (!traits_type::eq_int_type(__c, traits_type::eof())
00374 && !traits_type::eq_int_type(__c, __ival))
00375 {
00376 streamsize __n = __sb->egptr() - __sb->gptr();
00377 if (__n > 1)
00378 {
00379 const _CharT* __p = traits_type::find(__sb->gptr(),
00380 __n, __val);
00381 if (__p)
00382 __n = __p - __sb->gptr();
00383 __sb->gbump(__n);
00384 __c = __sb->sgetc();
00385 }
00386 else
00387 __c = __sb->snextc();
00388 }
00389
00390 if (!traits_type::eq_int_type(__c, traits_type::eof()))
00391 __first._M_c = __c;
00392 else
00393 __first._M_sbuf = 0;
00394 }
00395 return __first;
00396 }
00397
00398 _GLIBCXX_END_NAMESPACE
00399
00400 #endif