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_
19 #include <boost/move/core.hpp>
20 #include <boost/move/utility_core.hpp>
21 #include <boost/core/addressof.hpp>
22 #include <boost/log/detail/config.hpp>
23 #include <boost/log/core/core.hpp>
24 #include <boost/log/sources/basic_logger.hpp>
25 #include <boost/log/attributes/attribute.hpp>
26 #include <boost/log/attributes/attribute_set.hpp>
27 #include <boost/log/attributes/attribute_name.hpp>
28 #include <boost/log/attributes/constant.hpp>
29 #include <boost/log/utility/unused_variable.hpp>
30 #include <boost/log/utility/unique_identifier_name.hpp>
31 #include <boost/log/detail/header.hpp>
33 #ifdef BOOST_HAS_PRAGMA_ONCE
39 BOOST_LOG_OPEN_NAMESPACE
43 //! A base class for all scoped attribute guards
44 class attribute_scope_guard
50 //! Scoped attribute guard type
51 typedef aux::attribute_scope_guard const& scoped_attribute;
55 //! A scoped logger attribute guard
56 template< typename LoggerT >
57 class scoped_logger_attribute :
58 public attribute_scope_guard
60 BOOST_COPYABLE_AND_MOVABLE_ALT(scoped_logger_attribute)
64 typedef LoggerT logger_type;
67 //! A reference to the logger
68 logger_type* m_pLogger;
69 //! An iterator to the added attribute
70 attribute_set::iterator m_itAttribute;
74 scoped_logger_attribute(logger_type& l, attribute_name const& name, attribute const& attr) :
75 m_pLogger(boost::addressof(l))
78 attribute_set::iterator,
80 > res = l.add_attribute(name, attr);
82 m_itAttribute = res.first;
84 m_pLogger = 0; // if there already is a same-named attribute, don't register anything
87 scoped_logger_attribute(BOOST_RV_REF(scoped_logger_attribute) that) :
88 m_pLogger(that.m_pLogger),
89 m_itAttribute(that.m_itAttribute)
95 ~scoped_logger_attribute()
98 m_pLogger->remove_attribute(m_itAttribute);
101 #ifndef BOOST_LOG_BROKEN_REFERENCE_FROM_RVALUE_INIT
102 BOOST_DELETED_FUNCTION(scoped_logger_attribute(scoped_logger_attribute const&))
103 #else // BOOST_LOG_BROKEN_REFERENCE_FROM_RVALUE_INIT
104 scoped_logger_attribute(scoped_logger_attribute const& that) : m_pLogger(that.m_pLogger), m_itAttribute(that.m_itAttribute)
106 const_cast< scoped_logger_attribute& >(that).m_pLogger = 0;
108 #endif // BOOST_LOG_BROKEN_REFERENCE_FROM_RVALUE_INIT
110 BOOST_DELETED_FUNCTION(scoped_logger_attribute& operator= (scoped_logger_attribute const&))
115 // Generator helper functions
117 * Registers an attribute in the logger
119 * \param l Logger to register the attribute in
120 * \param name Attribute name
121 * \param attr The attribute. Must not be NULL.
122 * \return An unspecified guard object which may be used to initialize a \c scoped_attribute variable.
124 template< typename LoggerT >
125 BOOST_FORCEINLINE aux::scoped_logger_attribute< LoggerT > add_scoped_logger_attribute(LoggerT& l, attribute_name const& name, attribute const& attr)
127 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
128 return aux::scoped_logger_attribute< LoggerT >(l, name, attr);
130 aux::scoped_logger_attribute< LoggerT > guard(l, name, attr);
131 return boost::move(guard);
135 #ifndef BOOST_LOG_DOXYGEN_PASS
137 #define BOOST_LOG_SCOPED_LOGGER_ATTR_INTERNAL(logger, attr_name, attr, sentry_var_name)\
138 BOOST_LOG_UNUSED_VARIABLE(::boost::log::scoped_attribute, sentry_var_name,\
139 = ::boost::log::add_scoped_logger_attribute(logger, attr_name, (attr)));
141 #endif // BOOST_LOG_DOXYGEN_PASS
143 //! The macro sets a scoped logger-wide attribute in a more compact way
144 #define BOOST_LOG_SCOPED_LOGGER_ATTR(logger, attr_name, attr)\
145 BOOST_LOG_SCOPED_LOGGER_ATTR_INTERNAL(\
149 BOOST_LOG_UNIQUE_IDENTIFIER_NAME(_boost_log_scoped_logger_attr_sentry_))
151 //! The macro sets a scoped logger-wide tag in a more compact way
152 #define BOOST_LOG_SCOPED_LOGGER_TAG(logger, attr_name, attr_value)\
153 BOOST_LOG_SCOPED_LOGGER_ATTR(logger, attr_name, ::boost::log::attributes::make_constant(attr_value))
157 //! A scoped thread-specific attribute guard
158 class scoped_thread_attribute :
159 public attribute_scope_guard
161 BOOST_COPYABLE_AND_MOVABLE_ALT(scoped_thread_attribute)
164 //! A pointer to the logging core
166 //! An iterator to the added attribute
167 attribute_set::iterator m_itAttribute;
171 scoped_thread_attribute(attribute_name const& name, attribute const& attr) :
175 attribute_set::iterator,
177 > res = m_pCore->add_thread_attribute(name, attr);
179 m_itAttribute = res.first;
181 m_pCore.reset(); // if there already is a same-named attribute, don't register anything
184 scoped_thread_attribute(BOOST_RV_REF(scoped_thread_attribute) that) : m_itAttribute(that.m_itAttribute)
186 m_pCore.swap(that.m_pCore);
190 ~scoped_thread_attribute()
193 m_pCore->remove_thread_attribute(m_itAttribute);
196 #ifndef BOOST_LOG_BROKEN_REFERENCE_FROM_RVALUE_INIT
197 BOOST_DELETED_FUNCTION(scoped_thread_attribute(scoped_thread_attribute const&))
198 #else // BOOST_LOG_BROKEN_REFERENCE_FROM_RVALUE_INIT
199 scoped_thread_attribute(scoped_thread_attribute const& that) : m_itAttribute(that.m_itAttribute)
201 m_pCore.swap(const_cast< scoped_thread_attribute& >(that).m_pCore);
203 #endif // BOOST_LOG_BROKEN_REFERENCE_FROM_RVALUE_INIT
205 BOOST_DELETED_FUNCTION(scoped_thread_attribute& operator= (scoped_thread_attribute const&))
210 // Generator helper functions
212 * Registers a thread-specific attribute
214 * \param name Attribute name
215 * \param attr The attribute. Must not be NULL.
216 * \return An unspecified guard object which may be used to initialize a \c scoped_attribute variable.
218 BOOST_FORCEINLINE aux::scoped_thread_attribute add_scoped_thread_attribute(attribute_name const& name, attribute const& attr)
220 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
221 return aux::scoped_thread_attribute(name, attr);
223 aux::scoped_thread_attribute guard(name, attr);
224 return boost::move(guard);
228 #ifndef BOOST_LOG_DOXYGEN_PASS
230 #define BOOST_LOG_SCOPED_THREAD_ATTR_INTERNAL(attr_name, attr, sentry_var_name)\
231 BOOST_LOG_UNUSED_VARIABLE(::boost::log::scoped_attribute, sentry_var_name,\
232 = ::boost::log::add_scoped_thread_attribute(attr_name, (attr)));
234 #endif // BOOST_LOG_DOXYGEN_PASS
236 //! The macro sets a scoped thread-wide attribute in a more compact way
237 #define BOOST_LOG_SCOPED_THREAD_ATTR(attr_name, attr)\
238 BOOST_LOG_SCOPED_THREAD_ATTR_INTERNAL(\
241 BOOST_LOG_UNIQUE_IDENTIFIER_NAME(_boost_log_scoped_thread_attr_sentry_))
243 //! The macro sets a scoped thread-wide tag in a more compact way
244 #define BOOST_LOG_SCOPED_THREAD_TAG(attr_name, attr_value)\
245 BOOST_LOG_SCOPED_THREAD_ATTR(attr_name, ::boost::log::attributes::make_constant(attr_value))
247 BOOST_LOG_CLOSE_NAMESPACE // namespace log
251 #include <boost/log/detail/footer.hpp>
253 #endif // BOOST_LOG_ATTRIBUTES_SCOPED_ATTRIBUTE_HPP_INCLUDED_