Created
March 20, 2014 10:30
-
-
Save Enelar/9660991 to your computer and use it in GitHub Desktop.
With this gist you could get array of object overloaded methods(lambda+circuit) by its names. For simple example i support only constructors, but i hope you realize `what you should change` to get every function you want.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <functional> | |
#include <iostream> | |
using namespace std; | |
struct objT | |
{ | |
}; | |
struct a : objT | |
{ | |
a() | |
{ | |
cout << "A void" << endl; | |
} | |
a(int b) | |
{ | |
cout << "A " << b << endl; | |
} | |
}; | |
struct b : objT | |
{ | |
b() | |
{ | |
cout << "B void" << endl; | |
} | |
b(int b) | |
{ | |
cout << "B " << b << endl; | |
} | |
}; | |
template<class ConstructingObjectT> | |
struct constructor | |
{ | |
template<typename... _Args> | |
static ConstructingObjectT *construct(_Args &&...arg) | |
{ | |
return new ConstructingObjectT(forward<_Args>(arg)...); | |
} | |
template<typename... _Args> | |
static function<ConstructingObjectT *(_Args&&...)> GetConstructMethod() | |
{ | |
auto F = [](_Args&&... arg) | |
{ | |
return construct(forward<_Args>(arg)...); | |
}; | |
return F; | |
} | |
template<typename Parent, typename... _Args> | |
static function<Parent *(_Args&&...)> ParentConstruct() | |
{ | |
return GetConstructMethod<_Args...>(); | |
} | |
}; | |
#include <tuple> | |
#include <deque> | |
template<class Parent, class Tuple, int level = -1> | |
struct fabric | |
{ | |
template<typename... _Args> | |
static Parent *Make(int id, _Args&&...args) | |
{ | |
if (level != id + 1) | |
return fabric<Parent, Tuple, level - 1>::Make(id, forward<_Args>(args)...); | |
return ThisMaker(forward<_Args>(args)...); | |
} | |
template<typename... _Args> | |
static Parent *ThisMaker(_Args &&...args) | |
{ | |
auto f = FunctorThisMaker<_Args...>(); | |
return f(forward<_Args>(args)...); | |
} | |
template<typename... _Args> | |
static function<Parent *(_Args &&...)> FunctorThisMaker() | |
{ | |
typedef typename tuple_element<level - 1, Tuple>::type selected_type; | |
auto ret = constructor<selected_type>::ParentConstruct<Parent, _Args...>(); | |
return ret; | |
} | |
template<typename... _Args> | |
static deque<function<Parent *(_Args &&...)>> GetFunctors() | |
{ | |
auto ret = fabric<Parent, Tuple, level - 1>::GetFunctors<_Args...>(); | |
ret.push_back(FunctorThisMaker<_Args...>()); | |
return ret; | |
} | |
}; | |
template<class Parent, class Tuple> | |
struct fabric<Parent, Tuple, -1> | |
{ | |
static const int size = tuple_size<Tuple>::value; | |
template<typename... _Args> | |
static Parent *Make(int id, _Args&&...args) | |
{ | |
return fabric<Parent, Tuple, size>::Make<_Args...>(id, forward<_Args>(args)...); | |
} | |
template<typename... _Args> | |
static deque<function<Parent *(_Args &&...)>> GetFunctors() | |
{ | |
return fabric<Parent, Tuple, size>::GetFunctors<_Args...>(); | |
} | |
}; | |
template<class Parent, class Tuple> | |
struct fabric<Parent, Tuple, 0> | |
{ | |
template<typename... _Args> | |
static Parent *Make(int id, _Args&&...args) | |
{ | |
throw "OUT OF FABRIC RANGE"; | |
} | |
template<typename... _Args> | |
static deque<function<Parent *(_Args &&...)>> GetFunctors() | |
{ | |
return{}; | |
} | |
}; | |
int main() | |
{ | |
// пример разрешения конструктора для конкретного типа | |
auto f1 = constructor<a>::GetConstructMethod<int>(); | |
auto f2 = constructor<a>::GetConstructMethod<>(); | |
f1(6); | |
f2(); | |
typedef tuple<a, b> types; | |
typedef fabric<objT, types> example; | |
// пример рекурсивного разрешения конструктора для типа по номеру | |
example::Make(0, 5); | |
example::Make(1, 5); | |
example::Make(0); | |
example::Make(1); | |
// пример динамического(константного) разрешения конструктора | |
auto void_constructors = example::GetFunctors<>(); | |
void_constructors[0](); | |
void_constructors[1](); | |
auto int_constructors = example::GetFunctors<int>(); | |
int_constructors[0](2); | |
int_constructors[1](3); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment