Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <string>
- #include <typeinfo>
- #include <vector>
- #include <sstream>
- #include <regex>
- #include <unordered_map>
- #include <boost/variant.hpp>
- struct IType;
- struct IObject;
- struct FieldVar {
- protected:
- int offset;
- IType* type;
- std::string name;
- public:
- FieldVar() = default;
- FieldVar(int _offset,IType* _type, std::string _name) : offset(_offset), type(_type), name(_name) {}
- FieldVar(int offset) : FieldVar(offset,nullptr,"") {}
- FieldVar(IType* type) : FieldVar(0, type, "") {}
- FieldVar(std::string name) : FieldVar(0, nullptr, name) {}
- template<typename _type>
- _type getValue(void* obj) {
- return *(_type*)((char*)obj + offset);
- }
- template<typename _type>
- void setValue(void* obj, _type value) {
- *(_type*)((char*)obj + offset) = value;
- }
- template<typename _type>
- _type getValue(IObject* obj) {
- return getValue(obj->getObjPtr());
- }
- template<typename _type>
- void setValue(IObject* obj,_type value) {
- setValue(obj->getObjPtr(), value);
- }
- int getFieldOffset() { return offset; }
- int setFieldOffset(int offset) { this->offset = offset; }
- IType* getType() { return this->type; }
- void setType(IType* type) { this->type = type; }
- std::string getName() { return name; }
- void setName(std::string name) { this->name = name; }
- };
- struct FieldFunc {
- protected:
- friend struct IType;
- public:
- template <typename _restype, typename... _argstypes>
- _restype Invoke(void* object, _argstypes... args) {
- const _IRFieldFunc<_restype, _argstypes...>* irff = (const _IRFieldFunc<_restypes, _argstypes...>*)this;
- return irff->Invoke(object, args...);
- }
- };
- template <typename _restype, typename... _argstypes>
- struct _IRFieldFunc : public FieldFunc {
- protected:
- friend struct IType;
- public:
- virtual _restype Invoke(void* object, _argstypes... args) = 0;
- };
- template <typename _ctype,typename _restype, typename... _argstypes>
- struct _RFieldFunc : public _IRFieldFunc<_restype,_argstypes...> {
- protected:
- friend struct IType;
- public:
- _restype(_ctype::*funcptr)(_argstypes...);
- _restype Invoke(void* object, _argstypes... args) {
- _ctype *ct = (_ctype*)object;
- return ct->*funcptr(args..);
- }
- };
- template <typename _ctype, typename _restype, typename... _argstypes>
- struct _RCFieldFunc : public _IRFieldFunc<_restype, _argstypes...> {
- protected:
- friend struct IType;
- public:
- _restype(_ctype::*funcptr)(_argstypes...) const;
- _restype Invoke(void* object, _argstypes... args) {
- _ctype *ct = (_ctype*)object;
- return ct->*funcptr(args..);
- }
- };
- struct IObject;
- struct IType {
- using FieldContainer = boost::variant<FieldFunc, FieldVar>;
- using FieldPair = std::pair<std::string, FieldContainer>;
- using FieldsArray = std::unordered_map<std::string, boost::variant<FieldFunc, FieldVar>>;
- virtual IObject* newInstance() = 0;
- virtual FieldContainer getField(std::string name) = 0;
- virtual std::string getName() = 0;
- virtual std::string getId() = 0;
- virtual size_t getSize() = 0;
- virtual IType::FieldsArray getFields() const = 0;
- };
- struct IObject {
- virtual IType* getType() const = 0;
- virtual void* getInst() = 0;
- virtual IType::FieldContainer operator[](std::string) = 0;
- virtual IType::FieldsArray getFields() = 0;
- virtual IType::FieldContainer getField(std::string) = 0;
- };
- namespace details {
- template<typename T, typename U> constexpr size_t offsetOfCPtr(U T::*member)
- {
- return (char*)&((T*)nullptr->*member) - (char*)nullptr;
- }
- std::vector<std::string> splitString(const std::string &s, char delim) {
- std::stringstream ss(s);
- std::string item;
- std::vector<std::string> elems;
- while (std::getline(ss, item, delim)) {
- elems.push_back(item);
- // elems.push_back(std::move(item)); // if C++11 (based on comment from @mchiasson)
- }
- return elems;
- }
- std::string removeNamespaceName(std::string& s) {
- std::regex r(".*::");
- s = std::regex_replace(s, r, "");
- return s;
- }
- std::vector<std::string> removeNamespaceNames(std::vector<std::string>& s) {
- std::regex r(".*::");
- for (std::vector<std::string>::iterator it = s.begin(); it != s.end(); it++) {
- *it = removeNamespaceName(*it);
- }
- return s;
- }
- template<typename _ctype,typename _restype, typename ..._argstypes>
- IType::FieldPair makeTypeField(std::string name = "", _restype (_ctype::*ptr)(_argstypes...) = nullptr) {
- typename IType::FieldPair fp;
- auto v = new _RFieldFunc<_ctype, _restype, _argstypes...>();
- v.funcptr = ptr;
- FieldFunc *ff = v;
- fp.second = ff;
- fp.first = s;
- return fp;
- }
- template<typename _ctype, typename _restype, typename ..._argstypes>
- IType::FieldPair makeTypeField(std::string name = "", _restype(_ctype::*ptr)(_argstypes...) const = nullptr) {
- typename IType::FieldPair fp;
- auto v = new _RCFieldFunc<_ctype, _restype, _argstypes...>;
- v.funcptr = ptr;
- FieldFunc *ff = v;
- fp.second = ff;
- fp.first = s;
- return fp;
- }
- template<typename _ptrtype,
- typename = typename std::enable_if<std::is_member_pointer<_ptrtype>::value>::type>
- IType::FieldPair makeTypeField(std::string name = "", IType* t = nullptr, _ptrtype ptr = nullptr) {
- typename IType::FieldPair fp;
- FieldVar fv(details::offsetOfCPtr(ptr),t,name);
- fp.second = fv;
- return fp;
- }
- template<typename _ptrtype, typename = typename std::enable_if<std::is_pointer<_ptrtype>::value>::type>
- void wrapTypeField(IType* t,std::vector<std::string> names,int& nidx, IType::FieldsArray& fa, std::unordered_map<std::string, boost::variant<FieldFunc, FieldVar>>::iterator& curidx, _ptrtype ptr) {
- fa.insert(makeTypeField(names[nidx],curidx->first, t, ptr));
- curidx = fa.end();
- if (nidx + 1 != names.size() - 1) {
- nidx++;
- }
- }
- template<typename... _ptrtypes>
- IType::FieldsArray finalmakeTypeFields(std::string lss, _ptrtypes... ptrs) {
- auto vec = details::removeNamespaceNames(details::splitString(lss));
- IType::FieldsArray fa;
- int idx;
- IType::FieldsArray::iterator fait;
- wrapTypeField(t, vec, idx, fa, fait, ptrs)...;
- return fa;
- }
- }
- #define _IOBJECT(name) \
- public: \
- static name##_Type type;\
- IType* getType() const override { static name##_Type _type = type; return &_type; }\
- void* getInst() override { return (void*)this; }\
- IType::FieldContainer operator[](std::string name) { return getField(name); } \
- IType::FieldsArray getFields() override { return this->type.getFields(); } \
- IType::FieldContainer getField(std::string name) override { return type.fields[name]; }
- #define IOBJECT(name) _IOBJECT(name)
- #define _DEFINE_TYPE_ADVANCED(name) \
- struct name; \
- struct name##_Type : public IType { \
- private: \
- static IType::FieldsArray fields; \
- public: \
- IObject* newInstance() override { return new name(); }\
- std::string getName() override { return #name; } \
- std::string getId() override { return typeid(name).name(); }\
- size_t getSize() { return sizeof(name); }\
- IType::FieldsArray getFields() const override { return this->fields; } \
- IType::FieldContainer getField(std::string name) { return type.fields[name]; }\
- }
- #define _DEFINE_TYPE_AUTO(name,...) \
- struct name; \
- struct name##_Type : public IType { \
- private: \
- static IType::FieldsArray fields = details::finalmakeTypeFields(#__VA_ARGS__,__VA_ARGS__); \
- public: \
- IObject* newInstance() override { return new name(); }\
- std::string getName() override { return #name; } \
- std::string getId() override { return typeid(name).name(); }\
- size_t getSize() { return sizeof(name); }\
- IType::FieldsArray getFields() const override { return this->fields; } \
- IType::FieldContainer getField(std::string name) { return type.fields[name]; }\
- }
- #define DTYPE(name,...) _DEFINE_TYPE_AUTO(name,__VA_ARGS__)
- #define DTYPEA(name) _DEFINE_TYPE_ADVANCED(name)
- DTYPEA(MyTest)
- struct MyTest : public IObject {
- IOBJECT(MyTest)
- };
- //
- //struct IObject;
- //
- //struct IType {
- // typedef std::unordered_map<std::string, FieldContainer> FieldsType;
- // virtual IObject* newInstance() const = 0;
- // virtual std::string getName() const = 0;
- // virtual std::string getId() const = 0;
- // virtual size_t getSize() const = 0;
- // virtual IType::FieldsType getFields() const = 0;
- //};
- //
- //struct FieldContainer {
- // enum {
- // FUNC,
- // VAR,
- // }type;
- // union {
- // //FieldFunc* ff;
- // FieldVar* fv;
- // }val;
- //};
- //
- //struct IObject {
- // virtual IType* getType() const = 0;
- // virtual void* getObjPtr() const = 0;
- // virtual FieldContainer& operator[](std::string) = 0;
- //};
- //
- //
- //#define _IOBJECT_AUTO(NAME,...) \
- //public: \
- // static NAME##_Type type; \
- // IType* getType() const override { return type; } \
- // void* getObjPtr() const override { return (void*)this; } \
- // FieldContainer& operator[](std::string name) { \
- // return type.getFields()[name]; \
- // }
- //
- //
- //#define _IOBJECT_ADVANCED(NAME) \
- //public: \
- //static NAME##_Type type; \
- //IType* getType() const override { return &type; } \
- //void* getObjPtr() const override { return (void*)this; } \
- //FieldContainer& operator[](std::string name) { \
- // return type.getFields()[name]; \
- //}
- //
- //#define TYPE(NAME) \
- // struct NAME; \
- // struct NAME##_Type : public IType { \
- // private: \
- // static IType::FieldsType fields; \
- // public: \
- // std::string getName() const override { return #NAME; } \
- // std::string getId() const override { return typeid(NAME).name(); } \
- // size_t getSize() const override { return sizeof(NAME); } \
- // IObject* newInstance() const override { IObject *ptr = new NAME(); return ptr; } \
- // IType::FieldsType getFields() const override { return fields; } \
- // };
- //
- //#define IOBJECT(NAME,...) _IOBJECT_AUTO(NAME,__VA_ARGS__);
- //#define IOBJECTA(NAME) _IOBJECT_ADVANCED(NAME);
- //
- //TYPE(Test)
- //
- //struct Test : public IObject {
- // IOBJECTA(Test)
- //public:
- //
- // Test() {
- // }
- //};
- //
- //int test() {
- // IObject* t = Test::type.newInstance();
- // t->operator[]("h");
- // t[""]
- //}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement