00001 #include <set>
00002
00003 template <class T> class MutableShell {
00004 mutable T t;
00005 public:
00006 MutableShell (const T &t) : t(t) {}
00007 T &get ()const {return t;}
00008 T &operator* ()const {return t;}
00009 T *operator-> ()const {return &t;}
00010 operator T& () const {return t;}
00011 bool operator< (const MutableShell <T>& other) const {return t<other.t;}
00012 };
00013
00015 template <class T, class _Compare = std::less <MutableShell<T> > >
00016 class MutableSet: public std::multiset <MutableShell<T>,_Compare> {
00017 typedef std::multiset <MutableShell<T>,_Compare> SUPER;
00018 };
00019
00020 template <class T> class KeyMutableShell {
00021 mutable T *t;
00022 public:
00023 KeyMutableShell (T *t) :t(t) {}
00024 T &get ()const {return *t;}
00025 T &operator* ()const {return *t;}
00026 T *operator-> ()const {return t;}
00027 operator T* () const {return t;}
00028 bool operator< (const KeyMutableShell <T>& other) const {return (*t)<(*other.t);}
00029 };
00030
00032
00033 template <class Key, class T, class _Compare = std::less <KeyMutableShell<T> > >
00034 class KeyMutableSet : public std::multiset <KeyMutableShell<T>,_Compare> {
00035 typedef std::multiset <KeyMutableShell<T>,_Compare> SUPER;
00036 T &valueFromKey (const Key &key) {
00037 static T t;
00038 t.changeKey(key);
00039 return t;
00040 }
00041 public:
00043 typename SUPER::iterator find (T &key) {
00044 return SUPER::find(KeyMutableShell<T>(&key));
00045 }
00047 typename SUPER::iterator find (const Key &key) {
00048 return find(valueFromKey(key));
00049 }
00051 typename SUPER::iterator lower_bound (T &key) {
00052 return SUPER::lower_bound(KeyMutableShell<T>(&key));
00053 }
00055 typename SUPER::iterator lower_bound (const Key &key) {
00056 return lower_bound(valueFromKey(key));
00057 }
00059 typename SUPER::iterator upper_bound (T &key) {
00060 return SUPER::upper_bound(KeyMutableShell<T>(&key));
00061 }
00063 typename SUPER::iterator upper_bound (const Key &key) {
00064 return upper_bound(valueFromKey(key));
00065 }
00067 void checkSet () {
00068 _Compare comparator;
00069 if (begin()!=end()) {
00070 for (typename SUPER::iterator newiter=begin(), iter=newiter++;newiter!=end();iter=newiter++) {
00071 if (comparator(*newiter,*iter)) {
00072 printf("ERROR: keys out of order!!!!!!\n");
00073 }
00074 }
00075 }
00076 }
00078
00081 typename SUPER::iterator changeKey (typename SUPER::iterator iter, const Key & newKey) {
00082 typename SUPER::iterator templess=iter,tempmore=iter;
00083 tempmore++;
00084 if (templess!=begin())
00085 templess--;
00086 _Compare comparator;
00087 KeyMutableShell<T> newKeyShell(&valueFromKey(newKey));
00088 bool endOutOfOrder=false;
00089 if (tempmore!=end()) {
00090 endOutOfOrder=comparator(*tempmore,newKeyShell);
00091 }
00092 if (comparator(newKeyShell,*templess)||endOutOfOrder) {
00093 KeyMutableShell<T> k = *iter;
00094 erase(iter);
00095 k->changeKey(newKey);
00096 insert (k);
00097 }else {
00098 (*iter)->changeKey(newKey);
00099 }
00100
00101 return tempmore;
00102 }
00103 };