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 counter.hpp
|
Chris@16
|
9 * \author Andrey Semashev
|
Chris@16
|
10 * \date 01.05.2007
|
Chris@16
|
11 *
|
Chris@16
|
12 * The header contains implementation of the counter attribute.
|
Chris@16
|
13 */
|
Chris@16
|
14
|
Chris@16
|
15 #ifndef BOOST_LOG_ATTRIBUTES_COUNTER_HPP_INCLUDED_
|
Chris@16
|
16 #define BOOST_LOG_ATTRIBUTES_COUNTER_HPP_INCLUDED_
|
Chris@16
|
17
|
Chris@16
|
18 #include <boost/static_assert.hpp>
|
Chris@16
|
19 #include <boost/type_traits/is_integral.hpp>
|
Chris@16
|
20 #include <boost/log/detail/config.hpp>
|
Chris@16
|
21 #include <boost/log/attributes/attribute.hpp>
|
Chris@16
|
22 #include <boost/log/attributes/attribute_cast.hpp>
|
Chris@16
|
23 #include <boost/log/attributes/attribute_value_impl.hpp>
|
Chris@16
|
24 #ifndef BOOST_LOG_NO_THREADS
|
Chris@16
|
25 #include <boost/detail/atomic_count.hpp>
|
Chris@16
|
26 #endif // BOOST_LOG_NO_THREADS
|
Chris@16
|
27 #include <boost/log/detail/header.hpp>
|
Chris@16
|
28
|
Chris@16
|
29 #ifdef BOOST_HAS_PRAGMA_ONCE
|
Chris@16
|
30 #pragma once
|
Chris@16
|
31 #endif
|
Chris@16
|
32
|
Chris@16
|
33 namespace boost {
|
Chris@16
|
34
|
Chris@16
|
35 BOOST_LOG_OPEN_NAMESPACE
|
Chris@16
|
36
|
Chris@16
|
37 namespace attributes {
|
Chris@16
|
38
|
Chris@16
|
39 /*!
|
Chris@16
|
40 * \brief A class of an attribute that counts an integral value
|
Chris@16
|
41 *
|
Chris@16
|
42 * This type of attribute acts as a counter, that is, it returns a monotonously
|
Chris@16
|
43 * changing value each time requested. The attribute value type can be specified
|
Chris@16
|
44 * as a template parameter. However, the type must be an integral type of size no
|
Chris@16
|
45 * more than <tt>sizeof(long)</tt>.
|
Chris@16
|
46 */
|
Chris@16
|
47 template< typename T >
|
Chris@16
|
48 class counter :
|
Chris@16
|
49 public attribute
|
Chris@16
|
50 {
|
Chris@16
|
51 // For now only integral types up to long are supported
|
Chris@16
|
52 BOOST_STATIC_ASSERT_MSG(is_integral< T >::value && sizeof(T) <= sizeof(long), "Boost.Log: Only integral types up to long are supported by counter attribute");
|
Chris@16
|
53
|
Chris@16
|
54 public:
|
Chris@16
|
55 //! A counter value type
|
Chris@16
|
56 typedef T value_type;
|
Chris@16
|
57
|
Chris@16
|
58 protected:
|
Chris@16
|
59 //! Base class for factory implementation
|
Chris@16
|
60 class BOOST_LOG_NO_VTABLE BOOST_SYMBOL_VISIBLE impl :
|
Chris@16
|
61 public attribute::impl
|
Chris@16
|
62 {
|
Chris@16
|
63 };
|
Chris@16
|
64
|
Chris@16
|
65 //! Generic factory implementation
|
Chris@16
|
66 class impl_generic;
|
Chris@16
|
67 #ifndef BOOST_LOG_NO_THREADS
|
Chris@16
|
68 //! Increment-by-one factory implementation
|
Chris@16
|
69 class impl_inc;
|
Chris@16
|
70 //! Decrement-by-one factory implementation
|
Chris@16
|
71 class impl_dec;
|
Chris@16
|
72 #endif
|
Chris@16
|
73
|
Chris@16
|
74 public:
|
Chris@16
|
75 /*!
|
Chris@16
|
76 * Constructor
|
Chris@16
|
77 *
|
Chris@16
|
78 * \param initial Initial value of the counter
|
Chris@16
|
79 * \param step Changing step of the counter. Each value acquired from the attribute
|
Chris@16
|
80 * will be greater than the previous one to this amount.
|
Chris@16
|
81 */
|
Chris@16
|
82 explicit counter(value_type initial = (value_type)0, long step = 1) :
|
Chris@16
|
83 #ifndef BOOST_LOG_NO_THREADS
|
Chris@16
|
84 attribute()
|
Chris@16
|
85 {
|
Chris@16
|
86 if (step == 1)
|
Chris@16
|
87 this->set_impl(new impl_inc(initial));
|
Chris@16
|
88 else if (step == -1)
|
Chris@16
|
89 this->set_impl(new impl_dec(initial));
|
Chris@16
|
90 else
|
Chris@16
|
91 this->set_impl(new impl_generic(initial, step));
|
Chris@16
|
92 }
|
Chris@16
|
93 #else
|
Chris@16
|
94 attribute(new impl_generic(initial, step))
|
Chris@16
|
95 {
|
Chris@16
|
96 }
|
Chris@16
|
97 #endif
|
Chris@16
|
98 /*!
|
Chris@16
|
99 * Constructor for casting support
|
Chris@16
|
100 */
|
Chris@16
|
101 explicit counter(cast_source const& source) :
|
Chris@16
|
102 attribute(source.as< impl >())
|
Chris@16
|
103 {
|
Chris@16
|
104 }
|
Chris@16
|
105 };
|
Chris@16
|
106
|
Chris@16
|
107 #ifndef BOOST_LOG_NO_THREADS
|
Chris@16
|
108
|
Chris@16
|
109 template< typename T >
|
Chris@16
|
110 class counter< T >::impl_generic :
|
Chris@16
|
111 public impl
|
Chris@16
|
112 {
|
Chris@16
|
113 private:
|
Chris@16
|
114 //! Initial value
|
Chris@16
|
115 const value_type m_Initial;
|
Chris@16
|
116 //! Step value
|
Chris@16
|
117 const long m_Step;
|
Chris@16
|
118 //! The counter
|
Chris@16
|
119 boost::detail::atomic_count m_Counter;
|
Chris@16
|
120
|
Chris@16
|
121 public:
|
Chris@16
|
122 /*!
|
Chris@16
|
123 * Initializing constructor
|
Chris@16
|
124 */
|
Chris@16
|
125 impl_generic(value_type initial, long step) : m_Initial(initial), m_Step(step), m_Counter(-1)
|
Chris@16
|
126 {
|
Chris@16
|
127 }
|
Chris@16
|
128
|
Chris@16
|
129 attribute_value get_value()
|
Chris@16
|
130 {
|
Chris@101
|
131 const unsigned long next_counter = static_cast< unsigned long >(++m_Counter);
|
Chris@101
|
132 value_type next = static_cast< value_type >(m_Initial + (next_counter * m_Step));
|
Chris@16
|
133 return make_attribute_value(next);
|
Chris@16
|
134 }
|
Chris@16
|
135 };
|
Chris@16
|
136
|
Chris@16
|
137 template< typename T >
|
Chris@16
|
138 class counter< T >::impl_inc :
|
Chris@16
|
139 public impl
|
Chris@16
|
140 {
|
Chris@16
|
141 private:
|
Chris@16
|
142 //! The counter
|
Chris@16
|
143 boost::detail::atomic_count m_Counter;
|
Chris@16
|
144
|
Chris@16
|
145 public:
|
Chris@16
|
146 /*!
|
Chris@16
|
147 * Initializing constructor
|
Chris@16
|
148 */
|
Chris@16
|
149 explicit impl_inc(value_type initial) : m_Counter(initial - 1)
|
Chris@16
|
150 {
|
Chris@16
|
151 }
|
Chris@16
|
152
|
Chris@16
|
153 attribute_value get_value()
|
Chris@16
|
154 {
|
Chris@16
|
155 return make_attribute_value(static_cast< value_type >(++m_Counter));
|
Chris@16
|
156 }
|
Chris@16
|
157 };
|
Chris@16
|
158
|
Chris@16
|
159 template< typename T >
|
Chris@16
|
160 class counter< T >::impl_dec :
|
Chris@16
|
161 public impl
|
Chris@16
|
162 {
|
Chris@16
|
163 private:
|
Chris@16
|
164 //! The counter
|
Chris@16
|
165 boost::detail::atomic_count m_Counter;
|
Chris@16
|
166
|
Chris@16
|
167 public:
|
Chris@16
|
168 /*!
|
Chris@16
|
169 * Initializing constructor
|
Chris@16
|
170 */
|
Chris@16
|
171 explicit impl_dec(value_type initial) : m_Counter(initial + 1)
|
Chris@16
|
172 {
|
Chris@16
|
173 }
|
Chris@16
|
174
|
Chris@16
|
175 attribute_value get_value()
|
Chris@16
|
176 {
|
Chris@16
|
177 return make_attribute_value(static_cast< value_type >(--m_Counter));
|
Chris@16
|
178 }
|
Chris@16
|
179 };
|
Chris@16
|
180
|
Chris@16
|
181 #else // BOOST_LOG_NO_THREADS
|
Chris@16
|
182
|
Chris@16
|
183 template< typename T >
|
Chris@16
|
184 class counter< T >::impl_generic :
|
Chris@16
|
185 public impl
|
Chris@16
|
186 {
|
Chris@16
|
187 private:
|
Chris@16
|
188 //! Step value
|
Chris@16
|
189 const long m_Step;
|
Chris@16
|
190 //! The counter
|
Chris@16
|
191 value_type m_Counter;
|
Chris@16
|
192
|
Chris@16
|
193 public:
|
Chris@16
|
194 /*!
|
Chris@16
|
195 * Initializing constructor
|
Chris@16
|
196 */
|
Chris@16
|
197 impl_generic(value_type initial, long step) : m_Step(step), m_Counter(initial - step)
|
Chris@16
|
198 {
|
Chris@16
|
199 }
|
Chris@16
|
200
|
Chris@16
|
201 attribute_value get_value()
|
Chris@16
|
202 {
|
Chris@16
|
203 m_Counter += m_Step;
|
Chris@16
|
204 return make_attribute_value(m_Counter);
|
Chris@16
|
205 }
|
Chris@16
|
206 };
|
Chris@16
|
207
|
Chris@16
|
208 #endif // BOOST_LOG_NO_THREADS
|
Chris@16
|
209
|
Chris@16
|
210 } // namespace attributes
|
Chris@16
|
211
|
Chris@16
|
212 BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
Chris@16
|
213
|
Chris@16
|
214 } // namespace boost
|
Chris@16
|
215
|
Chris@16
|
216 #include <boost/log/detail/footer.hpp>
|
Chris@16
|
217
|
Chris@16
|
218 #endif // BOOST_LOG_ATTRIBUTES_COUNTER_HPP_INCLUDED_
|