Notes-10:lua binder另一只轮子成员函数

来源:互联网 发布:布料淘宝 编辑:程序博客网 时间:2024/05/29 19:59
#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_getparamtemplate<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_getparamtemplate<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_wftemplate<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_extrparamtemplate<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_extrparamtemplate<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_wftemplate<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