registerer.h 3.1 KB
Newer Older
X
xiexionghang 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
#pragma once

#include <map>
#include <string>
#include <iostream>
#include <vector>
#include <glog/logging.h>

namespace paddle {
namespace custom_trainer {
namespace feed {

class Any {
public:
    Any() : content_(NULL) {}

    template<typename ValueType>
        Any(const ValueType &value) : content_(new Holder<ValueType>(value)) {}

    Any(const Any &other) : content_(other.content_ ? other.content_->clone() : NULL) {}
    
    ~Any() {
        delete content_;
    }

    template<typename ValueType> ValueType *any_cast() {
        return content_ ? &static_cast<Holder<ValueType> *>(content_)->held_ : NULL;
    }

private:
    class PlaceHolder {
    public:
        virtual ~PlaceHolder() {}
        virtual PlaceHolder *clone() const = 0;
    };

    template<typename ValueType>
        class Holder : public PlaceHolder {
        public:
            explicit Holder(const ValueType &value) : held_(value) {}
            virtual PlaceHolder *clone() const {
                return new Holder(held_);
            }

            ValueType held_;
        };

    PlaceHolder *content_;
};

class ObjectFactory {
public:
    ObjectFactory() {}
    virtual ~ObjectFactory() {}
    virtual Any NewInstance() {
        return Any();
    }
private:
};

typedef std::map<std::string, ObjectFactory*> FactoryMap;
typedef std::map<std::string, FactoryMap> BaseClassMap;
#ifdef __cplusplus
extern "C" {
#endif
X
xiexionghang 已提交
66
BaseClassMap& global_reg_factory_map();
X
xiexionghang 已提交
67 68 69 70
#ifdef __cplusplus
}
#endif

X
xiexionghang 已提交
71
BaseClassMap& global_reg_factory_map_cpp();
X
xiexionghang 已提交
72

X
xiexionghang 已提交
73
#define REGIST_REGISTERER(base_class) \
X
xiexionghang 已提交
74 75 76
    class base_class ## Registerer { \
        public: \
            static base_class *CreateInstanceByName(const ::std::string &name) { \
X
xiexionghang 已提交
77 78
                if (global_reg_factory_map_cpp().find(#base_class) \
                        == global_reg_factory_map_cpp().end()) { \
X
xiexionghang 已提交
79 80 81
                    LOG(ERROR) << "Can't Find BaseClass For CreateClass with:" << #base_class; \
                    return NULL; \
                } \
X
xiexionghang 已提交
82
                FactoryMap &map = global_reg_factory_map_cpp()[#base_class]; \
X
xiexionghang 已提交
83 84 85 86 87 88 89 90 91 92
                FactoryMap::iterator iter = map.find(name); \
                if (iter == map.end()) { \
                    LOG(ERROR) << "Can't Find Class For Create with:" << name; \
                    return NULL; \
                } \
                Any object = iter->second->NewInstance(); \
                return *(object.any_cast<base_class*>()); \
            } \
    };

X
xiexionghang 已提交
93
#define REGIST_CLASS(clazz, name) \
X
xiexionghang 已提交
94 95 96 97 98 99 100
    class ObjectFactory##name : public ObjectFactory { \
        public: \
            Any NewInstance() { \
                return Any(new name()); \
            } \
    }; \
    void register_factory_##name() { \
X
xiexionghang 已提交
101
        FactoryMap &map = global_reg_factory_map_cpp()[#clazz]; \
X
xiexionghang 已提交
102 103 104 105 106 107
            if (map.find(#name) == map.end()) { \
                map[#name] = new ObjectFactory##name(); \
            } \
    } \
    void register_factory_##name() __attribute__((constructor)); 

X
xiexionghang 已提交
108
#define CREATE_INSTANCE(base_class, name) \
R
rensilin 已提交
109
    base_class##Registerer::CreateInstanceByName(name)
X
xiexionghang 已提交
110 111 112 113 114
    
}//namespace feed
}//namespace custom_trainer
}//namespace paddle
/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */