#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
struct Obj {
Obj(int o) : obj(o) {}
Obj(const Obj& o):obj(o.obj){}
Obj(Obj&& o) {
obj = o.obj;
o.obj = 0;
}
int obj;
};
template <typename Dst, typename Src>
Dst union_cast(Src s) {
union {
Src ss;
Dst dd;
};
ss = s;
return dd;
}
class Base{
public :
Base(){
}
virtual Base* type() = 0;
virtual ~Base(){
}
};
template<typename Ret,typename...Args>
class Derived : public Base{
public :
function<Ret(Args...)> fun ;
uint64_t add_fun;
public :
Derived(function<Ret(Args...)> f,u_int64_t add_fun):fun(f),add_fun(add_fun){
}
Base* type(){
return this;
}
~Derived(){
}
};
class function_factory{
private:
map<string,list<unique_ptr<Base> > > mslu;
public :
function_factory() = default;
template<typename Ret,class C,typename... Args>
bool register_function(const string& k,Ret (C::*f)(Args...args),C *obj){
u_int64_t add_fun = union_cast<u_int64_t>(f);
auto fun = [f,obj](Args...args)->Ret {
return (obj->*f)(args...);
};
if(mslu[k].size() == 0){
mslu[k].push_front(unique_ptr<Base>(new Derived<Ret,Args...>(fun,add_fun)));
}else{
list<unique_ptr<Base> >::iterator it = mslu[k].begin();
for(;it != mslu[k].end();it++){
Derived<int,Args...> *d = (reinterpret_cast<Derived<int,Args...>* >(it->get()));
if(add_fun == d->add_fun){
cout << "failed to register the function!!!" << endl;
return false;
}
}
mslu[k].push_front(unique_ptr<Base>(new Derived<Ret,Args...>(fun,add_fun)));
}
cout << k << ":success to register function..." << endl;
return true;
}
template <int a,typename Fun,typename Head,typename...Args>
struct Count {
static inline int Run(Fun fun,Head head,Args...args){
return Count<a-1,Fun,Head,Args...>::Run(fun,args...,head);
}
};
template <typename Fun,typename Head,typename...Args>
struct Count<0,Fun,Head,Args...> {
static inline int Run(Fun fun,Head head,Args...args){
return fun(head,args...);
}
};
template<typename FUNC,typename HEAD,typename...Args>
int deal(FUNC func,HEAD&& head,Args&&...args){
return Count<sizeof...(args)+1,FUNC,HEAD,Args...>::Run(func,head,args...);
}
template<typename...Args>
vector<int> call(const string k,Args&&...args){
vector<int> v;
list<unique_ptr<Base> >::iterator it = mslu[k].begin();
cout << k <<" size:" << mslu[k].size() << endl;
for(;it != mslu[k].end();it++){
if(typeid(*(*it)->type()) != typeid(Derived<int,Args...>)){
}
Derived<int,Args...> * d = (reinterpret_cast<Derived<int,Args...> *>(it->get()));
v.push_back(deal(d->fun,forward<Args>(args)...));
}
return v;
}
};
struct A {
int add(int a,int b){
return a + b;
}
};
struct B{
int mutiply(int a,int b,int c){
return a * b * c;
}
};
struct C{
int value(Obj& o){
return o.obj;
}
};
struct D{
int value(Obj& o) {
o.obj = 3;
return o.obj;
}
};
int main(){
function_factory fac;
A aa;
C cc;
D dd;
fac.register_function<int,A>("add",&A::add,&aa);
fac.register_function<int,A>("add",&A::add,&aa);
fac.register_function<int,C>("value",&C::value,&cc);
fac.register_function<int,D>("value",&D::value,&dd);
cout << "******************************" << endl;
try{
int a = 2;
const int b = 2;
Obj obj1(1);
vector<int> v = fac.call<>("value",Obj(1));
fac.call<>("value", obj1);
cout << "++++++++++++++++++++ " << obj1.obj << endl;
vector<int> v1 = fac.call<>("add",1,3);
cout << "--------------------" << endl;
cout << "add" << endl;
cout << v1.at(0) << endl;
cout << "--------------------" << endl;
cout << "value" << endl;
cout << v.front() << endl;
cout << v.at(1) << endl;
cout << "--------------------" << endl;
}catch(string& s){
cout << s << endl;
}catch(...){
cout << "failed" << endl;
}
cout << "*************************" << endl;
return 0;
}