Aleph-w  1.5a.2
Biblioteca general de algoritmos y estructuras de datos
 Todo Clases Archivos Funciones Variables 'typedefs' Enumeraciones Amigas Grupos Páginas
ahDry.H
1 
2 # ifndef AHDRY_H
3 # define AHDRY_H
4 
5 # include <functional>
6 # include <sstream>
7 
8 # include <ahFunctional.H>
9 
10 namespace Aleph
11 {
12 
13  template <typename T> class DynList;
14 
15 # define Generic_Traverse(Type) \
16  template <class Operation> \
17  bool traverse(Operation & operation) const \
18  { \
19  for (Iterator it(*this); it.has_curr(); it.next()) \
20  if (not operation(it.get_curr())) \
21  return false; \
22  return true; \
23  } \
24  \
25  template <class Operation> \
26  bool traverse(Operation & operation) \
27  { \
28  for (Iterator it(*this); it.has_curr(); it.next()) \
29  if (not operation(it.get_curr())) \
30  return false; \
31  return true; \
32  } \
33  \
34  template <class Operation> \
35  bool traverse(Operation && operation = Operation()) const \
36  { \
37  return traverse<Operation>(operation); \
38  } \
39  \
40  template <class Operation> \
41  bool traverse(Operation && operation = Operation()) \
42  { \
43  return traverse<Operation>(operation); \
44  }
45 
46 # define Functional_Methods(Type) \
47  template <class Operation> \
48  void for_each(Operation & operation) const \
49  { \
50  this->traverse([&operation] (const Type & item) \
51  { \
52  operation(item); \
53  return true; \
54  }); \
55  } \
56  \
57  template <class Operation> \
58  void for_each(Operation & operation) \
59  { \
60  this->traverse([&operation] (const Type & item) \
61  { \
62  operation(item); \
63  return true; \
64  }); \
65  } \
66  \
67  template <class Operation> \
68  void for_each(Operation && operation = Operation()) const \
69  { \
70  this->for_each<Operation>(operation); \
71  } \
72  \
73  template <class Operation> \
74  void for_each(Operation && operation = Operation()) \
75  { \
76  this->for_each<Operation>(operation); \
77  } \
78  \
79  template <class Operation> \
80  bool all(Operation & operation) const \
81  { \
82  return this->traverse<Operation>(operation); \
83  } \
84  \
85  template <class Operation> \
86  bool all(Operation & operation) \
87  { \
88  return this->traverse<Operation>(operation); \
89  } \
90  \
91  template <class Operation> \
92  bool all(Operation && operation = Operation()) const \
93  { \
94  return all<Operation>(operation); \
95  } \
96  \
97  template <class Operation> \
98  bool all(Operation && operation = Operation()) \
99  { \
100  return all<Operation>(operation); \
101  } \
102  \
103  template <class Operation> \
104  bool forall(Operation & operation) const \
105  { \
106  return all<Operation>(operation); \
107  } \
108  \
109  template <class Operation> \
110  bool forall(Operation & operation) \
111  { \
112  return all<Operation>(operation); \
113  } \
114  \
115  template <class Operation> \
116  bool forall(Operation && operation = Operation()) const \
117  { \
118  return all<Operation>(operation); \
119  } \
120  \
121  template <class Operation> \
122  bool forall(Operation && operation = Operation()) \
123  { \
124  return all<Operation>(operation); \
125  } \
126  \
127  template <class Operation> \
128  bool exists(Operation & operation) const \
129  { \
130  return not this->traverse([&operation] (const Type & item) \
131  { \
132  return not operation(item); \
133  }); \
134  } \
135  \
136  template <class Operation> \
137  bool exists(Operation & operation) \
138  { \
139  return not this->traverse([&operation] (const Type & item) \
140  { \
141  return not operation(item); \
142  }); \
143  } \
144  \
145  template <class Operation> \
146  bool exists(Operation && operation = Operation()) const \
147  { \
148  return exists<Operation>(operation); \
149  } \
150  \
151  template <class Operation> \
152  bool exists(Operation && operation = Operation()) \
153  { \
154  return exists<Operation>(operation); \
155  } \
156  \
157  template <class Operation> \
158  Type * find_ptr(Operation & operation) \
159  { \
160  Type * ptr = NULL; \
161  this->traverse([&ptr,&operation] (Type & item) \
162  { \
163  if (operation(item)) \
164  { \
165  ptr = &item; \
166  return false; \
167  } \
168  return true; \
169  }); \
170  return ptr; \
171  } \
172  \
173  template <class Operation> \
174  Type * find_ptr(Operation & operation) const \
175  { \
176  Type * ptr = NULL; \
177  this->traverse([&ptr,&operation] (Type & item) \
178  { \
179  if (operation(item)) \
180  { \
181  ptr = &item; \
182  return false; \
183  } \
184  return true; \
185  }); \
186  return ptr; \
187  } \
188  \
189  template <class Operation> \
190  Type * find_ptr(Operation && operation = Operation()) const \
191  { \
192  return find_ptr<Operation>(operation); \
193  } \
194  \
195  template <class Operation> \
196  Type * find_ptr(Operation && operation = Operation()) \
197  { \
198  return find_ptr<Operation>(operation); \
199  } \
200  \
201  template <typename __T = Type, \
202  template <typename> class Container = Aleph::DynList, \
203  class Operation = Dft_Map_Op<Type, __T>> \
204  Container<__T> map(Operation & operation) const \
205  { \
206  Container<__T> ret_val; \
207  this->for_each([&ret_val, &operation] (const Type & item) \
208  { \
209  ret_val.append(operation(item)); \
210  }); \
211  return ret_val; \
212  } \
213  \
214  template < typename __T = Type, \
215  template <typename> class Container = Aleph::DynList, \
216  class Operation = Dft_Map_Op<__T, __T>> \
217  Container<__T> map(Operation && operation = Operation()) const \
218  { \
219  return map<__T, Container, Operation>(operation); \
220  } \
221  \
222  \
223  template <typename __T = Type> \
224  __T foldl(const __T & init, \
225  std::function<__T(const __T&, const Type &)> operation) const \
226  { \
227  __T ret_val = init; \
228  this->for_each([&ret_val, &operation] (const Type & item) \
229  { \
230  ret_val = operation(ret_val, item); \
231  }); \
232  return ret_val; \
233  } \
234  \
235  template <class Operation> \
236  DynList<Type> filter(Operation & operation) const \
237  { \
238  DynList<Type> ret_val; \
239  this->for_each([&ret_val, &operation] (const Type & item) \
240  { \
241  if (operation(item)) \
242  ret_val.append(item); \
243  }); \
244  return ret_val; \
245  } \
246  \
247  template <class Operation> \
248  DynList<Type> filter(Operation & operation) \
249  { \
250  DynList<Type> ret_val; \
251  this->for_each([&ret_val, &operation] (const Type & item) \
252  { \
253  if (operation(item)) \
254  ret_val.append(item); \
255  }); \
256  return ret_val; \
257  } \
258  \
259  template <class Operation> \
260  DynList<Type> filter(Operation && operation = Operation()) const \
261  { \
262  return filter<Operation>(operation); \
263  } \
264  \
265  template <class Operation> \
266  DynList<Type> filter(Operation && operation = Operation()) \
267  { \
268  return filter<Operation>(operation); \
269  } \
270  \
271  template <class Operation> \
272  std::pair<DynList<Type>, DynList<Type>> partition(Operation & op) const \
273  { \
274  std::pair<DynList<Type>, DynList<Type>> ret_val; \
275  this->for_each([&ret_val, &op] (const Type & item) \
276  { \
277  if (op(item)) \
278  ret_val.first.append(item); \
279  else \
280  ret_val.second.append(item); \
281  }); \
282  return ret_val; \
283  } \
284  \
285  template <class Operation> \
286  std::pair<DynList<Type>, DynList<Type>> partition(Operation & op) \
287  { \
288  std::pair<DynList<Type>, DynList<Type>> ret_val; \
289  this->for_each([&ret_val, &op] (const Type & item) \
290  { \
291  if (op(item)) \
292  ret_val.first.append(item); \
293  else \
294  ret_val.second.append(item); \
295  }); \
296  return ret_val; \
297  } \
298  \
299  template <class Operation> \
300  std::pair<DynList<Type>, DynList<Type>> \
301  partition(Operation && op = Operation()) const \
302  { \
303  return partition<Operation>(op); \
304  } \
305  \
306  template <class Operation> \
307  std::pair<DynList<Type>, DynList<Type>> \
308  partition(Operation && op = Operation()) \
309  { \
310  return partition<Operation>(op); \
311  } \
312  \
313  size_t length() const \
314  { \
315  size_t count = 0; \
316  this->for_each([&count] (const Type &) { ++count; }); \
317  return count; \
318  } \
319  \
320  Type & nth(const size_t n) const \
321  { \
322  Type * ptr = NULL; \
323  size_t i = 0; \
324  this->traverse([&ptr, &i, &n] (Type & item) \
325  { \
326  if (i++ < n) \
327  return true; \
328  ptr = &item; \
329  return false; \
330  }); \
331  \
332  if (i != n + 1) \
333  throw std::out_of_range("nth"); \
334  \
335  return *ptr; \
336  } \
337  \
338  template <template <typename> class Container = Aleph::DynList> \
339  Container<Type> rev() const \
340  { \
341  Container<Type> ret_val; \
342  for_each([&ret_val] (const Type & item) \
343  { \
344  ret_val.insert(item); \
345  }); \
346  return ret_val; \
347  }
348 
349 
350 # define Generic_Keys(Type) \
351  template <template <typename> class Container = DynList> \
352  Container<Type> keys() const \
353  { \
354  return this->template map<Type, Container>([] (const Type & key) \
355  { return key; }); \
356  }
357 
358 # define Generic_Items(Type) \
359  template <template <typename> class Container = DynList> \
360  Container<Type> items() const \
361  { \
362  return this->template map<Type, Container> ([] (const Type & key) \
363  { return key; }); \
364  }
365 
366 
367 # define Equal_To_Method(class_name) \
368  bool equal_to(const class_name & r) const \
369  { \
370  if (this == &r) \
371  return true; \
372  \
373  if (this->size() != r.size()) \
374  return false; \
375  \
376  return this->all(/* Lambda */ [&r] (const Key & k) \
377  { return r.search(k) != NULL; }); \
378  } \
379  \
380  bool operator == (const class_name & r) const \
381  { \
382  return equal_to(r); \
383  } \
384  \
385  bool operator != (const class_name & r) const \
386  { \
387  return not equal_to(r); \
388  }
389 
390 
391 # define Map_Sequences_Methods() \
392  template <template <typename> class Container = ::DynList> \
393  Container<Key> keys() const \
394  { \
395  Container<Key> ret_val; \
396  this->for_each([&ret_val] (const std::pair<Key, Data> & p) \
397  { \
398  ret_val.append(p.first); \
399  }); \
400  return ret_val; \
401  } \
402  \
403  template <template <typename> class Container = ::DynList> \
404  Container<Data> values() const \
405  { \
406  Container<Data> ret_val; \
407  this->for_each([&ret_val] (const std::pair<Key, Data> & p) \
408  { \
409  ret_val.append(p.second); \
410  }); \
411  return ret_val; \
412  } \
413  \
414  template <template <typename> class Container = ::DynList> \
415  Container<Data*> values_ptr() const \
416  { \
417  Container<Data*> ret_val; \
418  this->for_each([&ret_val] (std::pair<Key, Data> & p) \
419  { \
420  ret_val.append(&p.second); \
421  }); \
422  return ret_val; \
423  } \
424  \
425  template <template <typename> class Container = ::DynList> \
426  Container<std::pair<Key, Data>> items() const \
427  { \
428  return this->Base::keys(); \
429  } \
430  \
431  template <template <typename> class Container = ::DynList> \
432  Container<std::pair<Key, Data*>> items_ptr() const \
433  { \
434  Container<Data> ret_val; \
435  this->for_each([&ret_val] (std::pair<Key, Data> & p) \
436  { \
437  ret_val.append(std::pair<Key,Data*>(p.first, p.second)); \
438  }); \
439  return ret_val; \
440  } \
441  \
442  Data & operator () (const Key & key) \
443  { \
444  return this->find(key); \
445  }
446 
447 # define Generate_Proxy_Operator(Class_Name) \
448  class Proxy \
449  { \
450  Class_Name & container; \
451  const Key & key; \
452  Data * data_ptr; \
453  \
454  public: \
455  \
456  Proxy(Class_Name & c, const Key &_key) : container(c), key(_key) \
457  { \
458  data_ptr = container.search(key); \
459  } \
460  \
461  Proxy & operator = (const Data & data) \
462  { \
463  if (data_ptr == NULL) \
464  container.insert(key, data); \
465  else \
466  *data_ptr = data; \
467  \
468  return *this; \
469  } \
470  \
471  Proxy & operator = (const Proxy & proxy) \
472  { \
473  if (this == &proxy) \
474  return *this; \
475  \
476  if (proxy.data_ptr == NULL) \
477  throw std::domain_error("key not found"); \
478  \
479  if (&container == &proxy.tree and key == proxy.key) \
480  return *this; \
481  \
482  if (data_ptr == NULL) \
483  container.insert(key, *proxy.data_ptr); \
484  else \
485  *data_ptr = proxy.data_ptr; \
486  \
487  return *this; \
488  } \
489  \
490  operator Data & () const \
491  { \
492  if (data_ptr == NULL) \
493  throw std::domain_error("key not found"); \
494  \
495  return *data_ptr; \
496  } \
497  }; \
498  \
499  Proxy operator [] (const Key & key) const \
500  Exception_Prototypes(std::domain_error) \
501  { \
502  return Proxy(*this, key); \
503  } \
504  \
505  Proxy operator [] (const Key & key) \
506  Exception_Prototypes(std::domain_error) \
507  { \
508  return Proxy(*this, key); \
509  }
510 
511  template <typename Type> inline
512 std::string to_str(const Type & d)
513 {
514  std::ostringstream os;
515  os << d;
516  return os.str();
517 }
518 
519 
520  // This class wrappes the compare class passed to DynMapLinHash which
521  // has form cpm<Key>
522  template <typename Key, typename Data, class Cmp = std::equal_to<Key>>
523  struct Dft_Pair_Cmp
524  {
525  bool operator () (const std::pair<Key, Data> & p1,
526  const std::pair<Key, Data> & p2) const
527  {
528  return Cmp () (p1.first, p2.first);
529  }
530  };
531 
532  template <typename Key, typename Data>
533  std::pair<Key, Data> * key_to_pair(Key * ptr)
534  {
535  return (std::pair<Key, Data>*) ptr;
536  }
537 
538  template <typename Key, typename Data>
539  std::pair<Key, Data> * data_to_pair(Data * ptr)
540  {
541  std::pair<Key, Data> * zero = 0;
542  return (std::pair<Key, Data>*) ((long) ptr - (long) &zero->second);
543  }
544 
545 
546 } // end namespace Aleph
547 
548 # endif // AHDRY_H
Definition: ahDry.H:523
Definition: ahDry.H:13

Leandro Rabindranath León