|
|
@ -18,6 +18,94 @@ EXPORT std::ostream& COUT(debug_level dl); |
|
|
|
|
|
|
|
|
|
|
|
typedef std::set<std::string> UsedType; |
|
|
|
typedef std::set<std::string> UsedType; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class EXPORT ObjectBase; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 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 checking and using several ObjectBase derivative classes
|
|
|
|
|
|
|
|
// Func is template of class-function template argument of which can be any of Derived classes.
|
|
|
|
|
|
|
|
// It must have at least one argument - pointer to constant object of Derived class and return non-void.
|
|
|
|
|
|
|
|
// Checking if arg is pointer on any of Derived classes: if(OBType<Func,Derived>(arg))
|
|
|
|
|
|
|
|
// Applying Func can be done by two ways:
|
|
|
|
|
|
|
|
// 1) Function bool Apply(Res& res, args...). Here res is result of calling Func with arguments args. Result of Func is statically casted to type Res.
|
|
|
|
|
|
|
|
// If arg is not a pointer on any of Derived classes, Apply() return false and res is not changed.
|
|
|
|
|
|
|
|
// 2) Overloaded operator ()(args). It returns result of calling Func with arguments args. Type of returning value is type of Func<Derived1>().
|
|
|
|
|
|
|
|
// Full definition. Never instantiated.
|
|
|
|
|
|
|
|
template<template<typename> class Func, class... O> |
|
|
|
|
|
|
|
class OBTypeM; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Recursive partial instantiation
|
|
|
|
|
|
|
|
template<template<typename> class Func, class O1, class... O> |
|
|
|
|
|
|
|
class OBTypeM<Func,O1,O...>: public OBTypeM<Func,O...> |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
bool right; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
OBTypeM() = delete; |
|
|
|
|
|
|
|
OBTypeM(OBTypeM&&) = delete; |
|
|
|
|
|
|
|
OBTypeM(OBTypeM&) = delete; |
|
|
|
|
|
|
|
protected: |
|
|
|
|
|
|
|
const ObjectBase* P() const {return OBTypeM<Func,O...>::P();} |
|
|
|
|
|
|
|
template<class Res, class... Args> |
|
|
|
|
|
|
|
Res F(Args... args) const |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if(right) return Func<O1>()(dynamic_cast<const O1*>(OBTypeM<Func,O...>::P()),args...); |
|
|
|
|
|
|
|
else return OBTypeM<Func,O...>::template F<Res,Args...>(args...); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
public: |
|
|
|
|
|
|
|
OBTypeM(const ObjectBase* arg):OBTypeM<Func,O...>(arg) {right=(typeid(*arg)==typeid(O1));} |
|
|
|
|
|
|
|
operator bool() const {return right || OBTypeM<Func,O...>::operator bool();} |
|
|
|
|
|
|
|
template<class Res, class... Args> |
|
|
|
|
|
|
|
bool Apply(Res& res, Args... args) const |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if(!right) return OBTypeM<Func,O...>::Apply(res,args...); |
|
|
|
|
|
|
|
res=static_cast<Res>(Func<O1>()(dynamic_cast<const O1*>(OBTypeM<Func,O...>::P()),args...)); |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
template<class... Args> |
|
|
|
|
|
|
|
auto operator ()(Args... args) -> decltype(Func<O1>()(dynamic_cast<const O1*>(this->P()),args...)) const |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
typedef decltype(Func<O1>()(dynamic_cast<const O1*>(this->P()),args...)) T; |
|
|
|
|
|
|
|
if(right) return Func<O1>()(dynamic_cast<const O1*>(OBTypeM<Func,O...>::P()),args...); |
|
|
|
|
|
|
|
else return OBTypeM<Func,O...>::template F<T,Args...>(args...); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Partial instantiation of the bottom of recursion
|
|
|
|
|
|
|
|
template<template<typename> class Func> |
|
|
|
|
|
|
|
class OBTypeM<Func> |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
const ObjectBase* p; // We save pointer on bottom
|
|
|
|
|
|
|
|
OBTypeM() = delete; |
|
|
|
|
|
|
|
OBTypeM(OBTypeM&&) = delete; |
|
|
|
|
|
|
|
OBTypeM(OBTypeM&) = delete; |
|
|
|
|
|
|
|
protected: // Only protected functions because such objects must never exists in the wild.
|
|
|
|
|
|
|
|
OBTypeM(const ObjectBase* arg):p(arg) {} |
|
|
|
|
|
|
|
operator bool() const {return false;} // If we go down to this place, p is not an pointer on appropriate type
|
|
|
|
|
|
|
|
const ObjectBase* P() const {return p;} |
|
|
|
|
|
|
|
template<class Res, class... Args> |
|
|
|
|
|
|
|
bool Apply(Res& res, Args... args) const {return false;} |
|
|
|
|
|
|
|
template<class... Args> |
|
|
|
|
|
|
|
void operator ()(Args... args) const {} |
|
|
|
|
|
|
|
template<class Res, class... Args> |
|
|
|
|
|
|
|
Res F(Args... args) const {return Res();} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Base class for all objects
|
|
|
|
// Base class for all objects
|
|
|
|
class EXPORT ObjectBase |
|
|
|
class EXPORT ObjectBase |
|
|
|
{ |
|
|
|
{ |
|
|
@ -45,23 +133,6 @@ public: |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 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 for objects without specific constructor/destructor
|
|
|
|
template<class T> |
|
|
|
template<class T> |
|
|
|
class EXPORT ObjectSimple: public ObjectBase |
|
|
|
class EXPORT ObjectSimple: public ObjectBase |
|
|
|