1 /******************************************************************************
3 * $Id: sortdict.h,v 1.3 2001/03/19 19:27:41 root Exp $
6 * Copyright (C) 1997-2012 by Dimitri van Heesch.
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.
14 * Documents produced by Doxygen are derivative works derived from the
15 * input used in their production; they are not affected by this license.
30 const uint SDict_primes[] =
74 template<class T> class SDict;
75 template<class T> class SIntDict;
77 /** internal wrapper class that redirects compareItems() to the
81 class SList : public QList<T>
84 SList(SDict<T> *owner) : m_owner(owner) {}
86 int compareItems(GCI item1,GCI item2)
88 return m_owner->compareItems(item1,item2);
94 /** Ordered dictionary of elements of type T.
95 * Internally uses a QList<T> and a QDict<T>.
106 /*! Create an ordered dictionary.
107 * \param size The size of the dictionary. Should be a prime number for
108 * best distribution of elements.
109 * \param caseSensitive indicated whether the keys should be sorted
110 * in a case sensitive way.
112 SDict(int size,bool caseSensitive=TRUE) : m_sizeIndex(0)
114 m_list = new SList<T>(this);
116 while ((uint)size>SDict_primes[m_sizeIndex]) m_sizeIndex++;
117 m_dict = new QDict<T>(SDict_primes[m_sizeIndex],caseSensitive);
119 m_dict = new QDict<T>(size,caseSensitive);
123 /*! Destroys the dictionary */
130 /*! Appends an element to the dictionary. The element is owned by the
132 * \param key The unique key to use to quicky find the item later on.
133 * \param d The compound to add.
136 void append(const char *key,const T *d)
139 m_dict->insert(key,d);
141 if (m_dict->size()>SDict_primes[m_sizeIndex])
143 m_dict->resize(SDict_primes[++m_sizeIndex]);
148 /*! Prepends an element to the dictionary. The element is owned by the
150 * \param key The unique key to use to quicky find the item later on.
151 * \param d The compound to add.
154 void prepend(const char *key,const T *d)
157 m_dict->insert(key,d);
159 if (m_dict->size()>SDict_primes[m_sizeIndex])
161 m_dict->resize(SDict_primes[++m_sizeIndex]);
166 /*! Remove an item from the dictionary */
167 bool remove(const char *key)
169 T *item = m_dict->take(key);
170 return item ? m_list->remove(item) : FALSE;
173 /*! Take an item out of the dictionary without deleting it */
174 T *take(const char *key)
176 T *item = m_dict->take(key);
179 int i = m_list->find(item);
185 /*! Sorts the members of the dictionary. First appending a number
186 * of members and then sorting them is faster (O(NlogN) than using
187 * inSort() for each member (O(N^2)).
193 /*! Inserts a compound into the dictionary in a sorted way.
194 * \param key The unique key to use to quicky find the item later on.
195 * \param d The compound to add.
198 void inSort(const char *key,const T *d)
201 m_dict->insert(key,d);
203 if (m_dict->size()>SDict_primes[m_sizeIndex])
205 m_dict->resize(SDict_primes[++m_sizeIndex]);
210 void insertAt(int i,const char *key,const T *d)
213 m_dict->insert(key,d);
215 if (m_dict->size()>SDict_primes[m_sizeIndex])
217 m_dict->resize(SDict_primes[++m_sizeIndex]);
222 /*! Indicates whether or not the dictionary owns its elements */
223 void setAutoDelete(bool val)
225 m_list->setAutoDelete(val);
228 /*! Looks up a compound given its key.
229 * \param key The key to identify this element.
230 * \return The requested compound or zero if it cannot be found.
233 T *find(const char *key)
235 return m_dict->find(key);
237 T *find(const QCString &key)
239 return m_dict->find(key);
241 T *find(const QString &key)
243 return m_dict->find(key);
245 int findAt(const QCString &key)
248 if (item==0) return -1;
249 return m_list->find(item);
252 /*! Equavalent to find(). */
253 T *operator[](const char *key) const
255 return m_dict->find(key);
258 /*! Returns the item at position \a i in the sorted dictionary */
261 return m_list->at(i);
264 /*! Function that is used to compare two items when sorting.
265 * Overload this to properly sort items.
268 virtual int compareItems(GCI item1,GCI item2)
273 /*! Clears the dictionary. Will delete items if setAutoDelete() was
283 /*! Returns the number of items stored in the dictionary
287 return m_list->count();
290 class Iterator; // first forward declare
291 friend class Iterator; // then make it a friend
292 /*! Simple iterator for SDict. It iterates in the order in which the
293 * elements are stored.
298 /*! Create an iterator given the dictionary. */
299 Iterator(const SDict<T> &dict)
301 m_li = new QListIterator<T>(*dict.m_list);
304 /*! Destroys the dictionary */
310 /*! Set the iterator to the first element in the list.
311 * \return The first compound, or zero if the list was empty.
315 return m_li->toFirst();
318 /*! Set the iterator to the last element in the list.
319 * \return The first compound, or zero if the list was empty.
323 return m_li->toLast();
326 /*! Returns the current compound */
329 return m_li->current();
332 /*! Moves the iterator to the next element.
333 * \return the new "current" element, or zero if the iterator was
334 * already pointing at the last element.
338 return m_li->operator++();
341 /*! Moves the iterator to the previous element.
342 * \return the new "current" element, or zero if the iterator was
343 * already pointing at the first element.
347 return m_li->operator--();
351 QListIterator<T> *m_li;
354 class IteratorDict; // first forward declare
355 friend class IteratorDict; // then make it a friend
356 /*! Simple iterator for SDict. It iterates over the dictionary elements
357 * in an unsorted way, but does provide information about the element's key.
362 /*! Create an iterator given the dictionary. */
363 IteratorDict(const SDict<T> &dict)
365 m_di = new QDictIterator<T>(*dict.m_dict);
368 /*! Destroys the dictionary */
369 virtual ~IteratorDict()
374 /*! Set the iterator to the first element in the list.
375 * \return The first compound, or zero if the list was empty.
379 return m_di->toFirst();
382 /*! Set the iterator to the last element in the list.
383 * \return The first compound, or zero if the list was empty.
387 return m_di->toLast();
390 /*! Returns the current compound */
393 return m_di->current();
396 /*! Returns the current key */
397 QCString currentKey() const
399 return m_di->currentKey();
402 /*! Moves the iterator to the next element.
403 * \return the new "current" element, or zero if the iterator was
404 * already pointing at the last element.
408 return m_di->operator++();
411 /*! Moves the iterator to the previous element.
412 * \return the new "current" element, or zero if the iterator was
413 * already pointing at the first element.
417 return m_di->operator--();
421 QDictIterator<T> *m_di;
425 /** internal wrapper class that redirects compareItems() to the
429 class SIntList : public QList<T>
432 SIntList(SIntDict<T> *owner) : m_owner(owner) {}
433 virtual ~SIntList() {}
434 int compareItems(GCI item1,GCI item2)
436 return m_owner->compareItems(item1,item2);
439 SIntDict<T> *m_owner;
442 /** Ordered dictionary of elements of type T.
443 * Internally uses a QList<T> and a QIntDict<T>.
454 /*! Create an ordered dictionary.
455 * \param size The size of the dictionary. Should be a prime number for
456 * best distribution of elements.
458 SIntDict(int size) : m_sizeIndex(0)
460 m_list = new SIntList<T>(this);
462 while ((uint)size>SDict_primes[m_sizeIndex]) m_sizeIndex++;
463 m_dict = new QIntDict<T>(SDict_primes[m_sizeIndex]);
465 m_dict = new QIntDict<T>(size);
469 /*! Destroys the dictionary */
476 /*! Appends a compound to the dictionary. The element is owned by the
478 * \param key The unique key to use to quicky find the item later on.
479 * \param d The compound to add.
482 void append(int key,const T *d)
485 m_dict->insert(key,d);
487 if (m_dict->size()>SDict_primes[m_sizeIndex])
489 m_dict->resize(SDict_primes[++m_sizeIndex]);
494 /*! Prepend a compound to the dictionary. The element is owned by the
496 * \param key The unique key to use to quicky find the item later on.
497 * \param d The compound to add.
500 void prepend(int key,const T *d)
503 m_dict->insert(key,d);
505 if (m_dict->size()>SDict_primes[m_sizeIndex])
507 m_dict->resize(SDict_primes[++m_sizeIndex]);
512 /*! Remove an item from the dictionary */
515 T *item = m_dict->take(key);
516 return item ? m_list->remove(item) : FALSE;
519 /*! Sorts the members of the dictionary. First appending a number
520 * of members and then sorting them is faster (O(NlogN) than using
521 * inSort() for each member (O(N^2)).
528 /*! Inserts a compound into the dictionary in a sorted way.
529 * \param key The unique key to use to quicky find the item later on.
530 * \param d The compound to add.
533 void inSort(int key,const T *d)
536 m_dict->insert(key,d);
538 if (m_dict->size()>SDict_primes[m_sizeIndex])
540 m_dict->resize(SDict_primes[++m_sizeIndex]);
545 /*! Indicates whether or not the dictionary owns its elements */
546 void setAutoDelete(bool val)
548 m_list->setAutoDelete(val);
551 /*! Looks up a compound given its key.
552 * \param key The key to identify this element.
553 * \return The requested compound or zero if it cannot be found.
558 return m_dict->find(key);
561 /*! Equavalent to find(). */
562 T *operator[](int key) const
564 return m_dict->find(key);
567 /*! Returns the item at position \a i in the sorted dictionary */
570 return m_list->at(i);
573 /*! Function that is used to compare two items when sorting.
574 * Overload this to properly sort items.
577 virtual int compareItems(GCI item1,GCI item2)
582 /*! Clears the dictionary. Will delete items if setAutoDelete() was
592 /*! Returns the number of items stored in the dictionary
596 return m_list->count();
599 class Iterator; // first forward declare
600 friend class Iterator; // then make it a friend
601 /*! Simple iterator for SDict. It iterates in the order in which the
602 * elements are stored.
607 /*! Create an iterator given the dictionary. */
608 Iterator(const SIntDict<T> &dict)
610 m_li = new QListIterator<T>(*dict.m_list);
613 /*! Destroys the dictionary */
619 /*! Set the iterator to the first element in the list.
620 * \return The first compound, or zero if the list was empty.
624 return m_li->toFirst();
627 /*! Set the iterator to the last element in the list.
628 * \return The first compound, or zero if the list was empty.
632 return m_li->toLast();
635 /*! Returns the current compound */
638 return m_li->current();
641 /*! Moves the iterator to the next element.
642 * \return the new "current" element, or zero if the iterator was
643 * already pointing at the last element.
647 return m_li->operator++();
650 /*! Moves the iterator to the previous element.
651 * \return the new "current" element, or zero if the iterator was
652 * already pointing at the first element.
656 return m_li->operator--();
660 QListIterator<T> *m_li;