diff --git a/C++ Bind.cpp b/C++ Bind.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8c1da16f8a803afe86f59b6975a86dbaf9879760 --- /dev/null +++ b/C++ Bind.cpp @@ -0,0 +1,87 @@ +#include +#include +#include +#include + +using namespace std; + +template +struct placeholder {}; + +template +struct select_arg +{ + decltype(auto) operator() (TArg arg, TFromOutterArgsTuple&) + { + return arg; + } +}; + +template +struct select_arg, TFromOutterArgsTuple> +{ + decltype(auto) operator() (placeholder, TFromOutterArgsTuple& args) + { + return get(args); + } +}; + +template +class binder final +{ +private: + using args = tuple; + using func = decay_t; + + func func_; + args args_; +public: + template + binder(func&& f,args&& ... a): + func_{ std::forward(f) }, + args_{ std::forward(a)... } + {} + +private: + template + decltype(auto) inv (func& f, args& a, TArgsTuple& t, index_sequence x) + { + return invoke(f, + select_arg::type, TArgsTuple>{}(get(a), t)...); + } + +public: + + template + decltype(auto) operator() (TFromOutterArgs&& ... outterArgs) + { + auto argTuple = make_tuple(std::forward(outterArgs)...); + auto seq = make_index_sequence::value>(); + return inv(func_,args_,argTuple,seq); + } +}; + +template +auto mybind(TFunc&& f, TArgs&&...args) +{ + return binder { + std::forward(f), + std::forward(args)... + }; +} + +int main() +{ + auto f = mybind( + [](int a, float b, float c) { + return a + b + c; + }, + placeholder<1>{}, + 1.5f, + placeholder<0>{}); + + const auto result = f(2.0f, 1); + cout << result << endl; + + return 0; +} \ No newline at end of file