#ifndef COMMON_H #define COMMON_H #include #include #include #include #include #include #include #include #define EXPORT __attribute__ ((visibility ("default"))) enum debug_level {INTERNALREQUEST,MOREDEBUG,DEBUG,INFO,NORMAL,WARNING,ERROR}; EXPORT std::ostream& COUT(debug_level dl); typedef std::set UsedType; // Base class for all objects class EXPORT ObjectBase { protected: // No save by default virtual const int8_t* Blob(size_t* size) const { *size=0; return 0; } virtual void DeallocBlob(const void* ptr) const {}; public: ObjectBase() = default; ObjectBase(const ObjectBase&) = delete; bool Save(const char* fname) const; // Pure virtual api virtual ~ObjectBase(){} virtual ObjectBase* Copy() const=0; virtual bool Print() const=0; virtual std::string Type() const=0; // Virtual api with default functions. Modules types must not override them. virtual std::string Dump() const {return "%"+Type()+"%";} virtual ObjectBase* Evaluate(bool* err) {*err=false; return 0;} virtual ObjectBase* ReplaceVar(const std::string& vname, ObjectBase* ob) {return 0;} virtual void UsedFuncs(UsedType& funcs) const {} virtual void UsedIdents(UsedType& ids) const {} }; // Template for checking and using ObjectBase derivative classes // Checking if arg is pointer on Derived: if(OBType(arg)) // Using const ObjectBase* arg as const Derived*: OBType(arg)->SomeCall() template class OBType { const O* p; public: OBType() = delete; OBType(OBType&&) = delete; OBType(OBType&) = delete; OBType(const ObjectBase* arg) {if(typeid(*arg)==typeid(O)) p=dynamic_cast(arg); else p=0;} const O* operator->() const {return p;} operator bool() const {return 0!=p;} }; // Template for objects without specific constructor/destructor template class EXPORT ObjectSimple: public ObjectBase { private: T val; static std::string type; const int8_t* Blob(size_t* size) const override {*size=sizeof(T); return reinterpret_cast(&val);} public: ObjectSimple(T t):val(t) {} ObjectSimple(const T* t):val(*t) {} ~ObjectSimple() {} // Pure virtual overrides ObjectBase* Copy() const override {return new ObjectSimple(val);} bool Print() const override { COUT(NORMAL)< ObjectBool; typedef ObjectSimple ObjectInt; typedef ObjectSimple ObjectReal; typedef ObjectSimple ObjectString; template<> inline const int8_t* ObjectString::Blob(size_t* size) const { *size=val.length(); return reinterpret_cast(val.c_str()); } // Class for name-value pair class EXPORT ObjectPair: public ObjectBase { private: std::string name; std::shared_ptr val; public: ObjectPair() {} ObjectPair(const std::string& n, ObjectBase* v):name(n) {val.reset(v);} ObjectPair(const std::string* n, ObjectBase* v):name(*n) {val.reset(v);} ~ObjectPair() {} // Pure virtual overrides ObjectBase* Copy() const override { auto ret=new ObjectPair; ret->name=name; ret->val=val; return ret; } bool Print() const override { if(!Exist()) return false; COUT(NORMAL)<Type()<ReplaceVar(vname,ob); if(0!=p) val.reset(p); return 0; } void UsedFuncs(UsedType& funcs) const override {return val->UsedFuncs(funcs);} void UsedIdents(UsedType& ids) const override {return val->UsedIdents(ids);} // Own functions bool Exist() const {return 0!=val.get();} ObjectBase* Get(const std::string& gname) const { if(gname==name) return val->Copy(); else return 0; } std::string Name() const {return name;} void SetPair(const std::string& n, ObjectBase* v) {if(!Exist()) {name=n; val.reset(v);}} const ObjectBase* Value() const {return val.get();} }; // Class for objects list class EXPORT ObjectList: public ObjectBase { public: typedef std::vector ListValues; private: std::shared_ptr vals; public: ObjectList() {vals.reset(new ListValues, [](ListValues* p){for(auto& i: *p) delete i; delete p;});} ObjectList(ObjectBase* o) {vals.reset(new ListValues, [](ListValues* p){for(auto& i: *p) delete i; delete p;}); PushBack(o);} ~ObjectList() {} // Pure virtual overrides ObjectBase* Copy() const override { auto ret=new ObjectList; ret->vals=vals; return ret; } bool Print() const override { if(!Exist()) return false; COUT(NORMAL)<Dump()+", "; if(vals->size()!=0) s.resize(s.length()-2); return s+")"; } ObjectBase* Evaluate(bool* err) override { ObjectBase* p; for(auto& i: *vals) { p=i->Evaluate(err); if(*err) { COUT(ERROR)<<" in list member "<Dump()<ReplaceVar(vname,ob); if(0!=p) { delete i; i=p; } } return 0; } void UsedFuncs(UsedType& funcs) const override {for(auto& i: *vals) i->UsedFuncs(funcs);} void UsedIdents(UsedType& ids) const override {for(auto& i: *vals) i->UsedIdents(ids);} // Own functions const ObjectBase* At(ListValues::size_type i) const {return (*vals)[i];} bool Exist() const {return 0!=vals->size();} ObjectBase* Get(const std::string& gname) const { ObjectBase* p; for(auto& i: *vals) { p=0; OBType pair(i); OBType list(i); if(pair) p=pair->Get(gname); else if(list) p=list->Get(gname); if(0!=p) return p; } return 0; } ListValues::size_type Size() const {return vals->size();} ObjectList* PushBack(ObjectBase* p) {vals->push_back(p); return this;} }; typedef ObjectBase* (*Func)(const ObjectList*); typedef int (*ModuleInitFunc)(const void*); extern "C" { EXPORT void RegisterFunction(const std::string& name, Func func); EXPORT int LoadModule(const std::string& name, const void* p, const std::string& modname=""); } #endif