sbuf_iter.h (istreambuf_iterator): Correct.
[gcc.git] / libstdc++-v3 / include / bits / std_sstream.h
1 // String based streams -*- C++ -*-
2
3 // Copyright (C) 1997-1999 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 2, or (at your option)
9 // any later version.
10
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING. If not, write to the Free
18 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19 // USA.
20
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction. Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License. This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
29
30 //
31 // ISO C++ 14882: 27.7 String-based streams
32 //
33
34 #ifndef _CPP_SSTREAM
35 #define _CPP_SSTREAM 1
36
37 #pragma GCC system_header
38
39 #include <bits/std_istream.h>
40 #include <bits/std_ostream.h>
41
42 namespace std
43 {
44 template<typename _CharT, typename _Traits, typename _Alloc>
45 class basic_stringbuf : public basic_streambuf<_CharT, _Traits>
46 {
47 public:
48 // Types:
49 typedef _CharT char_type;
50 typedef _Traits traits_type;
51 typedef typename traits_type::int_type int_type;
52 typedef typename traits_type::pos_type pos_type;
53 typedef typename traits_type::off_type off_type;
54
55 // Non-standard Types:
56 typedef basic_streambuf<char_type, traits_type> __streambuf_type;
57 typedef basic_string<char_type, _Traits, _Alloc> __string_type;
58 typedef typename __string_type::size_type __size_type;
59
60 private:
61 // Data Members:
62 __string_type _M_string;
63
64 public:
65 // Constructors:
66 explicit
67 basic_stringbuf(ios_base::openmode __mode = ios_base::in | ios_base::out)
68 : __streambuf_type(), _M_string()
69 { _M_stringbuf_init(__mode); }
70
71 explicit
72 basic_stringbuf(const __string_type& __str,
73 ios_base::openmode __mode = ios_base::in | ios_base::out)
74 : __streambuf_type(), _M_string(__str.c_str())
75 { _M_stringbuf_init(__mode); }
76
77 // Get and set:
78 __string_type
79 str() const
80 {
81 if (_M_mode & ios_base::out)
82 {
83 // This is the deal: _M_string.size() is value that
84 // represents the size of the intial string that makes
85 // _M_string, and may not be the correct size of the
86 // current stringbuf internal buffer.
87 __size_type __len = _M_string.size();
88 if (_M_out_cur > _M_out_beg)
89 __len = max(__size_type(_M_out_end - _M_out_beg), __len);
90 return __string_type(_M_out_beg, _M_out_beg + __len);
91 }
92 else
93 return _M_string;
94 }
95
96 void
97 str(const __string_type& __s)
98 {
99 _M_string = __s;
100 _M_stringbuf_init(_M_mode);
101 }
102
103 protected:
104 // Common initialization code for both ctors goes here.
105 void
106 _M_stringbuf_init(ios_base::openmode __mode)
107 {
108 // _M_buf_size is a convenient alias for "what the streambuf
109 // thinks the allocated size of the string really is." This is
110 // necessary as ostringstreams are implemented with the
111 // streambufs having control of the allocation and
112 // re-allocation of the internal string object, _M_string.
113 _M_buf_size = _M_string.size();
114
115 // NB: Start ostringstream buffers at 1024 bytes. This is an
116 // experimental value (pronounced "arbitrary" in some of the
117 // hipper english-speaking countries), and can be changed to
118 // suite particular needs.
119 _M_buf_size_opt = 512;
120 _M_mode = __mode;
121 if (_M_mode & ios_base::ate)
122 _M_really_sync(0, _M_buf_size);
123 else
124 _M_really_sync(0, 0);
125 }
126
127 // Overridden virtual functions:
128 virtual int_type
129 underflow()
130 {
131 if (_M_in_cur && _M_in_cur < _M_in_end)
132 return traits_type::to_int_type(*gptr());
133 else
134 return traits_type::eof();
135 }
136
137 virtual int_type
138 pbackfail(int_type __c = traits_type::eof());
139
140 virtual int_type
141 overflow(int_type __c = traits_type::eof());
142
143 virtual __streambuf_type*
144 setbuf(char_type* __s, streamsize __n)
145 {
146 if (__n)
147 {
148 _M_string = __string_type(__s, __n);
149 _M_really_sync(0, 0);
150 }
151 return this;
152 }
153
154 virtual pos_type
155 seekoff(off_type __off, ios_base::seekdir __way,
156 ios_base::openmode __mode = ios_base::in | ios_base::out);
157
158 virtual pos_type
159 seekpos(pos_type __sp,
160 ios_base::openmode __mode = ios_base::in | ios_base::out);
161
162 // Internal function for correctly updating the internal buffer
163 // for a particular _M_string, due to initialization or
164 // re-sizing of an existing _M_string.
165 // Assumes: contents of _M_string and internal buffer match exactly.
166 // __i == _M_in_cur - _M_in_beg
167 // __o == _M_out_cur - _M_out_beg
168 virtual int
169 _M_really_sync(__size_type __i, __size_type __o)
170 {
171 char_type* __base = const_cast<char_type*>(_M_string.data());
172 bool __testin = _M_mode & ios_base::in;
173 bool __testout = _M_mode & ios_base::out;
174 __size_type __len = _M_string.size();
175
176 _M_buf = __base;
177 if (__testin)
178 this->setg(__base, __base + __i, __base + __len);
179 if (__testout)
180 {
181 this->setp(__base, __base + __len);
182 _M_out_cur += __o;
183 }
184 return 0;
185 }
186 };
187
188
189 // 27.7.2 Template class basic_istringstream
190 template<typename _CharT, typename _Traits, typename _Alloc>
191 class basic_istringstream : public basic_istream<_CharT, _Traits>
192 {
193 public:
194 // Types:
195 typedef _CharT char_type;
196 typedef _Traits traits_type;
197 typedef typename traits_type::int_type int_type;
198 typedef typename traits_type::pos_type pos_type;
199 typedef typename traits_type::off_type off_type;
200
201 // Non-standard types:
202 typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
203 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type;
204 typedef basic_istream<char_type, traits_type> __istream_type;
205
206 // Constructors:
207 explicit
208 basic_istringstream(ios_base::openmode __mode = ios_base::in)
209 : __istream_type(new __stringbuf_type(__mode | ios_base::in))
210 { }
211
212 explicit
213 basic_istringstream(const __string_type& __str,
214 ios_base::openmode __mode = ios_base::in)
215 : __istream_type(new __stringbuf_type(__str, __mode | ios_base::in))
216 { }
217
218 ~basic_istringstream()
219 {
220 delete _M_streambuf;
221 _M_streambuf = NULL;
222 }
223
224 // Members:
225 __stringbuf_type*
226 rdbuf() const
227 { return static_cast<__stringbuf_type*>(_M_streambuf); }
228
229 __string_type
230 str() const
231 { return this->rdbuf()->str(); }
232
233 void
234 str(const __string_type& __s)
235 { rdbuf()->str(__s); }
236
237 };
238
239
240 // 27.7.3 Template class basic_ostringstream
241 template <typename _CharT, typename _Traits, typename _Alloc>
242 class basic_ostringstream : public basic_ostream<_CharT, _Traits>
243 {
244 public:
245 // Types:
246 typedef _CharT char_type;
247 typedef _Traits traits_type;
248 typedef typename traits_type::int_type int_type;
249 typedef typename traits_type::pos_type pos_type;
250 typedef typename traits_type::off_type off_type;
251
252 // Non-standard types:
253 typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
254 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type;
255 typedef basic_ostream<char_type, traits_type> __ostream_type;
256
257 // Constructors/destructor:
258 explicit
259 basic_ostringstream(ios_base::openmode __mode = ios_base::out)
260 : __ostream_type(new __stringbuf_type(__mode | ios_base::out))
261 { }
262
263 explicit
264 basic_ostringstream(const __string_type __str,
265 ios_base::openmode __mode = ios_base::out)
266 : __ostream_type(new __stringbuf_type(__str, __mode | ios_base::out))
267 { }
268
269 ~basic_ostringstream()
270 {
271 delete _M_streambuf;
272 _M_streambuf = NULL;
273 }
274
275 // Members:
276 __stringbuf_type*
277 rdbuf() const
278 { return static_cast<__stringbuf_type*>(_M_streambuf); }
279
280 __string_type
281 str() const
282 { return this->rdbuf()->str(); }
283
284 void
285 str(const __string_type& __s)
286 { rdbuf()->str(__s); }
287
288 };
289
290
291 // 27.7.4 Template class basic_stringstream
292 template <typename _CharT, typename _Traits, typename _Alloc>
293 class basic_stringstream : public basic_iostream<_CharT, _Traits>
294 {
295 public:
296 // Types:
297 typedef _CharT char_type;
298 typedef _Traits traits_type;
299 typedef typename traits_type::int_type int_type;
300 typedef typename traits_type::pos_type pos_type;
301 typedef typename traits_type::off_type off_type;
302
303 // Non-standard Types:
304 typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
305 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type;
306 typedef basic_iostream<char_type, traits_type> __iostream_type;
307
308 // Constructors/destructors
309 explicit
310 basic_stringstream(ios_base::openmode __mode =
311 ios_base::out | ios_base::in)
312 : __iostream_type(new __stringbuf_type(__mode))
313 { }
314
315 explicit
316 basic_stringstream(const __string_type& __str,
317 ios_base::openmode __mode =
318 ios_base::out | ios_base::in)
319 : __iostream_type(new __stringbuf_type(__str, __mode))
320 { }
321
322 ~basic_stringstream()
323 {
324 delete _M_streambuf;
325 _M_streambuf = NULL;
326 }
327
328 // Members:
329 __stringbuf_type*
330 rdbuf() const
331 { return static_cast<__stringbuf_type*>(_M_streambuf); }
332
333 __string_type
334 str() const
335 { return rdbuf()->str(); }
336
337 void
338 str(const __string_type& __s)
339 { rdbuf()->str(__s); }
340 };
341
342 } // namespace std
343
344
345
346 #ifdef _GLIBCPP_NO_TEMPLATE_EXPORT
347 # define export
348 #ifdef _GLIBCPP_FULLY_COMPLIANT_HEADERS
349 # include <bits/sstream.tcc>
350 #endif
351 #endif
352
353 #endif /* _CPP_SSTREAM */
354