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