#include <iostream> using namespace std; #include <string> #include <vector> #include <typeinfo> struct IAccessor { virtual string getType() const = 0; virtual string getName() const = 0; virtual ~IAccessor(){} }; template<class _Class, class _Attr> class CClassAccessor:public IAccessor { typedef void (_Class::*Setter) (_Attr); typedef _Attr (_Class::*Getter) (); typedef _Attr _Class::*Director; typedef _Attr Type; public: CClassAccessor():m_strName(""){} CClassAccessor(string name):m_strName(name){} CClassAccessor(Setter setter, Getter getter, string name): m_pSetter(setter) ,m_pGetter(getter) ,m_strName(name) ,m_pDirector(NULL){} CClassAccessor(Director attr, string name): m_pSetter(NULL) ,m_pGetter(NULL) ,m_strName(name) ,m_pDirector(attr){} CClassAccessor(Setter setter, Getter getter, Director attr, string name): m_pSetter(setter) ,m_pGetter(getter) ,m_strName(name) ,m_pDirector(attr){} public: void setSetter(Setter setter) { m_pSetter = setter; } void setGetter(Getter getter) { m_pGetter = getter; } Setter getSetter(){return m_pSetter;} Getter getGetter(){return m_pGetter;} void setValue(_Class* ins, _Attr value) { (ins->*m_pSetter)(value); } _Attr getValue(_Class* ins) { return (ins->*m_pGetter)(); } void directSet(_Class* ins, _Attr value) { ins->*m_pDirector = value; } _Attr directGet(_Class* ins) { return ins->*m_pDirector; } string getType() const { return typeid(Type).name(); } string getName() const { return m_strName; } private: Setter m_pSetter; Getter m_pGetter; string m_strName; Director m_pDirector; }; template<class _Class> class CClass: public IAccessor { typedef _Class Type; public: CClass() { } ~CClass() { vector<IAccessor*>::iterator iter = m_vecAccessors.begin(); for(; iter != m_vecAccessors.end(); ++iter) { delete (*iter); } m_vecAccessors.clear(); } template<class _Attr> void addField(void (_Class::*Setter) (_Attr), _Attr (_Class::*Getter) (), _Attr _Class::*Director, string name) { IAccessor* pAccessor = new CClassAccessor<_Class, _Attr>(Setter, Getter, Director, name); m_vecAccessors.push_back(pAccessor); } template<class _Attr > void setValue(string name, _Class* ins, _Attr value) { vector<IAccessor*>::iterator iter = m_vecAccessors.begin(); for(; iter != m_vecAccessors.end(); ++iter) { if((*iter)->getName() != name) { continue; } CClassAccessor<_Class, _Attr>* pAccessor = dynamic_cast<CClassAccessor<_Class, _Attr>* >(*iter); if(NULL == pAccessor) { //TODO: error }else { pAccessor->setValue(ins, value); } break; } } template<class _Attr > void getValue(string name, _Class* ins, _Attr& value) { vector<IAccessor*>::iterator iter = m_vecAccessors.begin(); for(; iter != m_vecAccessors.end(); ++iter) { if((*iter)->getName() != name) { continue; } CClassAccessor<_Class, _Attr>* pAccessor = dynamic_cast<CClassAccessor<_Class, _Attr>* >(*iter); if(NULL == pAccessor) { //TODO: error }else { value = pAccessor->getValue(ins); } break; } } template<class _Attr > void directSet(string name, _Class* ins, _Attr value) { vector<IAccessor*>::iterator iter = m_vecAccessors.begin(); for(; iter != m_vecAccessors.end(); ++iter) { if((*iter)->getName() != name) { continue; } CClassAccessor<_Class, _Attr>* pAccessor = dynamic_cast<CClassAccessor<_Class, _Attr>* >(*iter); if(NULL == pAccessor) { //TODO: error }else { pAccessor->directSet(ins, value); } break; } } template<class _Attr > void directGet(string name, _Class* ins, _Attr& value) { vector<IAccessor*>::iterator iter = m_vecAccessors.begin(); for(; iter != m_vecAccessors.end(); ++iter) { if((*iter)->getName() != name) { continue; } CClassAccessor<_Class, _Attr>* pAccessor = dynamic_cast<CClassAccessor<_Class, _Attr>* >(*iter); if(NULL == pAccessor) { //TODO: error }else { value = pAccessor->directGet(ins); } break; } } string getFieldType(string name) const { string type = ""; vector<IAccessor*>::const_iterator iter = m_vecAccessors.begin(); for(; iter != m_vecAccessors.end(); ++iter) { if((*iter)->getName() != name) { continue; } type = (*iter)->getType(); break; } return type; } string getType() const { return typeid(Type).name(); } string getName() const { return typeid(Type).name(); } private: vector<IAccessor*> m_vecAccessors; }; #include <map> class CMetaDataManager { typedef IAccessor IClass; public: ~CMetaDataManager() { } public: template<class _Class> void registry() { IClass* pClass = new CClass<_Class>(); m_mapClasses.insert(map<string, IClass*>::value_type(pClass->getType(), pClass)); } template<class _Class, class _Attr> void addField(void (_Class::*Setter) (_Attr), _Attr (_Class::*Getter) (), _Attr _Class::*Director, string name) { map<string, IClass*>::iterator iter = m_mapClasses.find(typeid(_Class).name()); if(iter == m_mapClasses.end()) { return ; } CClass<_Class> *pClass = dynamic_cast<CClass<_Class>* >(iter->second); if(NULL == pClass) { return ; } pClass->addField(Setter, Getter, Director, name); } template<class _Class, class _Attr > void setValue(string name, _Class* ins, _Attr value) { map<string, IClass*>::iterator iter = m_mapClasses.find(typeid(_Class).name()); if(iter == m_mapClasses.end()) { return ; } CClass<_Class> *pClass = dynamic_cast<CClass<_Class>* >(iter->second); if(NULL == pClass) { return ; } pClass->setValue(name, ins, value); } template<class _Class, class _Attr > void getValue(string name, _Class* ins, _Attr& value) { map<string, IClass*>::iterator iter = m_mapClasses.find(typeid(_Class).name()); if(iter == m_mapClasses.end()) { return ; } CClass<_Class> *pClass = dynamic_cast<CClass<_Class>* >(iter->second); if(NULL == pClass) { return ; } pClass->getValue(name, ins, value); } template<class _Class, class _Attr > void directSet(string name, _Class* ins, _Attr value) { map<string, IClass*>::iterator iter = m_mapClasses.find(typeid(_Class).name()); if(iter == m_mapClasses.end()) { return ; } CClass<_Class> *pClass = dynamic_cast<CClass<_Class>* >(iter->second); if(NULL == pClass) { return ; } pClass->directSet(name, ins, value); } template<class _Class, class _Attr > void directGet(string name, _Class* ins, _Attr& value) { map<string, IClass*>::iterator iter = m_mapClasses.find(typeid(_Class).name()); if(iter == m_mapClasses.end()) { return ; } CClass<_Class> *pClass = dynamic_cast<CClass<_Class>* >(iter->second); if(NULL == pClass) { return ; } pClass->directGet(name, ins, value); } private: map<string, IClass*> m_mapClasses; };