formatting_ostream.hpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720
  1. /*
  2. * Copyright Andrey Semashev 2007 - 2013.
  3. * Distributed under the Boost Software License, Version 1.0.
  4. * (See accompanying file LICENSE_1_0.txt or copy at
  5. * http://www.boost.org/LICENSE_1_0.txt)
  6. */
  7. /*!
  8. * \file formatting_ostream.hpp
  9. * \author Andrey Semashev
  10. * \date 11.07.2012
  11. *
  12. * The header contains implementation of a string stream used for log record formatting.
  13. */
  14. #ifndef BOOST_LOG_UTILITY_FORMATTING_OSTREAM_HPP_INCLUDED_
  15. #define BOOST_LOG_UTILITY_FORMATTING_OSTREAM_HPP_INCLUDED_
  16. #include <ostream>
  17. #include <string>
  18. #include <memory>
  19. #include <locale>
  20. #include <boost/utility/string_ref_fwd.hpp>
  21. #include <boost/type_traits/remove_cv.hpp>
  22. #include <boost/log/detail/config.hpp>
  23. #include <boost/log/detail/attachable_sstream_buf.hpp>
  24. #include <boost/log/detail/code_conversion.hpp>
  25. #include <boost/log/utility/string_literal_fwd.hpp>
  26. #include <boost/log/utility/formatting_ostream_fwd.hpp>
  27. #include <boost/utility/explicit_operator_bool.hpp>
  28. #include <boost/log/detail/header.hpp>
  29. #ifdef BOOST_HAS_PRAGMA_ONCE
  30. #pragma once
  31. #endif
  32. namespace boost {
  33. BOOST_LOG_OPEN_NAMESPACE
  34. namespace aux {
  35. template< typename T, typename R >
  36. struct enable_if_char_type {};
  37. template< typename R >
  38. struct enable_if_char_type< char, R > { typedef R type; };
  39. template< typename R >
  40. struct enable_if_char_type< wchar_t, R > { typedef R type; };
  41. #if !defined(BOOST_NO_CXX11_CHAR16_T)
  42. template< typename R >
  43. struct enable_if_char_type< char16_t, R > { typedef R type; };
  44. #endif
  45. #if !defined(BOOST_NO_CXX11_CHAR32_T)
  46. template< typename R >
  47. struct enable_if_char_type< char32_t, R > { typedef R type; };
  48. #endif
  49. } // namespace aux
  50. /*!
  51. * \brief Stream wrapper for log records formatting.
  52. *
  53. * This stream wrapper is used by the library for log record formatting. It implements the standard string stream interface
  54. * with a few differences:
  55. *
  56. * \li It does not derive from standard types <tt>std::basic_ostream</tt>, <tt>std::basic_ios</tt> and <tt>std::ios_base</tt>,
  57. * although it tries to implement their interfaces closely. There are a few small differences, mostly regarding <tt>rdbuf</tt>
  58. * and <tt>str</tt> signatures, as well as the supported insertion operator overloads. The actual wrapped stream can be accessed
  59. * through the <tt>stream</tt> methods.
  60. * \li By default, \c bool values are formatted using alphabetical representation rather than numeric.
  61. * \li The stream supports writing strings of character types different from the stream character type. The stream will perform
  62. * character code conversion as needed using the imbued locale.
  63. * \li The stream operates on an external string object rather than on the embedded one. The string can be attached or detached
  64. * from the stream dynamically.
  65. *
  66. * Although <tt>basic_formatting_ostream</tt> does not derive from <tt>std::basic_ostream</tt>, users are not required to add
  67. * special overloads of \c operator<< for it since the stream will by default reuse the operators for <tt>std::basic_ostream</tt>.
  68. * However, one can define special overloads of \c operator<< for <tt>basic_formatting_ostream</tt> if a certain type needs
  69. * special formatting when output to log.
  70. */
  71. template< typename CharT, typename TraitsT, typename AllocatorT >
  72. class basic_formatting_ostream
  73. {
  74. public:
  75. //! Character type
  76. typedef CharT char_type;
  77. //! Character traits
  78. typedef TraitsT traits_type;
  79. //! Memory allocator
  80. typedef AllocatorT allocator_type;
  81. //! Stream buffer type
  82. typedef boost::log::aux::basic_ostringstreambuf< char_type, traits_type, allocator_type > streambuf_type;
  83. //! Target string type
  84. typedef typename streambuf_type::string_type string_type;
  85. //! Stream type
  86. typedef std::basic_ostream< char_type, traits_type > ostream_type;
  87. //! Stream position type
  88. typedef typename ostream_type::pos_type pos_type;
  89. //! Stream offset type
  90. typedef typename ostream_type::off_type off_type;
  91. //! Integer type for characters
  92. typedef typename ostream_type::int_type int_type;
  93. typedef typename ostream_type::failure failure;
  94. typedef typename ostream_type::fmtflags fmtflags;
  95. typedef typename ostream_type::iostate iostate;
  96. typedef typename ostream_type::openmode openmode;
  97. typedef typename ostream_type::seekdir seekdir;
  98. typedef typename ostream_type::Init Init;
  99. typedef typename ostream_type::event event;
  100. typedef typename ostream_type::event_callback event_callback;
  101. class sentry :
  102. public ostream_type::sentry
  103. {
  104. typedef typename ostream_type::sentry base_type;
  105. public:
  106. explicit sentry(basic_formatting_ostream& strm) : base_type(strm.stream())
  107. {
  108. }
  109. BOOST_DELETED_FUNCTION(sentry(sentry const&))
  110. BOOST_DELETED_FUNCTION(sentry& operator= (sentry const&))
  111. };
  112. private:
  113. // Function types
  114. typedef std::ios_base& (*ios_base_manip)(std::ios_base&);
  115. typedef std::basic_ios< char_type, traits_type >& (*basic_ios_manip)(std::basic_ios< char_type, traits_type >&);
  116. typedef ostream_type& (*stream_manip)(ostream_type&);
  117. public:
  118. static BOOST_CONSTEXPR_OR_CONST fmtflags boolalpha = ostream_type::boolalpha;
  119. static BOOST_CONSTEXPR_OR_CONST fmtflags dec = ostream_type::dec;
  120. static BOOST_CONSTEXPR_OR_CONST fmtflags fixed = ostream_type::fixed;
  121. static BOOST_CONSTEXPR_OR_CONST fmtflags hex = ostream_type::hex;
  122. static BOOST_CONSTEXPR_OR_CONST fmtflags internal = ostream_type::internal;
  123. static BOOST_CONSTEXPR_OR_CONST fmtflags left = ostream_type::left;
  124. static BOOST_CONSTEXPR_OR_CONST fmtflags oct = ostream_type::oct;
  125. static BOOST_CONSTEXPR_OR_CONST fmtflags right = ostream_type::right;
  126. static BOOST_CONSTEXPR_OR_CONST fmtflags scientific = ostream_type::scientific;
  127. static BOOST_CONSTEXPR_OR_CONST fmtflags showbase = ostream_type::showbase;
  128. static BOOST_CONSTEXPR_OR_CONST fmtflags showpoint = ostream_type::showpoint;
  129. static BOOST_CONSTEXPR_OR_CONST fmtflags skipws = ostream_type::skipws;
  130. static BOOST_CONSTEXPR_OR_CONST fmtflags unitbuf = ostream_type::unitbuf;
  131. static BOOST_CONSTEXPR_OR_CONST fmtflags uppercase = ostream_type::uppercase;
  132. static BOOST_CONSTEXPR_OR_CONST fmtflags adjustfield = ostream_type::adjustfield;
  133. static BOOST_CONSTEXPR_OR_CONST fmtflags basefield = ostream_type::basefield;
  134. static BOOST_CONSTEXPR_OR_CONST fmtflags floatfield = ostream_type::floatfield;
  135. static BOOST_CONSTEXPR_OR_CONST iostate badbit = ostream_type::badbit;
  136. static BOOST_CONSTEXPR_OR_CONST iostate eofbit = ostream_type::eofbit;
  137. static BOOST_CONSTEXPR_OR_CONST iostate failbit = ostream_type::failbit;
  138. static BOOST_CONSTEXPR_OR_CONST iostate goodbit = ostream_type::goodbit;
  139. static BOOST_CONSTEXPR_OR_CONST openmode app = ostream_type::app;
  140. static BOOST_CONSTEXPR_OR_CONST openmode ate = ostream_type::ate;
  141. static BOOST_CONSTEXPR_OR_CONST openmode binary = ostream_type::binary;
  142. static BOOST_CONSTEXPR_OR_CONST openmode in = ostream_type::in;
  143. static BOOST_CONSTEXPR_OR_CONST openmode out = ostream_type::out;
  144. static BOOST_CONSTEXPR_OR_CONST openmode trunc = ostream_type::trunc;
  145. static BOOST_CONSTEXPR_OR_CONST seekdir beg = ostream_type::beg;
  146. static BOOST_CONSTEXPR_OR_CONST seekdir cur = ostream_type::cur;
  147. static BOOST_CONSTEXPR_OR_CONST seekdir end = ostream_type::end;
  148. static BOOST_CONSTEXPR_OR_CONST event erase_event = ostream_type::erase_event;
  149. static BOOST_CONSTEXPR_OR_CONST event imbue_event = ostream_type::imbue_event;
  150. static BOOST_CONSTEXPR_OR_CONST event copyfmt_event = ostream_type::copyfmt_event;
  151. private:
  152. mutable streambuf_type m_streambuf;
  153. ostream_type m_stream;
  154. public:
  155. /*!
  156. * Default constructor. Creates an empty record that is equivalent to the invalid record handle.
  157. * The stream capability is not available after construction.
  158. *
  159. * \post <tt>!*this == true</tt>
  160. */
  161. basic_formatting_ostream() : m_stream(&m_streambuf)
  162. {
  163. init_stream();
  164. }
  165. /*!
  166. * Initializing constructor. Attaches the string to the constructed stream.
  167. * The string will be used to store the formatted characters.
  168. *
  169. * \post <tt>!*this == false</tt>
  170. * \param str The string buffer to attach.
  171. */
  172. explicit basic_formatting_ostream(string_type& str) :
  173. m_streambuf(str),
  174. m_stream(&m_streambuf)
  175. {
  176. init_stream();
  177. }
  178. /*!
  179. * Destructor. Destroys the record, releases any sinks and attribute values that were involved in processing this record.
  180. */
  181. ~basic_formatting_ostream()
  182. {
  183. if (m_streambuf.storage())
  184. flush();
  185. }
  186. /*!
  187. * Attaches the stream to the string. The string will be used to store the formatted characters.
  188. *
  189. * \param str The string buffer to attach.
  190. */
  191. void attach(string_type& str)
  192. {
  193. m_streambuf.attach(str);
  194. m_stream.clear(ostream_type::goodbit);
  195. }
  196. /*!
  197. * Detaches the stream from the string. Any buffered data is flushed to the string.
  198. */
  199. void detach()
  200. {
  201. m_streambuf.detach();
  202. m_stream.clear(ostream_type::badbit);
  203. }
  204. /*!
  205. * \returns Reference to the attached string. The string must be attached before calling this method.
  206. */
  207. string_type const& str() const
  208. {
  209. string_type* storage = m_streambuf.storage();
  210. BOOST_ASSERT(storage != NULL);
  211. m_streambuf.pubsync();
  212. return *storage;
  213. }
  214. /*!
  215. * \returns Reference to the wrapped stream
  216. */
  217. ostream_type& stream() { return m_stream; }
  218. /*!
  219. * \returns Reference to the wrapped stream
  220. */
  221. ostream_type const& stream() const { return m_stream; }
  222. // std::ios_base method forwarders
  223. fmtflags flags() const { return m_stream.flags(); }
  224. fmtflags flags(fmtflags f) { return m_stream.flags(f); }
  225. fmtflags setf(fmtflags f) { return m_stream.setf(f); }
  226. fmtflags setf(fmtflags f, fmtflags mask) { return m_stream.setf(f, mask); }
  227. void unsetf(fmtflags f) { m_stream.unsetf(f); }
  228. std::streamsize precision() const { return m_stream.precision(); }
  229. std::streamsize precision(std::streamsize p) { return m_stream.precision(p); }
  230. std::streamsize width() const { return m_stream.width(); }
  231. std::streamsize width(std::streamsize w) { return m_stream.width(w); }
  232. std::locale getloc() const { return m_stream.getloc(); }
  233. std::locale imbue(std::locale const& loc) { return m_stream.imbue(loc); }
  234. static int xalloc() { return ostream_type::xalloc(); }
  235. long& iword(int index) { return m_stream.iword(index); }
  236. void*& pword(int index) { return m_stream.pword(index); }
  237. void register_callback(event_callback fn, int index) { m_stream.register_callback(fn, index); }
  238. static bool sync_with_stdio(bool sync = true) { return ostream_type::sync_with_stdio(sync); }
  239. // std::basic_ios method forwarders
  240. BOOST_EXPLICIT_OPERATOR_BOOL()
  241. bool operator! () const { return !m_stream; }
  242. iostate rdstate() const { return m_stream.rdstate(); }
  243. void clear(iostate state = goodbit) { m_stream.clear(state); }
  244. void setstate(iostate state) { m_stream.setstate(state); }
  245. bool good() const { return m_stream.good(); }
  246. bool eof() const { return m_stream.eof(); }
  247. bool fail() const { return m_stream.fail(); }
  248. bool bad() const { return m_stream.bad(); }
  249. iostate exceptions() const { return m_stream.exceptions(); }
  250. void exceptions(iostate s) { m_stream.exceptions(s); }
  251. ostream_type* tie() const { return m_stream.tie(); }
  252. ostream_type* tie(ostream_type* strm) { return m_stream.tie(strm); }
  253. streambuf_type* rdbuf() const { return &m_streambuf; }
  254. basic_formatting_ostream& copyfmt(std::basic_ios< char_type, traits_type >& rhs)
  255. {
  256. m_stream.copyfmt(rhs);
  257. return *this;
  258. }
  259. basic_formatting_ostream& copyfmt(basic_formatting_ostream& rhs)
  260. {
  261. m_stream.copyfmt(rhs.stream());
  262. return *this;
  263. }
  264. char_type fill() const { return m_stream.fill(); }
  265. char_type fill(char_type ch) { return m_stream.fill(ch); }
  266. char narrow(char_type ch, char def) const { return m_stream.narrow(ch, def); }
  267. char_type widen(char ch) const { return m_stream.widen(ch); }
  268. // std::basic_ostream method forwarders
  269. basic_formatting_ostream& flush()
  270. {
  271. m_stream.flush();
  272. return *this;
  273. }
  274. pos_type tellp() { return m_stream.tellp(); }
  275. basic_formatting_ostream& seekp(pos_type pos)
  276. {
  277. m_stream.seekp(pos);
  278. return *this;
  279. }
  280. basic_formatting_ostream& seekp(off_type off, std::ios_base::seekdir dir)
  281. {
  282. m_stream.seekp(off, dir);
  283. return *this;
  284. }
  285. basic_formatting_ostream& put(char_type c)
  286. {
  287. m_stream.put(c);
  288. return *this;
  289. }
  290. template< typename OtherCharT >
  291. typename aux::enable_if_char_type< OtherCharT, basic_formatting_ostream& >::type
  292. put(OtherCharT c)
  293. {
  294. write(&c, 1);
  295. return *this;
  296. }
  297. basic_formatting_ostream& write(const char_type* p, std::streamsize size)
  298. {
  299. m_stream.write(p, size);
  300. return *this;
  301. }
  302. template< typename OtherCharT >
  303. typename aux::enable_if_char_type< OtherCharT, basic_formatting_ostream& >::type
  304. write(const OtherCharT* p, std::streamsize size)
  305. {
  306. sentry guard(*this);
  307. if (guard)
  308. {
  309. m_stream.flush();
  310. string_type* storage = m_streambuf.storage();
  311. aux::code_convert(p, static_cast< std::size_t >(size), *storage, m_stream.getloc());
  312. }
  313. return *this;
  314. }
  315. basic_formatting_ostream& operator<< (ios_base_manip manip)
  316. {
  317. m_stream << manip;
  318. return *this;
  319. }
  320. basic_formatting_ostream& operator<< (basic_ios_manip manip)
  321. {
  322. m_stream << manip;
  323. return *this;
  324. }
  325. basic_formatting_ostream& operator<< (stream_manip manip)
  326. {
  327. m_stream << manip;
  328. return *this;
  329. }
  330. basic_formatting_ostream& operator<< (char c)
  331. {
  332. return this->formatted_write(&c, 1);
  333. }
  334. basic_formatting_ostream& operator<< (const char* p)
  335. {
  336. return this->formatted_write(p, static_cast< std::streamsize >(std::char_traits< char >::length(p)));
  337. }
  338. #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
  339. basic_formatting_ostream& operator<< (wchar_t c)
  340. {
  341. return this->formatted_write(&c, 1);
  342. }
  343. basic_formatting_ostream& operator<< (const wchar_t* p)
  344. {
  345. return this->formatted_write(p, static_cast< std::streamsize >(std::char_traits< wchar_t >::length(p)));
  346. }
  347. #endif
  348. #if !defined(BOOST_NO_CXX11_CHAR16_T)
  349. basic_formatting_ostream& operator<< (char16_t c)
  350. {
  351. return this->formatted_write(&c, 1);
  352. }
  353. basic_formatting_ostream& operator<< (const char16_t* p)
  354. {
  355. return this->formatted_write(p, static_cast< std::streamsize >(std::char_traits< char16_t >::length(p)));
  356. }
  357. #endif
  358. #if !defined(BOOST_NO_CXX11_CHAR32_T)
  359. basic_formatting_ostream& operator<< (char32_t c)
  360. {
  361. return this->formatted_write(&c, 1);
  362. }
  363. basic_formatting_ostream& operator<< (const char32_t* p)
  364. {
  365. return this->formatted_write(p, static_cast< std::streamsize >(std::char_traits< char32_t >::length(p)));
  366. }
  367. #endif
  368. basic_formatting_ostream& operator<< (bool value)
  369. {
  370. m_stream << value;
  371. return *this;
  372. }
  373. basic_formatting_ostream& operator<< (signed char value)
  374. {
  375. m_stream << value;
  376. return *this;
  377. }
  378. basic_formatting_ostream& operator<< (unsigned char value)
  379. {
  380. m_stream << value;
  381. return *this;
  382. }
  383. basic_formatting_ostream& operator<< (short value)
  384. {
  385. m_stream << value;
  386. return *this;
  387. }
  388. basic_formatting_ostream& operator<< (unsigned short value)
  389. {
  390. m_stream << value;
  391. return *this;
  392. }
  393. basic_formatting_ostream& operator<< (int value)
  394. {
  395. m_stream << value;
  396. return *this;
  397. }
  398. basic_formatting_ostream& operator<< (unsigned int value)
  399. {
  400. m_stream << value;
  401. return *this;
  402. }
  403. basic_formatting_ostream& operator<< (long value)
  404. {
  405. m_stream << value;
  406. return *this;
  407. }
  408. basic_formatting_ostream& operator<< (unsigned long value)
  409. {
  410. m_stream << value;
  411. return *this;
  412. }
  413. #if !defined(BOOST_NO_LONG_LONG)
  414. basic_formatting_ostream& operator<< (long long value)
  415. {
  416. m_stream << value;
  417. return *this;
  418. }
  419. basic_formatting_ostream& operator<< (unsigned long long value)
  420. {
  421. m_stream << value;
  422. return *this;
  423. }
  424. #endif
  425. basic_formatting_ostream& operator<< (float value)
  426. {
  427. m_stream << value;
  428. return *this;
  429. }
  430. basic_formatting_ostream& operator<< (double value)
  431. {
  432. m_stream << value;
  433. return *this;
  434. }
  435. basic_formatting_ostream& operator<< (long double value)
  436. {
  437. m_stream << value;
  438. return *this;
  439. }
  440. basic_formatting_ostream& operator<< (const void* value)
  441. {
  442. m_stream << value;
  443. return *this;
  444. }
  445. basic_formatting_ostream& operator<< (std::basic_streambuf< char_type, traits_type >* buf)
  446. {
  447. m_stream << buf;
  448. return *this;
  449. }
  450. template< typename OtherCharT, typename OtherTraitsT, typename OtherAllocatorT >
  451. friend typename aux::enable_if_char_type< OtherCharT, basic_formatting_ostream& >::type
  452. operator<< (basic_formatting_ostream& strm, std::basic_string< OtherCharT, OtherTraitsT, OtherAllocatorT > const& str)
  453. {
  454. return strm.formatted_write(str.c_str(), static_cast< std::streamsize >(str.size()));
  455. }
  456. template< typename OtherCharT, typename OtherTraitsT >
  457. friend typename aux::enable_if_char_type< OtherCharT, basic_formatting_ostream& >::type
  458. operator<< (basic_formatting_ostream& strm, basic_string_literal< OtherCharT, OtherTraitsT > const& str)
  459. {
  460. return strm.formatted_write(str.c_str(), static_cast< std::streamsize >(str.size()));
  461. }
  462. template< typename OtherCharT, typename OtherTraitsT >
  463. friend typename aux::enable_if_char_type< OtherCharT, basic_formatting_ostream& >::type
  464. operator<< (basic_formatting_ostream& strm, basic_string_ref< OtherCharT, OtherTraitsT > const& str)
  465. {
  466. return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
  467. }
  468. private:
  469. void init_stream()
  470. {
  471. m_stream.clear(m_streambuf.storage() ? ostream_type::goodbit : ostream_type::badbit);
  472. m_stream.flags
  473. (
  474. ostream_type::dec |
  475. ostream_type::skipws |
  476. ostream_type::boolalpha // this differs from the default stream flags but makes logs look better
  477. );
  478. m_stream.width(0);
  479. m_stream.precision(6);
  480. m_stream.fill(static_cast< char_type >(' '));
  481. }
  482. basic_formatting_ostream& formatted_write(const char_type* p, std::streamsize size)
  483. {
  484. sentry guard(*this);
  485. if (guard)
  486. {
  487. m_stream.flush();
  488. if (m_stream.width() <= size)
  489. m_streambuf.storage()->append(p, static_cast< std::size_t >(size));
  490. else
  491. this->aligned_write(p, size);
  492. m_stream.width(0);
  493. }
  494. return *this;
  495. }
  496. template< typename OtherCharT >
  497. basic_formatting_ostream& formatted_write(const OtherCharT* p, std::streamsize size)
  498. {
  499. sentry guard(*this);
  500. if (guard)
  501. {
  502. m_stream.flush();
  503. if (m_stream.width() <= size)
  504. aux::code_convert(p, static_cast< std::size_t >(size), *m_streambuf.storage(), m_stream.getloc());
  505. else
  506. this->aligned_write(p, size);
  507. m_stream.width(0);
  508. }
  509. return *this;
  510. }
  511. void aligned_write(const char_type* p, std::streamsize size);
  512. template< typename OtherCharT >
  513. void aligned_write(const OtherCharT* p, std::streamsize size);
  514. //! Copy constructor (closed)
  515. BOOST_DELETED_FUNCTION(basic_formatting_ostream(basic_formatting_ostream const& that))
  516. //! Assignment (closed)
  517. BOOST_DELETED_FUNCTION(basic_formatting_ostream& operator= (basic_formatting_ostream const& that))
  518. };
  519. template< typename CharT, typename TraitsT, typename AllocatorT >
  520. BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::boolalpha;
  521. template< typename CharT, typename TraitsT, typename AllocatorT >
  522. BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::dec;
  523. template< typename CharT, typename TraitsT, typename AllocatorT >
  524. BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fixed;
  525. template< typename CharT, typename TraitsT, typename AllocatorT >
  526. BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::hex;
  527. template< typename CharT, typename TraitsT, typename AllocatorT >
  528. BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::internal;
  529. template< typename CharT, typename TraitsT, typename AllocatorT >
  530. BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::left;
  531. template< typename CharT, typename TraitsT, typename AllocatorT >
  532. BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::oct;
  533. template< typename CharT, typename TraitsT, typename AllocatorT >
  534. BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::right;
  535. template< typename CharT, typename TraitsT, typename AllocatorT >
  536. BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::scientific;
  537. template< typename CharT, typename TraitsT, typename AllocatorT >
  538. BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::showbase;
  539. template< typename CharT, typename TraitsT, typename AllocatorT >
  540. BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::showpoint;
  541. template< typename CharT, typename TraitsT, typename AllocatorT >
  542. BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::skipws;
  543. template< typename CharT, typename TraitsT, typename AllocatorT >
  544. BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::unitbuf;
  545. template< typename CharT, typename TraitsT, typename AllocatorT >
  546. BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::uppercase;
  547. template< typename CharT, typename TraitsT, typename AllocatorT >
  548. BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::adjustfield;
  549. template< typename CharT, typename TraitsT, typename AllocatorT >
  550. BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::basefield;
  551. template< typename CharT, typename TraitsT, typename AllocatorT >
  552. BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::floatfield;
  553. template< typename CharT, typename TraitsT, typename AllocatorT >
  554. BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::iostate basic_formatting_ostream< CharT, TraitsT, AllocatorT >::badbit;
  555. template< typename CharT, typename TraitsT, typename AllocatorT >
  556. BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::iostate basic_formatting_ostream< CharT, TraitsT, AllocatorT >::eofbit;
  557. template< typename CharT, typename TraitsT, typename AllocatorT >
  558. BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::iostate basic_formatting_ostream< CharT, TraitsT, AllocatorT >::failbit;
  559. template< typename CharT, typename TraitsT, typename AllocatorT >
  560. BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::iostate basic_formatting_ostream< CharT, TraitsT, AllocatorT >::goodbit;
  561. template< typename CharT, typename TraitsT, typename AllocatorT >
  562. BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::app;
  563. template< typename CharT, typename TraitsT, typename AllocatorT >
  564. BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::ate;
  565. template< typename CharT, typename TraitsT, typename AllocatorT >
  566. BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::binary;
  567. template< typename CharT, typename TraitsT, typename AllocatorT >
  568. BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::in;
  569. template< typename CharT, typename TraitsT, typename AllocatorT >
  570. BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::out;
  571. template< typename CharT, typename TraitsT, typename AllocatorT >
  572. BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::trunc;
  573. template< typename CharT, typename TraitsT, typename AllocatorT >
  574. BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::seekdir basic_formatting_ostream< CharT, TraitsT, AllocatorT >::beg;
  575. template< typename CharT, typename TraitsT, typename AllocatorT >
  576. BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::seekdir basic_formatting_ostream< CharT, TraitsT, AllocatorT >::cur;
  577. template< typename CharT, typename TraitsT, typename AllocatorT >
  578. BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::seekdir basic_formatting_ostream< CharT, TraitsT, AllocatorT >::end;
  579. template< typename CharT, typename TraitsT, typename AllocatorT >
  580. BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::event basic_formatting_ostream< CharT, TraitsT, AllocatorT >::erase_event;
  581. template< typename CharT, typename TraitsT, typename AllocatorT >
  582. BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::event basic_formatting_ostream< CharT, TraitsT, AllocatorT >::imbue_event;
  583. template< typename CharT, typename TraitsT, typename AllocatorT >
  584. BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::event basic_formatting_ostream< CharT, TraitsT, AllocatorT >::copyfmt_event;
  585. template< typename CharT, typename TraitsT, typename AllocatorT >
  586. void basic_formatting_ostream< CharT, TraitsT, AllocatorT >::aligned_write(const char_type* p, std::streamsize size)
  587. {
  588. string_type* const storage = m_streambuf.storage();
  589. typename string_type::size_type const alignment_size =
  590. static_cast< typename string_type::size_type >(m_stream.width() - size);
  591. const bool align_left = (m_stream.flags() & ostream_type::adjustfield) == ostream_type::left;
  592. if (align_left)
  593. {
  594. storage->append(p, static_cast< std::size_t >(size));
  595. storage->append(alignment_size, m_stream.fill());
  596. }
  597. else
  598. {
  599. storage->append(alignment_size, m_stream.fill());
  600. storage->append(p, static_cast< std::size_t >(size));
  601. }
  602. }
  603. template< typename CharT, typename TraitsT, typename AllocatorT >
  604. template< typename OtherCharT >
  605. void basic_formatting_ostream< CharT, TraitsT, AllocatorT >::aligned_write(const OtherCharT* p, std::streamsize size)
  606. {
  607. string_type* const storage = m_streambuf.storage();
  608. typename string_type::size_type const alignment_size =
  609. static_cast< typename string_type::size_type >(m_stream.width() - size);
  610. const bool align_left = (m_stream.flags() & ostream_type::adjustfield) == ostream_type::left;
  611. if (align_left)
  612. {
  613. aux::code_convert(p, static_cast< std::size_t >(size), *storage, m_stream.getloc());
  614. storage->append(alignment_size, m_stream.fill());
  615. }
  616. else
  617. {
  618. storage->append(alignment_size, m_stream.fill());
  619. aux::code_convert(p, static_cast< std::size_t >(size), *storage, m_stream.getloc());
  620. }
  621. }
  622. template< typename CharT, typename TraitsT, typename AllocatorT, typename T >
  623. inline basic_formatting_ostream< CharT, TraitsT, AllocatorT >&
  624. operator<< (basic_formatting_ostream< CharT, TraitsT, AllocatorT >& strm, T const& value)
  625. {
  626. strm.stream() << value;
  627. return strm;
  628. }
  629. BOOST_LOG_CLOSE_NAMESPACE // namespace log
  630. } // namespace boost
  631. #include <boost/log/detail/footer.hpp>
  632. #endif // BOOST_LOG_UTILITY_FORMATTING_OSTREAM_HPP_INCLUDED_