#include <iostream>
#include <functional>
#include <queue>
using namespace std;
using namespace std::placeholders;
/*============================================================================
*
============================================================================*/
template<class R, class...A> struct xLB_caller {};
template<class R, class...A>
struct xLB_caller<R (*)(A...)> {
using function_t = R (*)(A...);
using return_t = R;
function_t __final;
xLB_caller(function_t _final) : __final(_final) {
__values.push(999);
__values.push(333);
__values.push(111);
}
std::queue<int> __values;
template<class T>void loadarg(T& __v) {
__v = __values.front();
__values.pop();
}
};
template<class R, class S, class...A>
struct xLB_caller<R (S::*)(A...)> {
using function_t = R (S::*)(A...);
using return_t = R;
function_t __final;
xLB_caller(function_t _final) : __final(_final) {
__values.push(110);
}
std::queue<int> __values;
template<class T>void loadarg(T& __v) {
__v = __values.front();
__values.pop();
}
S* loadobj() { return &__values; }
};
template<int N, class caller_t, class...A> struct xLB_getparam{};
template<class caller_t, class...A>
struct xLB_getparam<0, caller_t, A...> {
using return_t = typename caller_t::return_t;
caller_t* __caller;
xLB_getparam(caller_t* _caller) : __caller(_caller) {}
void depart(){ /* N==0 no more param for getting */ };
template<class...VA> return_t part(VA..._args) {
return __caller->__final(_args...);
}
}; // end of xLB_getparam
template<int N, class caller_t, class T, class ...A>
struct xLB_getparam<N, caller_t, T, A...> {
using next_t = xLB_getparam<N-1, caller_t, A...>;
using return_t = typename caller_t::return_t;
caller_t* __caller;
next_t __next;
T __arg;
xLB_getparam(caller_t* _caller) : __caller(_caller), __next(_caller) {}
void depart() {
__caller->loadarg(__arg);
__next.depart();
}
template<class...VA> return_t part(VA...__args) {
return __next.part(__args..., __arg);
}
return_t part(){ return __next.part(__arg); }
}; // end of xLB_getparam
template<class R> struct xLB_wf{};
template<class R, class ...A>
struct xLB_wf<R (*)(A...) > {
using function_t = R(*)(A...);
using caller_t = xLB_caller<R (*)(A...)>;
using geter_t = xLB_getparam<sizeof...(A), caller_t, A...>;
caller_t __caller;
geter_t __g;
xLB_wf(function_t _realfunc) : __caller(_realfunc), __g(&__caller) {}
R operator()() { __g.depart(); return __g.part(); }
}; // end of xLB_wf
template<int N, class caller_t, class...A> struct xLB_extrparam{};
template<class caller_t, class S, class...A>
struct xLB_extrparam<0, caller_t, S, A...> {
using return_t = typename caller_t::return_t;
caller_t* __caller;
xLB_extrparam(caller_t* _caller) : __caller(_caller) {}
void depart(){ /* N==0 no more param for getting */ };
S* depart_obj() { return __caller->loadobj(); }
template<class...VA> return_t part(S* _obj, VA..._args) {
return (_obj->*__caller->__final)(_args...);
}
}; // end of xLB_extrparam
template<int N, class caller_t, class S, class T, class ...A>
struct xLB_extrparam<N, caller_t, S, T, A...> {
using next_t = xLB_getparam<N-1, caller_t, S, A...>;
using return_t = typename caller_t::return_t;
caller_t* __caller;
next_t __next;
T __arg;
xLB_extrparam(caller_t* _caller) : __caller(_caller), __next(_caller) {}
void depart() {
__caller->loadarg(__arg);
__next.depart();
}
S* depart_obj() { return __caller->loadobj(); }
template<class...VA> return_t part(S* _obj, VA...__args) {
return __next.part(_obj, __args..., __arg);
}
return_t part(S* _obj){ return __next.part(_obj, __arg); }
}; // end of xLB_extrparam
template<class R, class S, class ...A>
struct xLB_wf<R (S::*)(A...) > {
using function_t = R(S::*)(A...);
using caller_t = xLB_caller<R (S::*)(A...)>;
using geter_t = xLB_extrparam<sizeof...(A), caller_t, S, A...>;
caller_t __caller;
geter_t __g;
xLB_wf(function_t _realfunc) : __caller(_realfunc), __g(&__caller) {}
R operator()() {
S* __obj = __g.depart_obj();
__g.depart();
return __g.part(__obj);
}
}; // end of xLB_wf
template<class R> struct xLB_noconst{ };
template<class R, class S, class...A>
struct xLB_noconst < R (S::*)(A...)> { using type = R(S::*)(A...); };
template<class R, class S, class...A>
struct xLB_noconst <R (S::*)(A...) const>{ using type = R(S::*)(A...); };
template<class R, class...A>
struct xLB_noconst <R (*)(A...)> { using type = R(*)(A...); };
template<class X>
auto xLB_bind(X f) -> xLB_wf<typename xLB_noconst<X>::type>{
return xLB_wf<typename xLB_noconst<X>::type>(
reinterpret_cast<typename xLB_noconst<X>::type>(f)); }
/*============================================================================
*
============================================================================*/
int x(int a, int b, int c) {
int r = a-b-c;
std::cout << "x(" << a << "," << b << "," << c << ") -> "
<< std::dec << r << std::endl;
return r;
}
int main() {
auto awx = xLB_bind(&x);
std::cout << "awx() -> " << awx() << std::endl;
auto bwx = xLB_bind(&std::queue<int>::size);
std::cout << "bwx() -> " << bwx() << std::endl;
return 0;
}
输入部分还是模拟的,输出结果:
x(999,333,111) -> 555
awx() -> 555
bwx() -> 1