OSDN Git Service

2004-10-06 Paolo Carlini <pcarlini@suse.de>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / bits / sstream.tcc
1 // String based streams -*- C++ -*-
2
3 // Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003, 2004
4 // Free Software Foundation, Inc.
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
31 //
32 // ISO C++ 14882: 27.7  String-based streams
33 //
34
35 #ifndef _SSTREAM_TCC
36 #define _SSTREAM_TCC 1
37
38 #pragma GCC system_header
39
40 #include <sstream>
41
42 namespace std
43 {
44   template <class _CharT, class _Traits, class _Alloc>
45     typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type
46     basic_stringbuf<_CharT, _Traits, _Alloc>::
47     pbackfail(int_type __c)
48     {
49       int_type __ret = traits_type::eof();
50       if (this->eback() < this->gptr())
51         {
52           // Try to put back __c into input sequence in one of three ways.
53           // Order these tests done in is unspecified by the standard.
54           const bool __testeof = traits_type::eq_int_type(__c, __ret);
55           if (!__testeof)
56             {
57               const bool __testeq = traits_type::eq(traits_type::
58                                                     to_char_type(__c),
59                                                     this->gptr()[-1]);    
60               const bool __testout = this->_M_mode & ios_base::out;
61               if (__testeq || __testout)
62                 {
63                   this->gbump(-1);
64                   if (!__testeq)
65                     *this->gptr() = traits_type::to_char_type(__c);
66                   __ret = __c;
67                 }
68             }
69           else
70             {
71               this->gbump(-1);
72               __ret = traits_type::not_eof(__c);
73             }
74         }
75       return __ret;
76     }
77
78   template <class _CharT, class _Traits, class _Alloc>
79     typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type
80     basic_stringbuf<_CharT, _Traits, _Alloc>::
81     overflow(int_type __c)
82     {
83       const bool __testout = this->_M_mode & ios_base::out;
84       if (__builtin_expect(!__testout, false))
85         return traits_type::eof();
86
87       const bool __testeof = traits_type::eq_int_type(__c, traits_type::eof());
88       if (__builtin_expect(__testeof, false))
89         return traits_type::not_eof(__c);
90
91       const __size_type __capacity = _M_string.capacity();
92       const __size_type __max_size = _M_string.max_size();
93       const bool __testput = this->pptr() < this->epptr();
94       if (__builtin_expect(!__testput && __capacity == __max_size, false))
95         return traits_type::eof();
96
97       // Try to append __c into output sequence in one of two ways.
98       // Order these tests done in is unspecified by the standard.
99       if (!__testput)
100         {
101           // NB: Start ostringstream buffers at 512 chars. This is an
102           // experimental value (pronounced "arbitrary" in some of the
103           // hipper english-speaking countries), and can be changed to
104           // suit particular needs.
105           // Then, in virtue of DR 169 (TC) we are allowed to grow more
106           // than one char.
107           const __size_type __opt_len = std::max(__size_type(2 * __capacity),
108                                                  __size_type(512));
109           const __size_type __len = std::min(__opt_len, __max_size);
110           __string_type __tmp;
111           __tmp.reserve(__len);
112           if (this->pbase())
113             __tmp.assign(this->pbase(), this->epptr() - this->pbase());
114           _M_string.swap(__tmp);
115           _M_sync(const_cast<char_type*>(_M_string.data()),
116                   this->gptr() - this->eback(), this->pptr() - this->pbase());
117         }
118       return this->sputc(traits_type::to_char_type(__c));
119     }
120
121   template <class _CharT, class _Traits, class _Alloc>
122     typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type
123     basic_stringbuf<_CharT, _Traits, _Alloc>::
124     underflow()
125     {
126       int_type __ret = traits_type::eof();
127       const bool __testin = this->_M_mode & ios_base::in;
128       if (__testin)
129         {
130           // Update egptr() to match the actual string end.
131           _M_update_egptr();
132
133           if (this->gptr() < this->egptr())
134             __ret = traits_type::to_int_type(*this->gptr());
135         }
136       return __ret;
137     }
138
139   template <class _CharT, class _Traits, class _Alloc>
140     typename basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type
141     basic_stringbuf<_CharT, _Traits, _Alloc>::
142     seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode)
143     {
144       pos_type __ret =  pos_type(off_type(-1));
145       bool __testin = (ios_base::in & this->_M_mode & __mode) != 0;
146       bool __testout = (ios_base::out & this->_M_mode & __mode) != 0;
147       const bool __testboth = __testin && __testout && __way != ios_base::cur;
148       __testin &= !(__mode & ios_base::out);
149       __testout &= !(__mode & ios_base::in);
150
151       // _GLIBCXX_RESOLVE_LIB_DEFECTS
152       // 453. basic_stringbuf::seekoff need not always fail for an empty stream.
153       const char_type* __beg = __testin ? this->eback() : this->pbase();
154       if ((__beg || !__off) && (__testin || __testout || __testboth))
155         {
156           _M_update_egptr();
157
158           off_type __newoffi = __off;
159           off_type __newoffo = __newoffi;
160           if (__way == ios_base::cur)
161             {
162               __newoffi += this->gptr() - __beg;
163               __newoffo += this->pptr() - __beg;
164             }
165           else if (__way == ios_base::end)
166             __newoffo = __newoffi += this->egptr() - __beg;
167
168           if ((__testin || __testboth)
169               && __newoffi >= 0
170               && this->egptr() - __beg >= __newoffi)
171             {
172               this->gbump((__beg + __newoffi) - this->gptr());
173               __ret = pos_type(__newoffi);
174             }
175           if ((__testout || __testboth)
176               && __newoffo >= 0
177               && this->egptr() - __beg >= __newoffo)
178             {
179               this->pbump((__beg + __newoffo) - this->pptr());
180               __ret = pos_type(__newoffo);
181             }
182         }
183       return __ret;
184     }
185
186   template <class _CharT, class _Traits, class _Alloc>
187     typename basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type
188     basic_stringbuf<_CharT, _Traits, _Alloc>::
189     seekpos(pos_type __sp, ios_base::openmode __mode)
190     {
191       pos_type __ret =  pos_type(off_type(-1));
192       const bool __testin = (ios_base::in & this->_M_mode & __mode) != 0;
193       const bool __testout = (ios_base::out & this->_M_mode & __mode) != 0;
194
195       const char_type* __beg = __testin ? this->eback() : this->pbase();
196       if (__beg && (__testin || __testout))
197         {
198           _M_update_egptr();
199
200           const off_type __pos(__sp);
201           const bool __testpos = 0 <= __pos
202                                  && __pos <=  this->egptr() - __beg;
203           if (__testpos)
204             {
205               if (__testin)
206                 this->gbump((__beg + __pos) - this->gptr());
207               if (__testout)
208                 this->pbump((__beg + __pos) - this->pptr());
209               __ret = __sp;
210             }
211         }
212       return __ret;
213     }
214
215   // Inhibit implicit instantiations for required instantiations,
216   // which are defined via explicit instantiations elsewhere.
217   // NB:  This syntax is a GNU extension.
218 #if _GLIBCXX_EXTERN_TEMPLATE
219   extern template class basic_stringbuf<char>;
220   extern template class basic_istringstream<char>;
221   extern template class basic_ostringstream<char>;
222   extern template class basic_stringstream<char>;
223
224 #ifdef _GLIBCXX_USE_WCHAR_T
225   extern template class basic_stringbuf<wchar_t>;
226   extern template class basic_istringstream<wchar_t>;
227   extern template class basic_ostringstream<wchar_t>;
228   extern template class basic_stringstream<wchar_t>;
229 #endif
230 #endif
231 } // namespace std
232
233 #endif