00001 #ifndef FLYWEIGHT_H
00002 #define FLYWEIGHT_H
00003
00004 #include <map>
00005 #include <vector>
00006 #include <iostream>
00007 #include <string>
00008
00009 #include <TObject.h>
00010 #include <TDirectory.h>
00011
00012 template <typename ValueType, typename UniqueTag=int>
00013 class FlyWeightLists:public TObject{
00014 public:
00015 FlyWeightLists(){};
00016 typedef int Proxy_t;
00017 typedef std::map<ValueType,Proxy_t> ValueToProxyMap;
00018 typedef std::vector<ValueType> ProxyToValueMap;
00019
00020 int GetProxy(const ValueType& v);
00021 const ValueType& GetValue(const Proxy_t& v);
00022
00023 bool empty()const{return sProxyToVals.empty();}
00024 void DumpTable()const;
00025
00026 private:
00027 ProxyToValueMap sProxyToVals;
00028 ValueToProxyMap sValsToProxies;
00029
00030 ClassDef(FlyWeightLists,1);
00031 };
00032
00054 template <typename ValueType, typename UniqueTag=int>
00055 class FlyWeight:public TObject{
00056 public:
00057 typedef int Proxy_t;
00058
00059 FlyWeight():fProxy(-1){}
00060 FlyWeight(const ValueType& val):fProxy(-1){
00061 SetValue(val);
00062 }
00063 void Reset(){fProxy=-1;}
00064
00065 void operator=(const ValueType& v){
00066 SetValue(v);
00067 }
00068 void SetValue(const ValueType&);
00069 const ValueType& GetValue()const;
00070 void DumpTable()const {fProxyList->DumpTable();}
00071
00072 static int LoadProxyList(TDirectory* file, const std::string& name );
00073 static int SaveProxyList(TDirectory* file, const std::string& name );
00074 static void InitProxyList(){fProxyList=new FlyWeightLists<ValueType,UniqueTag>();};
00075
00076 private:
00077 Proxy_t fProxy;
00078
00079 static FlyWeightLists<ValueType,UniqueTag>* fProxyList;
00080
00081 ClassDef(FlyWeight,2);
00082 };
00083
00084 template <typename ValueType, typename UniqueTag>
00085 inline const ValueType& FlyWeight<ValueType,UniqueTag>::GetValue()const{
00086 if(fProxy<0) std::cerr<<"Trying to get a value "
00087 "from an unitialized flyweight"<<std::endl;
00088 return fProxyList->GetValue(fProxy);
00089 }
00090
00091 template <typename ValueType, typename UniqueTag>
00092 inline void FlyWeight<ValueType,UniqueTag>::SetValue(const ValueType& v){
00093 if(!fProxyList)InitProxyList();
00094 fProxy=fProxyList->GetProxy(v);
00095 }
00096
00097 template <typename ValueType, typename UniqueTag>
00098 inline int FlyWeight<ValueType,UniqueTag>:: LoadProxyList(
00099 TDirectory* file, const std::string& name ){
00100 if(fProxyList && !fProxyList->empty()){
00101 std::cout<<"FlyWeight: Error: Proxy list is not empty but was asked to load the list from a file"<<std::endl;
00102 return 1;
00103 }
00104 if(!file) {
00105 std::cout<<"FlyWeight: Error: Cannot load a proxy list from a NULL file"<<std::endl;
00106 return 2;
00107 }
00108 file->GetObject(name.c_str(),fProxyList);
00109 if(!fProxyList){
00110 std::cout<<"FlyWeight: Error: Couldn't find proxy list '"<<name
00111 <<"' in file '"<<file->GetName()<<"'"<<std::endl;
00112 return 3;
00113 }
00114 return 0;
00115 }
00116
00117 template <typename ValueType, typename UniqueTag>
00118 inline int FlyWeight<ValueType,UniqueTag>::SaveProxyList(
00119 TDirectory* file, const std::string& name ){
00120 if(!file) {
00121 std::cout<<"FlyWeight: Error: Cannot save a proxy list from a NULL file"<<std::endl;
00122 return 1;
00123 }
00124 file->WriteObject(fProxyList,name.c_str());
00125 return 0;
00126 }
00127
00128
00129 template <typename ValueType, typename UniqueTag>
00130 FlyWeightLists<ValueType,UniqueTag>*
00131 FlyWeight<ValueType,UniqueTag>::fProxyList=NULL;
00132
00133 template <typename ValueType, typename UniqueTag>
00134 inline const ValueType& FlyWeightLists<ValueType,UniqueTag>::GetValue(
00135 const Proxy_t& v){
00136 return sProxyToVals.at(v);
00137 }
00138
00139 template <typename ValueType, typename UniqueTag>
00140 inline int FlyWeightLists<ValueType,UniqueTag>::GetProxy(const ValueType& v){
00141
00142 typename ValueToProxyMap::const_iterator it=sValsToProxies.find(v);
00143 if(it!=sValsToProxies.end()){
00144 return it->second;
00145 }
00146
00147 int proxy=sValsToProxies.size();
00148 sValsToProxies[v]=proxy;
00149 sProxyToVals.push_back(v);
00150 return proxy;
00151 }
00152
00153 template <typename ValueType, typename UniqueTag>
00154 inline void FlyWeightLists<ValueType,UniqueTag>::DumpTable()const{
00155 std::cout<<"Proxy | Value | Proxy"<<std::endl;
00156 for(unsigned i=0;i<sProxyToVals.size();i++){
00157 std::cout<<i<<" | "<<sProxyToVals[i]<<" | "<<sValsToProxies.find(sProxyToVals[i])->second<<std::endl;
00158 }
00159 }
00160 #endif //FLYWEIGHT_H