File indexing completed on 2025-01-18 09:39:26
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef BOOST_LOG_SOURCES_RECORD_OSTREAM_HPP_INCLUDED_
0017 #define BOOST_LOG_SOURCES_RECORD_OSTREAM_HPP_INCLUDED_
0018
0019 #include <string>
0020 #include <iosfwd>
0021 #include <ostream>
0022 #include <boost/assert.hpp>
0023 #include <boost/move/core.hpp>
0024 #include <boost/move/utility_core.hpp>
0025 #include <boost/type_traits/is_enum.hpp>
0026 #include <boost/type_traits/is_scalar.hpp>
0027 #include <boost/type_traits/remove_cv.hpp>
0028 #include <boost/core/addressof.hpp>
0029 #include <boost/core/enable_if.hpp>
0030 #include <boost/core/explicit_operator_bool.hpp>
0031 #include <boost/core/uncaught_exceptions.hpp>
0032 #include <boost/log/detail/config.hpp>
0033 #include <boost/log/detail/native_typeof.hpp>
0034 #include <boost/log/core/record.hpp>
0035 #include <boost/log/utility/unique_identifier_name.hpp>
0036 #include <boost/log/utility/formatting_ostream.hpp>
0037 #include <boost/log/detail/header.hpp>
0038
0039 #ifdef BOOST_HAS_PRAGMA_ONCE
0040 #pragma once
0041 #endif
0042
0043 namespace boost {
0044
0045 BOOST_LOG_OPEN_NAMESPACE
0046
0047 template< typename CharT >
0048 class basic_record_ostream;
0049
0050 namespace aux {
0051
0052 template< typename StreamT, typename T, bool ByValueV, typename R >
0053 struct enable_record_ostream_generic_operator {};
0054
0055 template< typename CharT, typename T, typename R >
0056 struct enable_record_ostream_generic_operator< basic_record_ostream< CharT >, T, false, R > :
0057 public boost::disable_if_c< boost::is_scalar< typename boost::remove_cv< T >::type >::value, R >
0058 {
0059 };
0060
0061 template< typename CharT, typename T, typename R >
0062 struct enable_record_ostream_generic_operator< basic_record_ostream< CharT >, T, true, R > :
0063 public boost::enable_if_c< boost::is_enum< typename boost::remove_cv< T >::type >::value, R >
0064 {
0065 };
0066
0067 template< typename CharT, typename T, typename R >
0068 struct enable_record_ostream_generic_operator< basic_record_ostream< CharT >, T*, true, R > :
0069 public disable_if_streamable_char_type< typename boost::remove_cv< T >::type, R >
0070 {
0071 };
0072
0073 }
0074
0075
0076
0077
0078
0079
0080
0081 template< typename CharT >
0082 class basic_record_ostream :
0083 public basic_formatting_ostream< CharT >
0084 {
0085
0086 typedef basic_record_ostream< CharT > this_type;
0087
0088 typedef basic_formatting_ostream< CharT > base_type;
0089
0090 public:
0091
0092 typedef CharT char_type;
0093
0094 typedef std::basic_string< char_type > string_type;
0095
0096 typedef std::basic_ostream< char_type > stream_type;
0097
0098 typedef typename base_type::traits_type traits_type;
0099
0100 private:
0101
0102 record* m_record;
0103
0104 public:
0105
0106
0107
0108
0109
0110
0111 basic_record_ostream() BOOST_NOEXCEPT : m_record(NULL) {}
0112
0113
0114
0115
0116
0117
0118
0119
0120 explicit basic_record_ostream(record& rec)
0121 {
0122 BOOST_ASSERT_MSG(!!rec, "Boost.Log: basic_record_ostream should only be attached to a valid record");
0123 m_record = &rec;
0124 init_stream();
0125 }
0126
0127
0128
0129
0130 ~basic_record_ostream() BOOST_NOEXCEPT
0131 {
0132 detach_from_record();
0133 }
0134
0135
0136
0137
0138
0139
0140
0141 BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
0142
0143
0144
0145
0146
0147
0148
0149 bool operator! () const BOOST_NOEXCEPT
0150 {
0151 return (!m_record || base_type::fail());
0152 }
0153
0154
0155
0156
0157
0158
0159 record& get_record()
0160 {
0161 BOOST_ASSERT(m_record != NULL);
0162 this->flush();
0163 return *m_record;
0164 }
0165
0166
0167
0168
0169
0170
0171 record const& get_record() const
0172 {
0173 BOOST_ASSERT(m_record != NULL);
0174 const_cast< this_type* >(this)->flush();
0175 return *m_record;
0176 }
0177
0178
0179
0180
0181
0182
0183
0184 void attach_record(record& rec)
0185 {
0186 BOOST_ASSERT_MSG(!!rec, "Boost.Log: basic_record_ostream should only be attached to a valid record");
0187 detach_from_record();
0188 m_record = &rec;
0189 init_stream();
0190 }
0191
0192
0193 BOOST_LOG_API void detach_from_record() BOOST_NOEXCEPT;
0194
0195 basic_record_ostream& operator<< (typename base_type::ios_base_manip manip)
0196 {
0197 static_cast< base_type& >(*this) << manip;
0198 return *this;
0199 }
0200 basic_record_ostream& operator<< (typename base_type::basic_ios_manip manip)
0201 {
0202 static_cast< base_type& >(*this) << manip;
0203 return *this;
0204 }
0205 basic_record_ostream& operator<< (typename base_type::stream_manip manip)
0206 {
0207 static_cast< base_type& >(*this) << manip;
0208 return *this;
0209 }
0210
0211 basic_record_ostream& operator<< (char c)
0212 {
0213 static_cast< base_type& >(*this) << c;
0214 return *this;
0215 }
0216 basic_record_ostream& operator<< (const char* p)
0217 {
0218 static_cast< base_type& >(*this) << p;
0219 return *this;
0220 }
0221
0222
0223
0224 #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
0225 basic_record_ostream& operator<< (wchar_t c)
0226 {
0227 static_cast< base_type& >(*this) << c;
0228 return *this;
0229 }
0230 basic_record_ostream& operator<< (const wchar_t* p)
0231 {
0232 static_cast< base_type& >(*this) << p;
0233 return *this;
0234 }
0235 #endif
0236 #if !defined(BOOST_LOG_NO_CXX11_CODECVT_FACETS)
0237 #if !defined(BOOST_NO_CXX11_CHAR16_T)
0238 basic_record_ostream& operator<< (char16_t c)
0239 {
0240 static_cast< base_type& >(*this) << c;
0241 return *this;
0242 }
0243 basic_record_ostream& operator<< (const char16_t* p)
0244 {
0245 static_cast< base_type& >(*this) << p;
0246 return *this;
0247 }
0248 #endif
0249 #if !defined(BOOST_NO_CXX11_CHAR32_T)
0250 basic_record_ostream& operator<< (char32_t c)
0251 {
0252 static_cast< base_type& >(*this) << c;
0253 return *this;
0254 }
0255 basic_record_ostream& operator<< (const char32_t* p)
0256 {
0257 static_cast< base_type& >(*this) << p;
0258 return *this;
0259 }
0260 #endif
0261 #endif
0262
0263 basic_record_ostream& operator<< (bool value)
0264 {
0265 static_cast< base_type& >(*this) << value;
0266 return *this;
0267 }
0268 basic_record_ostream& operator<< (signed char value)
0269 {
0270 static_cast< base_type& >(*this) << value;
0271 return *this;
0272 }
0273 basic_record_ostream& operator<< (unsigned char value)
0274 {
0275 static_cast< base_type& >(*this) << value;
0276 return *this;
0277 }
0278 basic_record_ostream& operator<< (short value)
0279 {
0280 static_cast< base_type& >(*this) << value;
0281 return *this;
0282 }
0283 basic_record_ostream& operator<< (unsigned short value)
0284 {
0285 static_cast< base_type& >(*this) << value;
0286 return *this;
0287 }
0288 basic_record_ostream& operator<< (int value)
0289 {
0290 static_cast< base_type& >(*this) << value;
0291 return *this;
0292 }
0293 basic_record_ostream& operator<< (unsigned int value)
0294 {
0295 static_cast< base_type& >(*this) << value;
0296 return *this;
0297 }
0298 basic_record_ostream& operator<< (long value)
0299 {
0300 static_cast< base_type& >(*this) << value;
0301 return *this;
0302 }
0303 basic_record_ostream& operator<< (unsigned long value)
0304 {
0305 static_cast< base_type& >(*this) << value;
0306 return *this;
0307 }
0308 #if !defined(BOOST_NO_LONG_LONG)
0309 basic_record_ostream& operator<< (long long value)
0310 {
0311 static_cast< base_type& >(*this) << value;
0312 return *this;
0313 }
0314 basic_record_ostream& operator<< (unsigned long long value)
0315 {
0316 static_cast< base_type& >(*this) << value;
0317 return *this;
0318 }
0319 #endif
0320
0321 basic_record_ostream& operator<< (float value)
0322 {
0323 static_cast< base_type& >(*this) << value;
0324 return *this;
0325 }
0326 basic_record_ostream& operator<< (double value)
0327 {
0328 static_cast< base_type& >(*this) << value;
0329 return *this;
0330 }
0331 basic_record_ostream& operator<< (long double value)
0332 {
0333 static_cast< base_type& >(*this) << value;
0334 return *this;
0335 }
0336
0337 basic_record_ostream& operator<< (std::basic_streambuf< char_type, traits_type >* buf)
0338 {
0339 static_cast< base_type& >(*this) << buf;
0340 return *this;
0341 }
0342
0343 private:
0344
0345 BOOST_LOG_API void init_stream();
0346
0347
0348 BOOST_DELETED_FUNCTION(basic_record_ostream(basic_record_ostream const&))
0349 BOOST_DELETED_FUNCTION(basic_record_ostream& operator= (basic_record_ostream const&))
0350 };
0351
0352
0353 #ifdef BOOST_LOG_USE_CHAR
0354 typedef basic_record_ostream< char > record_ostream;
0355 #endif
0356 #ifdef BOOST_LOG_USE_WCHAR_T
0357 typedef basic_record_ostream< wchar_t > wrecord_ostream;
0358 #endif
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369 template< typename StreamT, typename T >
0370 inline typename boost::log::aux::enable_record_ostream_generic_operator< StreamT, T, true, StreamT& >::type
0371 operator<< (StreamT& strm, T value)
0372 {
0373 typedef basic_formatting_ostream< typename StreamT::char_type > formatting_ostream_type;
0374 static_cast< formatting_ostream_type& >(strm) << value;
0375 return strm;
0376 }
0377
0378 template< typename StreamT, typename T >
0379 inline typename boost::log::aux::enable_record_ostream_generic_operator< StreamT, T, false, StreamT& >::type
0380 operator<< (StreamT& strm, T const& value)
0381 {
0382 typedef basic_formatting_ostream< typename StreamT::char_type > formatting_ostream_type;
0383 static_cast< formatting_ostream_type& >(strm) << value;
0384 return strm;
0385 }
0386
0387 template< typename StreamT, typename T >
0388 inline typename boost::log::aux::enable_record_ostream_generic_operator< StreamT, T, false, StreamT& >::type
0389 operator<< (StreamT& strm, T& value)
0390 {
0391 typedef basic_formatting_ostream< typename StreamT::char_type > formatting_ostream_type;
0392 static_cast< formatting_ostream_type& >(strm) << value;
0393 return strm;
0394 }
0395
0396 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0397
0398 template< typename StreamT, typename T >
0399 inline typename boost::log::aux::enable_record_ostream_generic_operator< StreamT, T, true, StreamT& >::type
0400 operator<< (StreamT&& strm, T value)
0401 {
0402 typedef basic_formatting_ostream< typename StreamT::char_type > formatting_ostream_type;
0403 static_cast< formatting_ostream_type& >(strm) << value;
0404 return strm;
0405 }
0406
0407 template< typename StreamT, typename T >
0408 inline typename boost::log::aux::enable_record_ostream_generic_operator< StreamT, T, false, StreamT& >::type
0409 operator<< (StreamT&& strm, T const& value)
0410 {
0411 typedef basic_formatting_ostream< typename StreamT::char_type > formatting_ostream_type;
0412 static_cast< formatting_ostream_type& >(strm) << value;
0413 return strm;
0414 }
0415
0416 template< typename StreamT, typename T >
0417 inline typename boost::log::aux::enable_record_ostream_generic_operator< StreamT, T, false, StreamT& >::type
0418 operator<< (StreamT&& strm, T& value)
0419 {
0420 typedef basic_formatting_ostream< typename StreamT::char_type > formatting_ostream_type;
0421 static_cast< formatting_ostream_type& >(strm) << value;
0422 return strm;
0423 }
0424
0425 #endif
0426
0427 namespace aux {
0428
0429
0430 template< typename CharT >
0431 struct stream_provider
0432 {
0433
0434 typedef CharT char_type;
0435
0436
0437 struct stream_compound
0438 {
0439 stream_compound* next;
0440
0441
0442 basic_record_ostream< char_type > stream;
0443
0444
0445 explicit stream_compound(record& rec) : next(NULL), stream(rec) {}
0446 };
0447
0448
0449 BOOST_LOG_API static stream_compound* allocate_compound(record& rec);
0450
0451 BOOST_LOG_API static void release_compound(stream_compound* compound) BOOST_NOEXCEPT;
0452
0453
0454 BOOST_DELETED_FUNCTION(stream_provider())
0455 BOOST_DELETED_FUNCTION(stream_provider(stream_provider const&))
0456 BOOST_DELETED_FUNCTION(stream_provider& operator= (stream_provider const&))
0457 };
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469 template< typename LoggerT >
0470 class record_pump
0471 {
0472 BOOST_MOVABLE_BUT_NOT_COPYABLE(record_pump)
0473
0474 private:
0475
0476 typedef LoggerT logger_type;
0477
0478 typedef typename logger_type::char_type char_type;
0479
0480 typedef stream_provider< char_type > stream_provider_type;
0481
0482 typedef typename stream_provider_type::stream_compound stream_compound;
0483
0484
0485 class auto_release;
0486 friend class auto_release;
0487 class auto_release
0488 {
0489 stream_compound* m_pCompound;
0490
0491 public:
0492 explicit auto_release(stream_compound* p) BOOST_NOEXCEPT : m_pCompound(p) {}
0493 ~auto_release() BOOST_NOEXCEPT { stream_provider_type::release_compound(m_pCompound); }
0494 };
0495
0496 protected:
0497
0498 logger_type* m_pLogger;
0499
0500 stream_compound* m_pStreamCompound;
0501
0502 const unsigned int m_ExceptionCount;
0503
0504 public:
0505
0506 explicit record_pump(logger_type& lg, record& rec) :
0507 m_pLogger(boost::addressof(lg)),
0508 m_pStreamCompound(stream_provider_type::allocate_compound(rec)),
0509 m_ExceptionCount(boost::core::uncaught_exceptions())
0510 {
0511 }
0512
0513 record_pump(BOOST_RV_REF(record_pump) that) BOOST_NOEXCEPT :
0514 m_pLogger(that.m_pLogger),
0515 m_pStreamCompound(that.m_pStreamCompound),
0516 m_ExceptionCount(that.m_ExceptionCount)
0517 {
0518 that.m_pLogger = 0;
0519 that.m_pStreamCompound = 0;
0520 }
0521
0522 ~record_pump() BOOST_NOEXCEPT_IF(false)
0523 {
0524 if (m_pLogger)
0525 {
0526 auto_release cleanup(m_pStreamCompound);
0527
0528 if (m_ExceptionCount >= boost::core::uncaught_exceptions())
0529 m_pLogger->push_record(boost::move(m_pStreamCompound->stream.get_record()));
0530 }
0531 }
0532
0533
0534 basic_record_ostream< char_type >& stream() const BOOST_NOEXCEPT
0535 {
0536 BOOST_ASSERT(m_pStreamCompound != 0);
0537 return m_pStreamCompound->stream;
0538 }
0539 };
0540
0541 template< typename LoggerT >
0542 BOOST_FORCEINLINE record_pump< LoggerT > make_record_pump(LoggerT& lg, record& rec)
0543 {
0544 return record_pump< LoggerT >(lg, rec);
0545 }
0546
0547 }
0548
0549 #ifndef BOOST_LOG_DOXYGEN_PASS
0550
0551 #define BOOST_LOG_STREAM_INTERNAL(logger, rec_var)\
0552 for (::boost::log::record rec_var = (logger).open_record(); !!rec_var;)\
0553 ::boost::log::aux::make_record_pump((logger), rec_var).stream()
0554
0555 #define BOOST_LOG_STREAM_WITH_PARAMS_INTERNAL(logger, rec_var, params_seq)\
0556 for (::boost::log::record rec_var = (logger).open_record((BOOST_PP_SEQ_ENUM(params_seq))); !!rec_var;)\
0557 ::boost::log::aux::make_record_pump((logger), rec_var).stream()
0558
0559 #endif
0560
0561
0562 #define BOOST_LOG_STREAM(logger)\
0563 BOOST_LOG_STREAM_INTERNAL(logger, BOOST_LOG_UNIQUE_IDENTIFIER_NAME(_boost_log_record_))
0564
0565
0566 #define BOOST_LOG_STREAM_WITH_PARAMS(logger, params_seq)\
0567 BOOST_LOG_STREAM_WITH_PARAMS_INTERNAL(logger, BOOST_LOG_UNIQUE_IDENTIFIER_NAME(_boost_log_record_), params_seq)
0568
0569 #ifndef BOOST_LOG_NO_SHORTHAND_NAMES
0570
0571
0572 #define BOOST_LOG(logger) BOOST_LOG_STREAM(logger)
0573
0574
0575 #define BOOST_LOG_WITH_PARAMS(logger, params_seq) BOOST_LOG_STREAM_WITH_PARAMS(logger, params_seq)
0576
0577 #endif
0578
0579 BOOST_LOG_CLOSE_NAMESPACE
0580
0581 }
0582
0583 #include <boost/log/detail/footer.hpp>
0584
0585 #endif