Browse Source

Replace IS_OTYPE macros on more useful template OBType

ObjPtr
Michael Uleysky 9 years ago
parent
commit
162a18c72b
  1. 8
      include/builtin.h
  2. 29
      include/common.h
  3. 4
      include/object.h
  4. 120
      src/builtin.cpp
  5. 8
      src/globals.cpp

8
include/builtin.h

@ -12,9 +12,9 @@ template<class T>
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<T> ob(input->At(0));
OBType<ObjectString> name(input->At(1));
if(!(ob && name)) return 0;
return dynamic_cast<const T*>(ob)->Get(dynamic_cast<const ObjectString*>(name)->Value());
return ob->Get(name->Value());
}

29
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<std::string> 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<Derived>(arg))
// Using const ObjectBase* arg as const Derived*: OBType<Derived>(arg)->SomeCall()
template<class O>
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<const O*>(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 T>
class EXPORT ObjectSimple: public ObjectBase
@ -244,9 +258,10 @@ public:
for(auto& i: *vals)
{
p=0;
if(IS_OTYPE(i,ObjectPair)) p=dynamic_cast<const ObjectPair*>(i)->Get(gname);
if(0!=p) return p;
if(IS_OTYPE(i,ObjectList)) p=dynamic_cast<const ObjectList*>(i)->Get(gname);
OBType<ObjectPair> pair(i);
OBType<ObjectList> list(i);
if(pair) p=pair->Get(gname);
else if(list) p=list->Get(gname);
if(0!=p) return p;
}
return 0;

4
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<ObjectList*>(p);
if(OBType<ObjectList>(p)) args=dynamic_cast<ObjectList*>(p);
else args=new ObjectList(p);
}
OFunc(const char* t, ObjectBase* p):name(t)
{
if(IS_OTYPE(p,ObjectList)) args=dynamic_cast<ObjectList*>(p);
if(OBType<ObjectList>(p)) args=dynamic_cast<ObjectList*>(p);
else args=new ObjectList(p);
}
~OFunc() {if(args!=0) delete args;}

120
src/builtin.cpp

@ -1,28 +1,31 @@
#include <math.h>
#include "object.h"
class Val
{
double v;
public:
Val() = delete;
Val(Val&&) = delete;
Val(Val&) = delete;
Val(const OBType<ObjectInt>& i, const OBType<ObjectReal>& r) {v=r?r->Value():i->Value();}
Val(const OBType<ObjectReal>& r, const OBType<ObjectInt>& 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<ObjectInt> i1(arg1), i2(arg2);
OBType<ObjectReal> 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<const ObjectInt*>(arg1)->Value() + dynamic_cast<const ObjectInt*>(arg2)->Value());
if(i1 && i2) return new ObjectInt(i1->Value()+i2->Value());
// Real arifmetic
double r1,r2;
if(t1==tr) r1=dynamic_cast<const ObjectReal*>(arg1)->Value();
else r1=dynamic_cast<const ObjectInt*>(arg1)->Value();
if(t2==tr) r2=dynamic_cast<const ObjectReal*>(arg2)->Value();
else r2=dynamic_cast<const ObjectInt*>(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<ObjectInt> i1(arg1), i2(arg2);
OBType<ObjectReal> 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<const ObjectInt*>(arg1)->Value() - dynamic_cast<const ObjectInt*>(arg2)->Value());
if(i1 && i2) return new ObjectInt(i1->Value()-i2->Value());
// Real arifmetic
double r1,r2;
if(t1==tr) r1=dynamic_cast<const ObjectReal*>(arg1)->Value();
else r1=dynamic_cast<const ObjectInt*>(arg1)->Value();
if(t2==tr) r2=dynamic_cast<const ObjectReal*>(arg2)->Value();
else r2=dynamic_cast<const ObjectInt*>(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<ObjectInt> i1(arg1), i2(arg2);
OBType<ObjectReal> 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<const ObjectInt*>(arg1)->Value() * dynamic_cast<const ObjectInt*>(arg2)->Value());
if(i1 && i2) return new ObjectInt(i1->Value()*i2->Value());
// Real arifmetic
double r1,r2;
if(t1==tr) r1=dynamic_cast<const ObjectReal*>(arg1)->Value();
else r1=dynamic_cast<const ObjectInt*>(arg1)->Value();
if(t2==tr) r2=dynamic_cast<const ObjectReal*>(arg2)->Value();
else r2=dynamic_cast<const ObjectInt*>(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<ObjectInt> i1(arg1), i2(arg2);
OBType<ObjectReal> 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<const ObjectInt*>(arg1)->Value() / dynamic_cast<const ObjectInt*>(arg2)->Value());
if(i1 && i2) return new ObjectInt(i1->Value()/i2->Value());
// Real arifmetic
double r1,r2;
if(t1==tr) r1=dynamic_cast<const ObjectReal*>(arg1)->Value();
else r1=dynamic_cast<const ObjectInt*>(arg1)->Value();
if(t2==tr) r2=dynamic_cast<const ObjectReal*>(arg2)->Value();
else r2=dynamic_cast<const ObjectInt*>(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<ObjectInt> i1(arg1), i2(arg2);
OBType<ObjectReal> 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<const ObjectReal*>(arg1)->Value();
else r1=dynamic_cast<const ObjectInt*>(arg1)->Value();
if(t2==tr) r2=dynamic_cast<const ObjectReal*>(arg2)->Value();
else r2=dynamic_cast<const ObjectInt*>(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<ObjectInt> i(arg);
OBType<ObjectReal> r(arg);
// Integer arifmetic
if(t==ti) return new ObjectInt(-dynamic_cast<const ObjectInt*>(arg)->Value());
if(i) return new ObjectInt(-i->Value());
// Real arifmetic
if(t==tr) return new ObjectReal(-dynamic_cast<const ObjectReal*>(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<ObjectInt> i(arg);
OBType<ObjectReal> r(arg);
// Integer arifmetic
if(t==ti) return new ObjectInt(dynamic_cast<const ObjectInt*>(arg)->Value());
if(i) return new ObjectInt(i->Value());
// Real arifmetic
if(t==tr) return new ObjectReal(dynamic_cast<const ObjectReal*>(arg)->Value());
if(r) return new ObjectReal(r->Value());
return 0;
}

8
src/globals.cpp

@ -116,12 +116,9 @@ bool Save(const ObjectList* input)
}
// Check arguments types
const ObjectBase* arg1;
const ObjectString* arg2;
for(i=0;i<sz/2;i++)
{
arg1=input->At(i*2+1);
if(!IS_OTYPE(arg1,ObjectString))
if(!OBType<ObjectString>(input->At(i*2+1)))
{
COUT(ERROR)<<"Save format is save(object_1,file_1,...,object_n,file_n) where file_i is string"<<std::endl;
return false;
@ -129,10 +126,11 @@ bool Save(const ObjectList* input)
}
// Save
const ObjectBase* arg1;
for(i=0;i<sz/2;i++)
{
arg1=input->At(i*2);
arg2=dynamic_cast<const ObjectString*>(input->At(i*2+1));
OBType<ObjectString> arg2(input->At(i*2+1));
if(!arg1->Save(arg2->Value().c_str()))
{
COUT(ERROR)<<"Can't save object "<<arg1->Dump()<<" to file "<<arg2->Value()<<std::endl;

Loading…
Cancel
Save