#include <tuple>
#include <iostream>
#include <typeinfo>
#include <vector>
#include <iterator>
#include <algorithm>
template <class T, class... Args>
class Runnable
{
public:
void print() const
{
std::vector<std::string> names {(typeid(Args).name())...};
std::cout << typeid(T).name() << "(";
std::copy(names.begin(), names.end(), std::ostream_iterator<std::string>(std::cout, ", "));
std::cout << ")\n";
};
};
/** PackDiff:
* Template Metafunction to deduce the difference of two parameter packs.
* To distinguish two packs we have to brace them in two tuples
*/
template <class Tup1, class Tup2> struct PackDiff;
/** Basic algorithm: (T, X1...) - (T, X2...) = (X1...) - (X2...) */
template <class T, class... Pack1, class... Pack2>
struct PackDiff<std::tuple<T, Pack1...>, std::tuple<T, Pack2...>>
: PackDiff<std::tuple<Pack1...>, std::tuple<Pack2...>> {};
/** End of recursion: (X1...) - () = (X1...) */
template <class... Pack1>
struct PackDiff<std::tuple<Pack1...>, std::tuple<>>
{
typedef std::tuple<Pack1...> type;
};
/** Mismatch: (T, X1...) - (U, X2...) is undefined */
template <class T1, class... Pack1, class T2, class... Pack2>
struct PackDiff<std::tuple<T1, Pack1...>, std::tuple<T2, Pack2...>>
{ typedef struct PACK_MISMATCH {} type; };
/** Rest: () - (X2...) is undefined */
template <class... Pack2>
struct PackDiff<std::tuple<>, std::tuple<Pack2...>>
{ typedef struct LEFT_PACK_TOO_SHORT{} type; };
//make Runnable Type of T and a diff tuple:
template <class T, class Tup1>
struct MakeRunnableType;
template <class T, class... Pack>
struct MakeRunnableType<T, std::tuple<Pack...>>
{
typedef Runnable<T, Pack...> type;
};
template<typename... AllArgs, typename T, typename... SomeArgs>
auto makeRunnable(T (*FunctionType)(AllArgs...), SomeArgs... ct_args)
-> typename MakeRunnableType<T, typename PackDiff<std::tuple<AllArgs...>, std::tuple<SomeArgs...>>::type>::type*
{
typedef typename PackDiff<std::tuple<AllArgs...>, std::tuple<SomeArgs...>>::type PackDiff_t;
typedef typename MakeRunnableType<T, PackDiff_t>::type ReturnType;
return new ReturnType();
}
int print_function(char arg1, int arg2, const char* arg3) { return 0; };
int main()
{
auto f = makeRunnable(&print_function, 'C', -3);
f-> print();
delete f;
auto f2 = makeRunnable(&print_function, 'C');
f2-> print();
delete f2;
}
I2luY2x1ZGUgPHR1cGxlPgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDx0eXBlaW5mbz4KI2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPGl0ZXJhdG9yPgojaW5jbHVkZSA8YWxnb3JpdGhtPgoKCnRlbXBsYXRlIDxjbGFzcyBULCBjbGFzcy4uLiBBcmdzPgpjbGFzcyBSdW5uYWJsZQp7CnB1YmxpYzogICAgCiAgdm9pZCBwcmludCgpIGNvbnN0CiAgewogICAgc3RkOjp2ZWN0b3I8c3RkOjpzdHJpbmc+IG5hbWVzIHsodHlwZWlkKEFyZ3MpLm5hbWUoKSkuLi59OwogICAgc3RkOjpjb3V0IDw8IHR5cGVpZChUKS5uYW1lKCkgPDwgIigiOwogICAgc3RkOjpjb3B5KG5hbWVzLmJlZ2luKCksIG5hbWVzLmVuZCgpLCBzdGQ6Om9zdHJlYW1faXRlcmF0b3I8c3RkOjpzdHJpbmc+KHN0ZDo6Y291dCwgIiwgIikpOwogICAgc3RkOjpjb3V0IDw8ICIpXG4iOwogIH07ICAKfTsKCi8qKiBQYWNrRGlmZjogCiAqICBUZW1wbGF0ZSBNZXRhZnVuY3Rpb24gdG8gZGVkdWNlIHRoZSBkaWZmZXJlbmNlIG9mIHR3byBwYXJhbWV0ZXIgcGFja3MuCiAqICBUbyBkaXN0aW5ndWlzaCB0d28gcGFja3Mgd2UgaGF2ZSB0byBicmFjZSB0aGVtIGluIHR3byB0dXBsZXMKICovCnRlbXBsYXRlIDxjbGFzcyBUdXAxLCBjbGFzcyBUdXAyPiBzdHJ1Y3QgUGFja0RpZmY7CgovKiogQmFzaWMgYWxnb3JpdGhtOiAoVCwgWDEuLi4pIC0gKFQsIFgyLi4uKSA9IChYMS4uLikgLSAoWDIuLi4pICovCnRlbXBsYXRlIDxjbGFzcyBULCBjbGFzcy4uLiBQYWNrMSwgY2xhc3MuLi4gUGFjazI+CnN0cnVjdCBQYWNrRGlmZjxzdGQ6OnR1cGxlPFQsIFBhY2sxLi4uPiwgc3RkOjp0dXBsZTxULCBQYWNrMi4uLj4+CiAgOiBQYWNrRGlmZjxzdGQ6OnR1cGxlPFBhY2sxLi4uPiwgc3RkOjp0dXBsZTxQYWNrMi4uLj4+IHt9OwoKLyoqIEVuZCBvZiByZWN1cnNpb246IChYMS4uLikgLSAoKSA9IChYMS4uLikgKi8KdGVtcGxhdGUgPGNsYXNzLi4uIFBhY2sxPgpzdHJ1Y3QgUGFja0RpZmY8c3RkOjp0dXBsZTxQYWNrMS4uLj4sIHN0ZDo6dHVwbGU8Pj4KewogIHR5cGVkZWYgc3RkOjp0dXBsZTxQYWNrMS4uLj4gdHlwZTsKfTsKCi8qKiBNaXNtYXRjaDogKFQsIFgxLi4uKSAtIChVLCBYMi4uLikgaXMgdW5kZWZpbmVkICovCnRlbXBsYXRlIDxjbGFzcyBUMSwgY2xhc3MuLi4gUGFjazEsIGNsYXNzIFQyLCBjbGFzcy4uLiBQYWNrMj4Kc3RydWN0IFBhY2tEaWZmPHN0ZDo6dHVwbGU8VDEsIFBhY2sxLi4uPiwgc3RkOjp0dXBsZTxUMiwgUGFjazIuLi4+Pgp7IHR5cGVkZWYgc3RydWN0IFBBQ0tfTUlTTUFUQ0gge30gdHlwZTsgfTsKCi8qKiBSZXN0OiAoKSAtIChYMi4uLikgaXMgdW5kZWZpbmVkICovICAKdGVtcGxhdGUgPGNsYXNzLi4uIFBhY2syPgpzdHJ1Y3QgUGFja0RpZmY8c3RkOjp0dXBsZTw+LCBzdGQ6OnR1cGxlPFBhY2syLi4uPj4KeyB0eXBlZGVmIHN0cnVjdCBMRUZUX1BBQ0tfVE9PX1NIT1JUe30gdHlwZTsgfTsKCgoKLy9tYWtlIFJ1bm5hYmxlIFR5cGUgb2YgVCBhbmQgYSBkaWZmIHR1cGxlOgp0ZW1wbGF0ZSA8Y2xhc3MgVCwgY2xhc3MgVHVwMT4Kc3RydWN0IE1ha2VSdW5uYWJsZVR5cGU7Cgp0ZW1wbGF0ZSA8Y2xhc3MgVCwgY2xhc3MuLi4gUGFjaz4Kc3RydWN0IE1ha2VSdW5uYWJsZVR5cGU8VCwgc3RkOjp0dXBsZTxQYWNrLi4uPj4KewogIHR5cGVkZWYgUnVubmFibGU8VCwgUGFjay4uLj4gdHlwZTsKfTsKCgp0ZW1wbGF0ZTx0eXBlbmFtZS4uLiBBbGxBcmdzLCB0eXBlbmFtZSBULCB0eXBlbmFtZS4uLiBTb21lQXJncz4gCmF1dG8gbWFrZVJ1bm5hYmxlKFQgKCpGdW5jdGlvblR5cGUpKEFsbEFyZ3MuLi4pLCBTb21lQXJncy4uLiBjdF9hcmdzKQogIC0+IHR5cGVuYW1lIE1ha2VSdW5uYWJsZVR5cGU8VCwgdHlwZW5hbWUgUGFja0RpZmY8c3RkOjp0dXBsZTxBbGxBcmdzLi4uPiwgc3RkOjp0dXBsZTxTb21lQXJncy4uLj4+Ojp0eXBlPjo6dHlwZSoKewogIHR5cGVkZWYgdHlwZW5hbWUgUGFja0RpZmY8c3RkOjp0dXBsZTxBbGxBcmdzLi4uPiwgc3RkOjp0dXBsZTxTb21lQXJncy4uLj4+Ojp0eXBlIFBhY2tEaWZmX3Q7CiAgdHlwZWRlZiB0eXBlbmFtZSBNYWtlUnVubmFibGVUeXBlPFQsIFBhY2tEaWZmX3Q+Ojp0eXBlIFJldHVyblR5cGU7CiAgcmV0dXJuIG5ldyBSZXR1cm5UeXBlKCk7Cn0KCmludCBwcmludF9mdW5jdGlvbihjaGFyIGFyZzEsIGludCBhcmcyLCBjb25zdCBjaGFyKiBhcmczKSB7IHJldHVybiAwOyB9OwoKaW50IG1haW4oKQp7CiAgYXV0byBmID0gbWFrZVJ1bm5hYmxlKCZwcmludF9mdW5jdGlvbiwgJ0MnLCAtMyk7CiAgZi0+IHByaW50KCk7CiAgZGVsZXRlIGY7CiAgYXV0byBmMiA9IG1ha2VSdW5uYWJsZSgmcHJpbnRfZnVuY3Rpb24sICdDJyk7CiAgZjItPiBwcmludCgpOwogIGRlbGV0ZSBmMjsKfQ==