0,0 → 1,288 |
// String based streams -*- C++ -*- |
|
// Copyright (C) 1997-2015 Free Software Foundation, Inc. |
// |
// This file is part of the GNU ISO C++ Library. This library is free |
// software; you can redistribute it and/or modify it under the |
// terms of the GNU General Public License as published by the |
// Free Software Foundation; either version 3, or (at your option) |
// any later version. |
|
// This library is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
|
// Under Section 7 of GPL version 3, you are granted additional |
// permissions described in the GCC Runtime Library Exception, version |
// 3.1, as published by the Free Software Foundation. |
|
// You should have received a copy of the GNU General Public License and |
// a copy of the GCC Runtime Library Exception along with this program; |
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see |
// <http://www.gnu.org/licenses/>. |
|
/** @file bits/sstream.tcc |
* This is an internal header file, included by other library headers. |
* Do not attempt to use it directly. @headername{sstream} |
*/ |
|
// |
// ISO C++ 14882: 27.7 String-based streams |
// |
|
#ifndef _SSTREAM_TCC |
#define _SSTREAM_TCC 1 |
|
#pragma GCC system_header |
|
namespace std _GLIBCXX_VISIBILITY(default) |
{ |
_GLIBCXX_BEGIN_NAMESPACE_VERSION |
|
template <class _CharT, class _Traits, class _Alloc> |
typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type |
basic_stringbuf<_CharT, _Traits, _Alloc>:: |
pbackfail(int_type __c) |
{ |
int_type __ret = traits_type::eof(); |
if (this->eback() < this->gptr()) |
{ |
// Try to put back __c into input sequence in one of three ways. |
// Order these tests done in is unspecified by the standard. |
const bool __testeof = traits_type::eq_int_type(__c, __ret); |
if (!__testeof) |
{ |
const bool __testeq = traits_type::eq(traits_type:: |
to_char_type(__c), |
this->gptr()[-1]); |
const bool __testout = this->_M_mode & ios_base::out; |
if (__testeq || __testout) |
{ |
this->gbump(-1); |
if (!__testeq) |
*this->gptr() = traits_type::to_char_type(__c); |
__ret = __c; |
} |
} |
else |
{ |
this->gbump(-1); |
__ret = traits_type::not_eof(__c); |
} |
} |
return __ret; |
} |
|
template <class _CharT, class _Traits, class _Alloc> |
typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type |
basic_stringbuf<_CharT, _Traits, _Alloc>:: |
overflow(int_type __c) |
{ |
const bool __testout = this->_M_mode & ios_base::out; |
if (__builtin_expect(!__testout, false)) |
return traits_type::eof(); |
|
const bool __testeof = traits_type::eq_int_type(__c, traits_type::eof()); |
if (__builtin_expect(__testeof, false)) |
return traits_type::not_eof(__c); |
|
const __size_type __capacity = _M_string.capacity(); |
const __size_type __max_size = _M_string.max_size(); |
const bool __testput = this->pptr() < this->epptr(); |
if (__builtin_expect(!__testput && __capacity == __max_size, false)) |
return traits_type::eof(); |
|
// Try to append __c into output sequence in one of two ways. |
// Order these tests done in is unspecified by the standard. |
const char_type __conv = traits_type::to_char_type(__c); |
if (!__testput) |
{ |
// NB: Start ostringstream buffers at 512 chars. This is an |
// experimental value (pronounced "arbitrary" in some of the |
// hipper English-speaking countries), and can be changed to |
// suit particular needs. |
// |
// _GLIBCXX_RESOLVE_LIB_DEFECTS |
// 169. Bad efficiency of overflow() mandated |
// 432. stringbuf::overflow() makes only one write position |
// available |
const __size_type __opt_len = std::max(__size_type(2 * __capacity), |
__size_type(512)); |
const __size_type __len = std::min(__opt_len, __max_size); |
__string_type __tmp; |
__tmp.reserve(__len); |
if (this->pbase()) |
__tmp.assign(this->pbase(), this->epptr() - this->pbase()); |
__tmp.push_back(__conv); |
_M_string.swap(__tmp); |
_M_sync(const_cast<char_type*>(_M_string.data()), |
this->gptr() - this->eback(), this->pptr() - this->pbase()); |
} |
else |
*this->pptr() = __conv; |
this->pbump(1); |
return __c; |
} |
|
template <class _CharT, class _Traits, class _Alloc> |
typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type |
basic_stringbuf<_CharT, _Traits, _Alloc>:: |
underflow() |
{ |
int_type __ret = traits_type::eof(); |
const bool __testin = this->_M_mode & ios_base::in; |
if (__testin) |
{ |
// Update egptr() to match the actual string end. |
_M_update_egptr(); |
|
if (this->gptr() < this->egptr()) |
__ret = traits_type::to_int_type(*this->gptr()); |
} |
return __ret; |
} |
|
template <class _CharT, class _Traits, class _Alloc> |
typename basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type |
basic_stringbuf<_CharT, _Traits, _Alloc>:: |
seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode) |
{ |
pos_type __ret = pos_type(off_type(-1)); |
bool __testin = (ios_base::in & this->_M_mode & __mode) != 0; |
bool __testout = (ios_base::out & this->_M_mode & __mode) != 0; |
const bool __testboth = __testin && __testout && __way != ios_base::cur; |
__testin &= !(__mode & ios_base::out); |
__testout &= !(__mode & ios_base::in); |
|
// _GLIBCXX_RESOLVE_LIB_DEFECTS |
// 453. basic_stringbuf::seekoff need not always fail for an empty stream. |
const char_type* __beg = __testin ? this->eback() : this->pbase(); |
if ((__beg || !__off) && (__testin || __testout || __testboth)) |
{ |
_M_update_egptr(); |
|
off_type __newoffi = __off; |
off_type __newoffo = __newoffi; |
if (__way == ios_base::cur) |
{ |
__newoffi += this->gptr() - __beg; |
__newoffo += this->pptr() - __beg; |
} |
else if (__way == ios_base::end) |
__newoffo = __newoffi += this->egptr() - __beg; |
|
if ((__testin || __testboth) |
&& __newoffi >= 0 |
&& this->egptr() - __beg >= __newoffi) |
{ |
this->setg(this->eback(), this->eback() + __newoffi, |
this->egptr()); |
__ret = pos_type(__newoffi); |
} |
if ((__testout || __testboth) |
&& __newoffo >= 0 |
&& this->egptr() - __beg >= __newoffo) |
{ |
_M_pbump(this->pbase(), this->epptr(), __newoffo); |
__ret = pos_type(__newoffo); |
} |
} |
return __ret; |
} |
|
template <class _CharT, class _Traits, class _Alloc> |
typename basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type |
basic_stringbuf<_CharT, _Traits, _Alloc>:: |
seekpos(pos_type __sp, ios_base::openmode __mode) |
{ |
pos_type __ret = pos_type(off_type(-1)); |
const bool __testin = (ios_base::in & this->_M_mode & __mode) != 0; |
const bool __testout = (ios_base::out & this->_M_mode & __mode) != 0; |
|
const char_type* __beg = __testin ? this->eback() : this->pbase(); |
if ((__beg || !off_type(__sp)) && (__testin || __testout)) |
{ |
_M_update_egptr(); |
|
const off_type __pos(__sp); |
const bool __testpos = (0 <= __pos |
&& __pos <= this->egptr() - __beg); |
if (__testpos) |
{ |
if (__testin) |
this->setg(this->eback(), this->eback() + __pos, |
this->egptr()); |
if (__testout) |
_M_pbump(this->pbase(), this->epptr(), __pos); |
__ret = __sp; |
} |
} |
return __ret; |
} |
|
template <class _CharT, class _Traits, class _Alloc> |
void |
basic_stringbuf<_CharT, _Traits, _Alloc>:: |
_M_sync(char_type* __base, __size_type __i, __size_type __o) |
{ |
const bool __testin = _M_mode & ios_base::in; |
const bool __testout = _M_mode & ios_base::out; |
char_type* __endg = __base + _M_string.size(); |
char_type* __endp = __base + _M_string.capacity(); |
|
if (__base != _M_string.data()) |
{ |
// setbuf: __i == size of buffer area (_M_string.size() == 0). |
__endg += __i; |
__i = 0; |
__endp = __endg; |
} |
|
if (__testin) |
this->setg(__base, __base + __i, __endg); |
if (__testout) |
{ |
_M_pbump(__base, __endp, __o); |
// egptr() always tracks the string end. When !__testin, |
// for the correct functioning of the streambuf inlines |
// the other get area pointers are identical. |
if (!__testin) |
this->setg(__endg, __endg, __endg); |
} |
} |
|
template <class _CharT, class _Traits, class _Alloc> |
void |
basic_stringbuf<_CharT, _Traits, _Alloc>:: |
_M_pbump(char_type* __pbeg, char_type* __pend, off_type __off) |
{ |
this->setp(__pbeg, __pend); |
while (__off > __gnu_cxx::__numeric_traits<int>::__max) |
{ |
this->pbump(__gnu_cxx::__numeric_traits<int>::__max); |
__off -= __gnu_cxx::__numeric_traits<int>::__max; |
} |
this->pbump(__off); |
} |
|
// Inhibit implicit instantiations for required instantiations, |
// which are defined via explicit instantiations elsewhere. |
#if _GLIBCXX_EXTERN_TEMPLATE |
extern template class basic_stringbuf<char>; |
extern template class basic_istringstream<char>; |
extern template class basic_ostringstream<char>; |
extern template class basic_stringstream<char>; |
|
#ifdef _GLIBCXX_USE_WCHAR_T |
extern template class basic_stringbuf<wchar_t>; |
extern template class basic_istringstream<wchar_t>; |
extern template class basic_ostringstream<wchar_t>; |
extern template class basic_stringstream<wchar_t>; |
#endif |
#endif |
|
_GLIBCXX_END_NAMESPACE_VERSION |
} // namespace std |
|
#endif |