Blender  V2.59
CTR_Map.h
Go to the documentation of this file.
00001 /*
00002  * $Id: CTR_Map.h 36523 2011-05-06 20:18:42Z blendix $
00003  * ***** BEGIN GPL LICENSE BLOCK *****
00004  *
00005  * This program is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License
00007  * as published by the Free Software Foundation; either version 2
00008  * of the License, or (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software Foundation,
00017  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00018  *
00019  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00020  * All rights reserved.
00021  *
00022  * The Original Code is: all of this file.
00023  *
00024  * Contributor(s): none yet.
00025  *
00026  * ***** END GPL LICENSE BLOCK *****
00027  */
00028 
00034 #ifndef CTR_MAP_H
00035 #define CTR_MAP_H
00036 
00037 template <class Key, class Value>
00038 class CTR_Map {
00039 private:
00040     struct Entry {
00041         Entry (Entry *next, Key key, Value value) :
00042             m_next(next),
00043             m_key(key),
00044             m_value(value) {}
00045 
00046         Entry *m_next;
00047         Key    m_key;
00048         Value  m_value;
00049     };
00050  
00051 public:
00052     CTR_Map(int num_buckets = 100) : m_num_buckets(num_buckets) {
00053         m_buckets = new Entry *[num_buckets];
00054         for (int i = 0; i < num_buckets; ++i) {
00055             m_buckets[i] = 0;
00056         }
00057     }
00058 
00059         CTR_Map(const CTR_Map& map)
00060         {
00061                 m_num_buckets = map.m_num_buckets;
00062                 m_buckets = new Entry *[m_num_buckets];
00063 
00064                 for (int i = 0; i < m_num_buckets; ++i) {
00065                         m_buckets[i] = 0;
00066 
00067                         for(Entry *entry = map.m_buckets[i]; entry; entry=entry->m_next)
00068                                 insert(entry->m_key, entry->m_value);
00069                 }
00070         }
00071     
00072     int size() { 
00073         int count=0;
00074         for (int i=0;i<m_num_buckets;i++)
00075         {
00076             Entry* bucket = m_buckets[i];
00077             while(bucket)
00078             {
00079                 bucket = bucket->m_next;
00080                 count++;
00081             }
00082         }
00083         return count;
00084     }
00085     
00086     Value* at(int index) {
00087         int count=0;
00088         for (int i=0;i<m_num_buckets;i++)
00089         {
00090             Entry* bucket = m_buckets[i];
00091             while(bucket)
00092             {
00093                 if (count==index)
00094                 {
00095                     return &bucket->m_value;
00096                 }
00097                 bucket = bucket->m_next;
00098                 count++;
00099             }
00100         }
00101         return 0;
00102     }
00103 
00104     Key* getKey(int index) {
00105         int count=0;
00106         for (int i=0;i<m_num_buckets;i++)
00107         {
00108             Entry* bucket = m_buckets[i];
00109             while(bucket)
00110             {
00111                 if (count==index)
00112                 {
00113                     return &bucket->m_key;
00114                 }
00115                 bucket = bucket->m_next;
00116                 count++;
00117             }
00118         }
00119         return 0;
00120     }
00121     
00122     void clear() {
00123         for (int i = 0; i < m_num_buckets; ++i) {
00124             Entry *entry_ptr = m_buckets[i];
00125             
00126             while (entry_ptr != 0) {
00127                 Entry *tmp_ptr = entry_ptr->m_next;
00128                 delete entry_ptr;
00129                 entry_ptr = tmp_ptr;
00130             }
00131             m_buckets[i] = 0;
00132         }
00133     }
00134     
00135     ~CTR_Map() {
00136         clear();
00137         delete [] m_buckets;
00138     }
00139     
00140     void insert(const Key& key, const Value& value) {
00141         Entry *entry_ptr = m_buckets[key.hash() % m_num_buckets];
00142         while ((entry_ptr != 0) && !(key == entry_ptr->m_key)) {
00143             entry_ptr = entry_ptr->m_next;
00144         }
00145         
00146         if (entry_ptr != 0) {
00147             entry_ptr->m_value = value;
00148         }
00149         else {
00150             Entry **bucket = &m_buckets[key.hash() % m_num_buckets];
00151             *bucket = new Entry(*bucket, key, value);
00152         }
00153     }
00154 
00155     void remove(const Key& key) {
00156         Entry **entry_ptr = &m_buckets[key.hash() % m_num_buckets];
00157         while ((*entry_ptr != 0) && !(key == (*entry_ptr)->m_key)) {
00158             entry_ptr = &(*entry_ptr)->m_next;
00159         }
00160         
00161         if (*entry_ptr != 0) {
00162             Entry *tmp_ptr = (*entry_ptr)->m_next;
00163             delete *entry_ptr;
00164             *entry_ptr = tmp_ptr;
00165         }
00166     }
00167 
00168     Value *operator[](Key key) {
00169         Entry *bucket = m_buckets[key.hash() % m_num_buckets];
00170         while ((bucket != 0) && !(key == bucket->m_key)) {
00171             bucket = bucket->m_next;
00172         }
00173         return bucket != 0 ? &bucket->m_value : 0;
00174     }
00175     
00176 private:
00177     int     m_num_buckets;
00178     Entry **m_buckets;
00179 };
00180 
00181 #endif
00182