Imported Upstream version 1.57.0
[platform/upstream/boost.git] / boost / log / attributes / attribute_value.hpp
1 /*
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)
6  */
7 /*!
8  * \file   attribute_value.hpp
9  * \author Andrey Semashev
10  * \date   21.05.2010
11  *
12  * The header contains \c attribute_value class definition.
13  */
14
15 #ifndef BOOST_LOG_ATTRIBUTE_VALUE_HPP_INCLUDED_
16 #define BOOST_LOG_ATTRIBUTE_VALUE_HPP_INCLUDED_
17
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>
28
29 #ifdef BOOST_HAS_PRAGMA_ONCE
30 #pragma once
31 #endif
32
33 namespace boost {
34
35 BOOST_LOG_OPEN_NAMESPACE
36
37 /*!
38  * \brief An attribute value class
39  *
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.
47  *
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.
51  *
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.
62  */
63 class attribute_value
64 {
65     BOOST_COPYABLE_AND_MOVABLE(attribute_value)
66
67 public:
68     /*!
69      * \brief A base class for an attribute value implementation
70      *
71      * All attribute value holders should derive from this interface.
72      */
73     struct BOOST_LOG_NO_VTABLE impl :
74         public attribute::impl
75     {
76     public:
77         /*!
78          * The method dispatches the value to the given object.
79          *
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.
82          */
83         virtual bool dispatch(type_dispatcher& dispatcher) = 0;
84
85         /*!
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.
88          *
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.
92          */
93         virtual intrusive_ptr< impl > detach_from_thread()
94         {
95             return this;
96         }
97
98         /*!
99          * \return The attribute value that refers to self implementation.
100          */
101         virtual attribute_value get_value() { return attribute_value(this); }
102
103         /*!
104          * \return The attribute value type
105          */
106         virtual type_info_wrapper get_type() const { return type_info_wrapper(); }
107     };
108
109 private:
110     //! Pointer to the value implementation
111     intrusive_ptr< impl > m_pImpl;
112
113 public:
114     /*!
115      * Default constructor. Creates an empty (absent) attribute value.
116      */
117     BOOST_DEFAULTED_FUNCTION(attribute_value(), {})
118
119     /*!
120      * Copy constructor
121      */
122     attribute_value(attribute_value const& that) BOOST_NOEXCEPT : m_pImpl(that.m_pImpl) {}
123
124     /*!
125      * Move constructor
126      */
127     attribute_value(BOOST_RV_REF(attribute_value) that) BOOST_NOEXCEPT { m_pImpl.swap(that.m_pImpl); }
128
129     /*!
130      * Initializing constructor. Creates an attribute value that refers to the specified holder.
131      *
132      * \param p A pointer to the attribute value holder.
133      */
134     explicit attribute_value(intrusive_ptr< impl > p) BOOST_NOEXCEPT { m_pImpl.swap(p); }
135
136     /*!
137      * Copy assignment
138      */
139     attribute_value& operator= (BOOST_COPY_ASSIGN_REF(attribute_value) that) BOOST_NOEXCEPT
140     {
141         m_pImpl = that.m_pImpl;
142         return *this;
143     }
144
145     /*!
146      * Move assignment
147      */
148     attribute_value& operator= (BOOST_RV_REF(attribute_value) that) BOOST_NOEXCEPT
149     {
150         m_pImpl.swap(that.m_pImpl);
151         return *this;
152     }
153
154     /*!
155      * The operator checks if the attribute value is empty
156      */
157     BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
158     /*!
159      * The operator checks if the attribute value is empty
160      */
161     bool operator! () const BOOST_NOEXCEPT { return !m_pImpl; }
162
163     /*!
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.
168      */
169     type_info_wrapper get_type() const
170     {
171         if (m_pImpl.get())
172             return m_pImpl->get_type();
173         else
174             return type_info_wrapper();
175     }
176
177     /*!
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.
180      *
181      * \post The attribute value no longer refers to any thread-specific resources.
182      */
183     void detach_from_thread()
184     {
185         if (m_pImpl.get())
186             m_pImpl->detach_from_thread().swap(m_pImpl);
187     }
188
189     /*!
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.
192      *
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.
196      */
197     bool dispatch(type_dispatcher& dispatcher) const
198     {
199         if (m_pImpl.get())
200             return m_pImpl->dispatch(dispatcher);
201         else
202             return false;
203     }
204
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
208 #else
209 #define BOOST_LOG_AUX_VOID_DEFAULT
210 #endif
211 #endif // !defined(BOOST_LOG_DOXYGEN_PASS)
212
213     /*!
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.
217      *
218      * \note Include <tt>value_extraction.hpp</tt> prior to using this method.
219      *
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.
223      */
224     template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT >
225     typename result_of::extract< T, TagT >::type extract() const;
226
227     /*!
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.
231      *
232      * \note Include <tt>value_extraction.hpp</tt> prior to using this method.
233      *
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.
237      */
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;
240
241     /*!
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.
245      *
246      * \note Include <tt>value_extraction.hpp</tt> prior to using this method.
247      *
248      * \param def_value Default value.
249      *
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.
253      */
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;
256
257     /*!
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.
261      *
262      * \note Include <tt>value_extraction.hpp</tt> prior to using this method.
263      *
264      * \param def_value Default value.
265      *
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.
269      */
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;
272
273 #if defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
274     /*!
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.
278      *
279      * \note Include <tt>value_extraction.hpp</tt> prior to using this method.
280      *
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.
284      */
285     template< typename T >
286     typename result_of::extract< T >::type extract() const;
287
288     /*!
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.
292      *
293      * \note Include <tt>value_extraction.hpp</tt> prior to using this method.
294      *
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.
298      */
299     template< typename T >
300     typename result_of::extract_or_throw< T >::type extract_or_throw() const;
301
302     /*!
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.
306      *
307      * \note Include <tt>value_extraction.hpp</tt> prior to using this method.
308      *
309      * \param def_value Default value.
310      *
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.
314      */
315     template< typename T >
316     typename result_of::extract_or_default< T, T >::type extract_or_default(T const& def_value) const;
317
318     /*!
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.
322      *
323      * \note Include <tt>value_extraction.hpp</tt> prior to using this method.
324      *
325      * \param def_value Default value.
326      *
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.
330      */
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)
334
335 #undef BOOST_LOG_AUX_VOID_DEFAULT
336
337     /*!
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.
342      *
343      * \note Include <tt>value_visitation.hpp</tt> prior to using this method.
344      *
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.
348      *
349      * \return The result of visitation.
350      */
351     template< typename T, typename VisitorT >
352     visitation_result visit(VisitorT visitor) const;
353
354     /*!
355      * The method swaps two attribute values
356      */
357     void swap(attribute_value& that) BOOST_NOEXCEPT
358     {
359         m_pImpl.swap(that.m_pImpl);
360     }
361 };
362
363 /*!
364  * The function swaps two attribute values
365  */
366 inline void swap(attribute_value& left, attribute_value& right) BOOST_NOEXCEPT
367 {
368     left.swap(right);
369 }
370
371 BOOST_LOG_CLOSE_NAMESPACE // namespace log
372
373 } // namespace boost
374
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>
378 #endif
379
380 #endif // BOOST_LOG_ATTRIBUTE_VALUE_HPP_INCLUDED_