diff -r 000000000000 -r 42188c7ea2d9 Orb/Doxygen/src/sortdict.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Orb/Doxygen/src/sortdict.h Thu Jan 21 17:29:01 2010 +0000 @@ -0,0 +1,647 @@ +/****************************************************************************** + * + * + * + * + * Copyright (C) 1997-2008 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + */ + +#ifndef _SORTDICT_H +#define _SORTDICT_H + +#include "qtbc.h" +#include +#include +#include + +#define AUTORESIZE 1 + +#if AUTORESIZE +const uint SDict_primes[] = +{ + 17, + 29, + 47, + 71, + 113, + 179, + 293, + 457, + 733, + 1171, + 1871, + 2999, + 4787, + 7669, + 12251, + 19603, + 31379, + 50177, + 80287, + 128449, + 205519, + 328829, + 526139, + 841801, + 1346881, + 2155007, + 3448033, + 5516827, + 8826919, + 14123059, + 23538433, + 39230771, + 65384537, + 108974231, + 181623707, + 302706181, + 504510283, + 840850487, + 0xffffffff +}; +#endif + +template class SDict; +template class SIntDict; + +/*! internal wrapper class that redirects compareItems() to the + * dictionary + */ +template +class SList : public QList +{ + public: + SList(SDict *owner) : m_owner(owner) {} + virtual ~SList() {} + int compareItems(GCI item1,GCI item2) + { + return m_owner->compareItems(item1,item2); + } + private: + SDict *m_owner; +}; + +/*! Ordered dictionary of elements of type T. + * Internally uses a QList and a QDict. + */ +template +class SDict +{ + private: + SList *m_list; + QDict *m_dict; + int m_sizeIndex; + + public: + /*! Create an ordered dictionary. + * \param size The size of the dictionary. Should be a prime number for + * best distribution of elements. + * \param caseSensitive indicated whether the keys should be sorted + * in a case sensitive way. + */ + SDict(int size,bool caseSensitive=TRUE) : m_sizeIndex(0) + { + m_list = new SList(this); +#if AUTORESIZE + while ((uint)size>SDict_primes[m_sizeIndex]) m_sizeIndex++; + m_dict = new QDict(SDict_primes[m_sizeIndex],caseSensitive); +#else + m_dict = new QDict(size,caseSensitive); +#endif + } + + /*! Destroys the dictionary */ + virtual ~SDict() + { + delete m_list; + delete m_dict; + } + + /*! Appends an element to the dictionary. The element is owned by the + * dictionary. + * \param key The unique key to use to quicky find the item later on. + * \param d The compound to add. + * \sa find() + */ + void append(const char *key,const T *d) + { + m_list->append(d); + m_dict->insert(key,d); +#if AUTORESIZE + if (m_dict->size()>SDict_primes[m_sizeIndex]) + { + m_dict->resize(SDict_primes[++m_sizeIndex]); + } +#endif + } + + /*! Prepends an element to the dictionary. The element is owned by the + * dictionary. + * \param key The unique key to use to quicky find the item later on. + * \param d The compound to add. + * \sa find() + */ + void prepend(const char *key,const T *d) + { + m_list->prepend(d); + m_dict->insert(key,d); +#if AUTORESIZE + if (m_dict->size()>SDict_primes[m_sizeIndex]) + { + m_dict->resize(SDict_primes[++m_sizeIndex]); + } +#endif + } + + /*! Remove an item from the dictionary */ + bool remove(const char *key) + { + T *item = m_dict->take(key); + return item ? m_list->remove(item) : FALSE; + } + + /*! Take an item out of the dictionary without deleting it */ + T *take(const char *key) + { + T *item = m_dict->take(key); + if (item) + { + int i = m_list->find(item); + m_list->take(i); + } + return item; + } + + /*! Sorts the members of the dictionary. First appending a number + * of members and then sorting them is faster (O(NlogN) than using + * inSort() for each member (O(N^2)). + */ + void sort() + { + m_list->sort(); + } + /*! Inserts a compound into the dictionary in a sorted way. + * \param key The unique key to use to quicky find the item later on. + * \param d The compound to add. + * \sa find() + */ + void inSort(const char *key,const T *d) + { + m_list->inSort(d); + m_dict->insert(key,d); +#if AUTORESIZE + if (m_dict->size()>SDict_primes[m_sizeIndex]) + { + m_dict->resize(SDict_primes[++m_sizeIndex]); + } +#endif + } + + /*! Indicates whether or not the dictionary owns its elements */ + void setAutoDelete(bool val) + { + m_list->setAutoDelete(val); + } + + /*! Looks up a compound given its key. + * \param key The key to identify this element. + * \return The requested compound or zero if it cannot be found. + * \sa append() + */ + T *find(const char *key) + { + return m_dict->find(key); + } + T *find(const QCString &key) + { + return m_dict->find(key); + } + T *find(const QString &key) + { + return m_dict->find(key); + } + + /*! Equavalent to find(). */ + T *operator[](const char *key) const + { + return m_dict->find(key); + } + + /*! Returns the item at position \a i in the sorted dictionary */ + T *at(uint i) + { + return m_list->at(i); + } + + /*! Function that is used to compare two items when sorting. + * Overload this to properly sort items. + * \sa inSort() + */ + virtual int compareItems(GCI item1,GCI item2) + { + return item1!=item2; + } + + /*! Clears the dictionary. Will delete items if setAutoDelete() was + * set to \c TRUE. + * \sa setAutoDelete + */ + void clear() + { + m_list->clear(); + m_dict->clear(); + } + + /*! Returns the number of items stored in the dictionary + */ + int count() const + { + return m_list->count(); + } + + class Iterator; // first forward declare + friend class Iterator; // then make it a friend + /*! Simple iterator for SDict. It iterates in the order in which the + * elements are stored. + */ + class Iterator + { + public: + /*! Create an iterator given the dictionary. */ + Iterator(const SDict &dict) + { + m_li = new QListIterator(*dict.m_list); + } + + /*! Destroys the dictionary */ + virtual ~Iterator() + { + delete m_li; + } + + /*! Set the iterator to the first element in the list. + * \return The first compound, or zero if the list was empty. + */ + T *toFirst() const + { + return m_li->toFirst(); + } + + /*! Set the iterator to the last element in the list. + * \return The first compound, or zero if the list was empty. + */ + T *toLast() const + { + return m_li->toLast(); + } + + /*! Returns the current compound */ + T *current() const + { + return m_li->current(); + } + + /*! Moves the iterator to the next element. + * \return the new "current" element, or zero if the iterator was + * already pointing at the last element. + */ + T *operator++() + { + return m_li->operator++(); + } + + /*! Moves the iterator to the previous element. + * \return the new "current" element, or zero if the iterator was + * already pointing at the first element. + */ + T *operator--() + { + return m_li->operator--(); + } + + private: + QListIterator *m_li; + }; + + class IteratorDict; // first forward declare + friend class IteratorDict; // then make it a friend + /*! Simple iterator for SDict. It iterates in over the dictionary elements + * in an unsorted way, but does provide information about the element's key. + */ + class IteratorDict + { + public: + /*! Create an iterator given the dictionary. */ + IteratorDict(const SDict &dict) + { + m_di = new QDictIterator(*dict.m_dict); + } + + /*! Destroys the dictionary */ + virtual ~IteratorDict() + { + delete m_di; + } + + /*! Set the iterator to the first element in the list. + * \return The first compound, or zero if the list was empty. + */ + T *toFirst() const + { + return m_di->toFirst(); + } + + /*! Set the iterator to the last element in the list. + * \return The first compound, or zero if the list was empty. + */ + T *toLast() const + { + return m_di->toLast(); + } + + /*! Returns the current compound */ + T *current() const + { + return m_di->current(); + } + + /*! Returns the current key */ + QCString currentKey() const + { + return m_di->currentKey(); + } + + /*! Moves the iterator to the next element. + * \return the new "current" element, or zero if the iterator was + * already pointing at the last element. + */ + T *operator++() + { + return m_di->operator++(); + } + + /*! Moves the iterator to the previous element. + * \return the new "current" element, or zero if the iterator was + * already pointing at the first element. + */ + T *operator--() + { + return m_di->operator--(); + } + + private: + QDictIterator *m_di; + }; +}; + +/*! internal wrapper class that redirects compareItems() to the + * dictionary + */ +template +class SIntList : public QList +{ + public: + SIntList(SIntDict *owner) : m_owner(owner) {} + virtual ~SIntList() {} + int compareItems(GCI item1,GCI item2) + { + return m_owner->compareItems(item1,item2); + } + private: + SIntDict *m_owner; +}; + +/*! Ordered dictionary of elements of type T. + * Internally uses a QList and a QIntDict. + */ +template +class SIntDict +{ + private: + SIntList *m_list; + QIntDict *m_dict; + int m_sizeIndex; + + public: + /*! Create an ordered dictionary. + * \param size The size of the dictionary. Should be a prime number for + * best distribution of elements. + */ + SIntDict(int size) : m_sizeIndex(0) + { + m_list = new SIntList(this); +#if AUTORESIZE + while ((uint)size>SDict_primes[m_sizeIndex]) m_sizeIndex++; + m_dict = new QIntDict(SDict_primes[m_sizeIndex]); +#else + m_dict = new QIntDict(size); +#endif + } + + /*! Destroys the dictionary */ + virtual ~SIntDict() + { + delete m_list; + delete m_dict; + } + + /*! Appends a compound to the dictionary. The element is owned by the + * dictionary. + * \param key The unique key to use to quicky find the item later on. + * \param d The compound to add. + * \sa find() + */ + void append(int key,const T *d) + { + m_list->append(d); + m_dict->insert(key,d); +#if AUTORESIZE + if (m_dict->size()>SDict_primes[m_sizeIndex]) + { + m_dict->resize(SDict_primes[++m_sizeIndex]); + } +#endif + } + + /*! Prepend a compound to the dictionary. The element is owned by the + * dictionary. + * \param key The unique key to use to quicky find the item later on. + * \param d The compound to add. + * \sa find() + */ + void prepend(int key,const T *d) + { + m_list->prepend(d); + m_dict->insert(key,d); +#if AUTORESIZE + if (m_dict->size()>SDict_primes[m_sizeIndex]) + { + m_dict->resize(SDict_primes[++m_sizeIndex]); + } +#endif + } + + /*! Remove an item from the dictionary */ + bool remove(int key) + { + T *item = m_dict->take(key); + return item ? m_list->remove(item) : FALSE; + } + + /*! Sorts the members of the dictionary. First appending a number + * of members and then sorting them is faster (O(NlogN) than using + * inSort() for each member (O(N^2)). + */ + void sort() + { + m_list->sort(); + } + + /*! Inserts a compound into the dictionary in a sorted way. + * \param key The unique key to use to quicky find the item later on. + * \param d The compound to add. + * \sa find() + */ + void inSort(int key,const T *d) + { + m_list->inSort(d); + m_dict->insert(key,d); +#if AUTORESIZE + if (m_dict->size()>SDict_primes[m_sizeIndex]) + { + m_dict->resize(SDict_primes[++m_sizeIndex]); + } +#endif + } + + /*! Indicates whether or not the dictionary owns its elements */ + void setAutoDelete(bool val) + { + m_list->setAutoDelete(val); + } + + /*! Looks up a compound given its key. + * \param key The key to identify this element. + * \return The requested compound or zero if it cannot be found. + * \sa append() + */ + T *find(int key) + { + return m_dict->find(key); + } + + /*! Equavalent to find(). */ + T *operator[](int key) const + { + return m_dict->find(key); + } + + /*! Returns the item at position \a i in the sorted dictionary */ + T *at(uint i) + { + return m_list->at(i); + } + + /*! Function that is used to compare two items when sorting. + * Overload this to properly sort items. + * \sa inSort() + */ + virtual int compareItems(GCI item1,GCI item2) + { + return item1!=item2; + } + + /*! Clears the dictionary. Will delete items if setAutoDelete() was + * set to \c TRUE. + * \sa setAutoDelete + */ + void clear() + { + m_list->clear(); + m_dict->clear(); + } + + /*! Returns the number of items stored in the dictionary + */ + int count() + { + return m_list->count(); + } + + class Iterator; // first forward declare + friend class Iterator; // then make it a friend + /*! Simple iterator for SDict. It iterates in the order in which the + * elements are stored. + */ + class Iterator + { + public: + /*! Create an iterator given the dictionary. */ + Iterator(const SIntDict &dict) + { + m_li = new QListIterator(*dict.m_list); + } + + /*! Destroys the dictionary */ + virtual ~Iterator() + { + delete m_li; + } + + /*! Set the iterator to the first element in the list. + * \return The first compound, or zero if the list was empty. + */ + T *toFirst() const + { + return m_li->toFirst(); + } + + /*! Set the iterator to the last element in the list. + * \return The first compound, or zero if the list was empty. + */ + T *toLast() const + { + return m_li->toLast(); + } + + /*! Returns the current compound */ + T *current() const + { + return m_li->current(); + } + + /*! Moves the iterator to the next element. + * \return the new "current" element, or zero if the iterator was + * already pointing at the last element. + */ + T *operator++() + { + return m_li->operator++(); + } + + /*! Moves the iterator to the previous element. + * \return the new "current" element, or zero if the iterator was + * already pointing at the first element. + */ + T *operator--() + { + return m_li->operator--(); + } + + private: + QListIterator *m_li; + }; + +}; + +#endif