]>
Commit | Line | Data |
---|---|---|
725dc051 BK |
1 | // Streambuf iterators |
2 | ||
2e2a38cd | 3 | // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 |
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 | |
19 | // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, | |
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 | ||
725dc051 BK |
46 | namespace std |
47 | { | |
725dc051 | 48 | // 24.5.3 Template class istreambuf_iterator |
39003c99 | 49 | template<typename _CharT, typename _Traits> |
725dc051 BK |
50 | class istreambuf_iterator |
51 | : public iterator<input_iterator_tag, _CharT, typename _Traits::off_type, | |
52 | _CharT*, _CharT&> | |
53 | { | |
54 | public: | |
725dc051 BK |
55 | // Types: |
56 | typedef _CharT char_type; | |
57 | typedef _Traits traits_type; | |
58 | typedef typename _Traits::int_type int_type; | |
59 | typedef basic_streambuf<_CharT, _Traits> streambuf_type; | |
60 | typedef basic_istream<_CharT, _Traits> istream_type; | |
725dc051 | 61 | |
39003c99 BK |
62 | private: |
63 | // 24.5.3 istreambuf_iterator | |
64 | // p 1 | |
65 | // If the end of stream is reached (streambuf_type::sgetc() | |
66 | // returns traits_type::eof()), the iterator becomes equal to | |
67 | // the "end of stream" iterator value. | |
68 | // NB: This implementation assumes the "end of stream" value | |
69 | // is EOF, or -1. | |
5c352a47 | 70 | mutable streambuf_type* _M_sbuf; |
39003c99 BK |
71 | int_type _M_c; |
72 | ||
73 | public: | |
725dc051 | 74 | istreambuf_iterator() throw() |
f13a69ec | 75 | : _M_sbuf(0), _M_c(traits_type::eof()) { } |
725dc051 BK |
76 | |
77 | istreambuf_iterator(istream_type& __s) throw() | |
f13a69ec | 78 | : _M_sbuf(__s.rdbuf()), _M_c(traits_type::eof()) { } |
725dc051 BK |
79 | |
80 | istreambuf_iterator(streambuf_type* __s) throw() | |
f13a69ec | 81 | : _M_sbuf(__s), _M_c(traits_type::eof()) { } |
725dc051 | 82 | |
9875ea05 | 83 | // NB: The result of operator*() on an end of stream is undefined. |
725dc051 BK |
84 | char_type |
85 | operator*() const | |
285b36d6 BK |
86 | { |
87 | #ifdef _GLIBCXX_DEBUG_PEDANTIC | |
88 | // Dereferencing a past-the-end istreambuf_iterator is a | |
89 | // libstdc++ extension | |
90 | __glibcxx_requires_cond(!_M_at_eof(), | |
91 | _M_message(__gnu_debug::__msg_deref_istreambuf) | |
92 | ._M_iterator(*this)); | |
93 | #endif | |
94 | return traits_type::to_char_type(_M_get()); | |
95 | } | |
725dc051 | 96 | |
b581eaf7 | 97 | istreambuf_iterator& |
725dc051 BK |
98 | operator++() |
99 | { | |
285b36d6 BK |
100 | __glibcxx_requires_cond(!_M_at_eof(), |
101 | _M_message(__gnu_debug::__msg_inc_istreambuf) | |
102 | ._M_iterator(*this)); | |
f13a69ec BK |
103 | const int_type __eof = traits_type::eof(); |
104 | if (_M_sbuf && traits_type::eq_int_type(_M_sbuf->sbumpc(), __eof)) | |
5c352a47 BK |
105 | _M_sbuf = 0; |
106 | else | |
f13a69ec | 107 | _M_c = __eof; |
725dc051 BK |
108 | return *this; |
109 | } | |
110 | ||
b581eaf7 | 111 | istreambuf_iterator |
725dc051 BK |
112 | operator++(int) |
113 | { | |
285b36d6 BK |
114 | __glibcxx_requires_cond(!_M_at_eof(), |
115 | _M_message(__gnu_debug::__msg_inc_istreambuf) | |
116 | ._M_iterator(*this)); | |
117 | ||
f13a69ec | 118 | const int_type __eof = traits_type::eof(); |
b581eaf7 | 119 | istreambuf_iterator __old = *this; |
f13a69ec BK |
120 | if (_M_sbuf |
121 | && traits_type::eq_int_type((__old._M_c = _M_sbuf->sbumpc()), | |
122 | __eof)) | |
5c352a47 BK |
123 | _M_sbuf = 0; |
124 | else | |
f13a69ec | 125 | _M_c = __eof; |
a85afd69 | 126 | return __old; |
725dc051 | 127 | } |
725dc051 | 128 | |
f5677b15 | 129 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
725dc051 | 130 | // 110 istreambuf_iterator::equal not const |
77cd227e | 131 | // NB: there is also number 111 (NAD, Future) pending on this function. |
725dc051 | 132 | bool |
b581eaf7 | 133 | equal(const istreambuf_iterator& __b) const |
725dc051 | 134 | { |
5c352a47 | 135 | const int_type __eof = traits_type::eof(); |
285b36d6 BK |
136 | bool __thiseof = _M_at_eof(); |
137 | bool __beof = __b._M_at_eof(); | |
725dc051 BK |
138 | return (__thiseof && __beof || (!__thiseof && !__beof)); |
139 | } | |
9875ea05 BK |
140 | |
141 | private: | |
142 | int_type | |
143 | _M_get() const | |
144 | { | |
f13a69ec BK |
145 | const int_type __eof = traits_type::eof(); |
146 | int_type __ret = __eof; | |
9875ea05 BK |
147 | if (_M_sbuf) |
148 | { | |
f13a69ec | 149 | if (!traits_type::eq_int_type(_M_c, __eof)) |
9875ea05 BK |
150 | __ret = _M_c; |
151 | else | |
f13a69ec | 152 | if (traits_type::eq_int_type((__ret = _M_sbuf->sgetc()), __eof)) |
9875ea05 BK |
153 | _M_sbuf = 0; |
154 | } | |
155 | return __ret; | |
156 | } | |
285b36d6 BK |
157 | |
158 | bool | |
159 | _M_at_eof() const | |
160 | { | |
161 | const int_type __eof = traits_type::eof(); | |
162 | return traits_type::eq_int_type(_M_get(), __eof); | |
163 | } | |
725dc051 BK |
164 | }; |
165 | ||
166 | template<typename _CharT, typename _Traits> | |
167 | inline bool | |
168 | operator==(const istreambuf_iterator<_CharT, _Traits>& __a, | |
169 | const istreambuf_iterator<_CharT, _Traits>& __b) | |
170 | { return __a.equal(__b); } | |
171 | ||
172 | template<typename _CharT, typename _Traits> | |
173 | inline bool | |
174 | operator!=(const istreambuf_iterator<_CharT, _Traits>& __a, | |
175 | const istreambuf_iterator<_CharT, _Traits>& __b) | |
176 | { return !__a.equal(__b); } | |
5c352a47 BK |
177 | |
178 | template<typename _CharT, typename _Traits> | |
179 | class ostreambuf_iterator | |
180 | : public iterator<output_iterator_tag, void, void, void, void> | |
181 | { | |
182 | public: | |
183 | // Types: | |
184 | typedef _CharT char_type; | |
185 | typedef _Traits traits_type; | |
186 | typedef basic_streambuf<_CharT, _Traits> streambuf_type; | |
187 | typedef basic_ostream<_CharT, _Traits> ostream_type; | |
188 | ||
189 | private: | |
190 | streambuf_type* _M_sbuf; | |
191 | bool _M_failed; | |
192 | ||
193 | public: | |
5c352a47 BK |
194 | ostreambuf_iterator(ostream_type& __s) throw () |
195 | : _M_sbuf(__s.rdbuf()), _M_failed(!_M_sbuf) { } | |
196 | ||
197 | ostreambuf_iterator(streambuf_type* __s) throw () | |
198 | : _M_sbuf(__s), _M_failed(!_M_sbuf) { } | |
199 | ||
200 | ostreambuf_iterator& | |
2e2a38cd BK |
201 | operator=(_CharT __c) |
202 | { | |
203 | if (!_M_failed && | |
204 | _Traits::eq_int_type(_M_sbuf->sputc(__c), _Traits::eof())) | |
205 | _M_failed = true; | |
206 | return *this; | |
207 | } | |
5c352a47 BK |
208 | |
209 | ostreambuf_iterator& | |
e0ec69c9 | 210 | operator*() |
5c352a47 BK |
211 | { return *this; } |
212 | ||
213 | ostreambuf_iterator& | |
e0ec69c9 | 214 | operator++(int) |
5c352a47 BK |
215 | { return *this; } |
216 | ||
217 | ostreambuf_iterator& | |
e0ec69c9 | 218 | operator++() |
5c352a47 BK |
219 | { return *this; } |
220 | ||
221 | bool | |
222 | failed() const throw() | |
223 | { return _M_failed; } | |
5c352a47 | 224 | |
2e2a38cd BK |
225 | ostreambuf_iterator& |
226 | _M_put(const _CharT* __ws, streamsize __len) | |
227 | { | |
53279c10 JQ |
228 | if (__builtin_expect(!_M_failed, true) |
229 | && __builtin_expect(this->_M_sbuf->sputn(__ws, __len) != __len, false)) | |
230 | _M_failed = true; | |
2e2a38cd BK |
231 | return *this; |
232 | } | |
233 | }; | |
b85381b9 | 234 | } // namespace std |
b85381b9 | 235 | #endif |