123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- #ifndef __FIXEDMAP_H
- #define __FIXEDMAP_H
- /*
- An STL map-like container. Quickly thrown together to replace STL maps
- in specific instances. Many gotchas. Use with caution.
- */
- #include <stdlib.h>
- template < class T, class U >
- class VVFixedMap
- {
- private:
- struct Data {
- T data;
- U key;
- };
- Data *items;
- unsigned int numItems;
- unsigned int maxItems;
- VVFixedMap(void) {}
- public:
- VVFixedMap(unsigned int maxItems)
- {
- items = new Data[maxItems];
- numItems = 0;
- this->maxItems = maxItems;
- }
- ~VVFixedMap(void)
- {
- items -= ( maxItems - numItems );
- delete [] items;
- numItems = 0;
- }
- bool Insert(const T &newItem, const U &key)
- {
- Data *storage = NULL;
- //Check for fullness.
- if(numItems >= maxItems) {
- assert( 0 );
- return false;
- }
- //Check for reuse.
- if(!FindUnsorted(key, storage)) {
- storage = items + numItems;
- numItems++;
- }
- else
- assert( 0 );
- storage->data = newItem;
- storage->key = key;
- return true;
- }
- // Faster version of Insert(), but it doesn't check for dupes. Used
- // by the filecode cache (when we know the data we're inserting is good).
- bool InsertUnsafe(const T &newItem, const U &key)
- {
- //Check for fullness.
- if(numItems >= maxItems) {
- return false;
- }
- Data *storage = items + numItems;
- numItems++;
- storage->data = newItem;
- storage->key = key;
- return true;
- }
- void Sort(void)
- {
- qsort(items, numItems, sizeof(Data),
- VVFixedMap< T, U >::FixedMapSorter);
- }
- //Binary search, items must have been sorted!
- T *Find(const U &key)
- {
- int i;
- int high;
- int low;
- for(low = -1, high = numItems; high - low > 1; ) {
- i = (high + low) / 2;
- if(key < items[i].key) {
- high = i;
- } else if(key > items[i].key) {
- low = i;
- } else {
- return &items[i].data;
- }
- }
- if(items[i+1].key == key) {
- return &items[i+1].data;
- } else if(items[i-1].key == key) {
- return &items[i-1].data;
- }
- return NULL;
- }
- //Slower, but don't need to call sort first.
- T *FindUnsorted(const U &key, Data *&storage)
- {
- int i;
- for(i=0; i<numItems; i++) {
- if(items[i].key == key) {
- storage = items + i;
- return &items[i].data;
- }
- }
- return NULL;
- }
- // returns the top item's data
- // and removes the item from the map
- T *Pop(void)
- {
- T* top = NULL;
- if(numItems)
- {
- top = &items[0].data;
- items++;
- numItems--;
- }
- return top;
- }
- static int FixedMapSorter(const void *a, const void *b)
- {
- if(((Data*)a)->key > ((Data*)b)->key) {
- return 1;
- } else if(((Data*)a)->key == ((Data*)b)->key) {
- return 0;
- } else {
- return -1;
- }
- }
- };
- #endif
|