diff options
Diffstat (limited to 'boost/log/attributes/scoped_attribute.hpp')
-rw-r--r-- | boost/log/attributes/scoped_attribute.hpp | 253 |
1 files changed, 253 insertions, 0 deletions
diff --git a/boost/log/attributes/scoped_attribute.hpp b/boost/log/attributes/scoped_attribute.hpp new file mode 100644 index 0000000000..33b1c395fe --- /dev/null +++ b/boost/log/attributes/scoped_attribute.hpp @@ -0,0 +1,253 @@ +/* + * Copyright Andrey Semashev 2007 - 2014. + * 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_ |