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