Back to home page

EIC code displayed by LXR

 
 

    


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

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   counter.hpp
0009  * \author Andrey Semashev
0010  * \date   01.05.2007
0011  *
0012  * The header contains implementation of the counter attribute.
0013  */
0014 
0015 #ifndef BOOST_LOG_ATTRIBUTES_COUNTER_HPP_INCLUDED_
0016 #define BOOST_LOG_ATTRIBUTES_COUNTER_HPP_INCLUDED_
0017 
0018 #include <boost/type_traits/is_integral.hpp>
0019 #include <boost/log/detail/config.hpp>
0020 #include <boost/log/attributes/attribute.hpp>
0021 #include <boost/log/attributes/attribute_cast.hpp>
0022 #include <boost/log/attributes/attribute_value_impl.hpp>
0023 #ifndef BOOST_LOG_NO_THREADS
0024 #include <boost/memory_order.hpp>
0025 #include <boost/atomic/atomic.hpp>
0026 #endif // BOOST_LOG_NO_THREADS
0027 #include <boost/log/detail/header.hpp>
0028 
0029 #ifdef BOOST_HAS_PRAGMA_ONCE
0030 #pragma once
0031 #endif
0032 
0033 namespace boost {
0034 
0035 BOOST_LOG_OPEN_NAMESPACE
0036 
0037 namespace attributes {
0038 
0039 /*!
0040  * \brief A class of an attribute that counts an integral value
0041  *
0042  * This attribute acts as a counter - it returns a monotonously
0043  * changing value each time requested. The attribute value type can be specified
0044  * as a template parameter. The type must be an integral type.
0045  */
0046 template< typename T >
0047 class counter :
0048     public attribute
0049 {
0050     static_assert(is_integral< T >::value, "Boost.Log: Only integral types are supported by the counter attribute");
0051 
0052 public:
0053     //! A counter value type
0054     typedef T value_type;
0055 
0056 protected:
0057     //! Factory implementation
0058     class BOOST_SYMBOL_VISIBLE impl :
0059         public attribute::impl
0060     {
0061     private:
0062 #ifndef BOOST_LOG_NO_THREADS
0063         boost::atomic< value_type > m_counter;
0064 #else
0065         value_type m_counter;
0066 #endif
0067         const value_type m_step;
0068 
0069     public:
0070         impl(value_type initial, value_type step) BOOST_NOEXCEPT :
0071             m_counter(initial), m_step(step)
0072         {
0073         }
0074 
0075         attribute_value get_value()
0076         {
0077 #ifndef BOOST_LOG_NO_THREADS
0078             value_type value = m_counter.fetch_add(m_step, boost::memory_order_relaxed);
0079 #else
0080             value_type value = m_counter;
0081             m_counter += m_step;
0082 #endif
0083             return make_attribute_value(value);
0084         }
0085     };
0086 
0087 public:
0088     /*!
0089      * Constructor
0090      *
0091      * \param initial Initial value of the counter
0092      * \param step Changing step of the counter. Each value acquired from the attribute
0093      *        will be greater than the previous one by this amount.
0094      */
0095     explicit counter(value_type initial = (value_type)0, value_type step = (value_type)1) :
0096         attribute(new impl(initial, step))
0097     {
0098     }
0099 
0100     /*!
0101      * Constructor for casting support
0102      */
0103     explicit counter(cast_source const& source) :
0104         attribute(source.as< impl >())
0105     {
0106     }
0107 };
0108 
0109 } // namespace attributes
0110 
0111 BOOST_LOG_CLOSE_NAMESPACE // namespace log
0112 
0113 } // namespace boost
0114 
0115 #include <boost/log/detail/footer.hpp>
0116 
0117 #endif // BOOST_LOG_ATTRIBUTES_COUNTER_HPP_INCLUDED_