1 // Iostreams base classes -*- C++ -*- 2 3 // Copyright (C) 1997-2016 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 // 26 // ISO C++ 14882: 27.4 Iostreams base classes 27 // 28 29 // Determines the version of ios_base::failure thrown by __throw_ios_failure. 30 // If !_GLIBCXX_USE_DUAL_ABI this will get undefined automatically. 31 #define _GLIBCXX_USE_CXX11_ABI 0 32 33 #include <ios> 34 #include <limits> 35 #include <bits/functexcept.h> 36 37 #ifdef _GLIBCXX_USE_NLS 38 # include <libintl.h> 39 # define _(msgid) gettext (msgid) 40 #else 41 # define _(msgid) (msgid) 42 #endif 43 44 namespace std _GLIBCXX_VISIBILITY(default) 45 { 46 _GLIBCXX_BEGIN_NAMESPACE_VERSION 47 48 void __throw_ios_failure(const char * __s)49 __throw_ios_failure(const char* __s __attribute__((unused))) 50 { _GLIBCXX_THROW_OR_ABORT(ios_base::failure(_(__s))); } 51 52 // Definitions for static const members of ios_base. 53 const ios_base::fmtflags ios_base::boolalpha; 54 const ios_base::fmtflags ios_base::dec; 55 const ios_base::fmtflags ios_base::fixed; 56 const ios_base::fmtflags ios_base::hex; 57 const ios_base::fmtflags ios_base::internal; 58 const ios_base::fmtflags ios_base::left; 59 const ios_base::fmtflags ios_base::oct; 60 const ios_base::fmtflags ios_base::right; 61 const ios_base::fmtflags ios_base::scientific; 62 const ios_base::fmtflags ios_base::showbase; 63 const ios_base::fmtflags ios_base::showpoint; 64 const ios_base::fmtflags ios_base::showpos; 65 const ios_base::fmtflags ios_base::skipws; 66 const ios_base::fmtflags ios_base::unitbuf; 67 const ios_base::fmtflags ios_base::uppercase; 68 const ios_base::fmtflags ios_base::adjustfield; 69 const ios_base::fmtflags ios_base::basefield; 70 const ios_base::fmtflags ios_base::floatfield; 71 72 const ios_base::iostate ios_base::badbit; 73 const ios_base::iostate ios_base::eofbit; 74 const ios_base::iostate ios_base::failbit; 75 const ios_base::iostate ios_base::goodbit; 76 77 const ios_base::openmode ios_base::app; 78 const ios_base::openmode ios_base::ate; 79 const ios_base::openmode ios_base::binary; 80 const ios_base::openmode ios_base::in; 81 const ios_base::openmode ios_base::out; 82 const ios_base::openmode ios_base::trunc; 83 84 const ios_base::seekdir ios_base::beg; 85 const ios_base::seekdir ios_base::cur; 86 const ios_base::seekdir ios_base::end; 87 88 _Atomic_word ios_base::Init::_S_refcount; 89 90 bool ios_base::Init::_S_synced_with_stdio = true; 91 ios_base()92 ios_base::ios_base() throw() 93 : _M_precision(), _M_width(), _M_flags(), _M_exception(), 94 _M_streambuf_state(), _M_callbacks(0), _M_word_zero(), 95 _M_word_size(_S_local_word_size), _M_word(_M_local_word), _M_ios_locale() 96 { 97 // Do nothing: basic_ios::init() does it. 98 // NB: _M_callbacks and _M_word must be zero for non-initialized 99 // ios_base to go through ~ios_base gracefully. 100 } 101 102 // 27.4.2.7 ios_base constructors/destructors ~ios_base()103 ios_base::~ios_base() 104 { 105 _M_call_callbacks(erase_event); 106 _M_dispose_callbacks(); 107 if (_M_word != _M_local_word) 108 { 109 delete [] _M_word; 110 _M_word = 0; 111 } 112 } 113 114 // 27.4.2.5 ios_base storage functions 115 int xalloc()116 ios_base::xalloc() throw() 117 { 118 // Implementation note: Initialize top to zero to ensure that 119 // initialization occurs before main() is started. 120 static _Atomic_word _S_top = 0; 121 return __gnu_cxx::__exchange_and_add_dispatch(&_S_top, 1) + 4; 122 } 123 124 void register_callback(event_callback __fn,int __index)125 ios_base::register_callback(event_callback __fn, int __index) 126 { _M_callbacks = new _Callback_list(__fn, __index, _M_callbacks); } 127 128 // 27.4.2.5 iword/pword storage 129 ios_base::_Words& _M_grow_words(int __ix,bool __iword)130 ios_base::_M_grow_words(int __ix, bool __iword) 131 { 132 // Precondition: _M_word_size <= __ix 133 int __newsize = _S_local_word_size; 134 _Words* __words = _M_local_word; 135 if (__ix > _S_local_word_size - 1) 136 { 137 if (__ix < numeric_limits<int>::max()) 138 { 139 __newsize = __ix + 1; 140 /* We still need to catch bad_alloc even though we use 141 a nothrow new, because the new-expression can throw 142 a bad_array_new_length. */ 143 __try 144 { __words = new (std::nothrow) _Words[__newsize]; } 145 __catch(const std::bad_alloc&) 146 { __words = nullptr; } 147 if (!__words) 148 { 149 _M_streambuf_state |= badbit; 150 if (_M_streambuf_state & _M_exception) 151 __throw_ios_failure(__N("ios_base::_M_grow_words " 152 "allocation failed")); 153 if (__iword) 154 _M_word_zero._M_iword = 0; 155 else 156 _M_word_zero._M_pword = 0; 157 return _M_word_zero; 158 } 159 for (int __i = 0; __i < _M_word_size; __i++) 160 __words[__i] = _M_word[__i]; 161 if (_M_word && _M_word != _M_local_word) 162 { 163 delete [] _M_word; 164 _M_word = 0; 165 } 166 } 167 else 168 { 169 _M_streambuf_state |= badbit; 170 if (_M_streambuf_state & _M_exception) 171 __throw_ios_failure(__N("ios_base::_M_grow_words is not valid")); 172 if (__iword) 173 _M_word_zero._M_iword = 0; 174 else 175 _M_word_zero._M_pword = 0; 176 return _M_word_zero; 177 } 178 } 179 _M_word = __words; 180 _M_word_size = __newsize; 181 return _M_word[__ix]; 182 } 183 184 void _M_call_callbacks(event __e)185 ios_base::_M_call_callbacks(event __e) throw() 186 { 187 _Callback_list* __p = _M_callbacks; 188 while (__p) 189 { 190 __try 191 { (*__p->_M_fn) (__e, *this, __p->_M_index); } 192 __catch(...) 193 { } 194 __p = __p->_M_next; 195 } 196 } 197 198 void _M_dispose_callbacks(void)199 ios_base::_M_dispose_callbacks(void) throw() 200 { 201 _Callback_list* __p = _M_callbacks; 202 while (__p && __p->_M_remove_reference() == 0) 203 { 204 _Callback_list* __next = __p->_M_next; 205 delete __p; 206 __p = __next; 207 } 208 _M_callbacks = 0; 209 } 210 211 void _M_move(ios_base & __rhs)212 ios_base::_M_move(ios_base& __rhs) noexcept 213 { 214 _M_precision = __rhs._M_precision; 215 _M_width = __rhs._M_width; 216 _M_flags = __rhs._M_flags; 217 _M_exception = __rhs._M_exception; 218 _M_streambuf_state = __rhs._M_streambuf_state; 219 _M_callbacks = std::__exchange(__rhs._M_callbacks, nullptr); 220 if (_M_word != _M_local_word) 221 delete[] _M_word; 222 if (__rhs._M_word == __rhs._M_local_word) 223 { 224 _M_word = _M_local_word; 225 _M_word_size = _S_local_word_size; 226 for (int __i = 0; __i < _S_local_word_size; __i++) 227 _M_word[__i] = std::__exchange(__rhs._M_word[__i], {}); 228 } 229 else 230 { 231 _M_word = std::__exchange(__rhs._M_word, __rhs._M_local_word); 232 _M_word_size 233 = std::__exchange(__rhs._M_word_size, _S_local_word_size); 234 } 235 _M_ios_locale = __rhs._M_ios_locale; 236 } 237 238 void _M_swap(ios_base & __rhs)239 ios_base::_M_swap(ios_base& __rhs) noexcept 240 { 241 std::swap(_M_precision, __rhs._M_precision); 242 std::swap(_M_width, __rhs._M_width); 243 std::swap(_M_flags, __rhs._M_flags); 244 std::swap(_M_exception, __rhs._M_exception); 245 std::swap(_M_streambuf_state, __rhs._M_streambuf_state); 246 std::swap(_M_callbacks, __rhs._M_callbacks); 247 const bool __lhs_local = _M_word == _M_local_word; 248 const bool __rhs_local = __rhs._M_word == __rhs._M_local_word; 249 if (__lhs_local && __rhs_local) 250 std::swap(_M_local_word, __rhs._M_local_word); // array swap 251 else 252 { 253 if (!__lhs_local && !__rhs_local) 254 std::swap(_M_word, __rhs._M_word); 255 else 256 { 257 ios_base* __local; 258 ios_base* __allocated; 259 if (__lhs_local) 260 { 261 __local = this; 262 __allocated = &__rhs; 263 } 264 else 265 { 266 __local = &__rhs; 267 __allocated= this; 268 } 269 for (int __i = 0; __i < _S_local_word_size; __i++) 270 __allocated->_M_local_word[__i] = __local->_M_local_word[__i]; 271 __local->_M_word = __allocated->_M_word; 272 __allocated->_M_word = __allocated->_M_local_word; 273 } 274 std::swap(_M_word_size, __rhs._M_word_size); 275 } 276 std::swap(_M_ios_locale, __rhs._M_ios_locale); 277 } 278 279 _GLIBCXX_END_NAMESPACE_VERSION 280 } // namespace 281