Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:39:19

0001 /*
0002  *          Copyright Andrey Semashev 2007 - 2015.
0003  * Distributed under the Boost Software License, Version 1.0.
0004  *    (See accompanying file LICENSE_1_0.txt or copy at
0005  *          http://www.boost.org/LICENSE_1_0.txt)
0006  */
0007 /*!
0008  * \file   mutable_constant.hpp
0009  * \author Andrey Semashev
0010  * \date   06.11.2007
0011  *
0012  * The header contains implementation of a mutable constant attribute.
0013  */
0014 
0015 #ifndef BOOST_LOG_ATTRIBUTES_MUTABLE_CONSTANT_HPP_INCLUDED_
0016 #define BOOST_LOG_ATTRIBUTES_MUTABLE_CONSTANT_HPP_INCLUDED_
0017 
0018 #include <boost/smart_ptr/intrusive_ptr.hpp>
0019 #include <boost/move/core.hpp>
0020 #include <boost/move/utility_core.hpp>
0021 #include <boost/type_traits/is_void.hpp>
0022 #include <boost/type_traits/conditional.hpp>
0023 #include <boost/log/detail/config.hpp>
0024 #include <boost/log/detail/locks.hpp>
0025 #include <boost/log/attributes/attribute.hpp>
0026 #include <boost/log/attributes/attribute_cast.hpp>
0027 #include <boost/log/attributes/attribute_value_impl.hpp>
0028 #include <boost/log/detail/header.hpp>
0029 
0030 #ifdef BOOST_HAS_PRAGMA_ONCE
0031 #pragma once
0032 #endif
0033 
0034 namespace boost {
0035 
0036 BOOST_LOG_OPEN_NAMESPACE
0037 
0038 namespace attributes {
0039 
0040 /*!
0041  * \brief A class of an attribute that holds a single constant value with ability to change it
0042  *
0043  * The mutable_constant attribute stores a single value of type, specified as the first template argument.
0044  * This value is returned on each attribute value acquisition.
0045  *
0046  * The attribute also allows to modify the stored value, even if the attribute is registered in an attribute set.
0047  * In order to ensure thread safety of such modifications the \c mutable_constant class is also parametrized
0048  * with three additional template arguments: mutex type, scoped write and scoped read lock types. If not specified,
0049  * the lock types are automatically deduced based on the mutex type.
0050  *
0051  * The implementation may avoid using these types to actually create and use the mutex, if a more efficient synchronization method is
0052  * available (such as atomic operations on the value type). By default no synchronization is done.
0053  */
0054 #ifdef BOOST_LOG_DOXYGEN_PASS
0055 template< typename T, typename MutexT = void, typename ScopedWriteLockT = auto, typename ScopedReadLockT = auto >
0056 #else // BOOST_LOG_DOXYGEN_PASS
0057 template<
0058     typename T,
0059     typename MutexT = void,
0060     typename ScopedWriteLockT =
0061 #ifndef BOOST_LOG_NO_THREADS
0062         typename boost::conditional<
0063             boost::log::aux::is_exclusively_lockable< MutexT >::value,
0064             boost::log::aux::exclusive_lock_guard< MutexT >,
0065             void
0066         >::type,
0067 #else
0068         void,
0069 #endif // BOOST_LOG_NO_THREADS
0070     typename ScopedReadLockT =
0071 #ifndef BOOST_LOG_NO_THREADS
0072         typename boost::conditional<
0073             boost::log::aux::is_shared_lockable< MutexT >::value,
0074             boost::log::aux::shared_lock_guard< MutexT >,
0075             ScopedWriteLockT
0076         >::type
0077 #else
0078         ScopedWriteLockT
0079 #endif // BOOST_LOG_NO_THREADS
0080 #endif // BOOST_LOG_DOXYGEN_PASS
0081 >
0082 class mutable_constant :
0083     public attribute
0084 {
0085 public:
0086     //! The attribute value type
0087     typedef T value_type;
0088 
0089 protected:
0090     //! Factory implementation
0091     class BOOST_SYMBOL_VISIBLE impl :
0092         public attribute::impl
0093     {
0094     private:
0095         //! Mutex type
0096         typedef MutexT mutex_type;
0097         //! Shared lock type
0098         typedef ScopedReadLockT scoped_read_lock;
0099         //! Exclusive lock type
0100         typedef ScopedWriteLockT scoped_write_lock;
0101         static_assert(!(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");
0102         //! Attribute value wrapper
0103         typedef attribute_value_impl< value_type > attr_value;
0104 
0105     private:
0106         //! Thread protection mutex
0107         mutable mutex_type m_Mutex;
0108         //! Pointer to the actual attribute value
0109         intrusive_ptr< attr_value > m_Value;
0110 
0111     public:
0112         /*!
0113          * Initializing constructor
0114          */
0115         explicit impl(value_type const& value) : m_Value(new attr_value(value))
0116         {
0117         }
0118         /*!
0119          * Initializing constructor
0120          */
0121         explicit impl(BOOST_RV_REF(value_type) value) : m_Value(new attr_value(boost::move(value)))
0122         {
0123         }
0124 
0125         attribute_value get_value()
0126         {
0127             scoped_read_lock lock(m_Mutex);
0128             return attribute_value(m_Value);
0129         }
0130 
0131         void set(value_type const& value)
0132         {
0133             intrusive_ptr< attr_value > p = new attr_value(value);
0134             scoped_write_lock lock(m_Mutex);
0135             m_Value.swap(p);
0136         }
0137 
0138         void set(BOOST_RV_REF(value_type) value)
0139         {
0140             intrusive_ptr< attr_value > p = new attr_value(boost::move(value));
0141             scoped_write_lock lock(m_Mutex);
0142             m_Value.swap(p);
0143         }
0144 
0145         value_type get() const
0146         {
0147             scoped_read_lock lock(m_Mutex);
0148             return m_Value->get();
0149         }
0150     };
0151 
0152 public:
0153     /*!
0154      * Constructor with the stored value initialization
0155      */
0156     explicit mutable_constant(value_type const& value) : attribute(new impl(value))
0157     {
0158     }
0159     /*!
0160      * Constructor with the stored value initialization
0161      */
0162     explicit mutable_constant(BOOST_RV_REF(value_type) value) : attribute(new impl(boost::move(value)))
0163     {
0164     }
0165     /*!
0166      * Constructor for casting support
0167      */
0168     explicit mutable_constant(cast_source const& source) : attribute(source.as< impl >())
0169     {
0170     }
0171 
0172     /*!
0173      * The method sets a new attribute value. The implementation exclusively locks the mutex in order
0174      * to protect the value assignment.
0175      */
0176     void set(value_type const& value)
0177     {
0178         get_impl()->set(value);
0179     }
0180 
0181     /*!
0182      * The method sets a new attribute value.
0183      */
0184     void set(BOOST_RV_REF(value_type) value)
0185     {
0186         get_impl()->set(boost::move(value));
0187     }
0188 
0189     /*!
0190      * The method acquires the current attribute value. The implementation non-exclusively locks the mutex in order
0191      * to protect the value acquisition.
0192      */
0193     value_type get() const
0194     {
0195         return get_impl()->get();
0196     }
0197 
0198 protected:
0199     /*!
0200      * \returns Pointer to the factory implementation
0201      */
0202     impl* get_impl() const
0203     {
0204         return static_cast< impl* >(attribute::get_impl());
0205     }
0206 };
0207 
0208 
0209 /*!
0210  * \brief Specialization for unlocked case
0211  *
0212  * This version of attribute does not perform thread synchronization to access the stored value.
0213  */
0214 template< typename T >
0215 class mutable_constant< T, void, void, void > :
0216     public attribute
0217 {
0218 public:
0219     //! The attribute value type
0220     typedef T value_type;
0221 
0222 protected:
0223     //! Factory implementation
0224     class BOOST_SYMBOL_VISIBLE impl :
0225         public attribute::impl
0226     {
0227     private:
0228         //! Attribute value wrapper
0229         typedef attribute_value_impl< value_type > attr_value;
0230 
0231     private:
0232         //! The actual value
0233         intrusive_ptr< attr_value > m_Value;
0234 
0235     public:
0236         /*!
0237          * Initializing constructor
0238          */
0239         explicit impl(value_type const& value) : m_Value(new attr_value(value))
0240         {
0241         }
0242         /*!
0243          * Initializing constructor
0244          */
0245         explicit impl(BOOST_RV_REF(value_type) value) : m_Value(new attr_value(boost::move(value)))
0246         {
0247         }
0248 
0249         attribute_value get_value()
0250         {
0251             return attribute_value(m_Value);
0252         }
0253 
0254         void set(value_type const& value)
0255         {
0256             m_Value = new attr_value(value);
0257         }
0258         void set(BOOST_RV_REF(value_type) value)
0259         {
0260             m_Value = new attr_value(boost::move(value));
0261         }
0262 
0263         value_type get() const
0264         {
0265             return m_Value->get();
0266         }
0267     };
0268 
0269 public:
0270     /*!
0271      * Constructor with the stored value initialization
0272      */
0273     explicit mutable_constant(value_type const& value) : attribute(new impl(value))
0274     {
0275     }
0276     /*!
0277      * Constructor with the stored value initialization
0278      */
0279     explicit mutable_constant(BOOST_RV_REF(value_type) value) : attribute(new impl(boost::move(value)))
0280     {
0281     }
0282     /*!
0283      * Constructor for casting support
0284      */
0285     explicit mutable_constant(cast_source const& source) : attribute(source.as< impl >())
0286     {
0287     }
0288 
0289     /*!
0290      * The method sets a new attribute value.
0291      */
0292     void set(value_type const& value)
0293     {
0294         get_impl()->set(value);
0295     }
0296 
0297     /*!
0298      * The method sets a new attribute value.
0299      */
0300     void set(BOOST_RV_REF(value_type) value)
0301     {
0302         get_impl()->set(boost::move(value));
0303     }
0304 
0305     /*!
0306      * The method acquires the current attribute value.
0307      */
0308     value_type get() const
0309     {
0310         return get_impl()->get();
0311     }
0312 
0313 protected:
0314     /*!
0315      * \returns Pointer to the factory implementation
0316      */
0317     impl* get_impl() const
0318     {
0319         return static_cast< impl* >(attribute::get_impl());
0320     }
0321 };
0322 
0323 } // namespace attributes
0324 
0325 BOOST_LOG_CLOSE_NAMESPACE // namespace log
0326 
0327 } // namespace boost
0328 
0329 #include <boost/log/detail/footer.hpp>
0330 
0331 #endif // BOOST_LOG_ATTRIBUTES_MUTABLE_CONSTANT_HPP_INCLUDED_