basic_ios.tcc revision 169691
1132720Skan// basic_ios member functions -*- C++ -*- 297403Sobrien 3169691Skan// Copyright (C) 1999, 2001, 2002, 2003, 2004, 2005 4169691Skan// Free Software Foundation, Inc. 597403Sobrien// 697403Sobrien// This file is part of the GNU ISO C++ Library. This library is free 797403Sobrien// software; you can redistribute it and/or modify it under the 897403Sobrien// terms of the GNU General Public License as published by the 997403Sobrien// Free Software Foundation; either version 2, or (at your option) 1097403Sobrien// any later version. 1197403Sobrien 1297403Sobrien// This library is distributed in the hope that it will be useful, 1397403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of 1497403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1597403Sobrien// GNU General Public License for more details. 1697403Sobrien 1797403Sobrien// You should have received a copy of the GNU General Public License along 1897403Sobrien// with this library; see the file COPYING. If not, write to the Free 19169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 2097403Sobrien// USA. 2197403Sobrien 2297403Sobrien// As a special exception, you may use this file as part of a free software 2397403Sobrien// library without restriction. Specifically, if other files instantiate 2497403Sobrien// templates or use macros or inline functions from this file, or you compile 2597403Sobrien// this file and link it with other files to produce an executable, this 2697403Sobrien// file does not by itself cause the resulting executable to be covered by 2797403Sobrien// the GNU General Public License. This exception does not however 2897403Sobrien// invalidate any other reasons why the executable file might be covered by 2997403Sobrien// the GNU General Public License. 3097403Sobrien 31169691Skan/** @file basic_ios.tcc 32169691Skan * This is an internal header file, included by other library headers. 33169691Skan * You should not attempt to use it directly. 34169691Skan */ 35169691Skan 36132720Skan#ifndef _BASIC_IOS_TCC 37132720Skan#define _BASIC_IOS_TCC 1 3897403Sobrien 3997403Sobrien#pragma GCC system_header 4097403Sobrien 41169691Skan_GLIBCXX_BEGIN_NAMESPACE(std) 42169691Skan 4397403Sobrien template<typename _CharT, typename _Traits> 4497403Sobrien void 4597403Sobrien basic_ios<_CharT, _Traits>::clear(iostate __state) 46132720Skan { 4797403Sobrien if (this->rdbuf()) 4897403Sobrien _M_streambuf_state = __state; 4997403Sobrien else 5097403Sobrien _M_streambuf_state = __state | badbit; 51132720Skan if (this->exceptions() & this->rdstate()) 52132720Skan __throw_ios_failure(__N("basic_ios::clear")); 5397403Sobrien } 54132720Skan 5597403Sobrien template<typename _CharT, typename _Traits> 56132720Skan basic_streambuf<_CharT, _Traits>* 5797403Sobrien basic_ios<_CharT, _Traits>::rdbuf(basic_streambuf<_CharT, _Traits>* __sb) 5897403Sobrien { 5997403Sobrien basic_streambuf<_CharT, _Traits>* __old = _M_streambuf; 6097403Sobrien _M_streambuf = __sb; 6197403Sobrien this->clear(); 6297403Sobrien return __old; 6397403Sobrien } 6497403Sobrien 6597403Sobrien template<typename _CharT, typename _Traits> 6697403Sobrien basic_ios<_CharT, _Traits>& 6797403Sobrien basic_ios<_CharT, _Traits>::copyfmt(const basic_ios& __rhs) 6897403Sobrien { 69132720Skan // _GLIBCXX_RESOLVE_LIB_DEFECTS 70132720Skan // 292. effects of a.copyfmt (a) 71132720Skan if (this != &__rhs) 7297403Sobrien { 73132720Skan // Per 27.1.1, do not call imbue, yet must trash all caches 74132720Skan // associated with imbue() 7597403Sobrien 76132720Skan // Alloc any new word array first, so if it fails we have "rollback". 77132720Skan _Words* __words = (__rhs._M_word_size <= _S_local_word_size) ? 78132720Skan _M_local_word : new _Words[__rhs._M_word_size]; 7997403Sobrien 80132720Skan // Bump refs before doing callbacks, for safety. 81132720Skan _Callback_list* __cb = __rhs._M_callbacks; 82132720Skan if (__cb) 83132720Skan __cb->_M_add_reference(); 84132720Skan _M_call_callbacks(erase_event); 85132720Skan if (_M_word != _M_local_word) 86132720Skan { 87132720Skan delete [] _M_word; 88132720Skan _M_word = 0; 89132720Skan } 90132720Skan _M_dispose_callbacks(); 91117397Skan 92132720Skan // NB: Don't want any added during above. 93132720Skan _M_callbacks = __cb; 94132720Skan for (int __i = 0; __i < __rhs._M_word_size; ++__i) 95132720Skan __words[__i] = __rhs._M_word[__i]; 96132720Skan _M_word = __words; 97132720Skan _M_word_size = __rhs._M_word_size; 98117397Skan 99132720Skan this->flags(__rhs.flags()); 100132720Skan this->width(__rhs.width()); 101132720Skan this->precision(__rhs.precision()); 102132720Skan this->tie(__rhs.tie()); 103132720Skan this->fill(__rhs.fill()); 104132720Skan _M_ios_locale = __rhs.getloc(); 105132720Skan _M_cache_locale(_M_ios_locale); 106117397Skan 107132720Skan _M_call_callbacks(copyfmt_event); 108117397Skan 109132720Skan // The next is required to be the last assignment. 110132720Skan this->exceptions(__rhs.exceptions()); 111132720Skan } 11297403Sobrien return *this; 11397403Sobrien } 11497403Sobrien 11597403Sobrien template<typename _CharT, typename _Traits> 11697403Sobrien char 11797403Sobrien basic_ios<_CharT, _Traits>::narrow(char_type __c, char __dfault) const 118132720Skan { return __check_facet(_M_ctype).narrow(__c, __dfault); } 11997403Sobrien 12097403Sobrien template<typename _CharT, typename _Traits> 12197403Sobrien _CharT 12297403Sobrien basic_ios<_CharT, _Traits>::widen(char __c) const 123132720Skan { return __check_facet(_M_ctype).widen(__c); } 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); 132117397Skan _M_cache_locale(__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(); 144132720Skan 145132720Skan // Cache locale data and specific facets used by iostreams. 146117397Skan _M_cache_locale(_M_ios_locale); 14797403Sobrien 14897403Sobrien // NB: The 27.4.4.1 Postconditions Table specifies requirements 14997403Sobrien // after basic_ios::init() has been called. As part of this, 15097403Sobrien // fill() must return widen(' ') any time after init() has been 15197403Sobrien // called, which needs an imbued ctype facet of char_type to 15297403Sobrien // return without throwing an exception. Unfortunately, 15397403Sobrien // ctype<char_type> is not necessarily a required facet, so 15497403Sobrien // streams with char_type != [char, wchar_t] will not have it by 15597403Sobrien // default. Because of this, the correct value for _M_fill is 15697403Sobrien // constructed on the first call of fill(). That way, 15797403Sobrien // unformatted input and output with non-required basic_ios 15897403Sobrien // instantiations is possible even without imbuing the expected 15997403Sobrien // ctype<char_type> facet. 160102782Skan _M_fill = _CharT(); 16197403Sobrien _M_fill_init = false; 16297403Sobrien 163132720Skan _M_tie = 0; 16497403Sobrien _M_exception = goodbit; 16597403Sobrien _M_streambuf = __sb; 16697403Sobrien _M_streambuf_state = __sb ? goodbit : badbit; 16797403Sobrien } 16897403Sobrien 16997403Sobrien template<typename _CharT, typename _Traits> 17097403Sobrien void 171117397Skan basic_ios<_CharT, _Traits>::_M_cache_locale(const locale& __loc) 17297403Sobrien { 173117397Skan if (__builtin_expect(has_facet<__ctype_type>(__loc), true)) 174132720Skan _M_ctype = &use_facet<__ctype_type>(__loc); 17597403Sobrien else 176132720Skan _M_ctype = 0; 177132720Skan 178132720Skan if (__builtin_expect(has_facet<__num_put_type>(__loc), true)) 179132720Skan _M_num_put = &use_facet<__num_put_type>(__loc); 18097403Sobrien else 181132720Skan _M_num_put = 0; 182132720Skan 183132720Skan if (__builtin_expect(has_facet<__num_get_type>(__loc), true)) 184132720Skan _M_num_get = &use_facet<__num_get_type>(__loc); 18597403Sobrien else 186132720Skan _M_num_get = 0; 18797403Sobrien } 18897403Sobrien 18997403Sobrien // Inhibit implicit instantiations for required instantiations, 190132720Skan // which are defined via explicit instantiations elsewhere. 19197403Sobrien // NB: This syntax is a GNU extension. 192132720Skan#if _GLIBCXX_EXTERN_TEMPLATE 19397403Sobrien extern template class basic_ios<char>; 194107606Sobrien 195132720Skan#ifdef _GLIBCXX_USE_WCHAR_T 19697403Sobrien extern template class basic_ios<wchar_t>; 197107606Sobrien#endif 198117397Skan#endif 19997403Sobrien 200169691Skan_GLIBCXX_END_NAMESPACE 201169691Skan 202132720Skan#endif 203