Corelink CPP Client
Corelink C++ client library
 
Loading...
Searching...
No Matches
concurrent_counter.hpp
Go to the documentation of this file.
1#pragma once
2
6
7namespace corelink
8{
9 namespace utils
10 {
15 template<class numeric_type = uint32_t>
16 class CORELINK_EXPORT concurrent_counter
17 {
18 private:
22 std::atomic<numeric_type> m_counter;
26 const numeric_type m_reset_value;
30 const numeric_type m_upper_bound;
34 const numeric_type m_lower_bound;
35
36 public:
40 typedef numeric_type counter_type;
41
42 // make sure that the type is an integral type
43 static_assert(std::is_integral<numeric_type>::value, "Not a integer numeric type");
44
53 : m_counter(0), m_reset_value(0), m_lower_bound(0),
54 m_upper_bound(std::numeric_limits<numeric_type>::max())
55 {}
56
62 explicit concurrent_counter(numeric_type upper_bound, numeric_type lower_bound)
63 : m_counter(0), m_reset_value(0), m_upper_bound(upper_bound), m_lower_bound(lower_bound)
64 {
65 }
66
73 concurrent_counter(numeric_type reset_value, numeric_type upper_bound, numeric_type lower_bound)
74 : m_counter(0), m_reset_value(reset_value), m_upper_bound(upper_bound), m_lower_bound(lower_bound)
75 {
76 }
77
85 concurrent_counter(numeric_type initial_value, numeric_type reset_value,
86 numeric_type upper_bound, numeric_type lower_bound)
87 : m_counter(initial_value), m_reset_value(reset_value), m_upper_bound(upper_bound),
88 m_lower_bound(lower_bound)
89 {
90 }
91
92 virtual ~concurrent_counter() = default;
93
98 inline std::atomic<numeric_type> &operator()()
99 {
100 return m_counter;
101 }
102
106 inline numeric_type operator++(int32_t)
107 {
108 if (m_counter < (m_upper_bound - 1)) return m_counter.fetch_add(1);
109
110 m_counter.store(m_reset_value);
111 return m_counter;
112 }
113
117 inline numeric_type operator++()
118 {
119 if (m_counter < (m_upper_bound - 1)) ++m_counter;
120 else m_counter.store(m_reset_value);
121 return m_counter;
122 }
123
127 inline numeric_type operator--(int32_t)
128 {
129 if (m_counter > m_lower_bound) return m_counter.fetch_sub(1);
130
131 m_counter.store(m_reset_value);
132 return m_counter;
133 }
134
138 inline numeric_type operator--()
139 {
140 if (m_counter > m_lower_bound) --m_counter;
141 else m_counter.store(m_reset_value);
142 return m_counter;
143 }
144
149 inline explicit operator numeric_type() const
150 {
151 return m_counter.load();
152 }
153
158 inline void reset()
159 {
160 m_counter.store(m_reset_value);
161 }
162
169 friend std::ostream &operator<<(std::ostream &os, const concurrent_counter &rhs)
170 {
171 os << rhs.m_counter;
172 return os;
173 }
174 };
175 }
176}