]>
Commit | Line | Data |
---|---|---|
725dc051 BK |
1 | // Streambuf iterators |
2 | ||
3cbc7af0 | 3 | // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 |
5c352a47 | 4 | // Free Software Foundation, Inc. |
725dc051 BK |
5 | // |
6 | // This file is part of the GNU ISO C++ Library. This library is free | |
7 | // software; you can redistribute it and/or modify it under the | |
8 | // terms of the GNU General Public License as published by the | |
9 | // Free Software Foundation; either version 2, or (at your option) | |
10 | // any later version. | |
11 | ||
12 | // This library is distributed in the hope that it will be useful, | |
13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | // GNU General Public License for more details. | |
16 | ||
17 | // You should have received a copy of the GNU General Public License along | |
18 | // with this library; see the file COPYING. If not, write to the Free | |
83f51799 | 19 | // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, |
725dc051 BK |
20 | // USA. |
21 | ||
22 | // As a special exception, you may use this file as part of a free software | |
23 | // library without restriction. Specifically, if other files instantiate | |
24 | // templates or use macros or inline functions from this file, or you compile | |
25 | // this file and link it with other files to produce an executable, this | |
26 | // file does not by itself cause the resulting executable to be covered by | |
27 | // the GNU General Public License. This exception does not however | |
28 | // invalidate any other reasons why the executable file might be covered by | |
29 | // the GNU General Public License. | |
30 | ||
729e3d3f PE |
31 | /** @file streambuf_iterator.h |
32 | * This is an internal header file, included by other library headers. | |
33 | * You should not attempt to use it directly. | |
34 | */ | |
35 | ||
3d7c150e BK |
36 | #ifndef _STREAMBUF_ITERATOR_H |
37 | #define _STREAMBUF_ITERATOR_H 1 | |
725dc051 | 38 | |
b0a85b86 GDR |
39 | #pragma GCC system_header |
40 | ||
2e2a38cd | 41 | #include <streambuf> |
285b36d6 | 42 | #include <debug/debug.h> |
2e2a38cd BK |
43 | |
44 | // NB: Should specialize copy, find algorithms for streambuf iterators. | |
45 | ||
3cbc7af0 BK |
46 | _GLIBCXX_BEGIN_NAMESPACE(std) |
47 | ||
725dc051 | 48 | // 24.5.3 Template class istreambuf_iterator |
ffcec5c8 | 49 | /// Provides input iterator semantics for streambufs. |
39003c99 | 50 | template<typename _CharT, typename _Traits> |
725dc051 BK |
51 | class istreambuf_iterator |
52 | : public iterator<input_iterator_tag, _CharT, typename _Traits::off_type, | |
ed6814f7 | 53 | _CharT*, _CharT&> |
725dc051 BK |
54 | { |
55 | public: | |
725dc051 | 56 | // Types: |
ffcec5c8 JQ |
57 | //@{ |
58 | /// Public typedefs | |
ed6814f7 BI |
59 | typedef _CharT char_type; |
60 | typedef _Traits traits_type; | |
61 | typedef typename _Traits::int_type int_type; | |
62 | typedef basic_streambuf<_CharT, _Traits> streambuf_type; | |
63 | typedef basic_istream<_CharT, _Traits> istream_type; | |
ffcec5c8 | 64 | //@} |
725dc051 | 65 | |
39003c99 | 66 | private: |
ed6814f7 BI |
67 | // 24.5.3 istreambuf_iterator |
68 | // p 1 | |
39003c99 BK |
69 | // If the end of stream is reached (streambuf_type::sgetc() |
70 | // returns traits_type::eof()), the iterator becomes equal to | |
71 | // the "end of stream" iterator value. | |
72 | // NB: This implementation assumes the "end of stream" value | |
73 | // is EOF, or -1. | |
ed6814f7 | 74 | mutable streambuf_type* _M_sbuf; |
15fb0dbe | 75 | mutable int_type _M_c; |
39003c99 BK |
76 | |
77 | public: | |
ffcec5c8 | 78 | /// Construct end of input stream iterator. |
ed6814f7 | 79 | istreambuf_iterator() throw() |
f13a69ec | 80 | : _M_sbuf(0), _M_c(traits_type::eof()) { } |
ed6814f7 | 81 | |
ffcec5c8 | 82 | /// Construct start of input stream iterator. |
725dc051 | 83 | istreambuf_iterator(istream_type& __s) throw() |
f13a69ec | 84 | : _M_sbuf(__s.rdbuf()), _M_c(traits_type::eof()) { } |
725dc051 | 85 | |
ffcec5c8 | 86 | /// Construct start of streambuf iterator. |
725dc051 | 87 | istreambuf_iterator(streambuf_type* __s) throw() |
f13a69ec | 88 | : _M_sbuf(__s), _M_c(traits_type::eof()) { } |
ed6814f7 | 89 | |
ffcec5c8 JQ |
90 | /// Return the current character pointed to by iterator. This returns |
91 | /// streambuf.sgetc(). It cannot be assigned. NB: The result of | |
92 | /// operator*() on an end of stream is undefined. | |
ed6814f7 | 93 | char_type |
725dc051 | 94 | operator*() const |
ed6814f7 | 95 | { |
285b36d6 BK |
96 | #ifdef _GLIBCXX_DEBUG_PEDANTIC |
97 | // Dereferencing a past-the-end istreambuf_iterator is a | |
98 | // libstdc++ extension | |
99 | __glibcxx_requires_cond(!_M_at_eof(), | |
100 | _M_message(__gnu_debug::__msg_deref_istreambuf) | |
ed6814f7 | 101 | ._M_iterator(*this)); |
285b36d6 | 102 | #endif |
ed6814f7 | 103 | return traits_type::to_char_type(_M_get()); |
285b36d6 | 104 | } |
ffcec5c8 JQ |
105 | |
106 | /// Advance the iterator. Calls streambuf.sbumpc(). | |
ed6814f7 | 107 | istreambuf_iterator& |
725dc051 | 108 | operator++() |
ed6814f7 | 109 | { |
285b36d6 BK |
110 | __glibcxx_requires_cond(!_M_at_eof(), |
111 | _M_message(__gnu_debug::__msg_inc_istreambuf) | |
ed6814f7 | 112 | ._M_iterator(*this)); |
eacf72d3 NM |
113 | if (_M_sbuf) |
114 | { | |
115 | _M_sbuf->sbumpc(); | |
116 | _M_c = traits_type::eof(); | |
117 | } | |
ed6814f7 | 118 | return *this; |
725dc051 BK |
119 | } |
120 | ||
ffcec5c8 | 121 | /// Advance the iterator. Calls streambuf.sbumpc(). |
b581eaf7 | 122 | istreambuf_iterator |
725dc051 BK |
123 | operator++(int) |
124 | { | |
285b36d6 BK |
125 | __glibcxx_requires_cond(!_M_at_eof(), |
126 | _M_message(__gnu_debug::__msg_inc_istreambuf) | |
ed6814f7 | 127 | ._M_iterator(*this)); |
285b36d6 | 128 | |
b581eaf7 | 129 | istreambuf_iterator __old = *this; |
eacf72d3 NM |
130 | if (_M_sbuf) |
131 | { | |
132 | __old._M_c = _M_sbuf->sbumpc(); | |
133 | _M_c = traits_type::eof(); | |
134 | } | |
ed6814f7 | 135 | return __old; |
725dc051 | 136 | } |
725dc051 | 137 | |
f5677b15 | 138 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
725dc051 | 139 | // 110 istreambuf_iterator::equal not const |
77cd227e | 140 | // NB: there is also number 111 (NAD, Future) pending on this function. |
ffcec5c8 | 141 | /// Return true both iterators are end or both are not end. |
ed6814f7 | 142 | bool |
b581eaf7 | 143 | equal(const istreambuf_iterator& __b) const |
725dc051 | 144 | { |
22352844 PC |
145 | const bool __thiseof = _M_at_eof(); |
146 | const bool __beof = __b._M_at_eof(); | |
725dc051 BK |
147 | return (__thiseof && __beof || (!__thiseof && !__beof)); |
148 | } | |
9875ea05 BK |
149 | |
150 | private: | |
ed6814f7 | 151 | int_type |
9875ea05 | 152 | _M_get() const |
ed6814f7 | 153 | { |
f13a69ec BK |
154 | const int_type __eof = traits_type::eof(); |
155 | int_type __ret = __eof; | |
9875ea05 | 156 | if (_M_sbuf) |
ed6814f7 | 157 | { |
50922820 | 158 | if (!traits_type::eq_int_type(_M_c, __eof)) |
9875ea05 | 159 | __ret = _M_c; |
50922820 PC |
160 | else if (!traits_type::eq_int_type((__ret = _M_sbuf->sgetc()), |
161 | __eof)) | |
162 | _M_c = __ret; | |
15fb0dbe | 163 | else |
15d72060 | 164 | _M_sbuf = 0; |
9875ea05 BK |
165 | } |
166 | return __ret; | |
167 | } | |
285b36d6 | 168 | |
ed6814f7 | 169 | bool |
285b36d6 BK |
170 | _M_at_eof() const |
171 | { | |
172 | const int_type __eof = traits_type::eof(); | |
173 | return traits_type::eq_int_type(_M_get(), __eof); | |
174 | } | |
725dc051 BK |
175 | }; |
176 | ||
177 | template<typename _CharT, typename _Traits> | |
ed6814f7 | 178 | inline bool |
725dc051 BK |
179 | operator==(const istreambuf_iterator<_CharT, _Traits>& __a, |
180 | const istreambuf_iterator<_CharT, _Traits>& __b) | |
181 | { return __a.equal(__b); } | |
182 | ||
183 | template<typename _CharT, typename _Traits> | |
ed6814f7 | 184 | inline bool |
725dc051 BK |
185 | operator!=(const istreambuf_iterator<_CharT, _Traits>& __a, |
186 | const istreambuf_iterator<_CharT, _Traits>& __b) | |
187 | { return !__a.equal(__b); } | |
5c352a47 | 188 | |
ffcec5c8 | 189 | /// Provides output iterator semantics for streambufs. |
5c352a47 BK |
190 | template<typename _CharT, typename _Traits> |
191 | class ostreambuf_iterator | |
192 | : public iterator<output_iterator_tag, void, void, void, void> | |
193 | { | |
194 | public: | |
195 | // Types: | |
ffcec5c8 JQ |
196 | //@{ |
197 | /// Public typedefs | |
5c352a47 BK |
198 | typedef _CharT char_type; |
199 | typedef _Traits traits_type; | |
200 | typedef basic_streambuf<_CharT, _Traits> streambuf_type; | |
201 | typedef basic_ostream<_CharT, _Traits> ostream_type; | |
ffcec5c8 | 202 | //@} |
5c352a47 BK |
203 | |
204 | private: | |
ed6814f7 BI |
205 | streambuf_type* _M_sbuf; |
206 | bool _M_failed; | |
5c352a47 BK |
207 | |
208 | public: | |
ffcec5c8 | 209 | /// Construct output iterator from ostream. |
5c352a47 BK |
210 | ostreambuf_iterator(ostream_type& __s) throw () |
211 | : _M_sbuf(__s.rdbuf()), _M_failed(!_M_sbuf) { } | |
ed6814f7 | 212 | |
ffcec5c8 | 213 | /// Construct output iterator from streambuf. |
5c352a47 BK |
214 | ostreambuf_iterator(streambuf_type* __s) throw () |
215 | : _M_sbuf(__s), _M_failed(!_M_sbuf) { } | |
216 | ||
ffcec5c8 | 217 | /// Write character to streambuf. Calls streambuf.sputc(). |
ed6814f7 | 218 | ostreambuf_iterator& |
2e2a38cd BK |
219 | operator=(_CharT __c) |
220 | { | |
ed6814f7 | 221 | if (!_M_failed && |
2e2a38cd BK |
222 | _Traits::eq_int_type(_M_sbuf->sputc(__c), _Traits::eof())) |
223 | _M_failed = true; | |
224 | return *this; | |
225 | } | |
5c352a47 | 226 | |
ffcec5c8 | 227 | /// Return *this. |
ed6814f7 | 228 | ostreambuf_iterator& |
e0ec69c9 | 229 | operator*() |
5c352a47 BK |
230 | { return *this; } |
231 | ||
ffcec5c8 | 232 | /// Return *this. |
ed6814f7 | 233 | ostreambuf_iterator& |
e0ec69c9 | 234 | operator++(int) |
5c352a47 BK |
235 | { return *this; } |
236 | ||
ffcec5c8 | 237 | /// Return *this. |
ed6814f7 | 238 | ostreambuf_iterator& |
e0ec69c9 | 239 | operator++() |
5c352a47 BK |
240 | { return *this; } |
241 | ||
ffcec5c8 | 242 | /// Return true if previous operator=() failed. |
ed6814f7 | 243 | bool |
5c352a47 BK |
244 | failed() const throw() |
245 | { return _M_failed; } | |
5c352a47 | 246 | |
ed6814f7 | 247 | ostreambuf_iterator& |
2e2a38cd BK |
248 | _M_put(const _CharT* __ws, streamsize __len) |
249 | { | |
53279c10 | 250 | if (__builtin_expect(!_M_failed, true) |
15d72060 PC |
251 | && __builtin_expect(this->_M_sbuf->sputn(__ws, __len) != __len, |
252 | false)) | |
53279c10 | 253 | _M_failed = true; |
2e2a38cd BK |
254 | return *this; |
255 | } | |
256 | }; | |
3cbc7af0 BK |
257 | |
258 | _GLIBCXX_END_NAMESPACE | |
259 | ||
b85381b9 | 260 | #endif |