Chris@16: /* Chris@101: * Copyright Andrey Semashev 2007 - 2015. Chris@16: * Distributed under the Boost Software License, Version 1.0. Chris@16: * (See accompanying file LICENSE_1_0.txt or copy at Chris@16: * http://www.boost.org/LICENSE_1_0.txt) Chris@16: */ Chris@16: /*! Chris@16: * \file scoped_attribute.hpp Chris@16: * \author Andrey Semashev Chris@16: * \date 13.05.2007 Chris@16: * Chris@16: * The header contains definition of facilities to define scoped attributes. Chris@16: */ Chris@16: Chris@16: #ifndef BOOST_LOG_ATTRIBUTES_SCOPED_ATTRIBUTE_HPP_INCLUDED_ Chris@16: #define BOOST_LOG_ATTRIBUTES_SCOPED_ATTRIBUTE_HPP_INCLUDED_ Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #ifdef BOOST_HAS_PRAGMA_ONCE Chris@16: #pragma once Chris@16: #endif Chris@16: Chris@16: namespace boost { Chris@16: Chris@16: BOOST_LOG_OPEN_NAMESPACE Chris@16: Chris@16: namespace aux { Chris@16: Chris@16: //! A base class for all scoped attribute guards Chris@16: class attribute_scope_guard Chris@16: { Chris@16: }; Chris@16: Chris@16: } // namespace aux Chris@16: Chris@16: //! Scoped attribute guard type Chris@16: typedef aux::attribute_scope_guard const& scoped_attribute; Chris@16: Chris@16: namespace aux { Chris@16: Chris@16: //! A scoped logger attribute guard Chris@16: template< typename LoggerT > Chris@16: class scoped_logger_attribute : Chris@16: public attribute_scope_guard Chris@16: { Chris@16: BOOST_COPYABLE_AND_MOVABLE_ALT(scoped_logger_attribute) Chris@16: Chris@16: private: Chris@16: //! Logger type Chris@16: typedef LoggerT logger_type; Chris@16: Chris@16: private: Chris@16: //! A reference to the logger Chris@16: logger_type* m_pLogger; Chris@16: //! An iterator to the added attribute Chris@16: attribute_set::iterator m_itAttribute; Chris@16: Chris@16: public: Chris@16: //! Constructor Chris@16: scoped_logger_attribute(logger_type& l, attribute_name const& name, attribute const& attr) : Chris@16: m_pLogger(boost::addressof(l)) Chris@16: { Chris@16: std::pair< Chris@16: attribute_set::iterator, Chris@16: bool Chris@16: > res = l.add_attribute(name, attr); Chris@16: if (res.second) Chris@16: m_itAttribute = res.first; Chris@16: else Chris@16: m_pLogger = 0; // if there already is a same-named attribute, don't register anything Chris@16: } Chris@16: //! Move constructor Chris@16: scoped_logger_attribute(BOOST_RV_REF(scoped_logger_attribute) that) : Chris@16: m_pLogger(that.m_pLogger), Chris@16: m_itAttribute(that.m_itAttribute) Chris@16: { Chris@16: that.m_pLogger = 0; Chris@16: } Chris@16: Chris@16: //! Destructor Chris@16: ~scoped_logger_attribute() Chris@16: { Chris@16: if (m_pLogger) Chris@16: m_pLogger->remove_attribute(m_itAttribute); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_LOG_BROKEN_REFERENCE_FROM_RVALUE_INIT Chris@16: BOOST_DELETED_FUNCTION(scoped_logger_attribute(scoped_logger_attribute const&)) Chris@16: #else // BOOST_LOG_BROKEN_REFERENCE_FROM_RVALUE_INIT Chris@16: scoped_logger_attribute(scoped_logger_attribute const& that) : m_pLogger(that.m_pLogger), m_itAttribute(that.m_itAttribute) Chris@16: { Chris@16: const_cast< scoped_logger_attribute& >(that).m_pLogger = 0; Chris@16: } Chris@16: #endif // BOOST_LOG_BROKEN_REFERENCE_FROM_RVALUE_INIT Chris@16: Chris@16: BOOST_DELETED_FUNCTION(scoped_logger_attribute& operator= (scoped_logger_attribute const&)) Chris@16: }; Chris@16: Chris@16: } // namespace aux Chris@16: Chris@16: // Generator helper functions Chris@16: /*! Chris@16: * Registers an attribute in the logger Chris@16: * Chris@16: * \param l Logger to register the attribute in Chris@16: * \param name Attribute name Chris@16: * \param attr The attribute. Must not be NULL. Chris@16: * \return An unspecified guard object which may be used to initialize a \c scoped_attribute variable. Chris@16: */ Chris@16: template< typename LoggerT > Chris@16: BOOST_FORCEINLINE aux::scoped_logger_attribute< LoggerT > add_scoped_logger_attribute(LoggerT& l, attribute_name const& name, attribute const& attr) Chris@16: { Chris@16: #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) Chris@16: return aux::scoped_logger_attribute< LoggerT >(l, name, attr); Chris@16: #else Chris@16: aux::scoped_logger_attribute< LoggerT > guard(l, name, attr); Chris@16: return boost::move(guard); Chris@16: #endif Chris@16: } Chris@16: Chris@16: #ifndef BOOST_LOG_DOXYGEN_PASS Chris@16: Chris@16: #define BOOST_LOG_SCOPED_LOGGER_ATTR_INTERNAL(logger, attr_name, attr, sentry_var_name)\ Chris@16: BOOST_LOG_UNUSED_VARIABLE(::boost::log::scoped_attribute, sentry_var_name,\ Chris@16: = ::boost::log::add_scoped_logger_attribute(logger, attr_name, (attr))); Chris@16: Chris@16: #endif // BOOST_LOG_DOXYGEN_PASS Chris@16: Chris@16: //! The macro sets a scoped logger-wide attribute in a more compact way Chris@16: #define BOOST_LOG_SCOPED_LOGGER_ATTR(logger, attr_name, attr)\ Chris@16: BOOST_LOG_SCOPED_LOGGER_ATTR_INTERNAL(\ Chris@16: logger,\ Chris@16: attr_name,\ Chris@16: attr,\ Chris@16: BOOST_LOG_UNIQUE_IDENTIFIER_NAME(_boost_log_scoped_logger_attr_sentry_)) Chris@16: Chris@16: //! The macro sets a scoped logger-wide tag in a more compact way Chris@16: #define BOOST_LOG_SCOPED_LOGGER_TAG(logger, attr_name, attr_value)\ Chris@16: BOOST_LOG_SCOPED_LOGGER_ATTR(logger, attr_name, ::boost::log::attributes::make_constant(attr_value)) Chris@16: Chris@16: namespace aux { Chris@16: Chris@16: //! A scoped thread-specific attribute guard Chris@16: class scoped_thread_attribute : Chris@16: public attribute_scope_guard Chris@16: { Chris@16: BOOST_COPYABLE_AND_MOVABLE_ALT(scoped_thread_attribute) Chris@16: Chris@16: private: Chris@16: //! A pointer to the logging core Chris@16: core_ptr m_pCore; Chris@16: //! An iterator to the added attribute Chris@16: attribute_set::iterator m_itAttribute; Chris@16: Chris@16: public: Chris@16: //! Constructor Chris@16: scoped_thread_attribute(attribute_name const& name, attribute const& attr) : Chris@16: m_pCore(core::get()) Chris@16: { Chris@16: std::pair< Chris@16: attribute_set::iterator, Chris@16: bool Chris@16: > res = m_pCore->add_thread_attribute(name, attr); Chris@16: if (res.second) Chris@16: m_itAttribute = res.first; Chris@16: else Chris@16: m_pCore.reset(); // if there already is a same-named attribute, don't register anything Chris@16: } Chris@16: //! Move constructor Chris@16: scoped_thread_attribute(BOOST_RV_REF(scoped_thread_attribute) that) : m_itAttribute(that.m_itAttribute) Chris@16: { Chris@16: m_pCore.swap(that.m_pCore); Chris@16: } Chris@16: Chris@16: //! Destructor Chris@16: ~scoped_thread_attribute() Chris@16: { Chris@16: if (!!m_pCore) Chris@16: m_pCore->remove_thread_attribute(m_itAttribute); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_LOG_BROKEN_REFERENCE_FROM_RVALUE_INIT Chris@16: BOOST_DELETED_FUNCTION(scoped_thread_attribute(scoped_thread_attribute const&)) Chris@16: #else // BOOST_LOG_BROKEN_REFERENCE_FROM_RVALUE_INIT Chris@16: scoped_thread_attribute(scoped_thread_attribute const& that) : m_itAttribute(that.m_itAttribute) Chris@16: { Chris@16: m_pCore.swap(const_cast< scoped_thread_attribute& >(that).m_pCore); Chris@16: } Chris@16: #endif // BOOST_LOG_BROKEN_REFERENCE_FROM_RVALUE_INIT Chris@16: Chris@16: BOOST_DELETED_FUNCTION(scoped_thread_attribute& operator= (scoped_thread_attribute const&)) Chris@16: }; Chris@16: Chris@16: } // namespace aux Chris@16: Chris@16: // Generator helper functions Chris@16: /*! Chris@16: * Registers a thread-specific attribute Chris@16: * Chris@16: * \param name Attribute name Chris@16: * \param attr The attribute. Must not be NULL. Chris@16: * \return An unspecified guard object which may be used to initialize a \c scoped_attribute variable. Chris@16: */ Chris@16: BOOST_FORCEINLINE aux::scoped_thread_attribute add_scoped_thread_attribute(attribute_name const& name, attribute const& attr) Chris@16: { Chris@16: #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) Chris@16: return aux::scoped_thread_attribute(name, attr); Chris@16: #else Chris@16: aux::scoped_thread_attribute guard(name, attr); Chris@16: return boost::move(guard); Chris@16: #endif Chris@16: } Chris@16: Chris@16: #ifndef BOOST_LOG_DOXYGEN_PASS Chris@16: Chris@16: #define BOOST_LOG_SCOPED_THREAD_ATTR_INTERNAL(attr_name, attr, sentry_var_name)\ Chris@16: BOOST_LOG_UNUSED_VARIABLE(::boost::log::scoped_attribute, sentry_var_name,\ Chris@16: = ::boost::log::add_scoped_thread_attribute(attr_name, (attr))); Chris@16: Chris@16: #endif // BOOST_LOG_DOXYGEN_PASS Chris@16: Chris@16: //! The macro sets a scoped thread-wide attribute in a more compact way Chris@16: #define BOOST_LOG_SCOPED_THREAD_ATTR(attr_name, attr)\ Chris@16: BOOST_LOG_SCOPED_THREAD_ATTR_INTERNAL(\ Chris@16: attr_name,\ Chris@16: attr,\ Chris@16: BOOST_LOG_UNIQUE_IDENTIFIER_NAME(_boost_log_scoped_thread_attr_sentry_)) Chris@16: Chris@16: //! The macro sets a scoped thread-wide tag in a more compact way Chris@16: #define BOOST_LOG_SCOPED_THREAD_TAG(attr_name, attr_value)\ Chris@16: BOOST_LOG_SCOPED_THREAD_ATTR(attr_name, ::boost::log::attributes::make_constant(attr_value)) Chris@16: Chris@16: BOOST_LOG_CLOSE_NAMESPACE // namespace log Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: #include Chris@16: Chris@16: #endif // BOOST_LOG_ATTRIBUTES_SCOPED_ATTRIBUTE_HPP_INCLUDED_