annotate DEPENDENCIES/generic/include/boost/log/attributes/mutable_constant.hpp @ 133:4acb5d8d80b6 tip

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