Jpp 19.3.0-rc.3
the software that should make you happy
Loading...
Searching...
No Matches
JHashCollection.hh
Go to the documentation of this file.
1#ifndef __JTOOLS__JHASHCOLLECTION__
2#define __JTOOLS__JHASHCOLLECTION__
3
4#include <vector>
5
6#include "JLang/JException.hh"
7#include "JLang/JVectorize.hh"
9#include "JTools/JRouter.hh"
10
11
12/**
13 * \file
14 *
15 * General purpose class for a hash collection of unique elements.
16 * \author mdejong
17 */
18namespace JTOOLS {}
19namespace JPP { using namespace JTOOLS; }
20
21namespace JTOOLS {
22
26
27
28 /**
29 * General purpose class for hash collection of unique elements.
30 *
31 * The elements in a hash collection are unique according to the specified evaluation.\n
32 * The evaluation of elements corresponds to a unary method returning an integer value for a given element;\n
33 * The default evaluator is JHashEvaluator.
34 */
35 template<class JElement_t, class JEvaluator_t = JHashEvaluator>
37 public std::vector<JElement_t>
38 {
39 public:
40
41 typedef JElement_t value_type;
42 typedef JEvaluator_t evaluator_type;
43
45
46 typedef typename container_type::const_iterator const_iterator;
47 typedef typename container_type::const_reverse_iterator const_reverse_iterator;
48 typedef typename container_type::iterator iterator;
49 typedef typename container_type::reverse_iterator reverse_iterator;
50
51
52 /**
53 * Constructor.
54 *
55 * \param evaluator evaluator
56 */
57 JHashCollection(const JEvaluator_t& evaluator = JEvaluator_t()) :
58 getValue(evaluator)
59 {}
60
61
62 /**
63 * Constructor.
64 *
65 * \param buffer input data
66 * \param evaluator evaluator
67 */
68 template<class JAllocator_t>
70 const JEvaluator_t& evaluator = JEvaluator_t()) :
71 getValue(evaluator)
72 {
73 for (typename array_type<JElement_t, JAllocator_t>::const_iterator i = buffer.begin(); i != buffer.end(); ++i) {
74 insert(*i);
75 }
76 }
77
78
79 /**
80 * Assignment operator.
81 *
82 * \param collection hash collection
83 * \return this hash collection
84 */
86 {
87 for (const_iterator i = this->begin(); i != this->end(); ++i) {
88 router.put(this->getValue(*i), router.getDefaultAddress());
89 }
90
91 container_type::assign(collection.begin(), collection.end());
92
93 router.align(collection.router);
94
95 getValue = collection.getValue;
96
97 for (iterator i = this->begin(); i != this->end(); ++i) {
98 router.put(this->getValue(*i), std::distance(this->begin(), i));
99 }
100
101 return *this;
102 }
103
104
105 /**
106 * Clear.
107 */
108 void clear()
109 {
110 for (const_iterator i = this->begin(); i != this->end(); ++i) {
111 router.put(this->getValue(*i), router.getDefaultAddress());
112 }
113
114 container_type::clear();
115 }
116
117
118 /**
119 * Swap hash collection.
120 *
121 * \param collection hash collection
122 */
123 void swap(JHashCollection& collection)
124 {
125 router.swap(collection.router);
126
127 container_type::swap(collection);
128 }
129
130
131 /**
132 * Find element with given value.
133 *
134 * \param value value
135 * \return position of element with given value or end()
136 */
137 template<class T>
138 const_iterator find(const T& value) const
139 {
140 const int ival = this->getValue(value);
141
142 if (router.has(ival))
143 return this->begin() + router.get(ival);
144 else
145 return this->end();
146 }
147
148
149 /**
150 * Find element with given value.
151 *
152 * \param value value
153 * \return position of element with given value or end()
154 */
155 template<class T>
156 iterator find(const T& value)
157 {
158 const int ival = this->getValue(value);
159
160 if (router.has(ival))
161 return this->begin() + router.get(ival);
162 else
163 return this->end();
164 }
165
166
167 /**
168 * Get element with given value.
169 *
170 * This method will throw an exception if given value is not present following the prerequisite of constness.
171 *
172 * \param value value
173 * \return element
174 */
175 template<class T>
176 value_type& get(const T& value)
177 {
178 const int ival = this->getValue(value);
179
180 if (!router.has(ival)) {
181 this->insert(value);
182 }
183
184 return container_type::operator[](router.get(ival)).second;
185 }
186
187
188 /**
189 * Get element with given value.
190 *
191 * This method will throw an exception if given value is not present following the prerequisite of constness.
192 *
193 * \param value value
194 * \return element
195 */
196 template<class T>
197 const value_type& get(const T& value) const
198 {
199 const int ival = this->getValue(value);
200
201 if (router.has(ival)) {
202 return container_type::operator[](router.get(ival)).second;
203 }
204
205 THROW(JIndexOutOfRange, "JHashCollection::get(): invalid value.");
206 }
207
208
209 /**
210 * Insert element.
211 *
212 * \param element element
213 * \return true if inserted; else false
214 */
215 virtual bool insert(const value_type& element)
216 {
217 const int ival = this->getValue(element);
218
219 if (!router.has(ival)) {
220
221 container_type::push_back(element);
222
223 router.put(ival, this->size() - 1);
224
225 return true;
226 }
227
228 return false;
229 }
230
231
232 /**
233 * Insert values.
234 *
235 * \param __begin begin of values
236 * \param __end end of values
237 */
238 template<class T>
239 void insert(T __begin, T __end)
240 {
241 for (T i = __begin; i != __end; ++i) {
242 insert(*i);
243 }
244 }
245
246
247 /**
248 * Erase element at given position.
249 *
250 * \param pos valid position
251 */
252 void erase(iterator pos)
253 {
254 router.put(this->getValue(*pos), router.getDefaultAddress());
255
256 for (iterator i = container_type::erase(pos); i != this->end(); ++i) {
257 router.put(this->getValue(*i), distance(this->begin(), i));
258 }
259 }
260
261
262 /**
263 * Erase elements in given range.
264 *
265 * \param __begin begin position (included)
266 * \param __end end position (excluded)
267 */
268 void erase(iterator __begin, iterator __end)
269 {
270 for (iterator i = __begin; i != __end; ++i) {
271 router.put(this->getValue(*i), router.getDefaultAddress());
272 }
273
274 for (iterator i = container_type::erase(__begin, __end); i != this->end(); ++i) {
275 router.put(this->getValue(*i), distance(this->begin(), i));
276 }
277 }
278
279
280 /**
281 * Erase element with given value.
282 *
283 * \param value value
284 * \return true if element has been erased; else false
285 */
286 template<class T>
287 bool erase(const T& value)
288 {
289 const int ival = this->getValue(value);
290
291 if (router.has(ival)) {
292
293 this->erase(this->begin() + router.get(ival));
294
295 return true;
296 }
297
298 return false;
299 }
300
301
302 /**
303 * Test whether given value is present.
304 *
305 * \param value value
306 * \return true if present; else false
307 */
308 template<class T>
309 bool has(const T& value) const
310 {
311 return router.has(this->getValue(value));
312 }
313
314
315 /**
316 * Get index of given value.
317 *
318 * \param value value
319 * \return indecx
320 */
321 template<class T>
322 int getIndex(const T& value) const
323 {
324 return router.get(this->getValue(value));
325 }
326
327
328 /**
329 * Function object for evaluation of element.
330 */
331 JEvaluator_t getValue;
332
333
334 protected:
335 /**
336 * Internal router.
337 */
338 struct router_type :
339 public JRouter<int>
340 {
341 /**
342 * Default constructor.
343 */
345 JRouter<int>(-1) // default address
346 {}
348
349 private:
350 void operator[](int);
351 void assign();
352 void resize();
353 void push_back();
354 void pop_back();
355 };
356}
357
358#endif
Exceptions.
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Auxiliary methods to convert data members or return values of member methods of a set of objects to a...
std::vector< T >::difference_type distance(typename std::vector< T >::const_iterator first, typename PhysicsEvent::const_iterator< T > second)
Specialisation of STL distance.
Exception for accessing an index in a collection that is outside of its range.
General purpose class for hash collection of unique elements.
bool has(const T &value) const
Test whether given value is present.
int getIndex(const T &value) const
Get index of given value.
std::vector< value_type > container_type
bool erase(const T &value)
Erase element with given value.
container_type::iterator iterator
iterator find(const T &value)
Find element with given value.
JHashCollection & operator=(const JHashCollection &collection)
Assignment operator.
container_type::const_reverse_iterator const_reverse_iterator
JEvaluator_t getValue
Function object for evaluation of element.
void swap(JHashCollection &collection)
Swap hash collection.
virtual bool insert(const value_type &element)
Insert element.
const value_type & get(const T &value) const
Get element with given value.
const_iterator find(const T &value) const
Find element with given value.
JHashCollection(const array_type< JElement_t, JAllocator_t > &buffer, const JEvaluator_t &evaluator=JEvaluator_t())
Constructor.
void erase(iterator __begin, iterator __end)
Erase elements in given range.
void insert(T __begin, T __end)
Insert values.
container_type::const_iterator const_iterator
value_type & get(const T &value)
Get element with given value.
container_type::reverse_iterator reverse_iterator
JTOOLS::JHashCollection::router_type router
JHashCollection(const JEvaluator_t &evaluator=JEvaluator_t())
Constructor.
void erase(iterator pos)
Erase element at given position.
Direct addressing of elements with unique identifiers.
Definition JRouter.hh:27
const array_type< JValue_t > & make_array(const JValue_t(&array)[N])
Method to create array of values.
Definition JVectorize.hh:54
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Auxiliary classes and methods for multi-dimensional interpolations and histograms.
Auxiliary data structure for return type of make methods.
Definition JVectorize.hh:28