00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef _cvcl__include__cdmap_h_
00030 #define _cvcl__include__cdmap_h_
00031
00032 #include <iterator>
00033 #include "context.h"
00034
00035 namespace CVCL {
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 template <class Key, class Data, class HashFcn = std::hash<Key> > class CDMap;
00055
00056 template <class Key, class Data, class HashFcn = std::hash<Key> >
00057 class CDOmap :public ContextObj {
00058 Key d_key;
00059 Data d_data;
00060 bool d_inMap;
00061 CDMap<Key, Data, HashFcn>* d_cdmap;
00062
00063
00064 CDOmap<Key, Data, HashFcn>* d_prev;
00065 CDOmap<Key, Data, HashFcn>* d_next;
00066
00067 virtual ContextObj* makeCopy(void) { return new CDOmap<Key, Data, HashFcn>(*this); }
00068
00069 virtual void restoreData(ContextObj* data) {
00070 CDOmap<Key, Data, HashFcn>* p((CDOmap<Key, Data, HashFcn>*)data);
00071 if(p->d_inMap) { d_data = p->d_data; d_inMap = true; }
00072 else setNull();
00073 }
00074 virtual void setNull(void) {
00075
00076
00077
00078 if(d_cdmap->d_map.count(d_key) > 0) {
00079 d_cdmap->d_map.erase(d_key);
00080 d_cdmap->d_trash.push_back(this);
00081 }
00082 d_prev->d_next = d_next;
00083 d_next->d_prev = d_prev;
00084 if (d_cdmap->d_first == this) {
00085 d_cdmap->d_first = d_next;
00086 if (d_next == this) {
00087 d_cdmap->d_first = NULL;
00088 }
00089 }
00090 }
00091
00092 public:
00093 CDOmap(Context* context, CDMap<Key, Data, HashFcn>* cdmap,
00094 const Key& key, const Data& data, int scope = -1)
00095 : ContextObj(context, true ),
00096 d_key(key), d_inMap(false), d_cdmap(cdmap) {
00097 set(data, scope);
00098 IF_DEBUG(setName("CDOmap"));
00099 CDOmap<Key, Data, HashFcn>*& first = d_cdmap->d_first;
00100 if (first == NULL) {
00101 first = d_next = d_prev = this;
00102 }
00103 else {
00104 d_prev = first->d_prev;
00105 d_next = first;
00106 d_prev->d_next = first->d_prev = this;
00107 }
00108 }
00109 ~CDOmap() {}
00110 void set(const Data& data, int scope=-1) {
00111 makeCurrent(scope); d_data = data; d_inMap = true;
00112 }
00113 const Key& getKey() const { return d_key; }
00114 const Data& get() const { return d_data; }
00115 operator Data() { return get(); }
00116 CDOmap<Key, Data, HashFcn>& operator=(const Data& data) { set(data); return *this; }
00117 CDOmap<Key, Data, HashFcn>* next() const {
00118 if (d_next == d_cdmap->d_first) return NULL;
00119 else return d_next;
00120 }
00121 };
00122
00123
00124 class CDMapData : public ContextObj {
00125 ContextObj* makeCopy(void) { return new CDMapData(*this); }
00126 void restoreData(ContextObj* data) { }
00127 void setNull(void) { }
00128 public:
00129 CDMapData(Context* context): ContextObj(context) { }
00130 CDMapData(const ContextObj& co): ContextObj(co) { }
00131 };
00132
00133
00134 template <class Key, class Data, class HashFcn>
00135 class CDMap: public ContextObj {
00136 friend class CDOmap<Key, Data, HashFcn>;
00137 private:
00138 std::hash_map<Key,CDOmap<Key, Data, HashFcn>*> d_map;
00139
00140 std::vector<CDOmap<Key, Data, HashFcn>*> d_trash;
00141 CDOmap<Key, Data, HashFcn>* d_first;
00142 Context* d_context;
00143
00144
00145 virtual ContextObj* makeCopy(void) { return new CDMapData(*this); }
00146
00147 virtual void restoreData(ContextObj* data) { }
00148
00149
00150 void emptyTrash() {
00151 for(typename std::vector<CDOmap<Key, Data, HashFcn>*>::iterator
00152 i=d_trash.begin(), iend=d_trash.end(); i!=iend; ++i)
00153 delete *i;
00154 d_trash.clear();
00155 }
00156
00157 virtual void setNull(void) {
00158
00159 for(typename std::hash_map<Key,CDOmap<Key, Data, HashFcn>*>::iterator
00160 i=d_map.begin(), iend=d_map.end();
00161 i!=iend; ++i) delete (*i).second;
00162 d_map.clear();
00163 emptyTrash();
00164 }
00165 public:
00166 CDMap(Context* context, int scope = -1)
00167 : ContextObj(context), d_first(NULL), d_context(context) {
00168 IF_DEBUG(setName("CDMap"));
00169 }
00170 ~CDMap() { setNull(); }
00171
00172 size_t size() const { return d_map.size(); }
00173 size_t count(const Key& k) const { return d_map.count(k); }
00174
00175
00176 CDOmap<Key, Data, HashFcn>& operator[](const Key& k) {
00177 emptyTrash();
00178 typename std::hash_map<Key,CDOmap<Key, Data, HashFcn>*>::iterator i(d_map.find(k));
00179 CDOmap<Key, Data, HashFcn>* obj;
00180 if(i == d_map.end()) {
00181 obj = new CDOmap<Key, Data, HashFcn>(d_context, this, k, Data());
00182 d_map[k] = obj;
00183 } else {
00184 obj = (*i).second;
00185 }
00186 return *obj;
00187 }
00188
00189 void insert(const Key& k, const Data& d, int scope = -1) {
00190 emptyTrash();
00191 typename std::hash_map<Key,CDOmap<Key, Data, HashFcn>*>::iterator i(d_map.find(k));
00192 if(i == d_map.end()) {
00193 CDOmap<Key, Data, HashFcn>*
00194 obj(new CDOmap<Key, Data, HashFcn>(d_context, this, k, d, scope));
00195 d_map[k] = obj;
00196 } else {
00197 (*i).second->set(d, scope);
00198 }
00199 }
00200
00201
00202
00203
00204 class iterator : public std::iterator<std::input_iterator_tag,std::pair<const Key, Data>,std::ptrdiff_t> {
00205 private:
00206
00207 typename std::hash_map<Key,CDOmap<Key, Data, HashFcn>*>::const_iterator d_it;
00208 public:
00209
00210 iterator(const typename std::hash_map<Key,CDOmap<Key, Data, HashFcn>*>::const_iterator& i)
00211 : d_it(i) { }
00212
00213 iterator(const iterator& i): d_it(i.d_it) { }
00214
00215 iterator() { }
00216
00217 bool operator==(const iterator& i) const {
00218 return d_it == i.d_it;
00219 }
00220 bool operator!=(const iterator& i) const {
00221 return d_it != i.d_it;
00222 }
00223
00224 std::pair<const Key, Data> operator*() const {
00225 const std::pair<const Key, CDOmap<Key, Data, HashFcn>*>& p(*d_it);
00226 return std::pair<const Key, Data>(p.first, *p.second);
00227 }
00228
00229
00230
00231
00232
00233
00234
00235
00236 iterator& operator++() { ++d_it; return *this; }
00237
00238
00239 class Proxy {
00240 const std::pair<const Key, Data>* d_pair;
00241 public:
00242 Proxy(const std::pair<const Key, Data>& p): d_pair(&p) { }
00243 std::pair<const Key, Data>& operator*() { return *d_pair; }
00244 };
00245
00246
00247
00248
00249 Proxy operator++(int) {
00250 Proxy e(*(*this));
00251 ++(*this);
00252 return e;
00253 }
00254 };
00255
00256 iterator begin() const { return iterator(d_map.begin()); }
00257 iterator end() const { return iterator(d_map.end()); }
00258
00259 class orderedIterator {
00260 const CDOmap<Key, Data, HashFcn>* d_it;
00261 public:
00262 orderedIterator(const CDOmap<Key, Data, HashFcn>* p): d_it(p) {}
00263 orderedIterator(const orderedIterator& i): d_it(i.d_it) { }
00264
00265 orderedIterator() { }
00266
00267 bool operator==(const orderedIterator& i) const {
00268 return d_it == i.d_it;
00269 }
00270 bool operator!=(const orderedIterator& i) const {
00271 return d_it != i.d_it;
00272 }
00273
00274 std::pair<const Key, Data> operator*() const {
00275 return std::pair<const Key, Data>(d_it->getKey(), d_it->get());
00276 }
00277
00278
00279 orderedIterator& operator++() { d_it = d_it->next(); return *this; }
00280
00281
00282 class Proxy {
00283 const std::pair<const Key, Data>* d_pair;
00284 public:
00285 Proxy(const std::pair<const Key, Data>& p): d_pair(&p) { }
00286 std::pair<const Key, Data>& operator*() { return *d_pair; }
00287 };
00288
00289
00290
00291
00292 Proxy operator++(int) {
00293 Proxy e(*(*this));
00294 ++(*this);
00295 return e;
00296 }
00297 };
00298
00299 orderedIterator orderedBegin() const { return orderedIterator(d_first); }
00300 orderedIterator orderedEnd() const { return orderedIterator(NULL); }
00301
00302 iterator find(const Key& k) const { return iterator(d_map.find(k)); }
00303
00304 };
00305
00306
00307 }
00308
00309 #endif