c++利用属性名设置和获取属性值

/*

 * @Filename:CMetaDataManager.h

 * @Date:2016-10-21

 * @Author:yuanzuochao

 * @Description:

 *  

 * @History:

 * Date                     Author                  Records

 * 2016-10-21               yuanzuochao             Create

 */

#ifndef CMETADATAMANAGER_H

#define CMETADATAMANAGER_H

#include <iostream>

using namespace std;

#include <string>

#include <vector>

#include <typeinfo>

#include <map>

struct IInfo

{

    virtual std::string getType() const = 0;

    virtual std::string getName() const = 0;

    virtual ~IInfo(){}

};

template<class _Class, class _Type> class CField;

template<class _Class, class _Type>

struct ISetter

{

    virtual void accecpt(CField<_Class, _Type>* field, _Class* ins, _Type value) = 0;

    virtual ~ISetter(){}

};

template<class _Class, class _Type>

struct IGetter

{

    virtual _Type accecpt(const CField<_Class, _Type>* field, _Class* ins) const = 0;

    virtual ~IGetter(){}

};

template<class _Class, class _Type>

class const_ref_param_setter:public ISetter<_Class, _Type>

{

public:

    typedef void (_Class::*Setter) (const _Type&);

public:

    const_ref_param_setter(Setter setter):

        m_pSetter(setter)

    {

    }

    void set(_Class* ins, _Type value)

    {

        (ins->*m_pSetter)(value);

    }

    void accecpt(CField<_Class, _Type>* field, _Class* ins, _Type value)

    {

        field->set(this, ins, value);

    }

private:

    Setter                  m_pSetter;

};

template<class _Class, class _Type>

class ordinary_setter:public ISetter<_Class, _Type>

{

public:

    typedef void (_Class::*Setter) (_Type);

public:

    ordinary_setter(Setter setter):

        m_pSetter(setter)

    {

    }

    void set(_Class* ins, _Type value)

    {

        (ins->*m_pSetter)(value);

    }

    void accecpt(CField<_Class, _Type>* field, _Class* ins, _Type value)

    {

        field->set(this, ins, value);

    }

private:

    Setter                  m_pSetter;

};

template<class _Class, class _Type>

class const_ref_ret_getter:public IGetter<_Class, _Type>

{

public:

    typedef const _Type& (_Class::*Getter) () const;

public:

    const_ref_ret_getter(Getter getter):

        m_pGetter(getter)

    {

    }

    const _Type& get(_Class* ins) const

    {

        return (ins->*m_pGetter)();

    }

    _Type accecpt(const CField<_Class, _Type>* field, _Class* ins) const 

    {

        return field->get(this, ins);

    }

private:

    Getter                  m_pGetter;

};

template<class _Class, class _Type>

class ordinary_getter:public IGetter<_Class, _Type>

{

public:

    typedef _Type (_Class::*Getter) () const;

public:

    ordinary_getter(Getter getter):

        m_pGetter(getter)

    {

    }

    _Type get(_Class* ins) const 

    {

        return (ins->*m_pGetter)();

    }

    _Type accecpt(const CField<_Class, _Type>* field, _Class* ins) const

    {

        return field->get(this, ins);

    }

private:

    Getter                  m_pGetter;

};

template<class _Class, class _Type>

class CField:public IInfo

{

public:

    typedef _Type _Class::* FieldType;

    typedef typename const_ref_param_setter<_Class, _Type>::Setter type_const_ref_param_setter;

    typedef typename ordinary_setter<_Class, _Type>::Setter type_ordinary_setter;

    typedef typename const_ref_ret_getter<_Class, _Type>::Getter type_const_ref_ret_getter;

    typedef typename ordinary_getter<_Class, _Type>::Getter type_ordinary_getter;

public:

    CField(std::string name,  type_const_ref_param_setter setter, type_const_ref_ret_getter getter):

        m_pField(NULL),

        m_strName(name)

    {

        m_pSetter = new const_ref_param_setter<_Class,_Type>(setter);

        m_pGetter = new const_ref_ret_getter<_Class, _Type>(getter);

    }

    CField(std::string name,  type_ordinary_setter setter, type_ordinary_getter getter):

        m_pField(NULL),

        m_strName(name)

    {

        m_pSetter = new ordinary_setter<_Class,_Type>(setter);

        m_pGetter = new ordinary_getter<_Class, _Type>(getter);

    }

