00001 #ifndef BASE_KEYLIST_H
00002 #define BASE_KEYLIST_H
00003 #include "Env.h"
00004 #include <list>
00005 #include <set>
00006
00007
00008 namespace Spr {;
00009
00010
00011
00012
00013 template <class T, class Pred=std DOUBLECOLON less<T> >
00014 class UTKeyList: std DOUBLECOLON list<T>{
00015 public:
00016 typedef std::list<T> base;
00017 typedef base::iterator iterator;
00018 typedef base::const_iterator const_iterator;
00019 struct SetPred{
00020 typedef TYPENAME std::list<T>::iterator listIt;
00021 bool operator() (const listIt& i1, const listIt& i2) const {
00022 Pred pred;
00023 return pred(*i1, *i2);
00024 }
00025 };
00026 typedef std::set< TYPENAME std::list<T>::iterator, SetPred > Finder;
00027 Finder finder;
00028 UTKeyList(){}
00029 UTKeyList(const UTKeyList<T>& l):std::list<T>(l){
00030 for(iterator it = begin(); it != end(); ++it) finder.insert(it);
00031 }
00032 void push_back(const T& t){
00033 base::push_back(t);
00034 InsToFinder(--base::end());
00035 }
00036 void pop_back(){
00037 EraseFromFinder(--base::end());
00038 base::pop_back();
00039 }
00040 void push_front(const T& t){
00041 base::push_front(t);
00042 InsToFinder(base::begin());
00043 }
00044 void pop_front(){
00045 EraseFromFinder(base::begin());
00046 base::pop_front();
00047 }
00048 void insert(base::iterator it, T& t = T()){
00049 base::iterator ins = base::insert(it, t);
00050 InsToFinder(ins);
00051 }
00052 void erase(base::iterator it){
00053 EraseFromFinder(it);
00054 base::erase(it);
00055 }
00056 void erase(const T& t){
00057 base::push_back(t);
00058 Finder::iterator rv = finder.find(--end());
00059 base::pop_back();
00060 if (rv != finder.end()) erase(*rv);
00061 }
00062 base::iterator find(const T& t){
00063 base::push_back(t);
00064 Finder::iterator rv = finder.find(--base::end());
00065 base::pop_back();
00066 if (rv == finder.end()){
00067 return end();
00068 }else{
00069 return *rv;
00070 }
00071 }
00072 base::const_iterator find(const T& t) const {
00073 return ((UTKeyList<T, Pred>*)this)->find(t);
00074 }
00075 base::iterator begin(){ return base::begin(); }
00076 base::const_iterator begin() const { return base::begin(); }
00077 base::iterator end(){ return base::end(); }
00078 base::const_iterator end() const { return base::end(); }
00079 size_t size() const { return base::size(); }
00080
00081 private:
00082 void InsToFinder(base::iterator& it){
00083 std::pair<Finder::iterator, bool> rv = finder.insert(it);
00084 if (!rv.second){
00085 base::erase(*rv.first);
00086 (base::iterator&)*rv.first = it;
00087 }
00088 }
00089 void EraseFromFinder(base::iterator& it){
00090 int ne = finder.erase(it);
00091 assert(ne == 1);
00092 }
00093 };
00094
00095 }
00096
00097 #endif