ostream.tcc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. // ostream classes -*- C++ -*-
  2. // Copyright (C) 1997-2022 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file bits/ostream.tcc
  21. * This is an internal header file, included by other library headers.
  22. * Do not attempt to use it directly. @headername{ostream}
  23. */
  24. //
  25. // ISO C++ 14882: 27.6.2 Output streams
  26. //
  27. #ifndef _OSTREAM_TCC
  28. #define _OSTREAM_TCC 1
  29. #pragma GCC system_header
  30. #include <bits/cxxabi_forced.h>
  31. namespace std _GLIBCXX_VISIBILITY(default)
  32. {
  33. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  34. template<typename _CharT, typename _Traits>
  35. basic_ostream<_CharT, _Traits>::sentry::
  36. sentry(basic_ostream<_CharT, _Traits>& __os)
  37. : _M_ok(false), _M_os(__os)
  38. {
  39. // XXX MT
  40. if (__os.tie() && __os.good())
  41. __os.tie()->flush();
  42. if (__os.good())
  43. _M_ok = true;
  44. else if (__os.bad())
  45. __os.setstate(ios_base::failbit);
  46. }
  47. template<typename _CharT, typename _Traits>
  48. template<typename _ValueT>
  49. basic_ostream<_CharT, _Traits>&
  50. basic_ostream<_CharT, _Traits>::
  51. _M_insert(_ValueT __v)
  52. {
  53. sentry __cerb(*this);
  54. if (__cerb)
  55. {
  56. ios_base::iostate __err = ios_base::goodbit;
  57. __try
  58. {
  59. const __num_put_type& __np = __check_facet(this->_M_num_put);
  60. if (__np.put(*this, *this, this->fill(), __v).failed())
  61. __err |= ios_base::badbit;
  62. }
  63. __catch(__cxxabiv1::__forced_unwind&)
  64. {
  65. this->_M_setstate(ios_base::badbit);
  66. __throw_exception_again;
  67. }
  68. __catch(...)
  69. { this->_M_setstate(ios_base::badbit); }
  70. if (__err)
  71. this->setstate(__err);
  72. }
  73. return *this;
  74. }
  75. template<typename _CharT, typename _Traits>
  76. basic_ostream<_CharT, _Traits>&
  77. basic_ostream<_CharT, _Traits>::
  78. operator<<(short __n)
  79. {
  80. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  81. // 117. basic_ostream uses nonexistent num_put member functions.
  82. const ios_base::fmtflags __fmt = this->flags() & ios_base::basefield;
  83. if (__fmt == ios_base::oct || __fmt == ios_base::hex)
  84. return _M_insert(static_cast<long>(static_cast<unsigned short>(__n)));
  85. else
  86. return _M_insert(static_cast<long>(__n));
  87. }
  88. template<typename _CharT, typename _Traits>
  89. basic_ostream<_CharT, _Traits>&
  90. basic_ostream<_CharT, _Traits>::
  91. operator<<(int __n)
  92. {
  93. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  94. // 117. basic_ostream uses nonexistent num_put member functions.
  95. const ios_base::fmtflags __fmt = this->flags() & ios_base::basefield;
  96. if (__fmt == ios_base::oct || __fmt == ios_base::hex)
  97. return _M_insert(static_cast<long>(static_cast<unsigned int>(__n)));
  98. else
  99. return _M_insert(static_cast<long>(__n));
  100. }
  101. template<typename _CharT, typename _Traits>
  102. basic_ostream<_CharT, _Traits>&
  103. basic_ostream<_CharT, _Traits>::
  104. operator<<(__streambuf_type* __sbin)
  105. {
  106. ios_base::iostate __err = ios_base::goodbit;
  107. sentry __cerb(*this);
  108. if (__cerb && __sbin)
  109. {
  110. __try
  111. {
  112. if (!__copy_streambufs(__sbin, this->rdbuf()))
  113. __err |= ios_base::failbit;
  114. }
  115. __catch(__cxxabiv1::__forced_unwind&)
  116. {
  117. this->_M_setstate(ios_base::badbit);
  118. __throw_exception_again;
  119. }
  120. __catch(...)
  121. { this->_M_setstate(ios_base::failbit); }
  122. }
  123. else if (!__sbin)
  124. __err |= ios_base::badbit;
  125. if (__err)
  126. this->setstate(__err);
  127. return *this;
  128. }
  129. template<typename _CharT, typename _Traits>
  130. basic_ostream<_CharT, _Traits>&
  131. basic_ostream<_CharT, _Traits>::
  132. put(char_type __c)
  133. {
  134. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  135. // DR 60. What is a formatted input function?
  136. // basic_ostream::put(char_type) is an unformatted output function.
  137. // DR 63. Exception-handling policy for unformatted output.
  138. // Unformatted output functions should catch exceptions thrown
  139. // from streambuf members.
  140. sentry __cerb(*this);
  141. if (__cerb)
  142. {
  143. ios_base::iostate __err = ios_base::goodbit;
  144. __try
  145. {
  146. const int_type __put = this->rdbuf()->sputc(__c);
  147. if (traits_type::eq_int_type(__put, traits_type::eof()))
  148. __err |= ios_base::badbit;
  149. }
  150. __catch(__cxxabiv1::__forced_unwind&)
  151. {
  152. this->_M_setstate(ios_base::badbit);
  153. __throw_exception_again;
  154. }
  155. __catch(...)
  156. { this->_M_setstate(ios_base::badbit); }
  157. if (__err)
  158. this->setstate(__err);
  159. }
  160. return *this;
  161. }
  162. template<typename _CharT, typename _Traits>
  163. basic_ostream<_CharT, _Traits>&
  164. basic_ostream<_CharT, _Traits>::
  165. write(const _CharT* __s, streamsize __n)
  166. {
  167. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  168. // DR 60. What is a formatted input function?
  169. // basic_ostream::write(const char_type*, streamsize) is an
  170. // unformatted output function.
  171. // DR 63. Exception-handling policy for unformatted output.
  172. // Unformatted output functions should catch exceptions thrown
  173. // from streambuf members.
  174. sentry __cerb(*this);
  175. if (__cerb)
  176. {
  177. ios_base::iostate __err = ios_base::goodbit;
  178. __try
  179. {
  180. if (this->rdbuf()->sputn(__s, __n) != __n)
  181. __err = ios_base::badbit;
  182. }
  183. __catch(__cxxabiv1::__forced_unwind&)
  184. {
  185. this->_M_setstate(ios_base::badbit);
  186. __throw_exception_again;
  187. }
  188. __catch(...)
  189. { this->_M_setstate(ios_base::badbit); }
  190. if (__err)
  191. this->setstate(ios_base::badbit);
  192. }
  193. return *this;
  194. }
  195. template<typename _CharT, typename _Traits>
  196. basic_ostream<_CharT, _Traits>&
  197. basic_ostream<_CharT, _Traits>::
  198. flush()
  199. {
  200. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  201. // DR 60. What is a formatted input function?
  202. // basic_ostream::flush() is *not* an unformatted output function.
  203. // 581. flush() not unformatted function
  204. // basic_ostream::flush() *is* an unformatted output function.
  205. if (__streambuf_type* __buf = this->rdbuf())
  206. {
  207. sentry __cerb(*this);
  208. if (__cerb)
  209. {
  210. ios_base::iostate __err = ios_base::goodbit;
  211. __try
  212. {
  213. if (this->rdbuf()->pubsync() == -1)
  214. __err |= ios_base::badbit;
  215. }
  216. __catch(__cxxabiv1::__forced_unwind&)
  217. {
  218. this->_M_setstate(ios_base::badbit);
  219. __throw_exception_again;
  220. }
  221. __catch(...)
  222. { this->_M_setstate(ios_base::badbit); }
  223. if (__err)
  224. this->setstate(__err);
  225. }
  226. }
  227. return *this;
  228. }
  229. template<typename _CharT, typename _Traits>
  230. typename basic_ostream<_CharT, _Traits>::pos_type
  231. basic_ostream<_CharT, _Traits>::
  232. tellp()
  233. {
  234. sentry __cerb(*this);
  235. pos_type __ret = pos_type(-1);
  236. if (!this->fail())
  237. __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out);
  238. return __ret;
  239. }
  240. template<typename _CharT, typename _Traits>
  241. basic_ostream<_CharT, _Traits>&
  242. basic_ostream<_CharT, _Traits>::
  243. seekp(pos_type __pos)
  244. {
  245. sentry __cerb(*this);
  246. if (!this->fail())
  247. {
  248. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  249. // 136. seekp, seekg setting wrong streams?
  250. const pos_type __p = this->rdbuf()->pubseekpos(__pos, ios_base::out);
  251. // 129. Need error indication from seekp() and seekg()
  252. if (__p == pos_type(off_type(-1)))
  253. this->setstate(ios_base::failbit);
  254. }
  255. return *this;
  256. }
  257. template<typename _CharT, typename _Traits>
  258. basic_ostream<_CharT, _Traits>&
  259. basic_ostream<_CharT, _Traits>::
  260. seekp(off_type __off, ios_base::seekdir __dir)
  261. {
  262. sentry __cerb(*this);
  263. if (!this->fail())
  264. {
  265. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  266. // 136. seekp, seekg setting wrong streams?
  267. const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir,
  268. ios_base::out);
  269. // 129. Need error indication from seekp() and seekg()
  270. if (__p == pos_type(off_type(-1)))
  271. this->setstate(ios_base::failbit);
  272. }
  273. return *this;
  274. }
  275. template<typename _CharT, typename _Traits>
  276. basic_ostream<_CharT, _Traits>&
  277. operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s)
  278. {
  279. if (!__s)
  280. __out.setstate(ios_base::badbit);
  281. else
  282. {
  283. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  284. // 167. Improper use of traits_type::length()
  285. const size_t __clen = char_traits<char>::length(__s);
  286. __try
  287. {
  288. struct __ptr_guard
  289. {
  290. _CharT *__p;
  291. __ptr_guard (_CharT *__ip): __p(__ip) { }
  292. ~__ptr_guard() { delete[] __p; }
  293. _CharT* __get() { return __p; }
  294. } __pg (new _CharT[__clen]);
  295. _CharT *__ws = __pg.__get();
  296. for (size_t __i = 0; __i < __clen; ++__i)
  297. __ws[__i] = __out.widen(__s[__i]);
  298. __ostream_insert(__out, __ws, __clen);
  299. }
  300. __catch(__cxxabiv1::__forced_unwind&)
  301. {
  302. __out._M_setstate(ios_base::badbit);
  303. __throw_exception_again;
  304. }
  305. __catch(...)
  306. { __out._M_setstate(ios_base::badbit); }
  307. }
  308. return __out;
  309. }
  310. // Inhibit implicit instantiations for required instantiations,
  311. // which are defined via explicit instantiations elsewhere.
  312. #if _GLIBCXX_EXTERN_TEMPLATE
  313. extern template class basic_ostream<char>;
  314. extern template ostream& endl(ostream&);
  315. extern template ostream& ends(ostream&);
  316. extern template ostream& flush(ostream&);
  317. extern template ostream& operator<<(ostream&, char);
  318. extern template ostream& operator<<(ostream&, unsigned char);
  319. extern template ostream& operator<<(ostream&, signed char);
  320. extern template ostream& operator<<(ostream&, const char*);
  321. extern template ostream& operator<<(ostream&, const unsigned char*);
  322. extern template ostream& operator<<(ostream&, const signed char*);
  323. extern template ostream& ostream::_M_insert(long);
  324. extern template ostream& ostream::_M_insert(unsigned long);
  325. extern template ostream& ostream::_M_insert(bool);
  326. #ifdef _GLIBCXX_USE_LONG_LONG
  327. extern template ostream& ostream::_M_insert(long long);
  328. extern template ostream& ostream::_M_insert(unsigned long long);
  329. #endif
  330. extern template ostream& ostream::_M_insert(double);
  331. extern template ostream& ostream::_M_insert(long double);
  332. extern template ostream& ostream::_M_insert(const void*);
  333. #ifdef _GLIBCXX_USE_WCHAR_T
  334. extern template class basic_ostream<wchar_t>;
  335. extern template wostream& endl(wostream&);
  336. extern template wostream& ends(wostream&);
  337. extern template wostream& flush(wostream&);
  338. extern template wostream& operator<<(wostream&, wchar_t);
  339. extern template wostream& operator<<(wostream&, char);
  340. extern template wostream& operator<<(wostream&, const wchar_t*);
  341. extern template wostream& operator<<(wostream&, const char*);
  342. extern template wostream& wostream::_M_insert(long);
  343. extern template wostream& wostream::_M_insert(unsigned long);
  344. extern template wostream& wostream::_M_insert(bool);
  345. #ifdef _GLIBCXX_USE_LONG_LONG
  346. extern template wostream& wostream::_M_insert(long long);
  347. extern template wostream& wostream::_M_insert(unsigned long long);
  348. #endif
  349. extern template wostream& wostream::_M_insert(double);
  350. extern template wostream& wostream::_M_insert(long double);
  351. extern template wostream& wostream::_M_insert(const void*);
  352. #endif
  353. #endif
  354. _GLIBCXX_END_NAMESPACE_VERSION
  355. } // namespace std
  356. #endif