diff --git a/include/builtin.h b/include/builtin.h index 64f3960..5e42a47 100644 --- a/include/builtin.h +++ b/include/builtin.h @@ -12,9 +12,9 @@ template ObjectBase* Get(const ObjectList* input) { if(input->Size()!=2) return 0; - const ObjectBase* ob=input->At(0); - const ObjectBase* name=input->At(1); - if( (!IS_OTYPE(ob,T)) || (!IS_OTYPE(name,ObjectString)) ) return 0; + OBType ob(input->At(0)); + OBType name(input->At(1)); + if(!(ob && name)) return 0; - return dynamic_cast(ob)->Get(dynamic_cast(name)->Value()); + return ob->Get(name->Value()); } diff --git a/include/common.h b/include/common.h index a931960..520096d 100644 --- a/include/common.h +++ b/include/common.h @@ -14,10 +14,6 @@ enum debug_level {INTERNALREQUEST,MOREDEBUG,DEBUG,INFO,NORMAL,WARNING,ERROR}; EXPORT std::ostream& COUT(debug_level dl); -// Check if pointer is ObjectBase derivative class -#define IS_OTYPE(quo,equ) (std::type_index(typeid(*quo))==std::type_index(typeid(equ))) -#define IS_OTYPEI(quo,equ) (std::type_index(typeid(quo))==std::type_index(typeid(equ))) - typedef std::set UsedType; // Base class for all objects @@ -46,6 +42,24 @@ public: 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 @@ -244,9 +258,10 @@ public: for(auto& i: *vals) { p=0; - if(IS_OTYPE(i,ObjectPair)) p=dynamic_cast(i)->Get(gname); - if(0!=p) return p; - if(IS_OTYPE(i,ObjectList)) p=dynamic_cast(i)->Get(gname); + 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; diff --git a/include/object.h b/include/object.h index 44ad3d3..8ced9ec 100644 --- a/include/object.h +++ b/include/object.h @@ -51,12 +51,12 @@ class OFunc: public ObjectBase public: OFunc(const std::string* t, ObjectBase* p):name(*t) { - if(IS_OTYPE(p,ObjectList)) args=dynamic_cast(p); + if(OBType(p)) args=dynamic_cast(p); else args=new ObjectList(p); } OFunc(const char* t, ObjectBase* p):name(t) { - if(IS_OTYPE(p,ObjectList)) args=dynamic_cast(p); + if(OBType(p)) args=dynamic_cast(p); else args=new ObjectList(p); } ~OFunc() {if(args!=0) delete args;} diff --git a/src/builtin.cpp b/src/builtin.cpp index df9ec0e..adabd3d 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -1,28 +1,31 @@ #include #include "object.h" +class Val +{ + double v; + public: + Val() = delete; + Val(Val&&) = delete; + Val(Val&) = delete; + Val(const OBType& i, const OBType& r) {v=r?r->Value():i->Value();} + Val(const OBType& r, const OBType& i) {v=r?r->Value():i->Value();} + operator double() const {return v;} +}; + ObjectBase* Arifm_Add(const ObjectList* input) { if(input->Size()!=2) return 0; const ObjectBase *arg1=input->At(0),*arg2=input->At(1); - std::type_index t1(typeid(*arg1)),t2(typeid(*arg2)); - std::type_index tr(typeid(ObjectReal)),ti(typeid(ObjectInt)); + OBType i1(arg1), i2(arg2); + OBType r1(arg1), r2(arg2); - if( (t1!=tr && t1!=ti) || (t2!=tr && t2!=ti) ) return 0; + if( !(i1 || r1) || !(i2 || r2) ) return 0; // Integer arifmetic - if(t1==ti && t2==ti) return new ObjectInt(dynamic_cast(arg1)->Value() + dynamic_cast(arg2)->Value()); - + if(i1 && i2) return new ObjectInt(i1->Value()+i2->Value()); // Real arifmetic - double r1,r2; - - if(t1==tr) r1=dynamic_cast(arg1)->Value(); - else r1=dynamic_cast(arg1)->Value(); - - if(t2==tr) r2=dynamic_cast(arg2)->Value(); - else r2=dynamic_cast(arg2)->Value(); - - return new ObjectReal(r1+r2); + return new ObjectReal(Val(i1,r1)+Val(i2,r2)); } @@ -30,24 +33,15 @@ ObjectBase* Arifm_Sub(const ObjectList* input) { if(input->Size()!=2) return 0; const ObjectBase *arg1=input->At(0),*arg2=input->At(1); - std::type_index t1(typeid(*arg1)),t2(typeid(*arg2)); - std::type_index tr(typeid(ObjectReal)),ti(typeid(ObjectInt)); + OBType i1(arg1), i2(arg2); + OBType r1(arg1), r2(arg2); - if( (t1!=tr && t1!=ti) || (t2!=tr && t2!=ti) ) return 0; + if( !(i1 || r1) || !(i2 || r2) ) return 0; // Integer arifmetic - if(t1==ti && t2==ti) return new ObjectInt(dynamic_cast(arg1)->Value() - dynamic_cast(arg2)->Value()); - + if(i1 && i2) return new ObjectInt(i1->Value()-i2->Value()); // Real arifmetic - double r1,r2; - - if(t1==tr) r1=dynamic_cast(arg1)->Value(); - else r1=dynamic_cast(arg1)->Value(); - - if(t2==tr) r2=dynamic_cast(arg2)->Value(); - else r2=dynamic_cast(arg2)->Value(); - - return new ObjectReal(r1-r2); + return new ObjectReal(Val(i1,r1)-Val(i2,r2)); } @@ -55,24 +49,15 @@ ObjectBase* Arifm_Mul(const ObjectList* input) { if(input->Size()!=2) return 0; const ObjectBase *arg1=input->At(0),*arg2=input->At(1); - std::type_index t1(typeid(*arg1)),t2(typeid(*arg2)); - std::type_index tr(typeid(ObjectReal)),ti(typeid(ObjectInt)); + OBType i1(arg1), i2(arg2); + OBType r1(arg1), r2(arg2); - if( (t1!=tr && t1!=ti) || (t2!=tr && t2!=ti) ) return 0; + if( !(i1 || r1) || !(i2 || r2) ) return 0; // Integer arifmetic - if(t1==ti && t2==ti) return new ObjectInt(dynamic_cast(arg1)->Value() * dynamic_cast(arg2)->Value()); - + if(i1 && i2) return new ObjectInt(i1->Value()*i2->Value()); // Real arifmetic - double r1,r2; - - if(t1==tr) r1=dynamic_cast(arg1)->Value(); - else r1=dynamic_cast(arg1)->Value(); - - if(t2==tr) r2=dynamic_cast(arg2)->Value(); - else r2=dynamic_cast(arg2)->Value(); - - return new ObjectReal(r1*r2); + return new ObjectReal(Val(i1,r1)*Val(i2,r2)); } @@ -80,24 +65,15 @@ ObjectBase* Arifm_Div(const ObjectList* input) { if(input->Size()!=2) return 0; const ObjectBase *arg1=input->At(0),*arg2=input->At(1); - std::type_index t1(typeid(*arg1)),t2(typeid(*arg2)); - std::type_index tr(typeid(ObjectReal)),ti(typeid(ObjectInt)); + OBType i1(arg1), i2(arg2); + OBType r1(arg1), r2(arg2); - if( (t1!=tr && t1!=ti) || (t2!=tr && t2!=ti) ) return 0; + if( !(i1 || r1) || !(i2 || r2) ) return 0; // Integer arifmetic - if(t1==ti && t2==ti) return new ObjectInt(dynamic_cast(arg1)->Value() / dynamic_cast(arg2)->Value()); - + if(i1 && i2) return new ObjectInt(i1->Value()/i2->Value()); // Real arifmetic - double r1,r2; - - if(t1==tr) r1=dynamic_cast(arg1)->Value(); - else r1=dynamic_cast(arg1)->Value(); - - if(t2==tr) r2=dynamic_cast(arg2)->Value(); - else r2=dynamic_cast(arg2)->Value(); - - return new ObjectReal(r1/r2); + return new ObjectReal(Val(i1,r1)/Val(i2,r2)); } @@ -105,21 +81,13 @@ ObjectBase* Arifm_Pow(const ObjectList* input) { if(input->Size()!=2) return 0; const ObjectBase *arg1=input->At(0),*arg2=input->At(1); - std::type_index t1(typeid(*arg1)),t2(typeid(*arg2)); - std::type_index tr(typeid(ObjectReal)),ti(typeid(ObjectInt)); + OBType i1(arg1), i2(arg2); + OBType r1(arg1), r2(arg2); - if( (t1!=tr && t1!=ti) || (t2!=tr && t2!=ti) ) return 0; + if( !(i1 || r1) || !(i2 || r2) ) return 0; // Only real arifmetic - double r1,r2; - - if(t1==tr) r1=dynamic_cast(arg1)->Value(); - else r1=dynamic_cast(arg1)->Value(); - - if(t2==tr) r2=dynamic_cast(arg2)->Value(); - else r2=dynamic_cast(arg2)->Value(); - - return new ObjectReal(pow(r1,r2)); + return new ObjectReal(pow(Val(i1,r1),Val(i2,r2))); } @@ -127,13 +95,13 @@ ObjectBase* Arifm_Neg(const ObjectList* input) { if(input->Size()!=1) return 0; const ObjectBase *arg=input->At(0); - std::type_index t(typeid(*arg)); - std::type_index tr(typeid(ObjectReal)),ti(typeid(ObjectInt)); + OBType i(arg); + OBType r(arg); // Integer arifmetic - if(t==ti) return new ObjectInt(-dynamic_cast(arg)->Value()); + if(i) return new ObjectInt(-i->Value()); // Real arifmetic - if(t==tr) return new ObjectReal(-dynamic_cast(arg)->Value()); + if(r) return new ObjectReal(-r->Value()); return 0; } @@ -143,13 +111,13 @@ ObjectBase* Arifm_Pos(const ObjectList* input) { if(input->Size()!=1) return 0; const ObjectBase *arg=input->At(0); - std::type_index t(typeid(*arg)); - std::type_index tr(typeid(ObjectReal)),ti(typeid(ObjectInt)); + OBType i(arg); + OBType r(arg); // Integer arifmetic - if(t==ti) return new ObjectInt(dynamic_cast(arg)->Value()); + if(i) return new ObjectInt(i->Value()); // Real arifmetic - if(t==tr) return new ObjectReal(dynamic_cast(arg)->Value()); + if(r) return new ObjectReal(r->Value()); return 0; } diff --git a/src/globals.cpp b/src/globals.cpp index a13a03a..1cd0002 100644 --- a/src/globals.cpp +++ b/src/globals.cpp @@ -116,12 +116,9 @@ bool Save(const ObjectList* input) } // Check arguments types - const ObjectBase* arg1; - const ObjectString* arg2; for(i=0;iAt(i*2+1); - if(!IS_OTYPE(arg1,ObjectString)) + if(!OBType(input->At(i*2+1))) { COUT(ERROR)<<"Save format is save(object_1,file_1,...,object_n,file_n) where file_i is string"<At(i*2); - arg2=dynamic_cast(input->At(i*2+1)); + OBType arg2(input->At(i*2+1)); if(!arg1->Save(arg2->Value().c_str())) { COUT(ERROR)<<"Can't save object "<Dump()<<" to file "<Value()<