]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/log/include/boost/log/attributes/attribute_value.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / log / include / boost / log / attributes / attribute_value.hpp
1 /*
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)
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/type_index.hpp>
19 #include <boost/move/core.hpp>
20 #include <boost/smart_ptr/intrusive_ptr.hpp>
21 #include <boost/log/detail/config.hpp>
22 #include <boost/utility/explicit_operator_bool.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 typeindex::type_index get_type() const { return typeindex::type_index(); }
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 typeindex::type_index get_type() const
170 {
171 if (m_pImpl.get())
172 return m_pImpl->get_type();
173 else
174 return typeindex::type_index();
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_