summaryrefslogtreecommitdiff
path: root/boost/log/attributes/scoped_attribute.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/log/attributes/scoped_attribute.hpp')
-rw-r--r--boost/log/attributes/scoped_attribute.hpp253
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_