basic_ios.tcc revision 132720
1132720Skan// basic_ios member functions -*- C++ -*- 297403Sobrien 3117397Skan// Copyright (C) 1999, 2001, 2002, 2003 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 30132720Skan#ifndef _BASIC_IOS_TCC 31132720Skan#define _BASIC_IOS_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) 40132720Skan { 4197403Sobrien if (this->rdbuf()) 4297403Sobrien _M_streambuf_state = __state; 4397403Sobrien else 4497403Sobrien _M_streambuf_state = __state | badbit; 45132720Skan if (this->exceptions() & this->rdstate()) 46132720Skan __throw_ios_failure(__N("basic_ios::clear")); 4797403Sobrien } 48132720Skan 4997403Sobrien template<typename _CharT, typename _Traits> 50132720Skan 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 { 63132720Skan // _GLIBCXX_RESOLVE_LIB_DEFECTS 64132720Skan // 292. effects of a.copyfmt (a) 65132720Skan if (this != &__rhs) 6697403Sobrien { 67132720Skan // Per 27.1.1, do not call imbue, yet must trash all caches 68132720Skan // associated with imbue() 6997403Sobrien 70132720Skan // Alloc any new word array first, so if it fails we have "rollback". 71132720Skan _Words* __words = (__rhs._M_word_size <= _S_local_word_size) ? 72132720Skan _M_local_word : new _Words[__rhs._M_word_size]; 7397403Sobrien 74132720Skan // Bump refs before doing callbacks, for safety. 75132720Skan _Callback_list* __cb = __rhs._M_callbacks; 76132720Skan if (__cb) 77132720Skan __cb->_M_add_reference(); 78132720Skan _M_call_callbacks(erase_event); 79132720Skan if (_M_word != _M_local_word) 80132720Skan { 81132720Skan delete [] _M_word; 82132720Skan _M_word = 0; 83132720Skan } 84132720Skan _M_dispose_callbacks(); 85117397Skan 86132720Skan // NB: Don't want any added during above. 87132720Skan _M_callbacks = __cb; 88132720Skan for (int __i = 0; __i < __rhs._M_word_size; ++__i) 89132720Skan __words[__i] = __rhs._M_word[__i]; 90132720Skan if (_M_word != _M_local_word) 91132720Skan { 92132720Skan delete [] _M_word; 93132720Skan _M_word = 0; 94132720Skan } 95132720Skan _M_word = __words; 96132720Skan _M_word_size = __rhs._M_word_size; 97117397Skan 98132720Skan this->flags(__rhs.flags()); 99132720Skan this->width(__rhs.width()); 100132720Skan this->precision(__rhs.precision()); 101132720Skan this->tie(__rhs.tie()); 102132720Skan this->fill(__rhs.fill()); 103132720Skan _M_ios_locale = __rhs.getloc(); 104132720Skan _M_cache_locale(_M_ios_locale); 105117397Skan 106132720Skan _M_call_callbacks(copyfmt_event); 107117397Skan 108132720Skan // The next is required to be the last assignment. 109132720Skan this->exceptions(__rhs.exceptions()); 110132720Skan } 11197403Sobrien return *this; 11297403Sobrien } 11397403Sobrien 11497403Sobrien template<typename _CharT, typename _Traits> 11597403Sobrien char 11697403Sobrien basic_ios<_CharT, _Traits>::narrow(char_type __c, char __dfault) const 117132720Skan { return __check_facet(_M_ctype).narrow(__c, __dfault); } 11897403Sobrien 11997403Sobrien template<typename _CharT, typename _Traits> 12097403Sobrien _CharT 12197403Sobrien basic_ios<_CharT, _Traits>::widen(char __c) const 122132720Skan { return __check_facet(_M_ctype).widen(__c); } 12397403Sobrien 12497403Sobrien // Locales: 12597403Sobrien template<typename _CharT, typename _Traits> 12697403Sobrien locale 12797403Sobrien basic_ios<_CharT, _Traits>::imbue(const locale& __loc) 12897403Sobrien { 12997403Sobrien locale __old(this->getloc()); 13097403Sobrien ios_base::imbue(__loc); 131117397Skan _M_cache_locale(__loc); 13297403Sobrien if (this->rdbuf() != 0) 13397403Sobrien this->rdbuf()->pubimbue(__loc); 13497403Sobrien return __old; 13597403Sobrien } 13697403Sobrien 13797403Sobrien template<typename _CharT, typename _Traits> 13897403Sobrien void 13997403Sobrien basic_ios<_CharT, _Traits>::init(basic_streambuf<_CharT, _Traits>* __sb) 14097403Sobrien { 14197403Sobrien // NB: This may be called more than once on the same object. 14297403Sobrien ios_base::_M_init(); 143132720Skan 144132720Skan // Cache locale data and specific facets used by iostreams. 145117397Skan _M_cache_locale(_M_ios_locale); 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. 159102782Skan _M_fill = _CharT(); 16097403Sobrien _M_fill_init = false; 16197403Sobrien 162132720Skan _M_tie = 0; 16397403Sobrien _M_exception = goodbit; 16497403Sobrien _M_streambuf = __sb; 16597403Sobrien _M_streambuf_state = __sb ? goodbit : badbit; 16697403Sobrien } 16797403Sobrien 16897403Sobrien template<typename _CharT, typename _Traits> 16997403Sobrien void 170117397Skan basic_ios<_CharT, _Traits>::_M_cache_locale(const locale& __loc) 17197403Sobrien { 172117397Skan if (__builtin_expect(has_facet<__ctype_type>(__loc), true)) 173132720Skan _M_ctype = &use_facet<__ctype_type>(__loc); 17497403Sobrien else 175132720Skan _M_ctype = 0; 176132720Skan 177132720Skan if (__builtin_expect(has_facet<__num_put_type>(__loc), true)) 178132720Skan _M_num_put = &use_facet<__num_put_type>(__loc); 17997403Sobrien else 180132720Skan _M_num_put = 0; 181132720Skan 182132720Skan if (__builtin_expect(has_facet<__num_get_type>(__loc), true)) 183132720Skan _M_num_get = &use_facet<__num_get_type>(__loc); 18497403Sobrien else 185132720Skan _M_num_get = 0; 18697403Sobrien } 18797403Sobrien 18897403Sobrien // Inhibit implicit instantiations for required instantiations, 189132720Skan // which are defined via explicit instantiations elsewhere. 19097403Sobrien // NB: This syntax is a GNU extension. 191132720Skan#if _GLIBCXX_EXTERN_TEMPLATE 19297403Sobrien extern template class basic_ios<char>; 193107606Sobrien 194132720Skan#ifdef _GLIBCXX_USE_WCHAR_T 19597403Sobrien extern template class basic_ios<wchar_t>; 196107606Sobrien#endif 197117397Skan#endif 19897403Sobrien} // namespace std 19997403Sobrien 200132720Skan#endif 201