    CField(std::string name, FieldType field):

        m_pField(field),

        m_strName(name),

        m_pSetter(NULL),

        m_pGetter(NULL)

    {

    }

    ~CField()

    {

        if(m_pGetter)

        {

            delete m_pGetter;

            m_pGetter = NULL;

        }

        if(m_pSetter)

        {

            delete m_pSetter;

            m_pSetter = NULL;

        }

    }

    std::string getType() const

    {

        return typeid(_Type).name();

    }

    std::string getName() const

    {

        return m_strName;

    }

    void set(_Class* ins, _Type value)

    {

        if(m_pField)

        {

            ins->*m_pField = value;

        }else if(m_pSetter)

        {

            m_pSetter->accecpt(this, ins, value);

        }else

        {

            std::cout<<"no setter matched!"<<std::endl;

        }

    }

    _Type get(_Class* ins) const

    {

        _Type value;

        if(m_pField)

        {

            value = ins->*m_pField;

        }else if(m_pGetter)

        {

            value = m_pGetter->accecpt(this, ins);

        }else

        {

            std::cout<<"no getter matched!"<<std::endl;

        }

        return value;

    }

    void set(const_ref_param_setter<_Class, _Type>* setter, _Class* ins, _Type value)

    {

        setter->set(ins, value);

    }

    _Type get(const const_ref_ret_getter<_Class, _Type>* getter, _Class* ins) const

    {

        return getter->get(ins);

    }

    void set(ordinary_setter<_Class, _Type>* setter, _Class* ins, _Type value)

    {

        setter->set(ins, value);

    }

    _Type get(const ordinary_getter<_Class, _Type>* getter, _Class* ins) const

    {

        return getter->get(ins);

    }

private:

    FieldType                              m_pField;

    std::string                            m_strName;

    ISetter<_Class, _Type>*                m_pSetter;

    IGetter<_Class, _Type>*                m_pGetter;

};

template <class _Class>

class CClass:public IInfo

{

    typedef std::map<std::string, IInfo*>::value_type type_map;

    typedef std::map<std::string, IInfo*>::iterator type_iter;

    typedef std::map<std::string, IInfo*>::const_iterator type_const_iter;

public:

    ~CClass()

    {

        type_iter iter = m_mapFieldInfo.begin();

        for(; iter != m_mapFieldInfo.end(); ++iter)

        {

            delete (iter->second);

        }

        m_mapFieldInfo.clear();

    }

    std::string getType() const

    {

        return typeid(_Class).name();

    }

    std::string getName() const

    {

        return typeid(_Class).name();

    }

public:

    //typedef typename CField<_Class, _Type>::type_const_ref_param_setter type_const_ref_param_setter;

    //typedef typename CField<_Class, _Type>::type_const_ref_ret_getter type_const_ref_ret_getter;

    template<class _Type>

    void addField(std::string name, void (_Class::*setter)(const _Type&),  const _Type& (_Class::*getter)() const )

    {

        IInfo* pField = new CField<_Class, _Type>(name, setter, getter);

        m_mapFieldInfo.insert(type_map(name, pField));

    }

    template<class _Type>

    void addField(std::string name, void (_Class::*setter)(_Type),   _Type (_Class::*getter)() const)

    {

        IInfo* pField = new CField<_Class, _Type>(name, setter, getter);

        m_mapFieldInfo.insert(type_map(name, pField));

    }

    template<class _Type>

    void addField(std::string name, _Type (_Class::*director))

    {

        IInfo* pField = new CField<_Class, _Type>(name, director);

        m_mapFieldInfo.insert(type_map(name, pField));

    }

    template<class _Type>

    void set(std::string name, _Class* ins, _Type value) const

    {

        type_const_iter iter = m_mapFieldInfo.find(name);

        if(iter == m_mapFieldInfo.end())

        {

            return;

        }

        CField<_Class, _Type>* pField = dynamic_cast<CField<_Class, _Type>*>(iter->second);

        if(NULL == pField)

        {

            return;

        }

        pField->set(ins, value);

    }

    template<class _Type>

    _Type get(std::string name, _Class* ins) const

