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