You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

408 lines
12KB

  1. // ostream classes -*- C++ -*-
  2. // Copyright (C) 1997-2020 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
  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. __try
  178. { _M_write(__s, __n); }
  179. __catch(__cxxabiv1::__forced_unwind&)
  180. {
  181. this->_M_setstate(ios_base::badbit);
  182. __throw_exception_again;
  183. }
  184. __catch(...)
  185. { this->_M_setstate(ios_base::badbit); }
  186. }
  187. return *this;
  188. }
  189. template<typename _CharT, typename _Traits>
  190. basic_ostream<_CharT, _Traits>&
  191. basic_ostream<_CharT, _Traits>::
  192. flush()
  193. {
  194. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  195. // DR 60. What is a formatted input function?
  196. // basic_ostream::flush() is *not* an unformatted output function.
  197. ios_base::iostate __err = ios_base::goodbit;
  198. __try
  199. {
  200. if (this->rdbuf() && this->rdbuf()->pubsync() == -1)
  201. __err |= ios_base::badbit;
  202. }
  203. __catch(__cxxabiv1::__forced_unwind&)
  204. {
  205. this->_M_setstate(ios_base::badbit);
  206. __throw_exception_again;
  207. }
  208. __catch(...)
  209. { this->_M_setstate(ios_base::badbit); }
  210. if (__err)
  211. this->setstate(__err);
  212. return *this;
  213. }
  214. template<typename _CharT, typename _Traits>
  215. typename basic_ostream<_CharT, _Traits>::pos_type
  216. basic_ostream<_CharT, _Traits>::
  217. tellp()
  218. {
  219. pos_type __ret = pos_type(-1);
  220. __try
  221. {
  222. if (!this->fail())
  223. __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out);
  224. }
  225. __catch(__cxxabiv1::__forced_unwind&)
  226. {
  227. this->_M_setstate(ios_base::badbit);
  228. __throw_exception_again;
  229. }
  230. __catch(...)
  231. { this->_M_setstate(ios_base::badbit); }
  232. return __ret;
  233. }
  234. template<typename _CharT, typename _Traits>
  235. basic_ostream<_CharT, _Traits>&
  236. basic_ostream<_CharT, _Traits>::
  237. seekp(pos_type __pos)
  238. {
  239. ios_base::iostate __err = ios_base::goodbit;
  240. __try
  241. {
  242. if (!this->fail())
  243. {
  244. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  245. // 136. seekp, seekg setting wrong streams?
  246. const pos_type __p = this->rdbuf()->pubseekpos(__pos,
  247. ios_base::out);
  248. // 129. Need error indication from seekp() and seekg()
  249. if (__p == pos_type(off_type(-1)))
  250. __err |= ios_base::failbit;
  251. }
  252. }
  253. __catch(__cxxabiv1::__forced_unwind&)
  254. {
  255. this->_M_setstate(ios_base::badbit);
  256. __throw_exception_again;
  257. }
  258. __catch(...)
  259. { this->_M_setstate(ios_base::badbit); }
  260. if (__err)
  261. this->setstate(__err);
  262. return *this;
  263. }
  264. template<typename _CharT, typename _Traits>
  265. basic_ostream<_CharT, _Traits>&
  266. basic_ostream<_CharT, _Traits>::
  267. seekp(off_type __off, ios_base::seekdir __dir)
  268. {
  269. ios_base::iostate __err = ios_base::goodbit;
  270. __try
  271. {
  272. if (!this->fail())
  273. {
  274. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  275. // 136. seekp, seekg setting wrong streams?
  276. const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir,
  277. ios_base::out);
  278. // 129. Need error indication from seekp() and seekg()
  279. if (__p == pos_type(off_type(-1)))
  280. __err |= ios_base::failbit;
  281. }
  282. }
  283. __catch(__cxxabiv1::__forced_unwind&)
  284. {
  285. this->_M_setstate(ios_base::badbit);
  286. __throw_exception_again;
  287. }
  288. __catch(...)
  289. { this->_M_setstate(ios_base::badbit); }
  290. if (__err)
  291. this->setstate(__err);
  292. return *this;
  293. }
  294. template<typename _CharT, typename _Traits>
  295. basic_ostream<_CharT, _Traits>&
  296. operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s)
  297. {
  298. if (!__s)
  299. __out.setstate(ios_base::badbit);
  300. else
  301. {
  302. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  303. // 167. Improper use of traits_type::length()
  304. const size_t __clen = char_traits<char>::length(__s);
  305. __try
  306. {
  307. struct __ptr_guard
  308. {
  309. _CharT *__p;
  310. __ptr_guard (_CharT *__ip): __p(__ip) { }
  311. ~__ptr_guard() { delete[] __p; }
  312. _CharT* __get() { return __p; }
  313. } __pg (new _CharT[__clen]);
  314. _CharT *__ws = __pg.__get();
  315. for (size_t __i = 0; __i < __clen; ++__i)
  316. __ws[__i] = __out.widen(__s[__i]);
  317. __ostream_insert(__out, __ws, __clen);
  318. }
  319. __catch(__cxxabiv1::__forced_unwind&)
  320. {
  321. __out._M_setstate(ios_base::badbit);
  322. __throw_exception_again;
  323. }
  324. __catch(...)
  325. { __out._M_setstate(ios_base::badbit); }
  326. }
  327. return __out;
  328. }
  329. // Inhibit implicit instantiations for required instantiations,
  330. // which are defined via explicit instantiations elsewhere.
  331. #if _GLIBCXX_EXTERN_TEMPLATE
  332. extern template class basic_ostream<char>;
  333. extern template ostream& endl(ostream&);
  334. extern template ostream& ends(ostream&);
  335. extern template ostream& flush(ostream&);
  336. extern template ostream& operator<<(ostream&, char);
  337. extern template ostream& operator<<(ostream&, unsigned char);
  338. extern template ostream& operator<<(ostream&, signed char);
  339. extern template ostream& operator<<(ostream&, const char*);
  340. extern template ostream& operator<<(ostream&, const unsigned char*);
  341. extern template ostream& operator<<(ostream&, const signed char*);
  342. extern template ostream& ostream::_M_insert(long);
  343. extern template ostream& ostream::_M_insert(unsigned long);
  344. extern template ostream& ostream::_M_insert(bool);
  345. #ifdef _GLIBCXX_USE_LONG_LONG
  346. extern template ostream& ostream::_M_insert(long long);
  347. extern template ostream& ostream::_M_insert(unsigned long long);
  348. #endif
  349. extern template ostream& ostream::_M_insert(double);
  350. extern template ostream& ostream::_M_insert(long double);
  351. extern template ostream& ostream::_M_insert(const void*);
  352. #ifdef _GLIBCXX_USE_WCHAR_T
  353. extern template class basic_ostream<wchar_t>;
  354. extern template wostream& endl(wostream&);
  355. extern template wostream& ends(wostream&);
  356. extern template wostream& flush(wostream&);
  357. extern template wostream& operator<<(wostream&, wchar_t);
  358. extern template wostream& operator<<(wostream&, char);
  359. extern template wostream& operator<<(wostream&, const wchar_t*);
  360. extern template wostream& operator<<(wostream&, const char*);
  361. extern template wostream& wostream::_M_insert(long);
  362. extern template wostream& wostream::_M_insert(unsigned long);
  363. extern template wostream& wostream::_M_insert(bool);
  364. #ifdef _GLIBCXX_USE_LONG_LONG
  365. extern template wostream& wostream::_M_insert(long long);
  366. extern template wostream& wostream::_M_insert(unsigned long long);
  367. #endif
  368. extern template wostream& wostream::_M_insert(double);
  369. extern template wostream& wostream::_M_insert(long double);
  370. extern template wostream& wostream::_M_insert(const void*);
  371. #endif
  372. #endif
  373. _GLIBCXX_END_NAMESPACE_VERSION
  374. } // namespace std
  375. #endif