    {

        _Type value;

        type_const_iter iter = m_mapFieldInfo.find(name);

        do

        {

            if(iter == m_mapFieldInfo.end())

            {

                std::cout<<"name: "<<name<<" not be found"<<std::endl;

                break;

            }

            CField<_Class, _Type>* pField = dynamic_cast<CField<_Class, _Type>*>(iter->second);

            if(NULL == pField)

            {

                std::cout<<"dynamic_cast failed"<<std::endl;

                break;

            }

            value = pField->get(ins);

        }while(0);

        return value;

    }

    std::string getFieldType(std::string name) const

    {

        std::string type;

        type_const_iter iter = m_mapFieldInfo.find(name);

        if(iter == m_mapFieldInfo.end())

        {

            std::cout<<"name: "<<name<<" not be found"<<std::endl;

            return type;

        }

        type = (iter->second)->getType();

        return type;

    }

private:

    std::map<std::string, IInfo*>                m_mapFieldInfo;

};

class CMetaDataManager

{

    typedef std::map<std::string, IInfo*>::value_type type_map;

    typedef std::map<std::string, IInfo*>::iterator type_iter;

    typedef std::map<std::string, IInfo*>::const_iterator type_const_iter;

public:

    template<class _Class>

    void registry()

    {

        IInfo* pClass = new CClass<_Class>();

        m_mapClassInfo.insert(type_map(typeid(_Class).name(), pClass));

    }

    template<class _Class, class _Type>

    void addField(std::string name, void (_Class::*setter)(const _Type&),  const _Type& (_Class::*getter)() const )

    {

        type_iter iter = m_mapClassInfo.find(typeid(_Class).name());

        if(iter == m_mapClassInfo.end())

        {

            return;

        }

        CClass<_Class>* pClass = dynamic_cast<CClass<_Class>*>(iter->second);

        if(NULL == pClass)

        {

            return;

        }

        pClass->addField(name, setter, getter);

    }

    template<class _Class, class _Type>

    void addField(std::string name, void (_Class::*setter)(_Type),   _Type (_Class::*getter)() const)

    {

        type_iter iter = m_mapClassInfo.find(typeid(_Class).name());

        if(iter == m_mapClassInfo.end())

        {

            return;

        }

        CClass<_Class>* pClass = dynamic_cast<CClass<_Class>*>(iter->second);

        if(NULL == pClass)

        {

            return;

        }

        pClass->addField(name, setter, getter);

    }

    template<class _Class, class _Type>

    void addField(std::string name, _Type (_Class::*director))

    {

        type_iter iter = m_mapClassInfo.find(typeid(_Class).name());

        if(iter == m_mapClassInfo.end())

        {

            return;

        }

        CClass<_Class>* pClass = dynamic_cast<CClass<_Class>*>(iter->second);

        if(NULL == pClass)

        {

            return;

        }

        pClass->addField(name, director);

    }

    template<class _Class, class _Type>

    void set(std::string name, _Class* ins, _Type value) const

    {

        type_const_iter iter = m_mapClassInfo.find(typeid(_Class).name());

        if(iter == m_mapClassInfo.end())

        {

            return;

        }

        CClass<_Class>* pClass = dynamic_cast<CClass<_Class>*>(iter->second);

        if(NULL == pClass)

        {

            return;

        }

        pClass->set(name, ins, value);

    }

    template<class _Class, class _Type>

    _Type get(std::string name, _Class* ins) const

    {

        _Type value;

        type_const_iter iter = m_mapClassInfo.find(typeid(_Class).name());

        do

        {

            if(iter == m_mapClassInfo.end())

            {

                break;

            }

            CClass<_Class>* pClass = dynamic_cast<CClass<_Class>*>(iter->second);

            if(NULL == pClass)

            {

                break;

            }

            value = pClass->get<_Type>(name, ins);

        }while(0);

        return value ;

    }

    template<class _Class>

    std::string getFieldType(std::string name) const

    {

        std::string type="";

        type_const_iter iter = m_mapClassInfo.find(typeid(_Class).name());

        if(iter == m_mapClassInfo.end())

        {

            return type;

        }

        CClass<_Class>* pClass = dynamic_cast<CClass<_Class>*>(iter->second);

        if(NULL == pClass)

        {

            return type;

        }

        return pClass->getFieldType(name);

    }

private:

    std::map<std::string, IInfo*>           m_mapClassInfo;

};

#endif //CMETADATAMANAGER_H

猜你喜欢

转载自becomebetter.iteye.com/blog/2332211
今日推荐