sortdict.h
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  *
4  *
5  *
6  * Copyright (C) 1997-2015 by Dimitri van Heesch.
7  *
8  * Permission to use, copy, modify, and distribute this software and its
9  * documentation under the terms of the GNU General Public License is hereby
10  * granted. No representations are made about the suitability of this software
11  * for any purpose. It is provided "as is" without express or implied warranty.
12  * See the GNU General Public License for more details.
13  *
14  * Documents produced by Doxygen are derivative works derived from the
15  * input used in their production; they are not affected by this license.
16  *
17  */
18 
19 #ifndef _SORTDICT_H
20 #define _SORTDICT_H
21 
22 #include <qlist.h>
23 #include <qdict.h>
24 #include <qintdict.h>
25 
26 #define AUTORESIZE 1
27 
28 #if AUTORESIZE
29 const uint SDict_primes[] =
30 {
31  17,
32  29,
33  47,
34  71,
35  113,
36  179,
37  293,
38  457,
39  733,
40  1171,
41  1871,
42  2999,
43  4787,
44  7669,
45  12251,
46  19603,
47  31379,
48  50177,
49  80287,
50  128449,
51  205519,
52  328829,
53  526139,
54  841801,
55  1346881,
56  2155007,
57  3448033,
58  5516827,
59  8826919,
60  14123059,
61  23538433,
62  39230771,
63  65384537,
64  108974231,
65  181623707,
66  302706181,
67  504510283,
68  840850487,
69  0xffffffff
70 };
71 #endif
72 
73 template<class T> class SDict;
74 template<class T> class SIntDict;
75 
76 /** internal wrapper class that redirects compareValues() to the
77  * dictionary
78  */
79 template<class T>
80 class SList : public QList<T>
81 {
82  public:
83  SList(SDict<T> *owner) : m_owner(owner) {}
84  virtual ~SList() {}
85  int compareValues(const T *item1,const T *item2) const
86  {
87  return m_owner->compareValues(item1,item2);
88  }
89  private:
91 };
92 
93 /** Ordered dictionary of elements of type T.
94  * Internally uses a QList<T> and a QDict<T>.
95  */
96 template<class T>
97 class SDict
98 {
99  private:
101  QDict<T> *m_dict;
103 
104  public:
105  /*! Create an ordered dictionary.
106  * \param size The size of the dictionary. Should be a prime number for
107  * best distribution of elements.
108  * \param caseSensitive indicated whether the keys should be sorted
109  * in a case sensitive way.
110  */
111  SDict(int size=17,bool caseSensitive=TRUE) : m_sizeIndex(0)
112  {
113  m_list = new SList<T>(this);
114 #if AUTORESIZE
115  while ((uint)size>SDict_primes[m_sizeIndex]) m_sizeIndex++;
116  m_dict = new QDict<T>(SDict_primes[m_sizeIndex],caseSensitive);
117 #else
118  m_dict = new QDict<T>(size,caseSensitive);
119 #endif
120  }
121 
122  /*! Destroys the dictionary */
123  virtual ~SDict()
124  {
125  delete m_list;
126  delete m_dict;
127  }
128 
129  /*! Appends an element to the dictionary. The element is owned by the
130  * dictionary.
131  * \param key The unique key to use to quicky find the item later on.
132  * \param d The compound to add.
133  * \sa find()
134  */
135  void append(const char *key,const T *d)
136  {
137  m_list->append(d);
138  m_dict->insert(key,d);
139 #if AUTORESIZE
140  if (m_dict->size()>SDict_primes[m_sizeIndex])
141  {
142  m_dict->resize(SDict_primes[++m_sizeIndex]);
143  }
144 #endif
145  }
146 
147  /*! Prepends an element to the dictionary. The element is owned by the
148  * dictionary.
149  * \param key The unique key to use to quicky find the item later on.
150  * \param d The compound to add.
151  * \sa find()
152  */
153  void prepend(const char *key,const T *d)
154  {
155  m_list->prepend(d);
156  m_dict->insert(key,d);
157 #if AUTORESIZE
158  if (m_dict->size()>SDict_primes[m_sizeIndex])
159  {
160  m_dict->resize(SDict_primes[++m_sizeIndex]);
161  }
162 #endif
163  }
164 
165  /*! Remove an item from the dictionary */
166  bool remove(const char *key)
167  {
168  T *item = m_dict->take(key);
169  return item ? m_list->remove(item) : FALSE;
170  }
171 
172  /*! Take an item out of the dictionary without deleting it */
173  T *take(const char *key)
174  {
175  T *item = m_dict->take(key);
176  if (item)
177  {
178  int i = m_list->find(item);
179  m_list->take(i);
180  }
181  return item;
182  }
183 
184  /*! Sorts the members of the dictionary. First appending a number
185  * of members and then sorting them is faster (O(NlogN) than using
186  * inSort() for each member (O(N^2)).
187  */
188  void sort()
189  {
190  m_list->sort();
191  }
192  /*! Inserts a compound into the dictionary in a sorted way.
193  * \param key The unique key to use to quicky find the item later on.
194  * \param d The compound to add.
195  * \sa find()
196  */
197  void inSort(const char *key,const T *d)
198  {
199  m_list->inSort(d);
200  m_dict->insert(key,d);
201 #if AUTORESIZE
202  if (m_dict->size()>SDict_primes[m_sizeIndex])
203  {
204  m_dict->resize(SDict_primes[++m_sizeIndex]);
205  }
206 #endif
207  }
208 
209  void insertAt(int i,const char *key,const T *d)
210  {
211  m_list->insert(i,d);
212  m_dict->insert(key,d);
213 #if AUTORESIZE
214  if (m_dict->size()>SDict_primes[m_sizeIndex])
215  {
216  m_dict->resize(SDict_primes[++m_sizeIndex]);
217  }
218 #endif
219  }
220 
221  /*! Indicates whether or not the dictionary owns its elements */
222  void setAutoDelete(bool val)
223  {
224  m_list->setAutoDelete(val);
225  }
226 
227  /*! Looks up a compound given its key.
228  * \param key The key to identify this element.
229  * \return The requested compound or zero if it cannot be found.
230  * \sa append()
231  */
232  T *find(const char *key)
233  {
234  return m_dict->find(key);
235  }
236  T *find(const QCString &key)
237  {
238  return m_dict->find(key);
239  }
240  T *find(const QString &key)
241  {
242  return m_dict->find(key);
243  }
244  int findAt(const QCString &key)
245  {
246  T *item = find(key);
247  if (item==0) return -1;
248  return m_list->find(item);
249  }
250 
251  /*! Equavalent to find(). */
252  T *operator[](const char *key) const
253  {
254  return m_dict->find(key);
255  }
256 
257  /*! Returns the item at position \a i in the sorted dictionary */
258  T *at(uint i)
259  {
260  return m_list->at(i);
261  }
262 
263  /*! Function that is used to compare two items when sorting.
264  * Overload this to properly sort items.
265  * \sa inSort()
266  */
267  virtual int compareValues(const T *item1,const T *item2) const
268  {
269  return item1!=item2;
270  }
271 
272  /*! Clears the dictionary. Will delete items if setAutoDelete() was
273  * set to \c TRUE.
274  * \sa setAutoDelete
275  */
276  void clear()
277  {
278  m_list->clear();
279  m_dict->clear();
280  }
281 
282  /*! Returns the number of items stored in the dictionary
283  */
284  int count() const
285  {
286  return m_list->count();
287  }
288 
289  class Iterator; // first forward declare
290  friend class Iterator; // then make it a friend
291  /*! Simple iterator for SDict. It iterates in the order in which the
292  * elements are stored.
293  */
294  class Iterator
295  {
296  public:
297  /*! Create an iterator given the dictionary. */
298  Iterator(const SDict<T> &dict)
299  {
300  m_li = new QListIterator<T>(*dict.m_list);
301  }
302 
303  /*! Destroys the dictionary */
304  virtual ~Iterator()
305  {
306  delete m_li;
307  }
308 
309  /*! Set the iterator to the first element in the list.
310  * \return The first compound, or zero if the list was empty.
311  */
312  T *toFirst() const
313  {
314  return m_li->toFirst();
315  }
316 
317  /*! Set the iterator to the last element in the list.
318  * \return The first compound, or zero if the list was empty.
319  */
320  T *toLast() const
321  {
322  return m_li->toLast();
323  }
324 
325  /*! Returns the current compound */
326  T *current() const
327  {
328  return m_li->current();
329  }
330 
331  /*! Moves the iterator to the next element.
332  * \return the new "current" element, or zero if the iterator was
333  * already pointing at the last element.
334  */
336  {
337  return m_li->operator++();
338  }
339 
340  /*! Moves the iterator to the previous element.
341  * \return the new "current" element, or zero if the iterator was
342  * already pointing at the first element.
343  */
345  {
346  return m_li->operator--();
347  }
348 
349  private:
351  };
352 
353  class IteratorDict; // first forward declare
354  friend class IteratorDict; // then make it a friend
355  /*! Simple iterator for SDict. It iterates over the dictionary elements
356  * in an unsorted way, but does provide information about the element's key.
357  */
359  {
360  public:
361  /*! Create an iterator given the dictionary. */
362  IteratorDict(const SDict<T> &dict)
363  {
364  m_di = new QDictIterator<T>(*dict.m_dict);
365  }
366 
367  /*! Destroys the dictionary */
368  virtual ~IteratorDict()
369  {
370  delete m_di;
371  }
372 
373  /*! Set the iterator to the first element in the list.
374  * \return The first compound, or zero if the list was empty.
375  */
376  T *toFirst() const
377  {
378  return m_di->toFirst();
379  }
380 
381  /*! Set the iterator to the last element in the list.
382  * \return The first compound, or zero if the list was empty.
383  */
384  T *toLast() const
385  {
386  return m_di->toLast();
387  }
388 
389  /*! Returns the current compound */
390  T *current() const
391  {
392  return m_di->current();
393  }
394 
395  /*! Returns the current key */
397  {
398  return m_di->currentKey();
399  }
400 
401  /*! Moves the iterator to the next element.
402  * \return the new "current" element, or zero if the iterator was
403  * already pointing at the last element.
404  */
406  {
407  return m_di->operator++();
408  }
409 
410  /*! Moves the iterator to the previous element.
411  * \return the new "current" element, or zero if the iterator was
412  * already pointing at the first element.
413  */
415  {
416  return m_di->operator--();
417  }
418 
419  private:
420  QDictIterator<T> *m_di;
421  };
422 };
423 
424 /** internal wrapper class that redirects compareValues() to the
425  * dictionary
426  */
427 template<class T>
428 class SIntList : public QList<T>
429 {
430  public:
431  SIntList(SIntDict<T> *owner) : m_owner(owner) {}
432  virtual ~SIntList() {}
433  private:
434  int compareValues(const T *item1,const T *item2) const
435  {
436  return m_owner->compareValues(item1,item2);
437  }
439 };
440 
441 /** Ordered dictionary of elements of type T.
442  * Internally uses a QList<T> and a QIntDict<T>.
443  */
444 template<class T>
445 class SIntDict
446 {
447  private:
451 
452  public:
453  /*! Create an ordered dictionary.
454  * \param size The size of the dictionary. Should be a prime number for
455  * best distribution of elements.
456  */
457  SIntDict(int size=17) : m_sizeIndex(0)
458  {
459  m_list = new SIntList<T>(this);
460 #if AUTORESIZE
461  while ((uint)size>SDict_primes[m_sizeIndex]) m_sizeIndex++;
462  m_dict = new QIntDict<T>(SDict_primes[m_sizeIndex]);
463 #else
464  m_dict = new QIntDict<T>(size);
465 #endif
466  }
467 
468  /*! Destroys the dictionary */
469  virtual ~SIntDict()
470  {
471  delete m_list;
472  delete m_dict;
473  }
474 
475  /*! Appends a compound to the dictionary. The element is owned by the
476  * dictionary.
477  * \param key The unique key to use to quicky find the item later on.
478  * \param d The compound to add.
479  * \sa find()
480  */
481  void append(int key,const T *d)
482  {
483  m_list->append(d);
484  m_dict->insert(key,d);
485 #if AUTORESIZE
486  if (m_dict->size()>SDict_primes[m_sizeIndex])
487  {
488  m_dict->resize(SDict_primes[++m_sizeIndex]);
489  }
490 #endif
491  }
492 
493  /*! Prepend a compound to the dictionary. The element is owned by the
494  * dictionary.
495  * \param key The unique key to use to quicky find the item later on.
496  * \param d The compound to add.
497  * \sa find()
498  */
499  void prepend(int key,const T *d)
500  {
501  m_list->prepend(d);
502  m_dict->insert(key,d);
503 #if AUTORESIZE
504  if (m_dict->size()>SDict_primes[m_sizeIndex])
505  {
506  m_dict->resize(SDict_primes[++m_sizeIndex]);
507  }
508 #endif
509  }
510 
511  /*! Remove an item from the dictionary */
512  bool remove(int key)
513  {
514  T *item = m_dict->take(key);
515  return item ? m_list->remove(item) : FALSE;
516  }
517 
518  /*! Sorts the members of the dictionary. First appending a number
519  * of members and then sorting them is faster (O(NlogN) than using
520  * inSort() for each member (O(N^2)).
521  */
522  void sort()
523  {
524  m_list->sort();
525  }
526 
527  /*! Inserts a compound into the dictionary in a sorted way.
528  * \param key The unique key to use to quicky find the item later on.
529  * \param d The compound to add.
530  * \sa find()
531  */
532  void inSort(int key,const T *d)
533  {
534  m_list->inSort(d);
535  m_dict->insert(key,d);
536 #if AUTORESIZE
537  if (m_dict->size()>SDict_primes[m_sizeIndex])
538  {
539  m_dict->resize(SDict_primes[++m_sizeIndex]);
540  }
541 #endif
542  }
543 
544  /*! Indicates whether or not the dictionary owns its elements */
545  void setAutoDelete(bool val)
546  {
547  m_list->setAutoDelete(val);
548  }
549 
550  /*! Looks up a compound given its key.
551  * \param key The key to identify this element.
552  * \return The requested compound or zero if it cannot be found.
553  * \sa append()
554  */
555  T *find(int key)
556  {
557  return m_dict->find(key);
558  }
559 
560  /*! Equavalent to find(). */
561  T *operator[](int key) const
562  {
563  return m_dict->find(key);
564  }
565 
566  /*! Returns the item at position \a i in the sorted dictionary */
567  T *at(uint i)
568  {
569  return m_list->at(i);
570  }
571 
572  /*! Function that is used to compare two items when sorting.
573  * Overload this to properly sort items.
574  * \sa inSort()
575  */
576  virtual int compareValues(const T *item1,const T *item2) const
577  {
578  return item1!=item2;
579  }
580 
581  /*! Clears the dictionary. Will delete items if setAutoDelete() was
582  * set to \c TRUE.
583  * \sa setAutoDelete
584  */
585  void clear()
586  {
587  m_list->clear();
588  m_dict->clear();
589  }
590 
591  /*! Returns the number of items stored in the dictionary
592  */
593  int count()
594  {
595  return m_list->count();
596  }
597 
598  class Iterator; // first forward declare
599  friend class Iterator; // then make it a friend
600  /*! Simple iterator for SDict. It iterates in the order in which the
601  * elements are stored.
602  */
603  class Iterator
604  {
605  public:
606  /*! Create an iterator given the dictionary. */
607  Iterator(const SIntDict<T> &dict)
608  {
609  m_li = new QListIterator<T>(*dict.m_list);
610  }
611 
612  /*! Destroys the dictionary */
613  virtual ~Iterator()
614  {
615  delete m_li;
616  }
617 
618  /*! Set the iterator to the first element in the list.
619  * \return The first compound, or zero if the list was empty.
620  */
621  T *toFirst() const
622  {
623  return m_li->toFirst();
624  }
625 
626  /*! Set the iterator to the last element in the list.
627  * \return The first compound, or zero if the list was empty.
628  */
629  T *toLast() const
630  {
631  return m_li->toLast();
632  }
633 
634  /*! Returns the current compound */
635  T *current() const
636  {
637  return m_li->current();
638  }
639 
640  /*! Moves the iterator to the next element.
641  * \return the new "current" element, or zero if the iterator was
642  * already pointing at the last element.
643  */
645  {
646  return m_li->operator++();
647  }
648 
649  /*! Moves the iterator to the previous element.
650  * \return the new "current" element, or zero if the iterator was
651  * already pointing at the first element.
652  */
654  {
655  return m_li->operator--();
656  }
657 
658  private:
660  };
661 
662  class IteratorDict; // first forward declare
663  friend class IteratorDict; // then make it a friend
664  /*! Simple iterator for SDict. It iterates over the dictionary elements
665  * in an unsorted way, but does provide information about the element's key.
666  */
668  {
669  public:
670  /*! Create an iterator given the dictionary. */
672  {
673  m_di = new QIntDictIterator<T>(*dict.m_dict);
674  }
675 
676  /*! Destroys the dictionary */
677  virtual ~IteratorDict()
678  {
679  delete m_di;
680  }
681 
682  /*! Set the iterator to the first element in the list.
683  * \return The first compound, or zero if the list was empty.
684  */
685  T *toFirst() const
686  {
687  return m_di->toFirst();
688  }
689 
690  /*! Set the iterator to the last element in the list.
691  * \return The first compound, or zero if the list was empty.
692  */
693  T *toLast() const
694  {
695  return m_di->toLast();
696  }
697 
698  /*! Returns the current compound */
699  T *current() const
700  {
701  return m_di->current();
702  }
703 
704  /*! Returns the current key */
705  int currentKey() const
706  {
707  return m_di->currentKey();
708  }
709 
710  /*! Moves the iterator to the next element.
711  * \return the new "current" element, or zero if the iterator was
712  * already pointing at the last element.
713  */
715  {
716  return m_di->operator++();
717  }
718 
719  /*! Moves the iterator to the previous element.
720  * \return the new "current" element, or zero if the iterator was
721  * already pointing at the first element.
722  */
724  {
725  return m_di->operator--();
726  }
727 
728  private:
729  QDictIterator<T> *m_di;
730  };
731 
732 };
733 
734 #endif
T * operator[](int key) const
Definition: sortdict.h:561
SIntList< T > * m_list
Definition: sortdict.h:448
void clear()
Definition: sortdict.h:276
T * toLast() const
Definition: sortdict.h:629
T * toFirst() const
Definition: sortdict.h:312
SIntDict(int size=17)
Definition: sortdict.h:457
void prepend(const char *key, const T *d)
Definition: sortdict.h:153
virtual ~Iterator()
Definition: sortdict.h:613
void inSort(const char *key, const T *d)
Definition: sortdict.h:197
int compareValues(const T *item1, const T *item2) const
Definition: sortdict.h:85
virtual int compareValues(const T *item1, const T *item2) const
Definition: sortdict.h:576
SDict(int size=17, bool caseSensitive=TRUE)
Definition: sortdict.h:111
void append(const T *d)
Definition: qlist.h:73
QCString currentKey() const
Definition: sortdict.h:396
T * find(int key)
Definition: sortdict.h:555
T * current() const
Definition: sortdict.h:390
T * at(uint i)
Definition: sortdict.h:567
void setAutoDelete(bool val)
Definition: sortdict.h:545
int count()
Definition: sortdict.h:593
SList< T > * m_list
Definition: sortdict.h:100
const bool FALSE
Definition: qglobal.h:370
T * find(const QString &key)
Definition: sortdict.h:240
T * at(uint i) const
Definition: qlist.h:94
virtual ~IteratorDict()
Definition: sortdict.h:677
The QString class provides an abstraction of Unicode text and the classic C null-terminated char arra...
Definition: qstring.h:350
T * toFirst() const
Definition: sortdict.h:685
Iterator(const SDict< T > &dict)
Definition: sortdict.h:298
int count() const
Definition: sortdict.h:284
type * take(long k)
Definition: qintdict.h:62
int find(const T *d) const
Definition: qlist.h:88
void append(const char *key, const T *d)
Definition: sortdict.h:135
QListIterator< T > * m_li
Definition: sortdict.h:659
virtual ~IteratorDict()
Definition: sortdict.h:368
bool insert(uint i, const T *d)
Definition: qlist.h:70
void setAutoDelete(bool val)
Definition: sortdict.h:222
int m_sizeIndex
Definition: sortdict.h:450
QDictIterator< T > * m_di
Definition: sortdict.h:729
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
Definition: sortdict.h:73
uint count() const
Definition: qlist.h:66
void insert(long k, const type *d)
Definition: qintdict.h:57
QDictIterator< T > * m_di
Definition: sortdict.h:420
void inSort(const T *d)
Definition: qlist.h:71
int currentKey() const
Definition: sortdict.h:705
void inSort(int key, const T *d)
Definition: sortdict.h:532
def key(type, name=None)
Definition: graph.py:13
void sort()
Definition: qlist.h:85
IteratorDict(const SDict< T > &dict)
Definition: sortdict.h:362
T * toLast() const
Definition: sortdict.h:384
void clear()
Definition: sortdict.h:585
void clear()
Definition: qlist.h:82
T * current() const
Definition: sortdict.h:699
int compareValues(const T *item1, const T *item2) const
Definition: sortdict.h:434
void append(int key, const T *d)
Definition: sortdict.h:481
QDict< T > * m_dict
Definition: sortdict.h:101
virtual ~SDict()
Definition: sortdict.h:123
T * find(const QCString &key)
Definition: sortdict.h:236
void sort()
Definition: sortdict.h:522
T * take(const char *key)
Definition: sortdict.h:173
int findAt(const QCString &key)
Definition: sortdict.h:244
T * toFirst() const
Definition: sortdict.h:376
T * operator++()
Definition: sortdict.h:335
const uint SDict_primes[]
Definition: sortdict.h:29
T * toLast() const
Definition: sortdict.h:693
virtual ~Iterator()
Definition: sortdict.h:304
void prepend(int key, const T *d)
Definition: sortdict.h:499
void sort()
Definition: sortdict.h:188
QListIterator< T > * m_li
Definition: sortdict.h:350
virtual ~SIntDict()
Definition: sortdict.h:469
T * current() const
Definition: sortdict.h:326
T * operator[](const char *key) const
Definition: sortdict.h:252
virtual ~SList()
Definition: sortdict.h:84
virtual ~SIntList()
Definition: sortdict.h:432
void clear()
Definition: qintdict.h:67
Definition: sortdict.h:80
T * at(uint i)
Definition: sortdict.h:258
Iterator(const SIntDict< T > &dict)
Definition: sortdict.h:607
uint size() const
Definition: qintdict.h:55
SList(SDict< T > *owner)
Definition: sortdict.h:83
IteratorDict(const SIntDict< T > &dict)
Definition: sortdict.h:671
T * toFirst() const
Definition: sortdict.h:621
void prepend(const T *d)
Definition: qlist.h:72
void resize(uint n)
Definition: qintdict.h:68
T * take(uint i)
Definition: qlist.h:81
T * find(const char *key)
Definition: sortdict.h:232
void insertAt(int i, const char *key, const T *d)
Definition: sortdict.h:209
bool remove(uint i)
Definition: qlist.h:76
unsigned uint
Definition: qglobal.h:351
void setAutoDelete(bool enable)
Definition: qlist.h:99
const bool TRUE
Definition: qglobal.h:371
SDict< T > * m_owner
Definition: sortdict.h:90
QIntDict< T > * m_dict
Definition: sortdict.h:449
SIntDict< T > * m_owner
Definition: sortdict.h:438
type * find(long k) const
Definition: qintdict.h:63
SIntList(SIntDict< T > *owner)
Definition: sortdict.h:431
virtual int compareValues(const T *item1, const T *item2) const
Definition: sortdict.h:267
Definition: qlist.h:54
int m_sizeIndex
Definition: sortdict.h:102
T * operator--()
Definition: sortdict.h:344
T * toLast() const
Definition: sortdict.h:320
T * current() const
Definition: sortdict.h:635