Lumiera  0.pre.03
»edit your freedom«
typed-counter.hpp
Go to the documentation of this file.
1 /*
2  TYPED-COUNTER.hpp - maintain a set of type based contexts
3 
4  Copyright (C)
5  2009, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 */
13 
14 
50 #ifndef LIB_TYPED_COUNTER_H
51 #define LIB_TYPED_COUNTER_H
52 
53 #include "lib/error.hpp"
54 #include "lib/sync-classlock.hpp"
55 
56 #include <atomic>
57 #include <string>
58 #include <deque>
59 
60 
61 namespace util {
62  std::string showSize (size_t) noexcept;
63 }
64 
65 namespace lib {
66 
67  typedef size_t IxID;
68 
69  using std::deque;
70  using std::string;
71 
72 
85  template<class CX>
87  {
88  static IxID lastGeneratedTypeID;
89 
90  public:
91  static IxID
92  newTypeID (IxID& typeID)
93  {
94  ClassLock<TypedContext> synchronised;
95  if (!typeID)
96  typeID = ++lastGeneratedTypeID;
97  return typeID;
98  }
99 
101  template<typename TY>
102  class ID
103  {
104  static IxID typeID;
105 
106  public:
107  static IxID
108  get()
109  {
110  if (typeID)
111  return typeID;
112  else
113  return newTypeID(typeID);
114  }
115  };
116  };
117 
119  template<class CX>
121 
123  template<class CX>
124  template<typename TY>
126 
127 
128 
129 
140  : public Sync<>
141  {
142  mutable deque<std::atomic_int64_t> counters_;
143 
144  template<typename TY>
145  IxID
146  slot() const
147  {
149  if (size() < typeID)
150  { // protect against concurrent slot allocations
151  Lock sync{this};
152  if (size() < typeID)
153  counters_.resize (typeID);
154  }
155 
156  ENSURE (counters_.size() >= typeID);
157  return (typeID - 1);
158  }
159 
160 
161  public:
162  template<class X>
163  int64_t
164  get() const
165  {
166  return counters_[slot<X>()].load(std::memory_order_relaxed);
167  }
168 
169  template<class X>
170  int64_t
171  inc()
172  { // yields the value seen previously
173  return 1 + counters_[slot<X>()].fetch_add(+1, std::memory_order_relaxed);
174  }
175 
176  template<class X>
177  int64_t
178  dec()
179  {
180  return -1 + counters_[slot<X>()].fetch_add(-1, std::memory_order_relaxed);
181  }
182 
183 
184  /* == diagnostics == */
185 
186  size_t size() const { return counters_.size(); }
187  bool empty() const { return counters_.empty();}
188  };
189 
190 
191 
202  template<typename TY>
204  {
205  const size_t id_;
206 
208  static std::atomic_size_t memberCounter;
209 
211  static size_t
213  { // Note : returning previous value before increment
214  return memberCounter.fetch_add(+1, std::memory_order_relaxed);
215  }
216 
217  public:
218  FamilyMember()
219  : id_{allocateNextMember()}
220  { }
221 
222  operator size_t() const
223  {
224  return id_;
225  }
226 
227  operator string() const
228  {
229  return util::showSize (this->id_);
230  }
231 
232  friend string
233  operator+ (string const& prefix, FamilyMember id)
234  {
235  return prefix+string(id);
236  }
237 
238  friend string
239  operator+ (const char* prefix, FamilyMember id)
240  {
241  return string(prefix)+id;
242  }
243  };
244 
246  template<typename TY>
247  std::atomic_size_t FamilyMember<TY>::memberCounter{0};
248 
249 
250 
251 } // namespace lib
252 #endif
Facility for monitor object based locking.
Definition: sync.hpp:209
Utility providing a set of counters, each tied to a specific type.
static IxID lastGeneratedTypeID
storage for the type-ID generation mechanism
Implementation namespace for support and library code.
static size_t allocateNextMember()
threadsafe allocation of member ID
std::string operator+(std::string str, Literal const &sym)
string concatenation
Definition: symbol.hpp:213
static std::atomic_size_t memberCounter
member counter shared per template instance
A special implementation of lib::Sync, where the storage of the object monitor is associated directly...
Lumiera error handling (C++ interface).
A synchronisation protection guard employing a lock scoped to the parameter type as a whole...
Utility to produce member IDs for objects belonging to a "Family", as defined by a distinguishing typ...
static IxID typeID
table holding all the generated type-IDs
Provide type-IDs for a specific context.