]>
Commit | Line | Data |
---|---|---|
1d487aca | 1 | // String based streams -*- C++ -*- |
2 | ||
f1717362 | 3 | // Copyright (C) 1997-2016 Free Software Foundation, Inc. |
1d487aca | 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 | |
6bc9506f | 8 | // Free Software Foundation; either version 3, or (at your option) |
1d487aca | 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 | ||
6bc9506f | 16 | // Under Section 7 of GPL version 3, you are granted additional |
17 | // permissions described in the GCC Runtime Library Exception, version | |
18 | // 3.1, as published by the Free Software Foundation. | |
19 | ||
20 | // You should have received a copy of the GNU General Public License and | |
21 | // a copy of the GCC Runtime Library Exception along with this program; | |
22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
23 | // <http://www.gnu.org/licenses/>. | |
1d487aca | 24 | |
5846aeac | 25 | /** @file bits/sstream.tcc |
b2a66747 | 26 | * This is an internal header file, included by other library headers. |
5846aeac | 27 | * Do not attempt to use it directly. @headername{sstream} |
b2a66747 | 28 | */ |
29 | ||
1d487aca | 30 | // |
31 | // ISO C++ 14882: 27.7 String-based streams | |
32 | // | |
33 | ||
5a64d8cf | 34 | #ifndef _SSTREAM_TCC |
35 | #define _SSTREAM_TCC 1 | |
1d487aca | 36 | |
24a7b0dd | 37 | #pragma GCC system_header |
38 | ||
2948dd21 | 39 | namespace std _GLIBCXX_VISIBILITY(default) |
40 | { | |
41 | _GLIBCXX_BEGIN_NAMESPACE_VERSION | |
1069247d | 42 | |
1d487aca | 43 | template <class _CharT, class _Traits, class _Alloc> |
bae9b8af | 44 | typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type |
1d487aca | 45 | basic_stringbuf<_CharT, _Traits, _Alloc>:: |
46 | pbackfail(int_type __c) | |
47 | { | |
48 | int_type __ret = traits_type::eof(); | |
eae50d4c | 49 | if (this->eback() < this->gptr()) |
1d487aca | 50 | { |
ff7023d7 | 51 | // Try to put back __c into input sequence in one of three ways. |
52 | // Order these tests done in is unspecified by the standard. | |
8a89c0ca | 53 | const bool __testeof = traits_type::eq_int_type(__c, __ret); |
54 | if (!__testeof) | |
55 | { | |
56 | const bool __testeq = traits_type::eq(traits_type:: | |
57 | to_char_type(__c), | |
58 | this->gptr()[-1]); | |
59 | const bool __testout = this->_M_mode & ios_base::out; | |
60 | if (__testeq || __testout) | |
61 | { | |
62 | this->gbump(-1); | |
63 | if (!__testeq) | |
64 | *this->gptr() = traits_type::to_char_type(__c); | |
65 | __ret = __c; | |
66 | } | |
67 | } | |
103f5339 | 68 | else |
1d487aca | 69 | { |
8a89c0ca | 70 | this->gbump(-1); |
71 | __ret = traits_type::not_eof(__c); | |
1d487aca | 72 | } |
1d487aca | 73 | } |
74 | return __ret; | |
75 | } | |
bae9b8af | 76 | |
1d487aca | 77 | template <class _CharT, class _Traits, class _Alloc> |
bae9b8af | 78 | typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type |
1d487aca | 79 | basic_stringbuf<_CharT, _Traits, _Alloc>:: |
80 | overflow(int_type __c) | |
81 | { | |
b30903fa | 82 | const bool __testout = this->_M_mode & ios_base::out; |
943886d6 | 83 | if (__builtin_expect(!__testout, false)) |
84 | return traits_type::eof(); | |
a2febbfb | 85 | |
05e4ef54 | 86 | const bool __testeof = traits_type::eq_int_type(__c, traits_type::eof()); |
943886d6 | 87 | if (__builtin_expect(__testeof, false)) |
88 | return traits_type::not_eof(__c); | |
89 | ||
8cbb7faa | 90 | const __size_type __capacity = _M_string.capacity(); |
91 | const __size_type __max_size = _M_string.max_size(); | |
eae50d4c | 92 | const bool __testput = this->pptr() < this->epptr(); |
8cbb7faa | 93 | if (__builtin_expect(!__testput && __capacity == __max_size, false)) |
943886d6 | 94 | return traits_type::eof(); |
1d487aca | 95 | |
96 | // Try to append __c into output sequence in one of two ways. | |
97 | // Order these tests done in is unspecified by the standard. | |
e8f3af83 | 98 | const char_type __conv = traits_type::to_char_type(__c); |
a2febbfb | 99 | if (!__testput) |
1d487aca | 100 | { |
e8f3af83 | 101 | // NB: Start ostringstream buffers at 512 chars. This is an |
8cbb7faa | 102 | // experimental value (pronounced "arbitrary" in some of the |
9fc1117c | 103 | // hipper English-speaking countries), and can be changed to |
8cbb7faa | 104 | // suit particular needs. |
e8f3af83 | 105 | // |
106 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
107 | // 169. Bad efficiency of overflow() mandated | |
108 | // 432. stringbuf::overflow() makes only one write position | |
109 | // available | |
8cbb7faa | 110 | const __size_type __opt_len = std::max(__size_type(2 * __capacity), |
111 | __size_type(512)); | |
112 | const __size_type __len = std::min(__opt_len, __max_size); | |
b1aadeef | 113 | __string_type __tmp; |
114 | __tmp.reserve(__len); | |
8a86cf44 | 115 | if (this->pbase()) |
116 | __tmp.assign(this->pbase(), this->epptr() - this->pbase()); | |
e8f3af83 | 117 | __tmp.push_back(__conv); |
b1aadeef | 118 | _M_string.swap(__tmp); |
03489a0f | 119 | _M_sync(const_cast<char_type*>(_M_string.data()), |
05e4ef54 | 120 | this->gptr() - this->eback(), this->pptr() - this->pbase()); |
1d487aca | 121 | } |
e8f3af83 | 122 | else |
123 | *this->pptr() = __conv; | |
124 | this->pbump(1); | |
125 | return __c; | |
1d487aca | 126 | } |
127 | ||
eae50d4c | 128 | template <class _CharT, class _Traits, class _Alloc> |
bae9b8af | 129 | typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type |
eae50d4c | 130 | basic_stringbuf<_CharT, _Traits, _Alloc>:: |
212d2161 | 131 | underflow() |
eae50d4c | 132 | { |
133 | int_type __ret = traits_type::eof(); | |
134 | const bool __testin = this->_M_mode & ios_base::in; | |
135 | if (__testin) | |
136 | { | |
137 | // Update egptr() to match the actual string end. | |
138 | _M_update_egptr(); | |
86777552 | 139 | |
eae50d4c | 140 | if (this->gptr() < this->egptr()) |
212d2161 | 141 | __ret = traits_type::to_int_type(*this->gptr()); |
eae50d4c | 142 | } |
143 | return __ret; | |
144 | } | |
145 | ||
1d487aca | 146 | template <class _CharT, class _Traits, class _Alloc> |
996f7892 | 147 | typename basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type |
1d487aca | 148 | basic_stringbuf<_CharT, _Traits, _Alloc>:: |
149 | seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode) | |
150 | { | |
bae9b8af | 151 | pos_type __ret = pos_type(off_type(-1)); |
954ad420 | 152 | bool __testin = (ios_base::in & this->_M_mode & __mode) != 0; |
153 | bool __testout = (ios_base::out & this->_M_mode & __mode) != 0; | |
b30903fa | 154 | const bool __testboth = __testin && __testout && __way != ios_base::cur; |
efd81e8d | 155 | __testin &= !(__mode & ios_base::out); |
156 | __testout &= !(__mode & ios_base::in); | |
157 | ||
17d9f11a | 158 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
159 | // 453. basic_stringbuf::seekoff need not always fail for an empty stream. | |
86777552 | 160 | const char_type* __beg = __testin ? this->eback() : this->pbase(); |
17d9f11a | 161 | if ((__beg || !__off) && (__testin || __testout || __testboth)) |
1d487aca | 162 | { |
eae50d4c | 163 | _M_update_egptr(); |
1d487aca | 164 | |
05fd6e90 | 165 | off_type __newoffi = __off; |
166 | off_type __newoffo = __newoffi; | |
1d487aca | 167 | if (__way == ios_base::cur) |
168 | { | |
05fd6e90 | 169 | __newoffi += this->gptr() - __beg; |
170 | __newoffo += this->pptr() - __beg; | |
1d487aca | 171 | } |
172 | else if (__way == ios_base::end) | |
05fd6e90 | 173 | __newoffo = __newoffi += this->egptr() - __beg; |
1d487aca | 174 | |
efd81e8d | 175 | if ((__testin || __testboth) |
05fd6e90 | 176 | && __newoffi >= 0 |
177 | && this->egptr() - __beg >= __newoffi) | |
1d487aca | 178 | { |
5affa0ef | 179 | this->setg(this->eback(), this->eback() + __newoffi, |
180 | this->egptr()); | |
1d487aca | 181 | __ret = pos_type(__newoffi); |
182 | } | |
efd81e8d | 183 | if ((__testout || __testboth) |
05fd6e90 | 184 | && __newoffo >= 0 |
185 | && this->egptr() - __beg >= __newoffo) | |
1d487aca | 186 | { |
5affa0ef | 187 | _M_pbump(this->pbase(), this->epptr(), __newoffo); |
1d487aca | 188 | __ret = pos_type(__newoffo); |
189 | } | |
190 | } | |
191 | return __ret; | |
192 | } | |
193 | ||
194 | template <class _CharT, class _Traits, class _Alloc> | |
996f7892 | 195 | typename basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type |
1d487aca | 196 | basic_stringbuf<_CharT, _Traits, _Alloc>:: |
197 | seekpos(pos_type __sp, ios_base::openmode __mode) | |
198 | { | |
bae9b8af | 199 | pos_type __ret = pos_type(off_type(-1)); |
86777552 | 200 | const bool __testin = (ios_base::in & this->_M_mode & __mode) != 0; |
201 | const bool __testout = (ios_base::out & this->_M_mode & __mode) != 0; | |
bae9b8af | 202 | |
86777552 | 203 | const char_type* __beg = __testin ? this->eback() : this->pbase(); |
034cb642 | 204 | if ((__beg || !off_type(__sp)) && (__testin || __testout)) |
86777552 | 205 | { |
eae50d4c | 206 | _M_update_egptr(); |
207 | ||
11f2ae69 | 208 | const off_type __pos(__sp); |
e8f3af83 | 209 | const bool __testpos = (0 <= __pos |
210 | && __pos <= this->egptr() - __beg); | |
11f2ae69 | 211 | if (__testpos) |
efd81e8d | 212 | { |
eae50d4c | 213 | if (__testin) |
5affa0ef | 214 | this->setg(this->eback(), this->eback() + __pos, |
215 | this->egptr()); | |
eae50d4c | 216 | if (__testout) |
5affa0ef | 217 | _M_pbump(this->pbase(), this->epptr(), __pos); |
ef7a6830 | 218 | __ret = __sp; |
efd81e8d | 219 | } |
1d487aca | 220 | } |
1d487aca | 221 | return __ret; |
222 | } | |
11e7cbd1 | 223 | |
e8f3af83 | 224 | template <class _CharT, class _Traits, class _Alloc> |
225 | void | |
226 | basic_stringbuf<_CharT, _Traits, _Alloc>:: | |
227 | _M_sync(char_type* __base, __size_type __i, __size_type __o) | |
228 | { | |
229 | const bool __testin = _M_mode & ios_base::in; | |
230 | const bool __testout = _M_mode & ios_base::out; | |
097d10ab | 231 | char_type* __endg = __base + _M_string.size(); |
232 | char_type* __endp = __base + _M_string.capacity(); | |
233 | ||
234 | if (__base != _M_string.data()) | |
235 | { | |
236 | // setbuf: __i == size of buffer area (_M_string.size() == 0). | |
237 | __endg += __i; | |
238 | __i = 0; | |
239 | __endp = __endg; | |
240 | } | |
241 | ||
e8f3af83 | 242 | if (__testin) |
097d10ab | 243 | this->setg(__base, __base + __i, __endg); |
e8f3af83 | 244 | if (__testout) |
245 | { | |
5affa0ef | 246 | _M_pbump(__base, __endp, __o); |
e8f3af83 | 247 | // egptr() always tracks the string end. When !__testin, |
248 | // for the correct functioning of the streambuf inlines | |
249 | // the other get area pointers are identical. | |
250 | if (!__testin) | |
097d10ab | 251 | this->setg(__endg, __endg, __endg); |
e8f3af83 | 252 | } |
253 | } | |
254 | ||
5affa0ef | 255 | template <class _CharT, class _Traits, class _Alloc> |
256 | void | |
257 | basic_stringbuf<_CharT, _Traits, _Alloc>:: | |
258 | _M_pbump(char_type* __pbeg, char_type* __pend, off_type __off) | |
259 | { | |
260 | this->setp(__pbeg, __pend); | |
261 | while (__off > __gnu_cxx::__numeric_traits<int>::__max) | |
262 | { | |
263 | this->pbump(__gnu_cxx::__numeric_traits<int>::__max); | |
264 | __off -= __gnu_cxx::__numeric_traits<int>::__max; | |
265 | } | |
266 | this->pbump(__off); | |
267 | } | |
268 | ||
11e7cbd1 | 269 | // Inhibit implicit instantiations for required instantiations, |
bae9b8af | 270 | // which are defined via explicit instantiations elsewhere. |
7e6f150a | 271 | #if _GLIBCXX_EXTERN_TEMPLATE |
11e7cbd1 | 272 | extern template class basic_stringbuf<char>; |
11e7cbd1 | 273 | extern template class basic_istringstream<char>; |
11e7cbd1 | 274 | extern template class basic_ostringstream<char>; |
11e7cbd1 | 275 | extern template class basic_stringstream<char>; |
42bc1f1c | 276 | |
5a64d8cf | 277 | #ifdef _GLIBCXX_USE_WCHAR_T |
42bc1f1c | 278 | extern template class basic_stringbuf<wchar_t>; |
279 | extern template class basic_istringstream<wchar_t>; | |
280 | extern template class basic_ostringstream<wchar_t>; | |
11e7cbd1 | 281 | extern template class basic_stringstream<wchar_t>; |
42bc1f1c | 282 | #endif |
7e6f150a | 283 | #endif |
1069247d | 284 | |
2948dd21 | 285 | _GLIBCXX_END_NAMESPACE_VERSION |
cb38c7e0 | 286 | } // namespace std |
1d487aca | 287 | |
a0bda314 | 288 | #endif |