basic_ios.tcc revision 97403
197403Sobrien// basic_ios locale and locale-related member functions -*- C++ -*- 297403Sobrien 397403Sobrien// Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc. 497403Sobrien// 597403Sobrien// This file is part of the GNU ISO C++ Library. This library is free 697403Sobrien// software; you can redistribute it and/or modify it under the 797403Sobrien// terms of the GNU General Public License as published by the 897403Sobrien// Free Software Foundation; either version 2, or (at your option) 997403Sobrien// any later version. 1097403Sobrien 1197403Sobrien// This library is distributed in the hope that it will be useful, 1297403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of 1397403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1497403Sobrien// GNU General Public License for more details. 1597403Sobrien 1697403Sobrien// You should have received a copy of the GNU General Public License along 1797403Sobrien// with this library; see the file COPYING. If not, write to the Free 1897403Sobrien// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 1997403Sobrien// USA. 2097403Sobrien 2197403Sobrien// As a special exception, you may use this file as part of a free software 2297403Sobrien// library without restriction. Specifically, if other files instantiate 2397403Sobrien// templates or use macros or inline functions from this file, or you compile 2497403Sobrien// this file and link it with other files to produce an executable, this 2597403Sobrien// file does not by itself cause the resulting executable to be covered by 2697403Sobrien// the GNU General Public License. This exception does not however 2797403Sobrien// invalidate any other reasons why the executable file might be covered by 2897403Sobrien// the GNU General Public License. 2997403Sobrien 3097403Sobrien#ifndef _CPP_BITS_BASICIOS_TCC 3197403Sobrien#define _CPP_BITS_BASICIOS_TCC 1 3297403Sobrien 3397403Sobrien#pragma GCC system_header 3497403Sobrien 3597403Sobriennamespace std 3697403Sobrien{ 3797403Sobrien template<typename _CharT, typename _Traits> 3897403Sobrien void 3997403Sobrien basic_ios<_CharT, _Traits>::clear(iostate __state) 4097403Sobrien { 4197403Sobrien if (this->rdbuf()) 4297403Sobrien _M_streambuf_state = __state; 4397403Sobrien else 4497403Sobrien _M_streambuf_state = __state | badbit; 4597403Sobrien if ((this->rdstate() & this->exceptions())) 4697403Sobrien __throw_ios_failure("basic_ios::clear(iostate) caused exception"); 4797403Sobrien } 4897403Sobrien 4997403Sobrien template<typename _CharT, typename _Traits> 5097403Sobrien basic_streambuf<_CharT, _Traits>* 5197403Sobrien basic_ios<_CharT, _Traits>::rdbuf(basic_streambuf<_CharT, _Traits>* __sb) 5297403Sobrien { 5397403Sobrien basic_streambuf<_CharT, _Traits>* __old = _M_streambuf; 5497403Sobrien _M_streambuf = __sb; 5597403Sobrien this->clear(); 5697403Sobrien return __old; 5797403Sobrien } 5897403Sobrien 5997403Sobrien template<typename _CharT, typename _Traits> 6097403Sobrien basic_ios<_CharT, _Traits>& 6197403Sobrien basic_ios<_CharT, _Traits>::copyfmt(const basic_ios& __rhs) 6297403Sobrien { 6397403Sobrien // Per 27.1.1.1, do not call imbue, yet must trash all caches 6497403Sobrien // associated with imbue() 6597403Sobrien 6697403Sobrien // Alloc any new word array first, so if it fails we have "rollback". 6797403Sobrien _Words* __words = (__rhs._M_word_size <= _S_local_word_size) ? 6897403Sobrien _M_local_word : new _Words[__rhs._M_word_size]; 6997403Sobrien 7097403Sobrien // Bump refs before doing callbacks, for safety. 7197403Sobrien _Callback_list* __cb = __rhs._M_callbacks; 7297403Sobrien if (__cb) 7397403Sobrien __cb->_M_add_reference(); 7497403Sobrien _M_call_callbacks(erase_event); 7597403Sobrien if (_M_word != _M_local_word) 7697403Sobrien { 7797403Sobrien delete [] _M_word; 7897403Sobrien _M_word = 0; 7997403Sobrien } 8097403Sobrien _M_dispose_callbacks(); 8197403Sobrien 8297403Sobrien _M_callbacks = __cb; // NB: Don't want any added during above. 8397403Sobrien for (int __i = 0; __i < __rhs._M_word_size; ++__i) 8497403Sobrien __words[__i] = __rhs._M_word[__i]; 8597403Sobrien if (_M_word != _M_local_word) 8697403Sobrien { 8797403Sobrien delete [] _M_word; 8897403Sobrien _M_word = 0; 8997403Sobrien } 9097403Sobrien _M_word = __words; 9197403Sobrien _M_word_size = __rhs._M_word_size; 9297403Sobrien 9397403Sobrien this->flags(__rhs.flags()); 9497403Sobrien this->width(__rhs.width()); 9597403Sobrien this->precision(__rhs.precision()); 9697403Sobrien this->tie(__rhs.tie()); 9797403Sobrien this->fill(__rhs.fill()); 9897403Sobrien // The next is required to be the last assignment. 9997403Sobrien this->exceptions(__rhs.exceptions()); 10097403Sobrien 10197403Sobrien _M_call_callbacks(copyfmt_event); 10297403Sobrien return *this; 10397403Sobrien } 10497403Sobrien 10597403Sobrien template<typename _CharT, typename _Traits> 10697403Sobrien char 10797403Sobrien basic_ios<_CharT, _Traits>::narrow(char_type __c, char __dfault) const 10897403Sobrien { 10997403Sobrien char __ret = __dfault; 11097403Sobrien if (_M_check_facet(_M_fctype)) 11197403Sobrien __ret = _M_fctype->narrow(__c, __dfault); 11297403Sobrien return __ret; 11397403Sobrien } 11497403Sobrien 11597403Sobrien template<typename _CharT, typename _Traits> 11697403Sobrien _CharT 11797403Sobrien basic_ios<_CharT, _Traits>::widen(char __c) const 11897403Sobrien { 11997403Sobrien char_type __ret = char_type(); 12097403Sobrien if (_M_check_facet(_M_fctype)) 12197403Sobrien __ret = _M_fctype->widen(__c); 12297403Sobrien return __ret; 12397403Sobrien } 12497403Sobrien 12597403Sobrien // Locales: 12697403Sobrien template<typename _CharT, typename _Traits> 12797403Sobrien locale 12897403Sobrien basic_ios<_CharT, _Traits>::imbue(const locale& __loc) 12997403Sobrien { 13097403Sobrien locale __old(this->getloc()); 13197403Sobrien ios_base::imbue(__loc); 13297403Sobrien _M_cache_facets(__loc); 13397403Sobrien if (this->rdbuf() != 0) 13497403Sobrien this->rdbuf()->pubimbue(__loc); 13597403Sobrien return __old; 13697403Sobrien } 13797403Sobrien 13897403Sobrien template<typename _CharT, typename _Traits> 13997403Sobrien void 14097403Sobrien basic_ios<_CharT, _Traits>::init(basic_streambuf<_CharT, _Traits>* __sb) 14197403Sobrien { 14297403Sobrien // NB: This may be called more than once on the same object. 14397403Sobrien ios_base::_M_init(); 14497403Sobrien _M_cache_facets(_M_ios_locale); 14597403Sobrien _M_tie = 0; 14697403Sobrien 14797403Sobrien // NB: The 27.4.4.1 Postconditions Table specifies requirements 14897403Sobrien // after basic_ios::init() has been called. As part of this, 14997403Sobrien // fill() must return widen(' ') any time after init() has been 15097403Sobrien // called, which needs an imbued ctype facet of char_type to 15197403Sobrien // return without throwing an exception. Unfortunately, 15297403Sobrien // ctype<char_type> is not necessarily a required facet, so 15397403Sobrien // streams with char_type != [char, wchar_t] will not have it by 15497403Sobrien // default. Because of this, the correct value for _M_fill is 15597403Sobrien // constructed on the first call of fill(). That way, 15697403Sobrien // unformatted input and output with non-required basic_ios 15797403Sobrien // instantiations is possible even without imbuing the expected 15897403Sobrien // ctype<char_type> facet. 15997403Sobrien _M_fill = 0; 16097403Sobrien _M_fill_init = false; 16197403Sobrien 16297403Sobrien _M_exception = goodbit; 16397403Sobrien _M_streambuf = __sb; 16497403Sobrien _M_streambuf_state = __sb ? goodbit : badbit; 16597403Sobrien } 16697403Sobrien 16797403Sobrien template<typename _CharT, typename _Traits> 16897403Sobrien void 16997403Sobrien basic_ios<_CharT, _Traits>::_M_cache_facets(const locale& __loc) 17097403Sobrien { 17197403Sobrien if (has_facet<__ctype_type>(__loc)) 17297403Sobrien _M_fctype = &use_facet<__ctype_type>(__loc); 17397403Sobrien else 17497403Sobrien _M_fctype = 0; 17597403Sobrien // Should be filled in by ostream and istream, respectively. 17697403Sobrien if (has_facet<__numput_type>(__loc)) 17797403Sobrien _M_fnumput = &use_facet<__numput_type>(__loc); 17897403Sobrien else 17997403Sobrien _M_fnumput = 0; 18097403Sobrien if (has_facet<__numget_type>(__loc)) 18197403Sobrien _M_fnumget = &use_facet<__numget_type>(__loc); 18297403Sobrien else 18397403Sobrien _M_fnumget = 0; 18497403Sobrien } 18597403Sobrien 18697403Sobrien // Inhibit implicit instantiations for required instantiations, 18797403Sobrien // which are defined via explicit instantiations elsewhere. 18897403Sobrien // NB: This syntax is a GNU extension. 18997403Sobrien extern template class basic_ios<char>; 19097403Sobrien extern template class basic_ios<wchar_t>; 19197403Sobrien} // namespace std 19297403Sobrien 19397403Sobrien#endif 194