2 * Copyright Andrey Semashev 2007 - 2014.
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 attribute_value.hpp
9 * \author Andrey Semashev
12 * The header contains \c attribute_value class definition.
15 #ifndef BOOST_LOG_ATTRIBUTE_VALUE_HPP_INCLUDED_
16 #define BOOST_LOG_ATTRIBUTE_VALUE_HPP_INCLUDED_
18 #include <boost/move/core.hpp>
19 #include <boost/smart_ptr/intrusive_ptr.hpp>
20 #include <boost/log/detail/config.hpp>
21 #include <boost/utility/explicit_operator_bool.hpp>
22 #include <boost/log/utility/type_info_wrapper.hpp>
23 #include <boost/log/utility/type_dispatch/type_dispatcher.hpp>
24 #include <boost/log/attributes/attribute.hpp>
25 #include <boost/log/attributes/value_extraction_fwd.hpp>
26 #include <boost/log/attributes/value_visitation_fwd.hpp>
27 #include <boost/log/detail/header.hpp>
29 #ifdef BOOST_HAS_PRAGMA_ONCE
35 BOOST_LOG_OPEN_NAMESPACE
38 * \brief An attribute value class
40 * An attribute value is an object that contains a piece of data that represents an attribute state
41 * at the point of the value acquisition. All major operations with log records, such as filtering and
42 * formatting, involve attribute values contained in a single view. Most likely an attribute value is
43 * implemented as a simple holder of some typed value. This holder implements the
44 * \c attribute_value::implementation interface and acts as a pimpl for the \c attribute_value
45 * object. The \c attribute_value class provides type dispatching support in order to allow
46 * to extract the value from the holder.
48 * Normally, attributes and their values shall be designed in order to exclude as much interference as
49 * reasonable. Such approach allows to have more than one attribute value simultaneously, which improves
50 * scalability and allows to implement generating attributes.
52 * However, there are cases when this approach does not help to achieve the required level of independency
53 * of attribute values and attribute itself from each other at a reasonable performance tradeoff.
54 * For example, an attribute or its values may use thread-specific data, which is global and shared
55 * between all the instances of the attribute/value. Passing such an attribute value to another thread
56 * would be a disaster. To solve this the library defines an additional method for attribute values,
57 * namely \c detach_from_thread. The \c attribute_value class forwards the call to its pimpl,
58 * which is supposed to ensure that it no longer refers to any thread-specific data after the call.
59 * The pimpl can create a new holder as a result of this method and return it to the \c attribute_value
60 * wrapper, which will keep the returned reference for any further calls.
61 * This method is called for all attribute values that are passed to another thread.
65 BOOST_COPYABLE_AND_MOVABLE(attribute_value)
69 * \brief A base class for an attribute value implementation
71 * All attribute value holders should derive from this interface.
73 struct BOOST_LOG_NO_VTABLE impl :
74 public attribute::impl
78 * The method dispatches the value to the given object.
80 * \param dispatcher The object that attempts to dispatch the stored value.
81 * \return true if \a dispatcher was capable to consume the real attribute value type and false otherwise.
83 virtual bool dispatch(type_dispatcher& dispatcher) = 0;
86 * The method is called when the attribute value is passed to another thread (e.g.
87 * in case of asynchronous logging). The value should ensure it properly owns all thread-specific data.
89 * \return An actual pointer to the attribute value. It may either point to this object or another.
90 * In the latter case the returned pointer replaces the pointer used by caller to invoke this
91 * method and is considered to be a functional equivalent to the previous pointer.
93 virtual intrusive_ptr< impl > detach_from_thread()
99 * \return The attribute value that refers to self implementation.
101 virtual attribute_value get_value() { return attribute_value(this); }
104 * \return The attribute value type
106 virtual type_info_wrapper get_type() const { return type_info_wrapper(); }
110 //! Pointer to the value implementation
111 intrusive_ptr< impl > m_pImpl;
115 * Default constructor. Creates an empty (absent) attribute value.
117 BOOST_DEFAULTED_FUNCTION(attribute_value(), {})
122 attribute_value(attribute_value const& that) BOOST_NOEXCEPT : m_pImpl(that.m_pImpl) {}
127 attribute_value(BOOST_RV_REF(attribute_value) that) BOOST_NOEXCEPT { m_pImpl.swap(that.m_pImpl); }
130 * Initializing constructor. Creates an attribute value that refers to the specified holder.
132 * \param p A pointer to the attribute value holder.
134 explicit attribute_value(intrusive_ptr< impl > p) BOOST_NOEXCEPT { m_pImpl.swap(p); }
139 attribute_value& operator= (BOOST_COPY_ASSIGN_REF(attribute_value) that) BOOST_NOEXCEPT
141 m_pImpl = that.m_pImpl;
148 attribute_value& operator= (BOOST_RV_REF(attribute_value) that) BOOST_NOEXCEPT
150 m_pImpl.swap(that.m_pImpl);
155 * The operator checks if the attribute value is empty
157 BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
159 * The operator checks if the attribute value is empty
161 bool operator! () const BOOST_NOEXCEPT { return !m_pImpl; }
164 * The method returns the type information of the stored value of the attribute.
165 * The returned type info wrapper may be empty if the attribute value is empty or
166 * the information cannot be provided. If the returned value is not empty, the type
167 * can be used for value extraction.
169 type_info_wrapper get_type() const
172 return m_pImpl->get_type();
174 return type_info_wrapper();
178 * The method is called when the attribute value is passed to another thread (e.g.
179 * in case of asynchronous logging). The value should ensure it properly owns all thread-specific data.
181 * \post The attribute value no longer refers to any thread-specific resources.
183 void detach_from_thread()
186 m_pImpl->detach_from_thread().swap(m_pImpl);
190 * The method dispatches the value to the given object. This method is a low level interface for
191 * attribute value visitation and extraction. For typical usage these interfaces may be more convenient.
193 * \param dispatcher The object that attempts to dispatch the stored value.
194 * \return \c true if the value is not empty and the \a dispatcher was capable to consume
195 * the real attribute value type and \c false otherwise.
197 bool dispatch(type_dispatcher& dispatcher) const
200 return m_pImpl->dispatch(dispatcher);
205 #if !defined(BOOST_LOG_DOXYGEN_PASS)
206 #if !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
207 #define BOOST_LOG_AUX_VOID_DEFAULT = void
209 #define BOOST_LOG_AUX_VOID_DEFAULT
211 #endif // !defined(BOOST_LOG_DOXYGEN_PASS)
214 * The method attempts to extract the stored value, assuming the value has the specified type.
215 * One can specify either a single type or an MPL type sequence, in which case the stored value
216 * is checked against every type in the sequence.
218 * \note Include <tt>value_extraction.hpp</tt> prior to using this method.
220 * \return The extracted value, if the attribute value is not empty and the value is the same
221 * as specified. Otherwise returns an empty value. See description of the \c result_of::extract
222 * metafunction for information on the nature of the result value.
224 template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT >
225 typename result_of::extract< T, TagT >::type extract() const;
228 * The method attempts to extract the stored value, assuming the value has the specified type.
229 * One can specify either a single type or an MPL type sequence, in which case the stored value
230 * is checked against every type in the sequence.
232 * \note Include <tt>value_extraction.hpp</tt> prior to using this method.
234 * \return The extracted value, if the attribute value is not empty and the value is the same
235 * as specified. Otherwise an exception is thrown. See description of the \c result_of::extract_or_throw
236 * metafunction for information on the nature of the result value.
238 template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT >
239 typename result_of::extract_or_throw< T, TagT >::type extract_or_throw() const;
242 * The method attempts to extract the stored value, assuming the value has the specified type.
243 * One can specify either a single type or an MPL type sequence, in which case the stored value
244 * is checked against every type in the sequence. If extraction fails, the default value is returned.
246 * \note Include <tt>value_extraction.hpp</tt> prior to using this method.
248 * \param def_value Default value.
250 * \return The extracted value, if the attribute value is not empty and the value is the same
251 * as specified. Otherwise returns the default value. See description of the \c result_of::extract_or_default
252 * metafunction for information on the nature of the result value.
254 template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT >
255 typename result_of::extract_or_default< T, T, TagT >::type extract_or_default(T const& def_value) const;
258 * The method attempts to extract the stored value, assuming the value has the specified type.
259 * One can specify either a single type or an MPL type sequence, in which case the stored value
260 * is checked against every type in the sequence. If extraction fails, the default value is returned.
262 * \note Include <tt>value_extraction.hpp</tt> prior to using this method.
264 * \param def_value Default value.
266 * \return The extracted value, if the attribute value is not empty and the value is the same
267 * as specified. Otherwise returns the default value. See description of the \c result_of::extract_or_default
268 * metafunction for information on the nature of the result value.
270 template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT, typename DefaultT >
271 typename result_of::extract_or_default< T, DefaultT, TagT >::type extract_or_default(DefaultT const& def_value) const;
273 #if defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
275 * The method attempts to extract the stored value, assuming the value has the specified type.
276 * One can specify either a single type or an MPL type sequence, in which case the stored value
277 * is checked against every type in the sequence.
279 * \note Include <tt>value_extraction.hpp</tt> prior to using this method.
281 * \return The extracted value, if the attribute value is not empty and the value is the same
282 * as specified. Otherwise returns an empty value. See description of the \c result_of::extract
283 * metafunction for information on the nature of the result value.
285 template< typename T >
286 typename result_of::extract< T >::type extract() const;
289 * The method attempts to extract the stored value, assuming the value has the specified type.
290 * One can specify either a single type or an MPL type sequence, in which case the stored value
291 * is checked against every type in the sequence.
293 * \note Include <tt>value_extraction.hpp</tt> prior to using this method.
295 * \return The extracted value, if the attribute value is not empty and the value is the same
296 * as specified. Otherwise an exception is thrown. See description of the \c result_of::extract_or_throw
297 * metafunction for information on the nature of the result value.
299 template< typename T >
300 typename result_of::extract_or_throw< T >::type extract_or_throw() const;
303 * The method attempts to extract the stored value, assuming the value has the specified type.
304 * One can specify either a single type or an MPL type sequence, in which case the stored value
305 * is checked against every type in the sequence. If extraction fails, the default value is returned.
307 * \note Include <tt>value_extraction.hpp</tt> prior to using this method.
309 * \param def_value Default value.
311 * \return The extracted value, if the attribute value is not empty and the value is the same
312 * as specified. Otherwise returns the default value. See description of the \c result_of::extract_or_default
313 * metafunction for information on the nature of the result value.
315 template< typename T >
316 typename result_of::extract_or_default< T, T >::type extract_or_default(T const& def_value) const;
319 * The method attempts to extract the stored value, assuming the value has the specified type.
320 * One can specify either a single type or an MPL type sequence, in which case the stored value
321 * is checked against every type in the sequence. If extraction fails, the default value is returned.
323 * \note Include <tt>value_extraction.hpp</tt> prior to using this method.
325 * \param def_value Default value.
327 * \return The extracted value, if the attribute value is not empty and the value is the same
328 * as specified. Otherwise returns the default value. See description of the \c result_of::extract_or_default
329 * metafunction for information on the nature of the result value.
331 template< typename T, typename DefaultT >
332 typename result_of::extract_or_default< T, DefaultT >::type extract_or_default(DefaultT const& def_value) const;
333 #endif // defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
335 #undef BOOST_LOG_AUX_VOID_DEFAULT
338 * The method attempts to extract the stored value, assuming the value has the specified type,
339 * and pass it to the \a visitor function object.
340 * One can specify either a single type or an MPL type sequence, in which case the stored value
341 * is checked against every type in the sequence.
343 * \note Include <tt>value_visitation.hpp</tt> prior to using this method.
345 * \param visitor A function object that will be invoked on the extracted attribute value.
346 * The visitor should be capable to be called with a single argument of
347 * any type of the specified types in \c T.
349 * \return The result of visitation.
351 template< typename T, typename VisitorT >
352 visitation_result visit(VisitorT visitor) const;
355 * The method swaps two attribute values
357 void swap(attribute_value& that) BOOST_NOEXCEPT
359 m_pImpl.swap(that.m_pImpl);
364 * The function swaps two attribute values
366 inline void swap(attribute_value& left, attribute_value& right) BOOST_NOEXCEPT
371 BOOST_LOG_CLOSE_NAMESPACE // namespace log
375 #include <boost/log/detail/footer.hpp>
376 #if defined(BOOST_LOG_ATTRIBUTES_ATTRIBUTE_HPP_INCLUDED_)
377 #include <boost/log/detail/attribute_get_value_impl.hpp>
380 #endif // BOOST_LOG_ATTRIBUTE_VALUE_HPP_INCLUDED_