00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef _NPT_MAP_H_
00011 #define _NPT_MAP_H_
00012
00013
00014
00015
00016 #include "NptTypes.h"
00017 #include "NptResults.h"
00018 #include "NptList.h"
00019
00020
00021
00022
00023 template <typename K, typename V>
00024 class NPT_Map
00025 {
00026 public:
00027
00028 class Entry {
00029 public:
00030
00031 Entry(const K& key, const V& value) : m_Key(key), m_Value(value) {}
00032 Entry(const K& key) : m_Key(key) {}
00033
00034
00035 const K& GetKey() const { return m_Key; }
00036 const V& GetValue() const { return m_Value; }
00037
00038
00039 bool operator==(const Entry& other) const {
00040 return m_Key == other.m_Key && m_Value == other.m_Value;
00041 }
00042
00043 protected:
00044
00045 void SetValue(const V& value) { m_Value = value; }
00046
00047
00048 K m_Key;
00049 V m_Value;
00050
00051
00052 friend class NPT_Map<K,V>;
00053 };
00054
00055 class EntryValueDeleter {
00056 public:
00057 void operator()(Entry* entry) const {
00058 delete entry->GetValue();
00059 }
00060 };
00061
00062
00063 NPT_Map<K,V>() {}
00064 NPT_Map<K,V>(const NPT_Map<K,V>& copy);
00065
00066
00067 ~NPT_Map<K,V>();
00068
00069
00070 NPT_Result Put(const K& key, const V& value);
00071 NPT_Result Get(const K& key, V*& value) const;
00072 bool HasKey(const K& key) const { return GetEntry(key) != NULL; }
00073 bool HasValue(const V& value) const;
00074 NPT_Result Erase(const K& key);
00075 NPT_Cardinal GetEntryCount() const { return m_Entries.GetItemCount(); }
00076 const NPT_List<Entry*>& GetEntries() const { return m_Entries; }
00077 NPT_Result Clear();
00078
00079
00080 V& operator[](const K& key);
00081 const NPT_Map<K,V>& operator=(const NPT_Map<K,V>& copy);
00082 bool operator==(const NPT_Map<K,V>& other) const;
00083 bool operator!=(const NPT_Map<K,V>& other) const;
00084
00085 private:
00086
00087 typedef typename NPT_List<Entry*>::Iterator ListIterator;
00088
00089
00090 Entry* GetEntry(const K& key) const;
00091
00092
00093 NPT_List<Entry*> m_Entries;
00094 };
00095
00096
00097
00098
00099 template <typename K, typename V>
00100 NPT_Map<K,V>::NPT_Map(const NPT_Map<K,V>& copy)
00101 {
00102 *this = copy;
00103 }
00104
00105
00106
00107
00108 template <typename K, typename V>
00109 inline
00110 NPT_Map<K,V>::~NPT_Map()
00111 {
00112
00113 Clear();
00114 }
00115
00116
00117
00118
00119 template <typename K, typename V>
00120 inline
00121 NPT_Result
00122 NPT_Map<K,V>::Clear()
00123 {
00124 m_Entries.Apply(NPT_ObjectDeleter<Entry>());
00125 m_Entries.Clear();
00126
00127 return NPT_SUCCESS;
00128 }
00129
00130
00131
00132
00133 template <typename K, typename V>
00134 typename NPT_Map<K,V>::Entry*
00135 NPT_Map<K,V>::GetEntry(const K& key) const
00136 {
00137 typename NPT_List<Entry*>::Iterator entry = m_Entries.GetFirstItem();
00138 while (entry) {
00139 if ((*entry)->GetKey() == key) {
00140 return *entry;
00141 }
00142 ++entry;
00143 }
00144
00145 return NULL;
00146 }
00147
00148
00149
00150
00151 template <typename K, typename V>
00152 inline
00153 NPT_Result
00154 NPT_Map<K,V>::Put(const K& key, const V& value)
00155 {
00156 Entry* entry = GetEntry(key);
00157 if (entry == NULL) {
00158
00159 m_Entries.Add(new Entry(key, value));
00160 } else {
00161
00162 entry->SetValue(value);
00163 }
00164
00165 return NPT_SUCCESS;
00166 }
00167
00168
00169
00170
00171 template <typename K, typename V>
00172 inline
00173 NPT_Result
00174 NPT_Map<K,V>::Get(const K& key, V*& value) const
00175 {
00176 Entry* entry = GetEntry(key);
00177 if (entry == NULL) {
00178
00179 value = NULL;
00180 return NPT_ERROR_NO_SUCH_ITEM;
00181 } else {
00182
00183 value = &entry->m_Value;
00184 return NPT_SUCCESS;
00185 }
00186 }
00187
00188
00189
00190
00191 template <typename K, typename V>
00192 bool
00193 NPT_Map<K,V>::HasValue(const V& value) const
00194 {
00195 ListIterator entry = m_Entries.GetFirstItem();
00196 while (entry) {
00197 if (value == (*entry)->m_Value) {
00198 return true;
00199 }
00200 ++entry;
00201 }
00202
00203 return false;
00204 }
00205
00206
00207
00208
00209 template <typename K, typename V>
00210 const NPT_Map<K,V>&
00211 NPT_Map<K,V>::operator=(const NPT_Map<K,V>& copy)
00212 {
00213
00214 if (this == ©) return copy;
00215
00216
00217 Clear();
00218
00219
00220 ListIterator entry = copy.m_Entries.GetFirstItem();
00221 while (entry) {
00222 m_Entries.Add(new Entry((*entry)->GetKey(), (*entry)->GetValue()));
00223 ++entry;
00224 }
00225
00226 return *this;
00227 }
00228
00229
00230
00231
00232 template <typename K, typename V>
00233 inline
00234 NPT_Result
00235 NPT_Map<K,V>::Erase(const K& key)
00236 {
00237 ListIterator entry = m_Entries.GetFirstItem();
00238 while (entry) {
00239 if ((*entry)->GetKey() == key) {
00240 delete *entry;
00241
00242
00243 m_Entries.Erase(entry);
00244 return NPT_SUCCESS;
00245 }
00246 ++entry;
00247 }
00248
00249 return NPT_ERROR_NO_SUCH_ITEM;
00250 }
00251
00252
00253
00254
00255 template <typename K, typename V>
00256 bool
00257 NPT_Map<K,V>::operator==(const NPT_Map<K,V>& other) const
00258 {
00259
00260 if (m_Entries.GetItemCount() != other.m_Entries.GetItemCount()) return false;
00261
00262
00263 ListIterator entry = m_Entries.GetFirstItem();
00264 while (entry) {
00265 V* value;
00266 if (NPT_SUCCEEDED(other.Get((*entry)->m_Key, value))) {
00267
00268 if (!(*value == (*entry)->m_Value)) return false;
00269 } else {
00270
00271 return false;
00272 }
00273 ++entry;
00274 }
00275
00276 return true;
00277 }
00278
00279
00280
00281
00282 template <typename K, typename V>
00283 inline
00284 bool
00285 NPT_Map<K,V>::operator!=(const NPT_Map<K,V>& other) const
00286 {
00287 return !(*this == other);
00288 }
00289
00290
00291
00292
00293 template <typename K, typename V>
00294 inline
00295 V&
00296 NPT_Map<K,V>::operator[](const K& key)
00297 {
00298 Entry* entry = GetEntry(key);
00299 if (entry == NULL) {
00300
00301 entry = new Entry(key);
00302 m_Entries.Add(entry);
00303 }
00304
00305 return entry->m_Value;
00306 }
00307
00308 #endif // _NPT_MAP_H_