2 * Copyright Andrey Semashev 2007 - 2015.
3 * Distributed under the Boost Software License, Version 1.0.
4 * (See accompanying file LICENSE_1_0.txt or copy at
5 * http://www.boost.org/LICENSE_1_0.txt)
8 * \file scoped_attribute.hpp
9 * \author Andrey Semashev
12 * The header contains definition of facilities to define scoped attributes.
15 #ifndef BOOST_LOG_ATTRIBUTES_SCOPED_ATTRIBUTE_HPP_INCLUDED_
16 #define BOOST_LOG_ATTRIBUTES_SCOPED_ATTRIBUTE_HPP_INCLUDED_
20 #include <boost/move/core.hpp>
21 #include <boost/move/utility_core.hpp>
22 #include <boost/core/addressof.hpp>
23 #include <boost/log/detail/config.hpp>
24 #include <boost/log/core/core.hpp>
25 #include <boost/log/sources/basic_logger.hpp>
26 #include <boost/log/attributes/attribute.hpp>
27 #include <boost/log/attributes/attribute_set.hpp>
28 #include <boost/log/attributes/attribute_name.hpp>
29 #include <boost/log/attributes/constant.hpp>
30 #include <boost/log/utility/unused_variable.hpp>
31 #include <boost/log/utility/unique_identifier_name.hpp>
32 #include <boost/log/detail/header.hpp>
34 #ifdef BOOST_HAS_PRAGMA_ONCE
40 BOOST_LOG_OPEN_NAMESPACE
44 //! A base class for all scoped attribute guards
45 class attribute_scope_guard
51 //! Scoped attribute guard type
52 typedef aux::attribute_scope_guard const& scoped_attribute;
56 //! A scoped logger attribute guard
57 template< typename LoggerT >
58 class scoped_logger_attribute :
59 public attribute_scope_guard
61 BOOST_COPYABLE_AND_MOVABLE_ALT(scoped_logger_attribute)
65 typedef LoggerT logger_type;
68 //! A reference to the logger
69 logger_type* m_pLogger;
70 //! An iterator to the added attribute
71 attribute_set::iterator m_itAttribute;
75 scoped_logger_attribute(logger_type& l, attribute_name const& name, attribute const& attr) :
76 m_pLogger(boost::addressof(l))
79 attribute_set::iterator,
81 > res = l.add_attribute(name, attr);
83 m_itAttribute = res.first;
85 m_pLogger = NULL; // if there already is a same-named attribute, don't register anything
88 scoped_logger_attribute(BOOST_RV_REF(scoped_logger_attribute) that) BOOST_NOEXCEPT :
89 m_pLogger(that.m_pLogger),
90 m_itAttribute(that.m_itAttribute)
92 that.m_pLogger = NULL;
96 ~scoped_logger_attribute()
99 m_pLogger->remove_attribute(m_itAttribute);
102 #ifndef BOOST_LOG_BROKEN_REFERENCE_FROM_RVALUE_INIT
103 BOOST_DELETED_FUNCTION(scoped_logger_attribute(scoped_logger_attribute const&))
104 #else // BOOST_LOG_BROKEN_REFERENCE_FROM_RVALUE_INIT
105 scoped_logger_attribute(scoped_logger_attribute const& that) BOOST_NOEXCEPT : m_pLogger(that.m_pLogger), m_itAttribute(that.m_itAttribute)
107 const_cast< scoped_logger_attribute& >(that).m_pLogger = NULL;
109 #endif // BOOST_LOG_BROKEN_REFERENCE_FROM_RVALUE_INIT
111 BOOST_DELETED_FUNCTION(scoped_logger_attribute& operator= (scoped_logger_attribute const&))
116 // Generator helper functions
118 * Registers an attribute in the logger
120 * \param l Logger to register the attribute in
121 * \param name Attribute name
122 * \param attr The attribute. Must not be NULL.
123 * \return An unspecified guard object which may be used to initialize a \c scoped_attribute variable.
125 template< typename LoggerT >
126 BOOST_FORCEINLINE aux::scoped_logger_attribute< LoggerT > add_scoped_logger_attribute(LoggerT& l, attribute_name const& name, attribute const& attr)
128 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
129 return aux::scoped_logger_attribute< LoggerT >(l, name, attr);
131 aux::scoped_logger_attribute< LoggerT > guard(l, name, attr);
132 return boost::move(guard);
136 #ifndef BOOST_LOG_DOXYGEN_PASS
138 #define BOOST_LOG_SCOPED_LOGGER_ATTR_INTERNAL(logger, attr_name, attr, sentry_var_name)\
139 BOOST_LOG_UNUSED_VARIABLE(::boost::log::scoped_attribute, sentry_var_name,\
140 = ::boost::log::add_scoped_logger_attribute(logger, attr_name, (attr)));
142 #endif // BOOST_LOG_DOXYGEN_PASS
144 //! The macro sets a scoped logger-wide attribute in a more compact way
145 #define BOOST_LOG_SCOPED_LOGGER_ATTR(logger, attr_name, attr)\
146 BOOST_LOG_SCOPED_LOGGER_ATTR_INTERNAL(\
150 BOOST_LOG_UNIQUE_IDENTIFIER_NAME(_boost_log_scoped_logger_attr_sentry_))
152 //! The macro sets a scoped logger-wide tag in a more compact way
153 #define BOOST_LOG_SCOPED_LOGGER_TAG(logger, attr_name, attr_value)\
154 BOOST_LOG_SCOPED_LOGGER_ATTR(logger, attr_name, ::boost::log::attributes::make_constant(attr_value))
158 //! A scoped thread-specific attribute guard
159 class scoped_thread_attribute :
160 public attribute_scope_guard
162 BOOST_COPYABLE_AND_MOVABLE_ALT(scoped_thread_attribute)
165 //! A pointer to the logging core
167 //! An iterator to the added attribute
168 attribute_set::iterator m_itAttribute;
172 scoped_thread_attribute(attribute_name const& name, attribute const& attr) :
176 attribute_set::iterator,
178 > res = m_pCore->add_thread_attribute(name, attr);
180 m_itAttribute = res.first;
182 m_pCore.reset(); // if there already is a same-named attribute, don't register anything
185 scoped_thread_attribute(BOOST_RV_REF(scoped_thread_attribute) that) : m_itAttribute(that.m_itAttribute)
187 m_pCore.swap(that.m_pCore);
191 ~scoped_thread_attribute()
194 m_pCore->remove_thread_attribute(m_itAttribute);
197 #ifndef BOOST_LOG_BROKEN_REFERENCE_FROM_RVALUE_INIT
198 BOOST_DELETED_FUNCTION(scoped_thread_attribute(scoped_thread_attribute const&))
199 #else // BOOST_LOG_BROKEN_REFERENCE_FROM_RVALUE_INIT
200 scoped_thread_attribute(scoped_thread_attribute const& that) : m_itAttribute(that.m_itAttribute)
202 m_pCore.swap(const_cast< scoped_thread_attribute& >(that).m_pCore);
204 #endif // BOOST_LOG_BROKEN_REFERENCE_FROM_RVALUE_INIT
206 BOOST_DELETED_FUNCTION(scoped_thread_attribute& operator= (scoped_thread_attribute const&))
211 // Generator helper functions
213 * Registers a thread-specific attribute
215 * \param name Attribute name
216 * \param attr The attribute. Must not be NULL.
217 * \return An unspecified guard object which may be used to initialize a \c scoped_attribute variable.
219 BOOST_FORCEINLINE aux::scoped_thread_attribute add_scoped_thread_attribute(attribute_name const& name, attribute const& attr)
221 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
222 return aux::scoped_thread_attribute(name, attr);
224 aux::scoped_thread_attribute guard(name, attr);
225 return boost::move(guard);
229 #ifndef BOOST_LOG_DOXYGEN_PASS
231 #define BOOST_LOG_SCOPED_THREAD_ATTR_INTERNAL(attr_name, attr, sentry_var_name)\
232 BOOST_LOG_UNUSED_VARIABLE(::boost::log::scoped_attribute, sentry_var_name,\
233 = ::boost::log::add_scoped_thread_attribute(attr_name, (attr)));
235 #endif // BOOST_LOG_DOXYGEN_PASS
237 //! The macro sets a scoped thread-wide attribute in a more compact way
238 #define BOOST_LOG_SCOPED_THREAD_ATTR(attr_name, attr)\
239 BOOST_LOG_SCOPED_THREAD_ATTR_INTERNAL(\
242 BOOST_LOG_UNIQUE_IDENTIFIER_NAME(_boost_log_scoped_thread_attr_sentry_))
244 //! The macro sets a scoped thread-wide tag in a more compact way
245 #define BOOST_LOG_SCOPED_THREAD_TAG(attr_name, attr_value)\
246 BOOST_LOG_SCOPED_THREAD_ATTR(attr_name, ::boost::log::attributes::make_constant(attr_value))
248 BOOST_LOG_CLOSE_NAMESPACE // namespace log
252 #include <boost/log/detail/footer.hpp>
254 #endif // BOOST_LOG_ATTRIBUTES_SCOPED_ATTRIBUTE_HPP_INCLUDED_