Jpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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"
8 #include "JTools/JRouter.hh"
9 
10 
11 /**
12  * \file
13  *
14  * General purpose class for a hash collection of unique elements.
15  * \author mdejong
16  */
17 namespace JTOOLS {}
18 namespace JPP { using namespace JTOOLS; }
19 
20 namespace JTOOLS {
21 
23 
24 
25  /**
26  * General purpose class for hash collection of unique elements.
27  *
28  * The elements in a hash collection are unique according to the specified evaluation.
29  * The evaluation of elements corresponds to a unary method returning an integer value for a given element;
30  * The default evaluator is JHashEvaluator.
31  */
32  template<class JElement_t, class JEvaluator_t = JHashEvaluator>
34  public std::vector<JElement_t>
35  {
36  public:
37 
38  typedef JElement_t value_type;
39  typedef JEvaluator_t evaluator_type;
40 
42 
43  typedef typename container_type::const_iterator const_iterator;
44  typedef typename container_type::const_reverse_iterator const_reverse_iterator;
45  typedef typename container_type::iterator iterator;
46  typedef typename container_type::reverse_iterator reverse_iterator;
47 
48 
49  /**
50  * Constructor.
51  *
52  * \param evaluator evaluator
53  */
54  JHashCollection(const JEvaluator_t& evaluator = JEvaluator_t()) :
55  getValue(evaluator),
56  router (-1) // default address
57  {}
58 
59 
60  /**
61  * Assignment operator.
62  *
63  * \param buffer hash collection
64  * \return this hash collection
65  */
67  {
68  for (const_iterator i = this->begin(); i != this->end(); ++i) {
69  router.put(this->getValue(*i), router.getDefaultAddress());
70  }
71 
72  static_cast<container_type&>(*this) = static_cast<const container_type&>(buffer);
73 
74  router.copy(buffer.router, false);
75 
76  for (iterator i = this->begin(); i != this->end(); ++i) {
77  router.put(this->getValue(*i), std::distance(this->begin(), i));
78  }
79 
80  return *this;
81  }
82 
83 
84  /**
85  * Clear.
86  */
87  void clear()
88  {
89  router.clear();
90 
91  container_type::clear();
92  }
93 
94 
95  /**
96  * Find element with given value.
97  *
98  * \param value value
99  * \return position of element with given value or end()
100  */
101  template<class T>
102  const_iterator find(const T& value) const
103  {
104  const int ival = this->getValue(value);
105 
106  if (router.has(ival))
107  return this->begin() + router.get(ival);
108  else
109  return this->end();
110  }
111 
112 
113  /**
114  * Find element with given value.
115  *
116  * \param value value
117  * \return position of element with given value or end()
118  */
119  template<class T>
120  iterator find(const T& value)
121  {
122  const int ival = this->getValue(value);
123 
124  if (router.has(ival))
125  return this->begin() + router.get(ival);
126  else
127  return this->end();
128  }
129 
130 
131  /**
132  * Get element with given value.
133  *
134  * This method will throw an exception if given value is not present following the prerequisite of constness.
135  *
136  * \param value value
137  * \return element
138  */
139  template<class T>
140  value_type& get(const T& value)
141  {
142  const int ival = this->getValue(value);
143 
144  if (!router.has(ival)) {
145  this->insert(value);
146  }
147 
148  return container_type::operator[](router.get(ival)).second;
149  }
150 
151 
152  /**
153  * Get element with given value.
154  *
155  * This method will throw an exception if given value is not present following the prerequisite of constness.
156  *
157  * \param value value
158  * \return element
159  */
160  template<class T>
161  const value_type& get(const T& value) const
162  {
163  const int ival = this->getValue(value);
164 
165  if (router.has(ival)) {
166  return container_type::operator[](router.get(ival)).second;
167  }
168 
169  THROW(JIndexOutOfRange, "JHasCollection::get(): invalid value.");
170  }
171 
172 
173  /**
174  * Insert element.
175  *
176  * \param element element
177  * \return true if inserted; else false
178  */
179  virtual bool insert(const value_type& element)
180  {
181  const int ival = this->getValue(element);
182 
183  if (!router.has(ival)) {
184 
185  container_type::push_back(element);
186 
187  router.put(ival, this->size() - 1);
188 
189  return true;
190  }
191 
192  return false;
193  }
194 
195 
196  /**
197  * Erase element at given position.
198  *
199  * \param pos valid position
200  */
201  void erase(iterator pos)
202  {
203  router.put(this->getValue(*pos), router.getDefaultAddress());
204 
205  for (iterator i = container_type::erase(pos); i != this->end(); ++i) {
206  router.put(this->getValue(*i), distance(this->begin(), i));
207  }
208  }
209 
210 
211  /**
212  * Erase elements in given range.
213  *
214  * \param __begin begin position (included)
215  * \param __end end position (excluded)
216  */
217  void erase(iterator __begin, iterator __end)
218  {
219  for (iterator i = __begin; i != __end; ++i) {
220  router.put(this->getValue(*i), router.getDefaultAddress());
221  }
222 
223  for (iterator i = container_type::erase(__begin, __end); i != this->end(); ++i) {
224  router.put(this->getValue(*i), distance(this->begin(), i));
225  }
226  }
227 
228 
229  /**
230  * Erase element with given value.
231  *
232  * \param value value
233  * \return true if element has been erased; else false
234  */
235  template<class T>
236  bool erase(const T& value)
237  {
238  const int ival = this->getValue(value);
239 
240  if (router.has(ival)) {
241 
242  this->erase(this->begin() + router.get(ival));
243 
244  return true;
245  }
246 
247  return false;
248  }
249 
250 
251  /**
252  * Test whether given value is present.
253  *
254  * \param value value
255  * \return true if present; else false
256  */
257  template<class T>
258  bool has(const T& value) const
259  {
260  return router.has(this->getValue(value));
261  }
262 
263 
264  /**
265  * Get index of given value.
266  *
267  * \param value value
268  * \return indecx
269  */
270  template<class T>
271  int getIndex(const T& value) const
272  {
273  return router.get(this->getValue(value));
274  }
275 
276 
277  /**
278  * Function object for evaluation of element.
279  */
280  JEvaluator_t getValue;
281 
282 
283  protected:
285 
286  private:
287  void operator[](int);
288  void resize();
289  void push_back();
290  void pop_back();
291  };
292 }
293 
294 #endif
Exceptions.
std::vector< T >::difference_type distance(typename std::vector< T >::const_iterator first, typename PhysicsEvent::const_iterator< T > second)
Specialisation of STL distance.
JHashCollection & operator=(const JHashCollection &buffer)
Assignment operator.
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Definition: JException.hh:670
void erase(iterator __begin, iterator __end)
Erase elements in given range.
int getIndex(const T &value) const
Get index of given value.
virtual bool insert(const value_type &element)
Insert element.
iterator find(const T &value)
Find element with given value.
do set_variable OUTPUT_DIRECTORY $WORKDIR T
void erase(iterator pos)
Erase element at given position.
bool erase(const T &value)
Erase element with given value.
const_iterator find(const T &value) const
Find element with given value.
General purpose class for hash collection of unique elements.
container_type::const_iterator const_iterator
container_type::reverse_iterator reverse_iterator
container_type::iterator iterator
container_type::const_reverse_iterator const_reverse_iterator
std::vector< value_type > container_type
Exception for accessing an index in a collection that is outside of its range.
Definition: JException.hh:90
bool has(const T &value) const
Test whether given value is present.
JHashCollection(const JEvaluator_t &evaluator=JEvaluator_t())
Constructor.
JEvaluator_t getValue
Function object for evaluation of element.