sstream.tcc revision 97403
1// String based streams -*- C++ -*- 2 3// Copyright (C) 1997, 1998, 1999, 2001, 2002 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 _CPP_BITS_SSTREAM_TCC 36#define _CPP_BITS_SSTREAM_TCC 1 37 38#pragma GCC system_header 39 40#include <sstream> 41 42namespace 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 bool __testeof = traits_type::eq_int_type(__c, traits_type::eof()); 51 bool __testpos = _M_in_cur && _M_in_beg < _M_in_cur; 52 53 // Try to put back __c into input sequence in one of three ways. 54 // Order these tests done in is unspecified by the standard. 55 if (__testpos) 56 { 57 if (traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]) 58 && !__testeof) 59 { 60 --_M_in_cur; 61 __ret = __c; 62 } 63 else if (!__testeof) 64 { 65 --_M_in_cur; 66 *_M_in_cur = traits_type::to_char_type(__c); 67 __ret = __c; 68 } 69 else if (__testeof) 70 { 71 --_M_in_cur; 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 int_type __ret = traits_type::eof(); 84 bool __testeof = traits_type::eq_int_type(__c, __ret); 85 bool __testwrite = _M_out_cur < _M_buf + _M_buf_size; 86 bool __testout = _M_mode & ios_base::out; 87 88 // Try to append __c into output sequence in one of two ways. 89 // Order these tests done in is unspecified by the standard. 90 if (__testout) 91 { 92 if (!__testeof) 93 { 94 __size_type __len = max(_M_buf_size, _M_buf_size_opt); 95 __len *= 2; 96 97 if (__testwrite) 98 __ret = this->sputc(__c); 99 else if (__len <= _M_string.max_size()) 100 { 101 // Force-allocate, re-sync. 102 _M_string = this->str(); 103 _M_string.reserve(__len); 104 _M_buf_size = static_cast<int_type>(__len); 105 _M_really_sync(_M_in_cur - _M_in_beg, 106 _M_out_cur - _M_out_beg); 107 *_M_out_cur = traits_type::to_char_type(__c); 108 _M_out_cur_move(1); 109 __ret = __c; 110 } 111 } 112 else 113 __ret = traits_type::not_eof(__c); 114 } 115 return __ret; 116 } 117 118 template <class _CharT, class _Traits, class _Alloc> 119 typename basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type 120 basic_stringbuf<_CharT, _Traits, _Alloc>:: 121 seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode) 122 { 123 pos_type __ret = pos_type(off_type(-1)); 124 bool __testin = (ios_base::in & _M_mode & __mode) != 0; 125 bool __testout = (ios_base::out & _M_mode & __mode) != 0; 126 bool __testboth = __testin && __testout && __way != ios_base::cur; 127 __testin &= !(__mode & ios_base::out); 128 __testout &= !(__mode & ios_base::in); 129 130 if (_M_buf_size && (__testin || __testout || __testboth)) 131 { 132 char_type* __beg = _M_buf; 133 char_type* __curi = NULL; 134 char_type* __curo = NULL; 135 char_type* __endi = NULL; 136 char_type* __endo = NULL; 137 138 if (__testin || __testboth) 139 { 140 __curi = this->gptr(); 141 __endi = this->egptr(); 142 } 143 if (__testout || __testboth) 144 { 145 __curo = this->pptr(); 146 __endo = this->epptr(); 147 } 148 149 off_type __newoffi = 0; 150 off_type __newoffo = 0; 151 if (__way == ios_base::cur) 152 { 153 __newoffi = __curi - __beg; 154 __newoffo = __curo - __beg; 155 } 156 else if (__way == ios_base::end) 157 { 158 __newoffi = __endi - __beg; 159 __newoffo = __endo - __beg; 160 } 161 162 if ((__testin || __testboth) 163 && __newoffi + __off >= 0 && __endi - __beg >= __newoffi + __off) 164 { 165 _M_in_cur = __beg + __newoffi + __off; 166 __ret = pos_type(__newoffi); 167 } 168 if ((__testout || __testboth) 169 && __newoffo + __off >= 0 && __endo - __beg >= __newoffo + __off) 170 { 171 _M_out_cur_move(__newoffo + __off - (_M_out_cur - __beg)); 172 __ret = pos_type(__newoffo); 173 } 174 } 175 return __ret; 176 } 177 178 template <class _CharT, class _Traits, class _Alloc> 179 typename basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type 180 basic_stringbuf<_CharT, _Traits, _Alloc>:: 181 seekpos(pos_type __sp, ios_base::openmode __mode) 182 { 183 pos_type __ret = pos_type(off_type(-1)); 184 185 if (_M_buf_size) 186 { 187 off_type __pos = __sp._M_position(); 188 char_type* __beg = NULL; 189 char_type* __end = NULL; 190 bool __testin = (ios_base::in & _M_mode & __mode) != 0; 191 bool __testout = (ios_base::out & _M_mode & __mode) != 0; 192 bool __testboth = __testin && __testout; 193 __testin &= !(__mode & ios_base::out); 194 __testout &= !(__mode & ios_base::in); 195 196 // NB: Ordered. 197 bool __testposi = false; 198 bool __testposo = false; 199 if (__testin || __testboth) 200 { 201 __beg = this->eback(); 202 __end = this->egptr(); 203 if (0 <= __pos && __pos <= __end - __beg) 204 __testposi = true; 205 } 206 if (__testout || __testboth) 207 { 208 __beg = this->pbase(); 209 __end = _M_buf + _M_buf_size; 210 if (0 <= __pos && __pos <= __end - __beg) 211 __testposo = true; 212 } 213 if (__testposi || __testposo) 214 { 215 if (__testposi) 216 _M_in_cur = _M_in_beg + __pos; 217 if (__testposo) 218 _M_out_cur_move((__pos) - (_M_out_cur - __beg)); 219 __ret = pos_type(off_type(__pos)); 220 } 221 } 222 return __ret; 223 } 224 225 // Inhibit implicit instantiations for required instantiations, 226 // which are defined via explicit instantiations elsewhere. 227 // NB: This syntax is a GNU extension. 228 extern template class basic_stringbuf<char>; 229 extern template class basic_stringbuf<wchar_t>; 230 extern template class basic_istringstream<char>; 231 extern template class basic_istringstream<wchar_t>; 232 extern template class basic_ostringstream<char>; 233 extern template class basic_ostringstream<wchar_t>; 234 extern template class basic_stringstream<char>; 235 extern template class basic_stringstream<wchar_t>; 236} // namespace std 237 238#endif 239