]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/log/include/boost/log/attributes/mutable_constant.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / log / include / boost / log / attributes / mutable_constant.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 mutable_constant.hpp
9 * \author Andrey Semashev
10 * \date 06.11.2007
11 *
12 * The header contains implementation of a mutable constant attribute.
13 */
14
15 #ifndef BOOST_LOG_ATTRIBUTES_MUTABLE_CONSTANT_HPP_INCLUDED_
16 #define BOOST_LOG_ATTRIBUTES_MUTABLE_CONSTANT_HPP_INCLUDED_
17
18 #include <boost/static_assert.hpp>
19 #include <boost/smart_ptr/intrusive_ptr.hpp>
20 #include <boost/mpl/if.hpp>
21 #include <boost/move/core.hpp>
22 #include <boost/move/utility_core.hpp>
23 #include <boost/type_traits/is_void.hpp>
24 #include <boost/log/detail/config.hpp>
25 #include <boost/log/detail/locks.hpp>
26 #include <boost/log/attributes/attribute.hpp>
27 #include <boost/log/attributes/attribute_cast.hpp>
28 #include <boost/log/attributes/attribute_value_impl.hpp>
29 #include <boost/log/detail/header.hpp>
30
31 #ifdef BOOST_HAS_PRAGMA_ONCE
32 #pragma once
33 #endif
34
35 namespace boost {
36
37 BOOST_LOG_OPEN_NAMESPACE
38
39 namespace attributes {
40
41 /*!
42 * \brief A class of an attribute that holds a single constant value with ability to change it
43 *
44 * The mutable_constant attribute stores a single value of type, specified as the first template argument.
45 * This value is returned on each attribute value acquisition.
46 *
47 * The attribute also allows to modify the stored value, even if the attribute is registered in an attribute set.
48 * In order to ensure thread safety of such modifications the \c mutable_constant class is also parametrized
49 * with three additional template arguments: mutex type, scoped write and scoped read lock types. If not specified,
50 * the lock types are automatically deduced based on the mutex type.
51 *
52 * The implementation may avoid using these types to actually create and use the mutex, if a more efficient synchronization method is
53 * available (such as atomic operations on the value type). By default no synchronization is done.
54 */
55 #ifdef BOOST_LOG_DOXYGEN_PASS
56 template< typename T, typename MutexT = void, typename ScopedWriteLockT = auto, typename ScopedReadLockT = auto >
57 #else // BOOST_LOG_DOXYGEN_PASS
58 template<
59 typename T,
60 typename MutexT = void,
61 typename ScopedWriteLockT =
62 #ifndef BOOST_LOG_NO_THREADS
63 typename mpl::if_c<
64 boost::log::aux::is_exclusively_lockable< MutexT >::value,
65 boost::log::aux::exclusive_lock_guard< MutexT >,
66 void
67 >::type,
68 #else
69 void,
70 #endif // BOOST_LOG_NO_THREADS
71 typename ScopedReadLockT =
72 #ifndef BOOST_LOG_NO_THREADS
73 typename mpl::if_c<
74 boost::log::aux::is_shared_lockable< MutexT >::value,
75 boost::log::aux::shared_lock_guard< MutexT >,
76 ScopedWriteLockT
77 >::type
78 #else
79 ScopedWriteLockT
80 #endif // BOOST_LOG_NO_THREADS
81 #endif // BOOST_LOG_DOXYGEN_PASS
82 >
83 class mutable_constant :
84 public attribute
85 {
86 public:
87 //! The attribute value type
88 typedef T value_type;
89
90 protected:
91 //! Factory implementation
92 class BOOST_SYMBOL_VISIBLE impl :
93 public attribute::impl
94 {
95 private:
96 //! Mutex type
97 typedef MutexT mutex_type;
98 //! Shared lock type
99 typedef ScopedReadLockT scoped_read_lock;
100 //! Exclusive lock type
101 typedef ScopedWriteLockT scoped_write_lock;
102 BOOST_STATIC_ASSERT_MSG(!(is_void< mutex_type >::value || is_void< scoped_read_lock >::value || is_void< scoped_write_lock >::value), "Boost.Log: Mutex and both lock types either must not be void or must all be void");
103 //! Attribute value wrapper
104 typedef attribute_value_impl< value_type > attr_value;
105
106 private:
107 //! Thread protection mutex
108 mutable mutex_type m_Mutex;
109 //! Pointer to the actual attribute value
110 intrusive_ptr< attr_value > m_Value;
111
112 public:
113 /*!
114 * Initializing constructor
115 */
116 explicit impl(value_type const& value) : m_Value(new attr_value(value))
117 {
118 }
119 /*!
120 * Initializing constructor
121 */
122 explicit impl(BOOST_RV_REF(value_type) value) : m_Value(new attr_value(boost::move(value)))
123 {
124 }
125
126 attribute_value get_value()
127 {
128 scoped_read_lock lock(m_Mutex);
129 return attribute_value(m_Value);
130 }
131
132 void set(value_type const& value)
133 {
134 intrusive_ptr< attr_value > p = new attr_value(value);
135 scoped_write_lock lock(m_Mutex);
136 m_Value.swap(p);
137 }
138
139 void set(BOOST_RV_REF(value_type) value)
140 {
141 intrusive_ptr< attr_value > p = new attr_value(boost::move(value));
142 scoped_write_lock lock(m_Mutex);
143 m_Value.swap(p);
144 }
145
146 value_type get() const
147 {
148 scoped_read_lock lock(m_Mutex);
149 return m_Value->get();
150 }
151 };
152
153 public:
154 /*!
155 * Constructor with the stored value initialization
156 */
157 explicit mutable_constant(value_type const& value) : attribute(new impl(value))
158 {
159 }
160 /*!
161 * Constructor with the stored value initialization
162 */
163 explicit mutable_constant(BOOST_RV_REF(value_type) value) : attribute(new impl(boost::move(value)))
164 {
165 }
166 /*!
167 * Constructor for casting support
168 */
169 explicit mutable_constant(cast_source const& source) : attribute(source.as< impl >())
170 {
171 }
172
173 /*!
174 * The method sets a new attribute value. The implementation exclusively locks the mutex in order
175 * to protect the value assignment.
176 */
177 void set(value_type const& value)
178 {
179 get_impl()->set(value);
180 }
181
182 /*!
183 * The method sets a new attribute value.
184 */
185 void set(BOOST_RV_REF(value_type) value)
186 {
187 get_impl()->set(boost::move(value));
188 }
189
190 /*!
191 * The method acquires the current attribute value. The implementation non-exclusively locks the mutex in order
192 * to protect the value acquisition.
193 */
194 value_type get() const
195 {
196 return get_impl()->get();
197 }
198
199 protected:
200 /*!
201 * \returns Pointer to the factory implementation
202 */
203 impl* get_impl() const
204 {
205 return static_cast< impl* >(attribute::get_impl());
206 }
207 };
208
209
210 /*!
211 * \brief Specialization for unlocked case
212 *
213 * This version of attribute does not perform thread synchronization to access the stored value.
214 */
215 template< typename T >
216 class mutable_constant< T, void, void, void > :
217 public attribute
218 {
219 public:
220 //! The attribute value type
221 typedef T value_type;
222
223 protected:
224 //! Factory implementation
225 class BOOST_SYMBOL_VISIBLE impl :
226 public attribute::impl
227 {
228 private:
229 //! Attribute value wrapper
230 typedef attribute_value_impl< value_type > attr_value;
231
232 private:
233 //! The actual value
234 intrusive_ptr< attr_value > m_Value;
235
236 public:
237 /*!
238 * Initializing constructor
239 */
240 explicit impl(value_type const& value) : m_Value(new attr_value(value))
241 {
242 }
243 /*!
244 * Initializing constructor
245 */
246 explicit impl(BOOST_RV_REF(value_type) value) : m_Value(new attr_value(boost::move(value)))
247 {
248 }
249
250 attribute_value get_value()
251 {
252 return attribute_value(m_Value);
253 }
254
255 void set(value_type const& value)
256 {
257 m_Value = new attr_value(value);
258 }
259 void set(BOOST_RV_REF(value_type) value)
260 {
261 m_Value = new attr_value(boost::move(value));
262 }
263
264 value_type get() const
265 {
266 return m_Value->get();
267 }
268 };
269
270 public:
271 /*!
272 * Constructor with the stored value initialization
273 */
274 explicit mutable_constant(value_type const& value) : attribute(new impl(value))
275 {
276 }
277 /*!
278 * Constructor with the stored value initialization
279 */
280 explicit mutable_constant(BOOST_RV_REF(value_type) value) : attribute(new impl(boost::move(value)))
281 {
282 }
283 /*!
284 * Constructor for casting support
285 */
286 explicit mutable_constant(cast_source const& source) : attribute(source.as< impl >())
287 {
288 }
289
290 /*!
291 * The method sets a new attribute value.
292 */
293 void set(value_type const& value)
294 {
295 get_impl()->set(value);
296 }
297
298 /*!
299 * The method sets a new attribute value.
300 */
301 void set(BOOST_RV_REF(value_type) value)
302 {
303 get_impl()->set(boost::move(value));
304 }
305
306 /*!
307 * The method acquires the current attribute value.
308 */
309 value_type get() const
310 {
311 return get_impl()->get();
312 }
313
314 protected:
315 /*!
316 * \returns Pointer to the factory implementation
317 */
318 impl* get_impl() const
319 {
320 return static_cast< impl* >(attribute::get_impl());
321 }
322 };
323
324 } // namespace attributes
325
326 BOOST_LOG_CLOSE_NAMESPACE // namespace log
327
328 } // namespace boost
329
330 #include <boost/log/detail/footer.hpp>
331
332 #endif // BOOST_LOG_ATTRIBUTES_MUTABLE_CONSTANT_HPP_INCLUDED_